sip-connector 16.2.0 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +128 -45
  2. package/dist/@SipConnector-CFYT0HQB.cjs +1 -0
  3. package/dist/{@SipConnector-D1YBDd7g.js → @SipConnector-UTHCoMXw.js} +880 -800
  4. package/dist/ApiManager/__tests-utils__/helpers.d.ts +2 -4
  5. package/dist/ApiManager/constants.d.ts +1 -2
  6. package/dist/ApiManager/eventNames.d.ts +1 -2
  7. package/dist/ApiManager/index.d.ts +1 -0
  8. package/dist/CallManager/@CallManager.d.ts +7 -6
  9. package/dist/CallManager/AbstractCallStrategy.d.ts +5 -1
  10. package/dist/CallManager/MCUCallStrategy.d.ts +1 -0
  11. package/dist/CallManager/eventNames.d.ts +42 -2
  12. package/dist/CallManager/index.d.ts +2 -1
  13. package/dist/CallManager/types.d.ts +5 -4
  14. package/dist/PresentationManager/types.d.ts +1 -1
  15. package/dist/SipConnector/@SipConnector.d.ts +4 -1
  16. package/dist/SipConnector/eventNames.d.ts +1 -1
  17. package/dist/SipConnectorFacade/index.d.ts +1 -1
  18. package/dist/StatsPeerConnection/index.d.ts +1 -1
  19. package/dist/TransceiverManager/@TransceiverManager.d.ts +70 -0
  20. package/dist/TransceiverManager/index.d.ts +1 -0
  21. package/dist/TransceiverManager/types.d.ts +11 -0
  22. package/dist/VideoSendingBalancer/index.d.ts +1 -1
  23. package/dist/__fixtures__/RTCPeerConnectionMock.d.ts +2 -1
  24. package/dist/__fixtures__/RTCRtpTransceiverMock.d.ts +16 -0
  25. package/dist/__fixtures__/eventNames.d.ts +1 -1
  26. package/dist/doMock.cjs +1 -1
  27. package/dist/doMock.js +166 -143
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.js +83 -83
  30. package/package.json +12 -12
  31. package/dist/@SipConnector-B5FFHZzJ.cjs +0 -1
  32. /package/dist/SipConnectorFacade/{SipConnectorFacade.d.ts → @SipConnectorFacade.d.ts} +0 -0
  33. /package/dist/StatsPeerConnection/{StatsPeerConnection.d.ts → @StatsPeerConnection.d.ts} +0 -0
  34. /package/dist/VideoSendingBalancer/{VideoSendingBalancer.d.ts → @VideoSendingBalancer.d.ts} +0 -0
package/README.md CHANGED
@@ -9,16 +9,20 @@
9
9
 
10
10
  **sip-connector** — это TypeScript SDK для интеграции WebRTC-приложений с платформой Vinteo через SIP-протокол. Библиотека построена на базе `@krivega/jssip` и предоставляет высокоуровневый API для создания полнофункциональных видеоконференций.
11
11
 
12
- ### 🚨 Breaking Changes в версии 16.0.0
13
-
14
- **Важные изменения, требующие обновления кода:**
12
+ ### 🎯 Основные возможности
15
13
 
16
- - **VideoSendingBalancer перенесен в SipConnector**: Теперь балансировка видео настраивается через конструктор `SipConnector` с параметром `videoBalancerOptions`
17
- - **Удален параметр `simulcastEncodings`**: Вместо него используется `sendEncodings` для настройки кодировок
18
- - **Автоматический запуск балансировки**: VideoSendingBalancer теперь автоматически запускается через 10 секунд после начала звонка
19
- - **Новые события балансировки**: Добавлены события `video-balancer:*` для мониторинга состояния балансировки
14
+ SDK предоставляет комплексное решение для:
20
15
 
21
- ### 🆕 Новые возможности версии 16.0.0
16
+ | Категория | Возможности |
17
+ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
18
+ | **SIP-подключения** | Регистрация на сервере (SIP REGISTER), управление сессиями |
19
+ | **WebRTC-коммуникации** | Исходящие/входящие звонки (SIP INVITE/200 OK), медиа-потоки, управление transceiver'ами, автоматический перезапуск ICE |
20
+ | **Презентации** | Отправка второго потока (screen sharing, демонстрация экрана) |
21
+ | **Системные сообщения** | DTMF, SIP INFO, синхронизация медиа-состояния |
22
+ | **Событийная архитектура** | Подписка на события платформы в реальном времени |
23
+ | **Мониторинг** | WebRTC-статистика (RTCRtpStats, ICE candidate stats) |
24
+ | **Управление конференциями** | Перемещение участников между ролями (участник/зритель) |
25
+ | **Лицензирование** | Мониторинг использования лицензий и состояния презентаций |
22
26
 
23
27
  - **Адаптивный polling**: Улучшенная система опроса для мониторинга изменений видеотреков
24
28
  - **Поддержка maxBitrate в PresentationManager**: Автоматическое управление битрейтом для презентаций
@@ -26,21 +30,9 @@
26
30
  - **Обработка смены треков**: Автоматическая адаптация балансировки при изменении видеотреков
27
31
  - **Улучшенная статистика**: Расширенные возможности сбора и анализа WebRTC статистики
28
32
  - **Автоматический перезапуск ICE**: Обработка событий `restart` от сервера с автоматическим вызовом `restartIce`
29
-
30
- ### 🎯 Основные возможности
31
-
32
- SDK предоставляет комплексное решение для:
33
-
34
- | Категория | Возможности |
35
- | ---------------------------- | ------------------------------------------------------------------------------------------ |
36
- | **SIP-подключения** | Регистрация на сервере (SIP REGISTER), управление сессиями |
37
- | **WebRTC-коммуникации** | Исходящие/входящие звонки (SIP INVITE/200 OK), медиа-потоки, автоматический перезапуск ICE |
38
- | **Презентации** | Отправка второго потока (screen sharing, демонстрация экрана) |
39
- | **Системные сообщения** | DTMF, SIP INFO, синхронизация медиа-состояния |
40
- | **Событийная архитектура** | Подписка на события платформы в реальном времени |
41
- | **Мониторинг** | WebRTC-статистика (RTCRtpStats, ICE candidate stats) |
42
- | **Управление конференциями** | Перемещение участников между ролями (участник/зритель) |
43
- | **Лицензирование** | Мониторинг использования лицензий и состояния презентаций |
33
+ - **Управление transceiver'ами**: Новый `TransceiverManager` для отслеживания и управления RTCRtpTransceiver'ами
34
+ - **Автоматическое добавление transceiver'ов**: Умное добавление презентационных transceiver'ов при событиях restart
35
+ |
44
36
 
45
37
  ### 🏗️ Архитектура
46
38
 
@@ -67,23 +59,6 @@ yarn add sip-connector
67
59
  pnpm add sip-connector
68
60
  ```
69
61
 
70
- ### 📋 Системные требования
71
-
72
- #### Обязательные зависимости
73
-
74
- | Компонент | Требование | Описание |
75
- | ------------------ | -------------------- | ------------------------------ |
76
- | `@krivega/jssip` | peer dependency | Для SIP-функциональности |
77
- | WebRTC API | Поддержка в браузере | Стандартные WebRTC возможности |
78
- | JavaScript runtime | ES2017+ | Современный синтаксис |
79
-
80
- #### Рекомендуемые зависимости
81
-
82
- | Компонент | Версия | Назначение |
83
- | ---------- | ------ | ------------------- |
84
- | TypeScript | 4.5+ | Полная типизация |
85
- | Node.js | 16+ | Сборка и разработка |
86
-
87
62
  ---
88
63
 
89
64
  ## 🎯 Быстрый старт
@@ -398,11 +373,13 @@ try {
398
373
 
399
374
  #### Автоматический перезапуск по событию сервера
400
375
 
401
- SDK автоматически обрабатывает события `restart` от сервера и инициирует перезапуск ICE-соединения:
376
+ SDK автоматически обрабатывает события `restart` от сервера и инициирует перезапуск ICE-соединения с интеллектуальным управлением transceiver'ами:
402
377
 
403
378
  ```typescript
404
379
  // SDK автоматически подписывается на события restart от ApiManager
405
- // и вызывает callManager.restartIce() при получении таких событий
380
+ // и выполняет следующие действия:
381
+ // 1. Проверяет необходимость добавления презентационного transceiver'а
382
+ // 2. Вызывает callManager.restartIce()
406
383
 
407
384
  // Мониторинг событий restart (опционально)
408
385
  sipConnector.on('api:restart', (data) => {
@@ -412,8 +389,14 @@ sipConnector.on('api:restart', (data) => {
412
389
  videoTrackCount: data.videoTrackCount,
413
390
  });
414
391
 
415
- // SDK автоматически вызовет restartIce()
392
+ // SDK автоматически:
393
+ // - Добавит презентационный transceiver если videoTrackCount === 2
394
+ // - Вызовет restartIce()
416
395
  console.log('ICE будет перезапущен автоматически');
396
+
397
+ if (data.videoTrackCount === 2) {
398
+ console.log('Может быть добавлен презентационный transceiver');
399
+ }
417
400
  });
418
401
  ```
419
402
 
@@ -429,6 +412,100 @@ sipConnector.on('api:restart', (data) => {
429
412
 
430
413
  ---
431
414
 
415
+ ## 🎛️ Управление RTCRtpTransceiver'ами
416
+
417
+ ### Обзор TransceiverManager
418
+
419
+ SDK автоматически отслеживает и управляет RTCRtpTransceiver'ами через новый класс `TransceiverManager`:
420
+
421
+ ```typescript
422
+ // Получение текущих transceiver'ов
423
+ const transceivers = sipConnector.callManager.getTransceivers();
424
+
425
+ console.log('Основной аудио transceiver:', transceivers.mainAudio);
426
+ console.log('Основной видео transceiver:', transceivers.mainVideo);
427
+ console.log('Презентационный видео transceiver:', transceivers.presentationVideo);
428
+ ```
429
+
430
+ ### Типы transceiver'ов
431
+
432
+ SDK автоматически классифицирует transceiver'ы по их `mid` значению:
433
+
434
+ | Тип transceiver'а | mid | Назначение |
435
+ | ------------------- | --- | --------------------------- |
436
+ | `mainAudio` | '0' | Основной аудио поток |
437
+ | `mainVideo` | '1' | Основной видео поток |
438
+ | `presentationVideo` | '2' | Презентационный видео поток |
439
+
440
+ ### Автоматическое добавление transceiver'ов
441
+
442
+ При получении события `restart` с `videoTrackCount === 2`, SDK автоматически добавляет презентационный transceiver если он отсутствует:
443
+
444
+ ```typescript
445
+ // SDK автоматически обрабатывает события restart
446
+ sipConnector.on('api:restart', (data) => {
447
+ if (data.videoTrackCount === 2) {
448
+ // SDK проверит наличие presentationVideo transceiver'а
449
+ // и добавит его автоматически если необходимо
450
+ console.log('Будет добавлен презентационный transceiver');
451
+ }
452
+ });
453
+ ```
454
+
455
+ ### Ручное управление transceiver'ами
456
+
457
+ ```typescript
458
+ // Добавление нового transceiver'а
459
+ try {
460
+ const audioTransceiver = await sipConnector.callManager.addTransceiver('audio', {
461
+ direction: 'sendrecv',
462
+ });
463
+
464
+ const videoTransceiver = await sipConnector.callManager.addTransceiver('video', {
465
+ direction: 'sendonly',
466
+ sendEncodings: [
467
+ { rid: 'low', maxBitrate: 500_000, scaleResolutionDownBy: 4 },
468
+ { rid: 'high', maxBitrate: 2_000_000, scaleResolutionDownBy: 1 },
469
+ ],
470
+ });
471
+
472
+ console.log('Transceiver'ы добавлены:', { audioTransceiver, videoTransceiver });
473
+ } catch (error) {
474
+ console.error('Ошибка добавления transceiver'а:', error);
475
+ }
476
+ ```
477
+
478
+ ### Мониторинг transceiver'ов
479
+
480
+ ```typescript
481
+ // Проверка состояния transceiver'ов
482
+ const checkTransceivers = () => {
483
+ const transceivers = sipConnector.callManager.getTransceivers();
484
+
485
+ console.log('Статус transceiver'ов:', {
486
+ hasAudio: transceivers.mainAudio !== undefined,
487
+ hasVideo: transceivers.mainVideo !== undefined,
488
+ hasPresentation: transceivers.presentationVideo !== undefined,
489
+ });
490
+
491
+ // Детальная информация
492
+ if (transceivers.mainVideo) {
493
+ console.log('Основное видео:', {
494
+ mid: transceivers.mainVideo.mid,
495
+ direction: transceivers.mainVideo.direction,
496
+ currentDirection: transceivers.mainVideo.currentDirection,
497
+ });
498
+ }
499
+ };
500
+
501
+ // Проверка после установки соединения
502
+ sipConnector.on('call:confirmed', () => {
503
+ checkTransceivers();
504
+ });
505
+ ```
506
+
507
+ ---
508
+
432
509
  ## 📡 События и их обработка
433
510
 
434
511
  ### Архитектура событий
@@ -494,7 +571,7 @@ const roomData = await sipConnector.wait('api:enterRoom');
494
571
  console.log('Данные комнаты:', roomData);
495
572
  ```
496
573
 
497
- ### События балансировки видео (версия 16.0.0+)
574
+ ### События балансировки видео
498
575
 
499
576
  ```typescript
500
577
  // Мониторинг автоматической балансировки видео
@@ -644,7 +721,7 @@ monitor.subscribe(videoSender, () => {
644
721
 
645
722
  ### Автоматическая балансировка
646
723
 
647
- С версии 16.0.0 `VideoSendingBalancer` интегрирован в `SipConnector` и запускается автоматически:
724
+ `VideoSendingBalancer` интегрирован в `SipConnector` и запускается автоматически:
648
725
 
649
726
  ```typescript
650
727
  const sipConnector = new SipConnector(
@@ -753,6 +830,7 @@ import {
753
830
  SipConnector, // Низкоуровневый API
754
831
  SipConnectorFacade, // Высокоуровневый фасад
755
832
  StatsPeerConnection, // Сбор статистики
833
+ TransceiverManager, // Управление transceiver'ами
756
834
  // ... другие экспорты
757
835
  } from 'sip-connector';
758
836
  ```
@@ -769,6 +847,10 @@ await facade.replaceMediaStream(mediaStream, options);
769
847
  // Получение удаленных потоков
770
848
  const streams = facade.getRemoteStreams();
771
849
 
850
+ // Управление transceiver'ами (низкоуровневый API)
851
+ const transceivers = sipConnector.callManager.getTransceivers();
852
+ await sipConnector.callManager.addTransceiver('video', { direction: 'sendrecv' });
853
+
772
854
  // Перезапуск ICE-соединения (низкоуровневый API)
773
855
  await sipConnector.callManager.restartIce(options);
774
856
  ```
@@ -791,6 +873,7 @@ import {
791
873
  type TInboundStats, // Входящая статистика
792
874
  type TOutboundStats, // Исходящая статистика
793
875
  type TRestartData, // Данные события restart
876
+ type ITransceiverStorage, // Интерфейс хранения transceiver'ов
794
877
  } from 'sip-connector';
795
878
  ```
796
879
 
@@ -0,0 +1 @@
1
+ "use strict";const O=require("events-constructor"),H=require("debug"),x=require("repeated-calls"),j=require("xstate"),Z=require("stack-promises"),me=require("@krivega/cancelable-promise"),ee=require("@krivega/timeout-requester");require("ua-parser-js");require("sequent-promises");const q="sip-connector",E=H(q),Me=()=>{H.enable(q)},pe=()=>{H.enable(`-${q}`)},Pe="Error decline with 603",ve=1006,fe=n=>typeof n=="object"&&n!==null&&"code"in n&&n.code===ve,Oe=n=>n.message===Pe;var h=(n=>(n.CONTENT_TYPE="content-type",n.CONTENT_ENTER_ROOM="x-webrtc-enter-room",n.CONTENT_USE_LICENSE="X-WEBRTC-USE-LICENSE",n.PARTICIPANT_NAME="X-WEBRTC-PARTICIPANT-NAME",n.INPUT_CHANNELS="X-WEBRTC-INPUT-CHANNELS",n.OUTPUT_CHANNELS="X-WEBRTC-OUTPUT-CHANNELS",n.MAIN_CAM="X-WEBRTC-MAINCAM",n.MIC="X-WEBRTC-MIC",n.MEDIA_SYNC="X-WEBRTC-SYNC",n.MAIN_CAM_RESOLUTION="X-WEBRTC-MAINCAM-RESOLUTION",n.MEDIA_STATE="X-WEBRTC-MEDIA-STATE",n.MEDIA_TYPE="X-Vinteo-Media-Type",n.MAIN_CAM_STATE="X-Vinteo-MainCam-State",n.MIC_STATE="X-Vinteo-Mic-State",n.CONTENT_PARTICIPANT_STATE="X-WEBRTC-PARTSTATE",n.NOTIFY="X-VINTEO-NOTIFY",n.CONTENT_ENABLE_MEDIA_DEVICE="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE",n.CONTENT_SHARE_STATE="x-webrtc-share-state",n.MUST_STOP_PRESENTATION_P2P="x-webrtc-share-state: YOUMUSTSTOPSENDCONTENT",n.START_PRESENTATION_P2P="x-webrtc-share-state: YOUCANRECEIVECONTENT",n.STOP_PRESENTATION_P2P="x-webrtc-share-state: CONTENTEND",n.STOP_PRESENTATION="x-webrtc-share-state: STOPPRESENTATION",n.START_PRESENTATION="x-webrtc-share-state: LETMESTARTPRESENTATION",n.ENABLE_MAIN_CAM="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM",n.AVAILABLE_INCOMING_BITRATE="X-WEBRTC-AVAILABLE-INCOMING-BITRATE",n.AUDIO_TRACK_COUNT="X-WEBRTC-AUDIO-TRACK-COUNT",n.VIDEO_TRACK_COUNT="X-WEBRTC-VIDEO-TRACK-COUNT",n.TRACKS_DIRECTION="X-WEBRTC-TRACKS-DIRECTION",n))(h||{}),B=(n=>(n.AVAILABLE_SECOND_REMOTE_STREAM="YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="CONTENTEND",n.MUST_STOP_PRESENTATION="YOUMUSTSTOPSENDCONTENT",n))(B||{}),$=(n=>(n.SPECTATOR="SPECTATOR",n.PARTICIPANT="PARTICIPANT",n))($||{}),v=(n=>(n.ENTER_ROOM="application/vinteo.webrtc.roomname",n.MIC="application/vinteo.webrtc.mic",n.USE_LICENSE="application/vinteo.webrtc.uselic",n.PARTICIPANT_STATE="application/vinteo.webrtc.partstate",n.NOTIFY="application/vinteo.webrtc.notify",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.RESTART="application/vinteo.webrtc.restart",n))(v||{}),M=(n=>(n.CHANNELS="application/vinteo.webrtc.channels",n.MEDIA_STATE="application/vinteo.webrtc.mediastate",n.REFUSAL="application/vinteo.webrtc.refusal",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.STATS="application/vinteo.webrtc.stats",n))(M||{}),P=(n=>(n.PAUSE_MAIN_CAM="PAUSEMAINCAM",n.RESUME_MAIN_CAM="RESUMEMAINCAM",n.MAX_MAIN_CAM_RESOLUTION="MAXMAINCAMRESOLUTION",n.ADMIN_STOP_MAIN_CAM="ADMINSTOPMAINCAM",n.ADMIN_START_MAIN_CAM="ADMINSTARTMAINCAM",n))(P||{}),V=(n=>(n.ADMIN_STOP_MIC="ADMINSTOPMIC",n.ADMIN_START_MIC="ADMINSTARTMIC",n))(V||{}),W=(n=>(n.ADMIN_SYNC_FORCED="1",n.ADMIN_SYNC_NOT_FORCED="0",n))(W||{}),te=(n=>(n.AUDIO="AUDIO",n.VIDEO="VIDEO",n.AUDIOPLUSPRESENTATION="AUDIOPLUSPRESENTATION",n))(te||{}),g=(n=>(n.CHANNELS_NOTIFY="channels:notify",n.PARTICIPANT_ADDED_TO_LIST_MODERATORS="participant:added-to-list-moderators",n.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS="participant:removed-from-list-moderators",n.PARTICIPANT_MOVE_REQUEST_TO_STREAM="participant:move-request-to-stream",n.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS="participant:move-request-to-spectators",n.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS="participant:move-request-to-participants",n.PARTICIPATION_ACCEPTING_WORD_REQUEST="participation:accepting-word-request",n.PARTICIPATION_CANCELLING_WORD_REQUEST="participation:cancelling-word-request",n.WEBCAST_STARTED="webcast:started",n.WEBCAST_STOPPED="webcast:stopped",n.ACCOUNT_CHANGED="account:changed",n.ACCOUNT_DELETED="account:deleted",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="conference:participant-token-issued",n.CHANNELS="channels",n.ENTER_ROOM="enterRoom",n.SHARE_STATE="shareState",n.MAIN_CAM_CONTROL="main-cam-control",n.USE_LICENSE="useLicense",n.ADMIN_START_MAIN_CAM="admin-start-main-cam",n.ADMIN_STOP_MAIN_CAM="admin-stop-main-cam",n.ADMIN_START_MIC="admin-start-mic",n.ADMIN_STOP_MIC="admin-stop-mic",n.ADMIN_FORCE_SYNC_MEDIA_STATE="admin-force-sync-media-state",n.AVAILABLE_SECOND_REMOTE_STREAM="availableSecondRemoteStream",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="notAvailableSecondRemoteStream",n.MUST_STOP_PRESENTATION="mustStopPresentation",n.NEW_DTMF="newDTMF",n.RESTART="restart",n))(g||{});const ne=["participation:accepting-word-request","participation:cancelling-word-request","participant:move-request-to-stream","channels:notify","conference:participant-token-issued","account:changed","account:deleted","webcast:started","webcast:stopped","participant:added-to-list-moderators","participant:removed-from-list-moderators","participant:move-request-to-spectators","participant:move-request-to-participants","channels","enterRoom","shareState","main-cam-control","useLicense","admin-start-main-cam","admin-stop-main-cam","admin-start-mic","admin-stop-mic","admin-force-sync-media-state","availableSecondRemoteStream","notAvailableSecondRemoteStream","mustStopPresentation","newDTMF","restart"];var _=(n=>(n.CHANNELS="channels",n.WEBCAST_STARTED="WebcastStarted",n.WEBCAST_STOPPED="WebcastStopped",n.ACCOUNT_CHANGED="accountChanged",n.ACCOUNT_DELETED="accountDeleted",n.ADDED_TO_LIST_MODERATORS="addedToListModerators",n.REMOVED_FROM_LIST_MODERATORS="removedFromListModerators",n.ACCEPTING_WORD_REQUEST="ParticipationRequestAccepted",n.CANCELLING_WORD_REQUEST="ParticipationRequestRejected",n.MOVE_REQUEST_TO_STREAM="ParticipantMovedToWebcast",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="ConferenceParticipantTokenIssued",n))(_||{});class De{events;connectionManager;callManager;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.callManager=t,this.events=new O.Events(ne),this.subscribe()}async waitChannels(){return this.wait(g.CHANNELS)}async waitSyncMediaState(){return this.wait(g.ADMIN_FORCE_SYNC_MEDIA_STATE)}async sendDTMF(e){return new Promise((t,s)=>{let r;try{r=this.getEstablishedRTCSessionProtected()}catch(i){s(i)}r&&(this.callManager.once("newDTMF",({originator:i})=>{i==="local"&&t()}),r.sendDTMF(e,{duration:120,interToneGap:600}))})}async sendChannels({inputChannels:e,outputChannels:t}){const s=this.getEstablishedRTCSessionProtected(),r=`${h.INPUT_CHANNELS}: ${e}`,i=`${h.OUTPUT_CHANNELS}: ${t}`,a=[r,i];return s.sendInfo(M.CHANNELS,void 0,{extraHeaders:a})}async sendMediaState({cam:e,mic:t},s={}){const r=this.getEstablishedRTCSessionProtected(),i=`${h.MEDIA_STATE}: currentstate`,a=`${h.MAIN_CAM_STATE}: ${Number(e)}`,o=`${h.MIC_STATE}: ${Number(t)}`,c=[i,a,o];return r.sendInfo(M.MEDIA_STATE,void 0,{noTerminateWhenError:!0,...s,extraHeaders:c})}async sendStats({availableIncomingBitrate:e}){const t=this.getEstablishedRTCSessionProtected(),r=[`${h.AVAILABLE_INCOMING_BITRATE}: ${e}`];return t.sendInfo(M.STATS,void 0,{noTerminateWhenError:!0,extraHeaders:r})}async sendRefusalToTurnOn(e,t={}){const s=this.getEstablishedRTCSessionProtected(),a=e==="mic"?0:1,c=[`${h.MEDIA_TYPE}: ${a}`];return s.sendInfo(M.REFUSAL,void 0,{noTerminateWhenError:!0,...t,extraHeaders:c})}async sendRefusalToTurnOnMic(e={}){return this.sendRefusalToTurnOn("mic",{noTerminateWhenError:!0,...e})}async sendRefusalToTurnOnCam(e={}){return this.sendRefusalToTurnOn("cam",{noTerminateWhenError:!0,...e})}async sendMustStopPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.MUST_STOP_PRESENTATION_P2P]})}async sendStoppedPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.STOP_PRESENTATION_P2P]})}async sendStoppedPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.STOP_PRESENTATION]})}async askPermissionToStartPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.START_PRESENTATION_P2P]})}async askPermissionToStartPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.START_PRESENTATION]})}async askPermissionToEnableCam(e={}){const t=this.getEstablishedRTCSessionProtected(),s=[h.ENABLE_MAIN_CAM];return t.sendInfo(M.MAIN_CAM,void 0,{noTerminateWhenError:!0,...e,extraHeaders:s}).catch(r=>{if(Oe(r))throw r})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}getEstablishedRTCSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};subscribe(){this.connectionManager.on("sipEvent",this.handleSipEvent),this.callManager.on("newInfo",this.handleNewInfo),this.callManager.on("newDTMF",e=>{this.events.trigger("newDTMF",e)})}handleSipEvent=({request:e})=>{this.maybeHandleNotify(e)};maybeHandleNotify=e=>{try{const t=e.getHeader(h.NOTIFY);if(t){const s=JSON.parse(t);this.handleNotify(s)}}catch(t){E("error parse notify",t)}};handleNotify=e=>{switch(e.cmd){case _.CHANNELS:{const t=e;this.triggerChannelsNotify(t);break}case _.WEBCAST_STARTED:{const t=e;this.triggerWebcastStartedNotify(t);break}case _.WEBCAST_STOPPED:{const t=e;this.triggerWebcastStoppedNotify(t);break}case _.ADDED_TO_LIST_MODERATORS:{const t=e;this.triggerAddedToListModeratorsNotify(t);break}case _.REMOVED_FROM_LIST_MODERATORS:{const t=e;this.triggerRemovedFromListModeratorsNotify(t);break}case _.ACCEPTING_WORD_REQUEST:{const t=e;this.triggerParticipationAcceptingWordRequest(t);break}case _.CANCELLING_WORD_REQUEST:{const t=e;this.triggerParticipationCancellingWordRequest(t);break}case _.MOVE_REQUEST_TO_STREAM:{const t=e;this.triggerParticipantMoveRequestToStream(t);break}case _.ACCOUNT_CHANGED:{this.triggerAccountChangedNotify();break}case _.ACCOUNT_DELETED:{this.triggerAccountDeletedNotify();break}case _.CONFERENCE_PARTICIPANT_TOKEN_ISSUED:{const t=e;this.triggerConferenceParticipantTokenIssued(t);break}default:E("unknown cmd",e)}};handleNewInfo=e=>{const{originator:t}=e;if(t!=="remote")return;const{request:s}=e,r=s,i=r.getHeader(h.CONTENT_TYPE);if(i!==void 0)switch(i){case v.ENTER_ROOM:{this.triggerEnterRoom(r),this.maybeTriggerChannels(r);break}case v.NOTIFY:{this.maybeHandleNotify(r);break}case v.SHARE_STATE:{this.triggerShareState(r);break}case v.MAIN_CAM:{this.triggerMainCamControl(r);break}case v.MIC:{this.triggerMicControl(r);break}case v.USE_LICENSE:{this.triggerUseLicense(r);break}case v.PARTICIPANT_STATE:{this.maybeTriggerParticipantMoveRequest(r);break}case v.RESTART:{this.triggerRestart(r);break}}};triggerChannelsNotify=e=>{const t=e.input,s=e.output,r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS_NOTIFY,r)};triggerWebcastStartedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STARTED,s)};triggerWebcastStoppedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STOPPED,s)};triggerAddedToListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_ADDED_TO_LIST_MODERATORS,t)};triggerRemovedFromListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS,t)};triggerParticipationAcceptingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_ACCEPTING_WORD_REQUEST,t)};triggerParticipationCancellingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_CANCELLING_WORD_REQUEST,t)};triggerParticipantMoveRequestToStream=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_STREAM,t)};triggerAccountChangedNotify=()=>{this.events.trigger(g.ACCOUNT_CHANGED,void 0)};triggerAccountDeletedNotify=()=>{this.events.trigger(g.ACCOUNT_DELETED,void 0)};triggerConferenceParticipantTokenIssued=({body:{conference:e,participant:t,jwt:s}})=>{const r={conference:e,participant:t,jwt:s};this.events.trigger(g.CONFERENCE_PARTICIPANT_TOKEN_ISSUED,r)};maybeTriggerChannels=e=>{const t=e.getHeader(h.INPUT_CHANNELS),s=e.getHeader(h.OUTPUT_CHANNELS);if(t&&s){const r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS,r)}};triggerEnterRoom=e=>{const t=e.getHeader(h.CONTENT_ENTER_ROOM),s=e.getHeader(h.PARTICIPANT_NAME);this.events.trigger(g.ENTER_ROOM,{room:t,participantName:s})};triggerShareState=e=>{const t=e.getHeader(h.CONTENT_SHARE_STATE);if(t!==void 0)switch(t){case B.AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.AVAILABLE_SECOND_REMOTE_STREAM,void 0);break}case B.NOT_AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.NOT_AVAILABLE_SECOND_REMOTE_STREAM,void 0);break}case B.MUST_STOP_PRESENTATION:{this.events.trigger(g.MUST_STOP_PRESENTATION,void 0);break}}};maybeTriggerParticipantMoveRequest=e=>{const t=e.getHeader(h.CONTENT_PARTICIPANT_STATE);t===$.SPECTATOR&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,void 0),t===$.PARTICIPANT&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS,void 0)};triggerMainCamControl=e=>{const t=e.getHeader(h.MAIN_CAM),s=e.getHeader(h.MEDIA_SYNC),r=s===W.ADMIN_SYNC_FORCED;if(t===P.ADMIN_START_MAIN_CAM){this.events.trigger(g.ADMIN_START_MAIN_CAM,{isSyncForced:r});return}if(t===P.ADMIN_STOP_MAIN_CAM){this.events.trigger(g.ADMIN_STOP_MAIN_CAM,{isSyncForced:r});return}(t===P.RESUME_MAIN_CAM||t===P.PAUSE_MAIN_CAM)&&s!==void 0&&this.events.trigger(g.ADMIN_FORCE_SYNC_MEDIA_STATE,{isSyncForced:r});const i=e.getHeader(h.MAIN_CAM_RESOLUTION);this.events.trigger(g.MAIN_CAM_CONTROL,{mainCam:t,resolutionMainCam:i})};triggerMicControl=e=>{const t=e.getHeader(h.MIC),r=e.getHeader(h.MEDIA_SYNC)===W.ADMIN_SYNC_FORCED;t===V.ADMIN_START_MIC?this.events.trigger(g.ADMIN_START_MIC,{isSyncForced:r}):t===V.ADMIN_STOP_MIC&&this.events.trigger(g.ADMIN_STOP_MIC,{isSyncForced:r})};triggerUseLicense=e=>{const t=e.getHeader(h.CONTENT_USE_LICENSE);this.events.trigger(g.USE_LICENSE,t)};triggerRestart=e=>{const t=e.getHeader(h.TRACKS_DIRECTION),s=Number(e.getHeader(h.AUDIO_TRACK_COUNT)),r=Number(e.getHeader(h.VIDEO_TRACK_COUNT)),i={tracksDirection:t,audioTrackCount:s,videoTrackCount:r};this.events.trigger(g.RESTART,i)}}var N=(n=>(n.PEER_CONNECTION="peerconnection",n.CONNECTING="connecting",n.SENDING="sending",n.PROGRESS="progress",n.ACCEPTED="accepted",n.CONFIRMED="confirmed",n.ENDED="ended",n.FAILED="failed",n.NEW_DTMF="newDTMF",n.NEW_INFO="newInfo",n.HOLD="hold",n.UNHOLD="unhold",n.MUTED="muted",n.UNMUTED="unmuted",n.REINVITE="reinvite",n.UPDATE="update",n.REFER="refer",n.REPLACES="replaces",n.SDP="sdp",n.ICE_CANDIDATE="icecandidate",n.GET_USER_MEDIA_FAILED="getusermediafailed",n.PEER_CONNECTION_CREATE_OFFER_FAILED="peerconnection:createofferfailed",n.PEER_CONNECTION_CREATE_ANSWER_FAILED="peerconnection:createanswerfailed",n.PEER_CONNECTION_SET_LOCAL_DESCRIPTION_FAILED="peerconnection:setlocaldescriptionfailed",n.PEER_CONNECTION_SET_REMOTE_DESCRIPTION_FAILED="peerconnection:setremotedescriptionfailed",n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n.PEER_CONNECTION_CONFIRMED="peerconnection:confirmed",n.PEER_CONNECTION_ONTRACK="peerconnection:ontrack",n.ENDED_FROM_SERVER="ended:fromserver",n))(N||{}),se=(n=>(n.LOCAL="local",n.REMOTE="remote",n.SYSTEM="system",n))(se||{});const re=["peerconnection","connecting","sending","progress","accepted","confirmed","ended","failed","newInfo","newDTMF","presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed","reinvite","update","refer","replaces","sdp","icecandidate","getusermediafailed","peerconnection:createofferfailed","peerconnection:createanswerfailed","peerconnection:setlocaldescriptionfailed","peerconnection:setremotedescriptionfailed"],ye=["peerconnection:confirmed","peerconnection:ontrack","ended:fromserver"],ie=[...re,...ye],be=(n,e)=>{n.getVideoTracks().forEach(s=>{"contentHint"in s&&s.contentHint!==e&&(s.contentHint=e)})},U=(n,{directionVideo:e,directionAudio:t,contentHint:s}={})=>{if(!n||e==="recvonly"&&t==="recvonly")return;const r=t==="recvonly"?[]:n.getAudioTracks(),i=e==="recvonly"?[]:n.getVideoTracks(),a=[...r,...i],o=new MediaStream(a);return o.getTracks=()=>[...o.getAudioTracks(),...o.getVideoTracks()],s&&s!=="none"&&be(o,s),o};function we(n){return e=>`sip:${e}@${n}`}const Ue=(n,e)=>()=>Math.floor(Math.random()*(e-n))+n,ae=n=>n.trim().replaceAll(" ","_"),Le=Ue(1e5,99999999),Be=n=>n.some(t=>{const{kind:s}=t;return s==="video"});class ke{isPendingCall=!1;isPendingAnswer=!1;rtcSession;remoteStreams={};events;callConfiguration={};constructor(e){this.events=e}}var G=(n=>(n.BYE="Terminated",n.WEBRTC_ERROR="WebRTC Error",n.CANCELED="Canceled",n.REQUEST_TIMEOUT="Request Timeout",n.REJECTED="Rejected",n.REDIRECTED="Redirected",n.UNAVAILABLE="Unavailable",n.NOT_FOUND="Not Found",n.ADDRESS_INCOMPLETE="Address Incomplete",n.INCOMPATIBLE_SDP="Incompatible SDP",n.BAD_MEDIA_DESCRIPTION="Bad Media Description",n))(G||{});class Fe{remoteStreams={};reset(){this.remoteStreams={}}generateStream(e,t){const{id:s}=e,r=this.remoteStreams[s]??new MediaStream;return t&&r.addTrack(t),r.addTrack(e),this.remoteStreams[s]=r,r}generateAudioStream(e){const{id:t}=e,s=this.remoteStreams[t]??new MediaStream;return s.addTrack(e),this.remoteStreams[t]=s,s}generateStreams(e){const t=[];return e.forEach((s,r)=>{if(s.kind==="audio")return;const i=s,a=e[r-1];let o;a?.kind==="audio"&&(o=a);const c=this.generateStream(i,o);t.push(c)}),t}generateAudioStreams(e){return e.map(t=>this.generateAudioStream(t))}}class $e extends ke{remoteStreamsManager=new Fe;disposers=new Set;constructor(e){super(e),e.on(N.FAILED,this.handleEnded),e.on(N.ENDED,this.handleEnded)}get requested(){return this.isPendingCall||this.isPendingAnswer}get connection(){return this.rtcSession?.connection}get isCallActive(){return this.rtcSession?.isEstablished()===!0}get establishedRTCSession(){return this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0}startCall=async(e,t,{number:s,mediaStream:r,extraHeaders:i=[],ontrack:a,iceServers:o,directionVideo:c,directionAudio:d,contentHint:u,offerToReceiveAudio:T=!0,offerToReceiveVideo:l=!0,degradationPreference:C,sendEncodings:m,onAddedTransceiver:I})=>(this.isPendingCall=!0,new Promise((R,y)=>{this.callConfiguration.number=s,this.callConfiguration.answer=!1,this.handleCall({ontrack:a}).then(R).catch(k=>{y(k)}),this.rtcSession=e.call(t(s),{mediaStream:U(r,{directionVideo:c,directionAudio:d,contentHint:u}),pcConfig:{iceServers:o},rtcOfferConstraints:{offerToReceiveAudio:T,offerToReceiveVideo:l},eventHandlers:this.events.triggers,extraHeaders:i,directionVideo:c,directionAudio:d,degradationPreference:C,sendEncodings:m,onAddedTransceiver:I})}).finally(()=>{this.isPendingCall=!1}));async endCall(){const{rtcSession:e}=this;if(e&&!e.isEnded())return e.terminateAsync({cause:G.CANCELED}).finally(()=>{this.reset()});this.reset()}answerToIncomingCall=async(e,{mediaStream:t,ontrack:s,extraHeaders:r=[],iceServers:i,directionVideo:a,directionAudio:o,offerToReceiveAudio:c,offerToReceiveVideo:d,contentHint:u,degradationPreference:T,sendEncodings:l,onAddedTransceiver:C})=>(this.isPendingAnswer=!0,new Promise((m,I)=>{try{const R=e();this.rtcSession=R,this.subscribeToSessionEvents(R),this.callConfiguration.answer=!0,this.callConfiguration.number=R.remote_identity.uri.user,this.handleCall({ontrack:s}).then(m).catch(y=>{I(y)}),R.answer({pcConfig:{iceServers:i},rtcOfferConstraints:{offerToReceiveAudio:c,offerToReceiveVideo:d},mediaStream:U(t,{directionVideo:a,directionAudio:o,contentHint:u}),extraHeaders:r,directionVideo:a,directionAudio:o,degradationPreference:T,sendEncodings:l,onAddedTransceiver:C})}catch(R){I(R)}}).finally(()=>{this.isPendingAnswer=!1}));getEstablishedRTCSession(){return this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0}getCallConfiguration(){return{...this.callConfiguration}}getRemoteStreams(){if(!this.connection)return;const t=this.connection.getReceivers().map(({track:s})=>s);return Be(t)?this.remoteStreamsManager.generateStreams(t):this.remoteStreamsManager.generateAudioStreams(t)}async replaceMediaStream(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");const{contentHint:s}=t??{},r=U(e,{contentHint:s});if(r===void 0)throw new Error("No preparedMediaStream");return this.rtcSession.replaceMediaStream(r,t)}async restartIce(e){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.restartIce(e)}async addTransceiver(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.addTransceiver(e,t)}handleCall=async({ontrack:e})=>new Promise((t,s)=>{const r=()=>{this.events.on(N.PEER_CONNECTION,u),this.events.on(N.CONFIRMED,T)},i=()=>{this.events.off(N.PEER_CONNECTION,u),this.events.off(N.CONFIRMED,T)},a=()=>{this.events.on(N.FAILED,c),this.events.on(N.ENDED,c)},o=()=>{this.events.off(N.FAILED,c),this.events.off(N.ENDED,c)},c=l=>{i(),o(),s(l)};let d;const u=({peerconnection:l})=>{d=l;const C=m=>{this.events.trigger(N.PEER_CONNECTION_ONTRACK,m),e&&e(m)};l.addEventListener("track",C),this.disposers.add(()=>{l.removeEventListener("track",C)})},T=()=>{d!==void 0&&this.events.trigger(N.PEER_CONNECTION_CONFIRMED,d),i(),o(),t(d)};r(),a()});subscribeToSessionEvents(e){this.events.eachTriggers((t,s)=>{const r=re.find(i=>i===s);r&&(e.on(r,t),this.disposers.add(()=>{e.off(r,t)}))})}unsubscribeFromSessionEvents(){this.disposers.forEach(e=>{e()}),this.disposers.clear()}handleEnded=e=>{const{originator:t}=e;t==="remote"&&this.events.trigger(N.ENDED_FROM_SERVER,e),this.reset()};reset=()=>{delete this.rtcSession,this.remoteStreamsManager.reset(),this.unsubscribeFromSessionEvents(),this.callConfiguration.number=void 0,this.callConfiguration.answer=!1}}class Ve{events;strategy;constructor(e){this.events=new O.TypedEvents(ie),this.strategy=e??new $e(this.events)}get requested(){return this.strategy.requested}get connection(){return this.strategy.connection}get establishedRTCSession(){return this.strategy.establishedRTCSession}get isCallActive(){return this.strategy.isCallActive}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}setStrategy(e){this.strategy=e}startCall=async(...e)=>this.strategy.startCall(...e);endCall=async()=>this.strategy.endCall();answerToIncomingCall=async(...e)=>this.strategy.answerToIncomingCall(...e);getEstablishedRTCSession=()=>this.strategy.getEstablishedRTCSession();getCallConfiguration=()=>this.strategy.getCallConfiguration();getRemoteStreams=()=>this.strategy.getRemoteStreams();addTransceiver=async(...e)=>this.strategy.addTransceiver(...e);replaceMediaStream=async(...e)=>this.strategy.replaceMediaStream(...e);restartIce=async e=>this.strategy.restartIce(e)}const We=(n,e)=>(n.degradationPreference=e.degradationPreference,n),He=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},oe=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,xe=oe(),qe=(n,e)=>{if(xe(n,e))return n},Ge=(n,e)=>{const t=n.maxBitrate,s=qe(e,t);return s!==void 0&&(n.maxBitrate=s),n},ce=1,Qe=oe(ce),Ye=(n,e)=>{const t=n===void 0?void 0:Math.max(n,ce);if(t!==void 0&&Qe(t,e))return t},ze=(n,e)=>{const t=n.scaleResolutionDownBy,s=Ye(e,t);return s!==void 0&&(n.scaleResolutionDownBy=s),n},Xe=(n,e)=>{const t=e.encodings?.length??0;return He(n,t),n.encodings.forEach((s,r)=>{const i=(e?.encodings??[])[r],a=i?.maxBitrate,o=i?.scaleResolutionDownBy;Ge(s,a),ze(s,o)}),n},Je=(n,e)=>{if(n.codecs?.length!==e.codecs?.length)return!0;for(let t=0;t<(n.codecs?.length??0);t++)if(JSON.stringify(n.codecs[t])!==JSON.stringify(e.codecs[t]))return!0;if(n.headerExtensions?.length!==e.headerExtensions?.length)return!0;for(let t=0;t<(n.headerExtensions?.length??0);t++)if(JSON.stringify(n.headerExtensions[t])!==JSON.stringify(e.headerExtensions[t]))return!0;if(n.encodings?.length!==e.encodings?.length)return!0;for(let t=0;t<(n.encodings?.length??0);t++)if(JSON.stringify(n.encodings[t])!==JSON.stringify(e.encodings[t]))return!0;return n.rtcp?.cname!==e.rtcp?.cname||n.rtcp?.reducedSize!==e.rtcp?.reducedSize||n.degradationPreference!==e.degradationPreference},de=async(n,e)=>{const t=n.getParameters(),s=JSON.parse(JSON.stringify(t));Xe(t,e),We(t,e);const r=Je(s,t);return r&&await n.setParameters(t),{parameters:t,isChanged:r}},Q=async(n,e,t)=>{const{isChanged:s,parameters:r}=await de(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return s&&t&&t(r),{isChanged:s,parameters:r}},Ke=(n,e)=>n.find(t=>t.track!==null&&e.getTracks().includes(t.track)),je=async(n,e,t)=>{const s=Ke(n,e);if(s)return Q(s,{maxBitrate:t})};var f=(n=>(n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n))(f||{});const he=["presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed"],Ze=1,et=n=>x.hasCanceledError(n);class tt{events;promisePendingStartPresentation;promisePendingStopPresentation;streamPresentationCurrent;maxBitrate;cancelableSendPresentationWithRepeatedCalls;callManager;constructor({callManager:e,maxBitrate:t}){this.callManager=e,this.maxBitrate=t,this.events=new O.Events(he),this.subscribe()}get isPendingPresentation(){return!!this.promisePendingStartPresentation||!!this.promisePendingStopPresentation}async startPresentation(e,t,{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a}={},o){const c=this.getRtcSessionProtected();if(this.streamPresentationCurrent)throw new Error("Presentation is already started");return this.sendPresentationWithDuplicatedCalls(e,{rtcSession:c,stream:t,presentationOptions:{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a},options:o})}async stopPresentation(e){this.cancelSendPresentationWithRepeatedCalls();const t=this.streamPresentationCurrent;let s=this.promisePendingStartPresentation??Promise.resolve(void 0);this.promisePendingStartPresentation&&await this.promisePendingStartPresentation.catch(()=>{});const r=this.callManager.getEstablishedRTCSession();return r&&t?s=e().then(async()=>r.stopPresentation(t)).catch(i=>{throw this.events.trigger(f.FAILED_PRESENTATION,i),i}):t&&this.events.trigger(f.ENDED_PRESENTATION,t),this.promisePendingStopPresentation=s,s.finally(()=>{this.resetPresentation()})}async updatePresentation(e,t,{contentHint:s,sendEncodings:r,onAddedTransceiver:i}={}){const a=this.getRtcSessionProtected();if(!this.streamPresentationCurrent)throw new Error("Presentation has not started yet");return this.promisePendingStartPresentation&&await this.promisePendingStartPresentation,this.sendPresentation(e,a,t,{contentHint:s,isNeedReinvite:!1,sendEncodings:r,onAddedTransceiver:i}).then(async o=>(await this.setMaxBitrate(),o))}cancelSendPresentationWithRepeatedCalls(){this.cancelableSendPresentationWithRepeatedCalls?.stopRepeatedCalls()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("presentation:start",e=>{this.events.trigger(f.START_PRESENTATION,e)}),this.callManager.on("presentation:started",e=>{this.events.trigger(f.STARTED_PRESENTATION,e)}),this.callManager.on("presentation:end",e=>{this.events.trigger(f.END_PRESENTATION,e)}),this.callManager.on("presentation:ended",e=>{this.events.trigger(f.ENDED_PRESENTATION,e)}),this.callManager.on("presentation:failed",e=>{this.events.trigger(f.FAILED_PRESENTATION,e)}),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded)}async sendPresentationWithDuplicatedCalls(e,{rtcSession:t,stream:s,presentationOptions:r,options:i={callLimit:Ze}}){const a=async()=>this.sendPresentation(e,t,s,r),o=()=>!!this.streamPresentationCurrent;return this.cancelableSendPresentationWithRepeatedCalls=x.repeatedCallsAsync({targetFunction:a,isComplete:o,isRejectAsValid:!0,...i}),this.cancelableSendPresentationWithRepeatedCalls.then(c=>c)}async sendPresentation(e,t,s,{isNeedReinvite:r=!0,contentHint:i="detail",degradationPreference:a,sendEncodings:o,onAddedTransceiver:c}){const d=U(s,{contentHint:i});if(d===void 0)throw new Error("No streamPresentationTarget");this.streamPresentationCurrent=d;const u=e().then(async()=>t.startPresentation(d,r,{degradationPreference:a,sendEncodings:o,onAddedTransceiver:c})).then(this.setMaxBitrate).then(()=>s).catch(T=>{throw this.removeStreamPresentationCurrent(),this.events.trigger(f.FAILED_PRESENTATION,T),T});return this.promisePendingStartPresentation=u,u.finally(()=>{this.promisePendingStartPresentation=void 0})}setMaxBitrate=async()=>{const{connection:e}=this.callManager,{streamPresentationCurrent:t}=this,{maxBitrate:s}=this;if(!e||!t||s===void 0)return;const r=e.getSenders();await je(r,t,s)};getRtcSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};handleEnded=()=>{this.reset()};reset(){this.cancelSendPresentationWithRepeatedCalls(),this.resetPresentation()}resetPresentation(){this.removeStreamPresentationCurrent(),this.promisePendingStartPresentation=void 0,this.promisePendingStopPresentation=void 0}removeStreamPresentationCurrent(){delete this.streamPresentationCurrent}}class nt{data={};getUa;constructor(e){this.getUa=e.getUa}isConfigured(){return this.getUa()!==void 0}get(){return{...this.data}}set(e){this.data={...e}}update(e,t){this.data[e]=t}clear(){this.data={}}isRegister(){return this.data.register===!0}getSipServerUrl(){return this.data.sipServerUrl}getDisplayName(){return this.data.displayName}getUser(){return this.data.user}getPassword(){return this.data.password}isRegisterEnabled(){return this.data.register===!0}}var A=(n=>(n.CONNECTING="connecting",n.CONNECTED="connected",n.DISCONNECTED="disconnected",n.NEW_RTC_SESSION="newRTCSession",n.REGISTERED="registered",n.UNREGISTERED="unregistered",n.REGISTRATION_FAILED="registrationFailed",n.NEW_MESSAGE="newMessage",n.SIP_EVENT="sipEvent",n))(A||{});const le=["connecting","connected","disconnected","newRTCSession","registered","unregistered","registrationFailed","newMessage","sipEvent"],ge=[...le],st=3;class rt{cancelableConnectWithRepeatedCalls;JsSIP;events;uaFactory;stateMachine;registrationManager;getUa;setUa;getConnectionConfiguration;setConnectionConfiguration;updateConnectionConfiguration;setSipServerUrl;setSocket;constructor(e){this.JsSIP=e.JsSIP,this.events=e.events,this.uaFactory=e.uaFactory,this.stateMachine=e.stateMachine,this.registrationManager=e.registrationManager,this.getUa=e.getUa,this.setUa=e.setUa,this.getConnectionConfiguration=e.getConnectionConfiguration,this.setConnectionConfiguration=e.setConnectionConfiguration,this.updateConnectionConfiguration=e.updateConnectionConfiguration,this.setSipServerUrl=e.setSipServerUrl,this.setSocket=e.setSocket}connect=async(e,t)=>(this.cancelRequests(),this.connectWithDuplicatedCalls(e,t));set=async({displayName:e})=>new Promise((t,s)=>{const r=this.getUa();if(!r){s(new Error("this.ua is not initialized"));return}let i=!1;const a=this.getConnectionConfiguration();e!==void 0&&e!==a.displayName&&(i=r.set("display_name",ae(e)),this.updateConnectionConfiguration("displayName",e));const o=i;o?t(o):s(new Error("nothing changed"))});disconnect=async()=>{const e=new Promise(s=>{this.events.once(A.DISCONNECTED,()=>{s()})}),t=this.getUa();return t?t.stop():this.events.trigger(A.DISCONNECTED,void 0),e.finally(()=>{this.setUa(void 0),this.stateMachine.reset()})};cancelRequests(){this.cancelConnectWithRepeatedCalls()}connectWithDuplicatedCalls=async(e,{callLimit:t=st}={})=>{const s=async()=>this.connectInner(e),r=i=>{const c=this.getUa()?.isConnected()===!0&&this.hasEqualConnectionConfiguration(e),d=i!=null&&!fe(i);return c||d};return this.stateMachine.startConnect(),this.cancelableConnectWithRepeatedCalls=x.repeatedCallsAsync({targetFunction:s,isComplete:r,callLimit:t,isRejectAsValid:!0,isCheckBeforeCall:!1}),this.cancelableConnectWithRepeatedCalls.then(i=>{if(i instanceof this.JsSIP.UA)return i;throw i})};hasEqualConnectionConfiguration(e){const{configuration:t}=this.uaFactory.createConfiguration(e),r=this.getUa()?.configuration;return r?r.password===t.password&&r.register===t.register&&r.uri.toString()===t.uri&&r.display_name===t.display_name&&r.user_agent===t.user_agent&&r.sockets===t.sockets&&r.session_timers===t.session_timers&&r.register_expires===t.register_expires&&r.connection_recovery_min_interval===t.connection_recovery_min_interval&&r.connection_recovery_max_interval===t.connection_recovery_max_interval:!1}connectInner=async e=>this.initUa(e).then(async()=>this.start());initUa=async({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:d,userAgent:u,displayName:T="",register:l=!1,extraHeaders:C=[]})=>{this.stateMachine.startInitUa(),this.setConnectionConfiguration({sipServerUrl:s,displayName:T,register:l,user:e,password:t}),this.getUa()&&await this.disconnect();const{ua:I,helpers:R}=this.uaFactory.createUAWithConfiguration({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,displayName:T,register:l,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:d,userAgent:u,remoteAddress:i,extraHeaders:C},this.events);return this.setUa(I),this.setSipServerUrl(R.getSipServerUrl),this.setSocket(R.socket),I};start=async()=>new Promise((e,t)=>{const s=this.getUa();if(!s){t(new Error("this.ua is not initialized"));return}let r;r=((c,d)=>{if(this.getConnectionConfiguration().register===!0)return this.registrationManager.subscribeToStartEvents(c,d);const T=A.CONNECTED,l=[A.DISCONNECTED];return this.events.on(T,c),l.forEach(C=>{this.events.on(C,d)}),()=>{this.events.off(T,c),l.forEach(C=>{this.events.off(C,d)})}})(()=>{r?.(),e(s)},c=>{r?.(),t(c)}),s.start()});cancelConnectWithRepeatedCalls(){this.cancelableConnectWithRepeatedCalls?.cancel()}}var ue=(n=>(n.START_CONNECT="START_CONNECT",n.START_INIT_UA="START_INIT_UA",n.UA_CONNECTED="UA_CONNECTED",n.UA_REGISTERED="UA_REGISTERED",n.UA_UNREGISTERED="UA_UNREGISTERED",n.UA_DISCONNECTED="UA_DISCONNECTED",n.CONNECTION_FAILED="CONNECTION_FAILED",n.RESET="RESET",n))(ue||{});const it=j.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{E(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{E("ConnectionStateMachine state changed",e.state)}}}).createMachine({id:"connection",initial:"idle",context:{},states:{idle:{entry:{type:"logStateChange",params:{state:"idle"}},on:{START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"idle",to:"connecting",event:"START_CONNECT"}}}}},connecting:{entry:{type:"logStateChange",params:{state:"connecting"}},on:{START_INIT_UA:{target:"initializing",actions:{type:"logTransition",params:{from:"connecting",to:"initializing",event:"START_INIT_UA"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connecting",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connecting",to:"failed",event:"CONNECTION_FAILED"}}}}},initializing:{entry:{type:"logStateChange",params:{state:"initializing"}},on:{UA_CONNECTED:{target:"connected",actions:{type:"logTransition",params:{from:"initializing",to:"connected",event:"UA_CONNECTED"}}},UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"initializing",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"initializing",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"initializing",to:"failed",event:"CONNECTION_FAILED"}}}}},connected:{entry:{type:"logStateChange",params:{state:"connected"}},on:{UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"connected",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connected",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connected",to:"failed",event:"CONNECTION_FAILED"}}}}},registered:{entry:{type:"logStateChange",params:{state:"registered"}},on:{UA_UNREGISTERED:{target:"connected",actions:{type:"logTransition",params:{from:"registered",to:"connected",event:"UA_UNREGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"registered",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"registered",to:"failed",event:"CONNECTION_FAILED"}}}}},disconnected:{entry:{type:"logStateChange",params:{state:"disconnected"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"disconnected",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"disconnected",to:"connecting",event:"START_CONNECT"}}}}},failed:{entry:{type:"logStateChange",params:{state:"failed"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"failed",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"failed",to:"connecting",event:"START_CONNECT"}}}}}}});class at{actor;stateChangeListeners=new Set;events;unsubscribeFromEvents;actorSubscription;constructor(e){this.events=e,this.actor=j.createActor(it),this.actorSubscription=this.actor.subscribe(t=>{const s=t.value;this.stateChangeListeners.forEach(r=>{r(s)})}),this.actor.start(),this.subscribeToEvents()}get state(){return this.actor.getSnapshot().value}get isIdle(){return this.hasState("idle")}get isConnecting(){return this.hasState("connecting")}get isInitializing(){return this.hasState("initializing")}get isConnected(){return this.hasState("connected")}get isRegistered(){return this.hasState("registered")}get isDisconnected(){return this.hasState("disconnected")}get isFailed(){return this.hasState("failed")}get isPending(){return this.isConnecting||this.isInitializing}get isPendingConnect(){return this.isConnecting}get isPendingInitUa(){return this.isInitializing}get isActiveConnection(){return this.isConnected||this.isRegistered}startConnect(){this.toStartConnect()}startInitUa(){this.toStartInitUa()}reset(){this.toIdle()}destroy(){this.unsubscribeFromEvents?.(),this.actorSubscription?.unsubscribe(),this.actor.stop()}onStateChange(e){return this.stateChangeListeners.add(e),()=>{this.stateChangeListeners.delete(e)}}canTransition(e){return this.actor.getSnapshot().can({type:e})}getValidEvents(){return Object.values(ue).filter(e=>this.canTransition(e))}hasState(e){return this.actor.getSnapshot().matches(e)}sendEvent(e){const t=this.actor.getSnapshot(),s={type:e};if(!t.can(s)){E(`Invalid transition: ${s.type} from ${this.state}. Event cannot be processed in current state.`);return}this.actor.send(s)}toStartConnect=()=>{this.sendEvent("START_CONNECT")};toStartInitUa=()=>{this.sendEvent("START_INIT_UA")};toConnected=()=>{this.sendEvent("UA_CONNECTED")};toRegistered=()=>{this.sendEvent("UA_REGISTERED")};toUnregistered=()=>{this.sendEvent("UA_UNREGISTERED")};toDisconnected=()=>{this.sendEvent("UA_DISCONNECTED")};toFailed=()=>{this.sendEvent("CONNECTION_FAILED")};toIdle=()=>{this.sendEvent("RESET")};subscribeToEvents(){this.events.on("connected",this.toConnected),this.events.on("registered",this.toRegistered),this.events.on("unregistered",this.toUnregistered),this.events.on("disconnected",this.toDisconnected),this.events.on("registrationFailed",this.toFailed),this.unsubscribeFromEvents=()=>{this.events.off("connected",this.toConnected),this.events.off("registered",this.toRegistered),this.events.off("unregistered",this.toUnregistered),this.events.off("disconnected",this.toDisconnected),this.events.off("registrationFailed",this.toFailed)}}}class ot{events;getUaProtected;constructor(e){this.events=e.events,this.getUaProtected=e.getUaProtected}async register(){const e=this.getUaProtected();return new Promise((t,s)=>{e.on(A.REGISTERED,t),e.on(A.REGISTRATION_FAILED,s),e.register()})}async unregister(){const e=this.getUaProtected();return new Promise(t=>{e.on(A.UNREGISTERED,t),e.unregister()})}async tryRegister(){try{await this.unregister()}catch(e){E("tryRegister",e)}return this.register()}subscribeToStartEvents(e,t){const s=A.REGISTERED,r=[A.REGISTRATION_FAILED,A.DISCONNECTED];return this.events.on(s,e),r.forEach(i=>{this.events.on(i,t)}),()=>{this.events.off(s,e),r.forEach(i=>{this.events.off(i,t)})}}}class ct{uaFactory;getUaProtected;constructor(e){this.uaFactory=e.uaFactory,this.getUaProtected=e.getUaProtected}async sendOptions(e,t,s){const r=this.getUaProtected();return new Promise((i,a)=>{try{r.sendOptions(e,t,{extraHeaders:s,eventHandlers:{succeeded:()=>{i()},failed:a}})}catch(o){a(o)}})}async ping(e,t){const r=this.getUaProtected().configuration.uri;return this.sendOptions(r,e,t)}async checkTelephony({userAgent:e,displayName:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,extraHeaders:a}){return new Promise((o,c)=>{const{configuration:d}=this.uaFactory.createConfiguration({sipWebSocketServerURL:r,displayName:t,userAgent:e,sipServerUrl:s}),u=this.uaFactory.createUA({...d,remoteAddress:i,extraHeaders:a}),T=()=>{const C=new Error("Telephony is not available");c(C)};u.once(A.DISCONNECTED,T);const l=()=>{u.removeAllListeners(),u.once(A.DISCONNECTED,()=>{o()}),u.stop()};u.once(A.CONNECTED,l),u.start()})}}const dt=n=>{const e=[];return n!==void 0&&n!==""&&e.push(`X-Vinteo-Remote: ${n}`),e};class D{JsSIP;constructor(e){this.JsSIP=e}static isRegisteredUA(e){return!!e&&e.isRegistered()}static validateConfiguration({register:e,password:t,user:s,sipServerUrl:r,sipWebSocketServerURL:i}){if(!r)throw new Error("sipServerUrl is required");if(!i)throw new Error("sipWebSocketServerURL is required");if(e&&(t===void 0||t===""))throw new Error("password is required for authorized connection");if(e&&(s===void 0||s===""))throw new Error("user is required for authorized connection")}static resolveAuthorizationUser(e,t){return e&&t!==void 0&&t.trim()!==""?t.trim():`${Le()}`}static buildExtraHeaders(e,t){const s=e!==void 0&&e!==""?dt(e):[];return t===void 0?s:[...s,...t]}createConfiguration({user:e,password:t,sipWebSocketServerURL:s,displayName:r="",sipServerUrl:i,register:a=!1,sessionTimers:o=!1,registerExpires:c=300,connectionRecoveryMinInterval:d=2,connectionRecoveryMaxInterval:u=6,userAgent:T}){D.validateConfiguration({register:a,password:t,user:e,sipServerUrl:i,sipWebSocketServerURL:s});const l=D.resolveAuthorizationUser(a,e),C=we(i),m=C(l),I=new this.JsSIP.WebSocketInterface(s);return{configuration:{password:t,register:a,uri:m,display_name:ae(r),user_agent:T,sdpSemantics:"unified-plan",sockets:[I],session_timers:o,register_expires:c,connection_recovery_min_interval:d,connection_recovery_max_interval:u},helpers:{socket:I,getSipServerUrl:C}}}createUA({remoteAddress:e,extraHeaders:t,...s}){const r=new this.JsSIP.UA(s),i=D.buildExtraHeaders(e,t);return i.length>0&&r.registrator().setExtraHeaders(i),r}createUAWithConfiguration(e,t){const{configuration:s,helpers:r}=this.createConfiguration(e),i=this.createUA({...s,remoteAddress:e.remoteAddress,extraHeaders:e.extraHeaders});return t.eachTriggers((a,o)=>{const c=le.find(d=>d===o);c&&i.on(c,a)}),{ua:i,helpers:r}}}class ht{events;ua;socket;uaFactory;registrationManager;stateMachine;connectionFlow;sipOperations;configurationManager;JsSIP;constructor({JsSIP:e}){this.JsSIP=e,this.events=new O.Events(ge),this.uaFactory=new D(e),this.registrationManager=new ot({events:this.events,getUaProtected:this.getUaProtected}),this.stateMachine=new at(this.events),this.configurationManager=new nt({getUa:this.getUa}),this.sipOperations=new ct({uaFactory:this.uaFactory,getUaProtected:this.getUaProtected}),this.connectionFlow=new rt({JsSIP:this.JsSIP,events:this.events,uaFactory:this.uaFactory,stateMachine:this.stateMachine,registrationManager:this.registrationManager,getUa:this.getUa,getConnectionConfiguration:this.getConnectionConfiguration,setConnectionConfiguration:t=>{this.configurationManager.set(t)},updateConnectionConfiguration:(t,s)=>{this.configurationManager.update(t,s)},setUa:t=>{this.ua=t},setSipServerUrl:t=>{this.getSipServerUrl=t},setSocket:t=>{this.socket=t}})}get requested(){return this.stateMachine.isPending}get isPendingConnect(){return this.stateMachine.isPendingConnect}get isPendingInitUa(){return this.stateMachine.isPendingInitUa}get connectionState(){return this.stateMachine.state}get isRegistered(){return D.isRegisteredUA(this.ua)}get isRegisterConfig(){return this.configurationManager.isRegister()}connect=async(e,t)=>this.connectionFlow.connect(e,t);set=async({displayName:e})=>this.connectionFlow.set({displayName:e});disconnect=async()=>this.connectionFlow.disconnect();async register(){return this.registrationManager.register()}async unregister(){return this.registrationManager.unregister()}tryRegister=async()=>this.registrationManager.tryRegister();sendOptions=async(e,t,s)=>this.sipOperations.sendOptions(e,t,s);ping=async(e,t)=>this.sipOperations.ping(e,t);checkTelephony=async e=>this.sipOperations.checkTelephony(e);on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}isConfigured(){return this.configurationManager.isConfigured()}getConnectionConfiguration=()=>this.configurationManager.get();destroy(){this.stateMachine.destroy()}getSipServerUrl=e=>e;getUaProtected=()=>{if(!this.ua)throw new Error("UA not initialized");return this.ua};getUa=()=>this.ua}class lt{connectionManager;stackPromises=Z.createStackPromises({noRunIsNotActual:!0});constructor({connectionManager:e}){this.connectionManager=e}connect=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.connect(...e));disconnect=async()=>this.stackPromises.run(async()=>this.connectionManager.disconnect());register=async()=>this.stackPromises.run(async()=>this.connectionManager.register());unregister=async()=>this.stackPromises.run(async()=>this.connectionManager.unregister());tryRegister=async()=>this.stackPromises.run(async()=>this.connectionManager.tryRegister());checkTelephony=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.checkTelephony(...e));sendOptions=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.sendOptions(...e));ping=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.ping(...e));set=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.set(...e))}var w=(n=>(n.INCOMING_CALL="incomingCall",n.DECLINED_INCOMING_CALL="declinedIncomingCall",n.TERMINATED_INCOMING_CALL="terminatedIncomingCall",n.FAILED_INCOMING_CALL="failedIncomingCall",n))(w||{});const Te=["incomingCall","declinedIncomingCall","terminatedIncomingCall","failedIncomingCall"],gt=486,ut=487;class Tt{events;incomingRTCSession;connectionManager;constructor(e){this.connectionManager=e,this.events=new O.Events(Te),this.start()}get remoteCallerData(){return{displayName:this.incomingRTCSession?.remote_identity.display_name,host:this.incomingRTCSession?.remote_identity.uri.host,incomingNumber:this.incomingRTCSession?.remote_identity.uri.user,rtcSession:this.incomingRTCSession}}get isAvailableIncomingCall(){return!!this.incomingRTCSession}start(){this.subscribe()}stop(){this.unsubscribe(),this.removeIncomingSession()}getIncomingRTCSession=()=>{const{incomingRTCSession:e}=this;if(!e)throw new Error("No incomingRTCSession");return e};extractIncomingRTCSession=()=>{const e=this.getIncomingRTCSession();return this.removeIncomingSession(),e};async declineToIncomingCall({statusCode:e=ut}={}){return new Promise((t,s)=>{try{const r=this.getIncomingRTCSession(),i=this.remoteCallerData;this.removeIncomingSession(),this.events.trigger(w.DECLINED_INCOMING_CALL,i),r.terminate({status_code:e}),t()}catch(r){s(r)}})}async busyIncomingCall(){return this.declineToIncomingCall({statusCode:gt})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.connectionManager.on("newRTCSession",this.handleNewRTCSession)}unsubscribe(){this.connectionManager.off("newRTCSession",this.handleNewRTCSession)}handleNewRTCSession=({originator:e,session:t})=>{e==="remote"&&this.setIncomingSession(t)};setIncomingSession(e){this.incomingRTCSession=e;const t=this.remoteCallerData;e.on("failed",s=>{this.removeIncomingSession(),s.originator==="local"?this.events.trigger(w.TERMINATED_INCOMING_CALL,t):this.events.trigger(w.FAILED_INCOMING_CALL,t)}),this.events.trigger(w.INCOMING_CALL,t)}removeIncomingSession(){delete this.incomingRTCSession}}const b=1e3;var S=(n=>(n.INBOUND_RTP="inbound-rtp",n.REMOTE_OUTBOUND_RTP="remote-outbound-rtp",n.MEDIA_SOURCE="media-source",n.OUTBOUND_RTP="outbound-rtp",n.REMOTE_INBOUND_RTP="remote-inbound-rtp",n.CODEC="codec",n.CANDIDATE_PAIR="candidate-pair",n.CERTIFICATE="certificate",n.TRANSPORT="transport",n.LOCAL_CANDIDATE="local-candidate",n.REMOTE_CANDIDATE="remote-candidate",n))(S||{});const Se=["collected"],z=()=>"performance"in window?performance.now():Date.now(),L=n=>[...n.keys()].reduce((e,t)=>{const s=n.get(t);return s===void 0?e:{...e,[s.type]:s}},{}),St=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=L(n);return{outboundRtp:e[S.OUTBOUND_RTP],codec:e[S.CODEC],mediaSource:e[S.MEDIA_SOURCE],remoteInboundRtp:e[S.REMOTE_INBOUND_RTP]}},X=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=L(n);return{outboundRtp:e[S.OUTBOUND_RTP],codec:e[S.CODEC],mediaSource:e[S.MEDIA_SOURCE],remoteInboundRtp:e[S.REMOTE_INBOUND_RTP]}},J=({videoReceiversStats:n,synchronizationSourcesVideo:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,synchronizationSources:e};const t=L(n);return{inboundRtp:t[S.INBOUND_RTP],codec:t[S.CODEC],synchronizationSources:e}},Ct=({audioReceiverStats:n,synchronizationSourcesAudio:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,remoteOutboundRtp:void 0,synchronizationSources:e};const t=L(n);return{inboundRtp:t[S.INBOUND_RTP],codec:t[S.CODEC],remoteOutboundRtp:t[S.REMOTE_OUTBOUND_RTP],synchronizationSources:e}},Ce=n=>{if(!n)return{candidatePair:void 0,certificate:void 0,localCandidate:void 0,remoteCandidate:void 0,transport:void 0};const e=L(n);return{candidatePair:e[S.CANDIDATE_PAIR],certificate:e[S.CERTIFICATE],localCandidate:e[S.LOCAL_CANDIDATE],remoteCandidate:e[S.REMOTE_CANDIDATE],transport:e[S.TRANSPORT]}},Et=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t})=>({video:X(e),secondVideo:X(t),audio:St(n),additional:Ce(n??e??t)}),Nt=({audioReceiverStats:n,videoReceiverFirstStats:e,videoReceiverSecondStats:t,synchronizationSources:s})=>({video:J({videoReceiversStats:e,synchronizationSourcesVideo:s.video}),secondVideo:J({videoReceiversStats:t,synchronizationSourcesVideo:s.video}),audio:Ct({audioReceiverStats:n,synchronizationSourcesAudio:s.audio}),additional:Ce(n??e??t)}),At=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t,audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a})=>{const o=Et({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t}),c=Nt({audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a});return{outbound:o,inbound:c}},Rt=async n=>{const e="audio",t="video",s=n.getSenders(),r=s.find(l=>l.track?.kind===e),i=s.filter(l=>l.track?.kind===t),a=n.getReceivers(),o=a.find(l=>l.track.kind===e),c=a.filter(l=>l.track.kind===t),d={trackIdentifier:o?.track.id,item:o?.getSynchronizationSources()[0]},u={trackIdentifier:c[0]?.track.id,item:c[0]?.getSynchronizationSources()[0]},T={audio:d,video:u};return Promise.all([r?.getStats()??Promise.resolve(void 0),i[0]?.getStats()??Promise.resolve(void 0),i[1]?.getStats()??Promise.resolve(void 0),o?.getStats()??Promise.resolve(void 0),c[0]?.getStats()??Promise.resolve(void 0),c[1]?.getStats()??Promise.resolve(void 0)]).then(l=>{const[C,m,I,R,y,k]=l;return{synchronizationSources:T,audioSenderStats:C,videoSenderFirstStats:m,videoSenderSecondStats:I,audioReceiverStats:R,videoReceiverFirstStats:y,videoReceiverSecondStats:k}})},It=n=>{E(String(n))};class Ee{events;setTimeoutRequest;requesterAllStatistics=new me.CancelableRequest(Rt);constructor(){this.events=new O.TypedEvents(Se),this.setTimeoutRequest=new ee.SetTimeoutRequest}get requested(){return this.setTimeoutRequest.requested}start(e,{interval:t=b,onError:s=It}={}){this.stop(),this.setTimeoutRequest.request(()=>{this.collectStatistics(e,{onError:s})},t)}stop(){this.setTimeoutRequest.cancelRequest(),this.requesterAllStatistics.cancelRequest()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}collectStatistics=(e,{onError:t})=>{const s=z();this.requesterAllStatistics.request(e).then(r=>{this.events.trigger("collected",At(r));const a=z()-s;let o=b;a>48?o=b*4:a>32?o=b*3:a>16&&(o=b*2),this.start(e,{onError:t,interval:o})}).catch(r=>{t&&t(r)})}}class _t{availableIncomingBitrate;statsPeerConnection;callManager;apiManager;previousAvailableIncomingBitrate;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.statsPeerConnection=new Ee,this.subscribe()}get events(){return this.statsPeerConnection.events}on(e,t){return this.statsPeerConnection.on(e,t)}once(e,t){return this.statsPeerConnection.once(e,t)}onceRace(e,t){return this.statsPeerConnection.onceRace(e,t)}async wait(e){return this.statsPeerConnection.wait(e)}off(e,t){this.statsPeerConnection.off(e,t)}hasAvailableIncomingBitrateChangedQuarter(){const e=this.previousAvailableIncomingBitrate,t=this.availableIncomingBitrate;return e===void 0||t===void 0?!1:e===0?t>0:Math.abs(t-e)/e>=.25}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleStarted),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.statsPeerConnection.on("collected",this.handleStatsCollected)}handleStatsCollected=e=>{this.previousAvailableIncomingBitrate=this.availableIncomingBitrate,this.availableIncomingBitrate=e.inbound.additional.candidatePair?.availableIncomingBitrate,this.maybeSendStats()};handleStarted=e=>{this.statsPeerConnection.start(e)};handleEnded=()=>{this.statsPeerConnection.stop(),this.availableIncomingBitrate=void 0,this.previousAvailableIncomingBitrate=void 0};maybeSendStats(){this.availableIncomingBitrate!==void 0&&this.hasAvailableIncomingBitrateChangedQuarter()&&this.apiManager.sendStats({availableIncomingBitrate:this.availableIncomingBitrate}).catch(e=>{E("Failed to send stats",e)})}}const mt=(n,e)=>n.filter(s=>e.some(r=>r.clockRate===s.clockRate&&r.mimeType===s.mimeType&&r.channels===s.channels&&r.sdpFmtpLine===s.sdpFmtpLine)),Mt=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),s=e===null?[]:e.codecs,r=t===null?[]:t.codecs;return mt(s,r)},pt=(n,e)=>e===void 0||e.length===0?n:n.sort((t,s)=>{const r=e.indexOf(t.mimeType),i=e.indexOf(s.mimeType),a=r===-1?Number.MAX_VALUE:r,o=i===-1?Number.MAX_VALUE:i;return a-o}),Pt=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),vt=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>{try{if(typeof n.setCodecPreferences=="function"&&n.sender.track?.kind==="video"&&(e!==void 0&&e.length>0||t!==void 0&&t.length>0)){const s=Mt("video"),r=Pt(s,t),i=pt(r,e);n.setCodecPreferences(i)}}catch(s){E("setCodecPreferences error",s)}};class ft{transceivers={};callManager;apiManager;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.subscribe()}storeTransceiver(e,t){const{kind:s}=t;if(s==="audio")this.transceivers.mainAudio??=e;else{const{mid:r}=e;r==="2"?this.transceivers.presentationVideo??=e:this.transceivers.mainVideo??=e}}getTransceivers(){return{...this.transceivers}}getMainAudioTransceiver(){return this.transceivers.mainAudio}getMainVideoTransceiver(){return this.transceivers.mainVideo}getPresentationVideoTransceiver(){return this.transceivers.presentationVideo}hasTransceiver(e){return this.transceivers[e]!==void 0}clear(){this.transceivers.mainVideo=void 0,this.transceivers.mainAudio=void 0,this.transceivers.presentationVideo=void 0}getCount(){let e=0;return this.transceivers.mainAudio&&(e+=1),this.transceivers.mainVideo&&(e+=1),this.transceivers.presentationVideo&&(e+=1),e}isEmpty(){return this.getCount()===0}handleRestart=e=>{this.updateTransceivers(e).catch(t=>{E("Failed to update transceivers",t)}).finally(()=>{this.callManager.restartIce().catch(t=>{E("Failed to restart ICE",t)})})};updateTransceivers=async e=>{const{videoTrackCount:t}=e;t===2&&(this.getTransceivers().presentationVideo!==void 0||await this.callManager.addTransceiver("video",{direction:"recvonly"}).catch(i=>{E("Failed to add presentation video transceiver",i)}))};subscribe(){this.callManager.on("peerconnection:ontrack",this.handleTrack),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.apiManager.on("restart",this.handleRestart)}handleTrack=e=>{this.storeTransceiver(e.transceiver,e.track)};handleEnded=()=>{this.clear()}}const Ot=n=>[...n.keys()].map(e=>n.get(e)),Dt=(n,e)=>Ot(n).find(t=>t?.type===e),Ne=async n=>n.getStats().then(e=>Dt(e,"codec")?.mimeType);class yt{async getCodecFromSender(e){return await Ne(e)??""}}class bt{stackPromises=Z.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{E("TaskQueue: error",e)})}}class wt{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new bt}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>Q(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}const Ae=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),Ut=1e6,p=n=>n*Ut,Re=p(.06),Ie=p(4),Lt=n=>n<=64?Re:n<=128?p(.12):n<=256?p(.25):n<=384?p(.32):n<=426?p(.38):n<=640?p(.5):n<=848?p(.7):n<=1280?p(1):n<=1920?p(2):Ie,Bt="av1",kt=n=>Ae(n,Bt),Ft=.6,Y=(n,e)=>kt(e)?n*Ft:n,$t=n=>Y(Re,n),Vt=n=>Y(Ie,n),K=(n,e)=>{const t=Lt(n);return Y(t,e)},F=1,Wt=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),s=t.width,r=t.height,i=s===void 0?F:s/e.width,a=r===void 0?F:r/e.height;return Math.max(i,a,F)};class Ht{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:s},r){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=s,this.ignoreForCodec=r.ignoreForCodec}async balance(e,t){const s=e.getSenders(),r=this.senderFinder.findVideoSender(s);if(!r?.track)return{...this.resultNoChanged,sender:r};const i=await this.codecProvider.getCodecFromSender(r);if(Ae(i,this.ignoreForCodec))return{...this.resultNoChanged,sender:r};const{mainCam:a,resolutionMainCam:o}=t??{};return this.processSender({mainCam:a,resolutionMainCam:o},{sender:r,codec:i,videoTrack:r.track}).then(c=>({...c,sender:r}))}async processSender(e,t){const{mainCam:s,resolutionMainCam:r}=e;switch(s){case P.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case P.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case P.MAX_MAIN_CAM_RESOLUTION:return r!==void 0?this.setResolutionSender(r,t):this.setBitrateByTrackResolution(t);case P.ADMIN_STOP_MAIN_CAM:case P.ADMIN_START_MAIN_CAM:case void 0:return this.setBitrateByTrackResolution(t);default:return this.setBitrateByTrackResolution(t)}}async downgradeResolutionSender(e){const{sender:t,codec:s}=e,r={scaleResolutionDownBy:200,maxBitrate:$t(s)};return this.parametersSetter.setEncodingsToSender(t,r)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:s,codec:r}=e,a=s.getSettings().width,o=a===void 0?Vt(r):K(a,r);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:o})}async setResolutionSender(e,t){const[s,r]=e.split("x"),{sender:i,videoTrack:a,codec:o}=t,c={width:Number(s),height:Number(r)},d=Wt({videoTrack:a,targetSize:c}),u=K(c.width,o),T={scaleResolutionDownBy:d,maxBitrate:u};return this.parametersSetter.setEncodingsToSender(i,T)}}const xt=n=>n.find(e=>e.track?.kind==="video");class qt{findVideoSender(e){return xt(e)}}class Gt{currentSender;originalReplaceTrack;lastWidth;lastHeight;maxPollIntervalMs;currentPollIntervalMs;pollIntervalMs;setTimeoutRequest;constructor({pollIntervalMs:e=1e3,maxPollIntervalMs:t}){this.pollIntervalMs=e,this.maxPollIntervalMs=t??e*16,this.currentPollIntervalMs=this.pollIntervalMs,this.setTimeoutRequest=new ee.SetTimeoutRequest}subscribe(e,t){if(!e){this.detachSender();return}this.currentSender!==e&&(this.detachSender(),this.attachSender(e,t))}unsubscribe(){this.detachSender()}attachSender(e,t){this.currentSender=e;const s=e.replaceTrack.bind(e);this.originalReplaceTrack=s,e.replaceTrack=async r=>{await s(r),this.attachTrack(t,r??void 0),t()},this.attachTrack(t,e.track)}detachSender(){this.currentSender&&this.originalReplaceTrack&&(this.currentSender.replaceTrack=this.originalReplaceTrack),this.originalReplaceTrack=void 0,this.currentSender=void 0,this.detachTrack()}attachTrack(e,t){if(this.detachTrack(),!t)return;const{width:s,height:r}=t.getSettings();this.lastWidth=s,this.lastHeight=r,this.currentPollIntervalMs=this.pollIntervalMs,this.schedulePoll(t,e)}schedulePoll(e,t){const s=()=>{const{width:r,height:i}=e.getSettings();r!==this.lastWidth||i!==this.lastHeight?(this.lastWidth=r,this.lastHeight=i,this.currentPollIntervalMs=this.pollIntervalMs,t()):this.currentPollIntervalMs=Math.min(this.currentPollIntervalMs*2,this.maxPollIntervalMs),this.setTimeoutRequest.request(s,this.currentPollIntervalMs)};this.setTimeoutRequest.request(s,this.currentPollIntervalMs)}detachTrack(){this.setTimeoutRequest.cancelRequest(),this.lastWidth=void 0,this.lastHeight=void 0}}class Qt{apiManager;currentHandler;constructor(e){this.apiManager=e}subscribe(e){this.currentHandler=e,this.apiManager.on("main-cam-control",e)}unsubscribe(){this.currentHandler&&(this.apiManager.off("main-cam-control",this.currentHandler),this.currentHandler=void 0)}}class Yt{eventHandler;senderBalancer;parametersSetterWithQueue;getConnection;serverHeaders;trackMonitor;constructor(e,t,{ignoreForCodec:s,onSetParameters:r,pollIntervalMs:i}={}){this.getConnection=t,this.eventHandler=new Qt(e),this.parametersSetterWithQueue=new wt(r),this.senderBalancer=new Ht({senderFinder:new qt,codecProvider:new yt,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:s}),this.trackMonitor=new Gt({pollIntervalMs:i})}subscribe(){this.eventHandler.subscribe(this.handleMainCamControl)}unsubscribe(){this.eventHandler.unsubscribe(),this.parametersSetterWithQueue.stop(),this.reset()}reset(){delete this.serverHeaders,this.trackMonitor.unsubscribe()}async balance(){const e=this.getConnection();if(!e)throw new Error("connection is not exist");const t=await this.senderBalancer.balance(e,this.serverHeaders);return this.trackMonitor.subscribe(t.sender,()=>{this.balance().catch(s=>{E("balance on track change: error",s)})}),t}handleMainCamControl=e=>{this.serverHeaders=e,this.balance().catch(t=>{E("handleMainCamControl: error",t)})}}const _e=["balancing-scheduled","balancing-started","balancing-stopped","parameters-updated"];class zt{isBalancingActive=!1;events;callManager;balancingStartDelay;videoSendingBalancer;startBalancingTimer;constructor(e,t,s={}){this.events=new O.TypedEvents(_e),this.callManager=e,this.balancingStartDelay=s.balancingStartDelay??1e4,this.videoSendingBalancer=new Yt(t,()=>e.connection,{...s,onSetParameters:r=>{this.events.trigger("parameters-updated",r),s.onSetParameters?.(r)}}),this.subscribe()}get isBalancingScheduled(){return this.startBalancingTimer!==void 0}async startBalancing(){this.isBalancingActive||(this.clearStartTimer(),await this.videoSendingBalancer.balance(),this.videoSendingBalancer.subscribe(),this.isBalancingActive=!0,this.events.trigger("balancing-started",{delay:this.balancingStartDelay}))}stopBalancing(){this.clearStartTimer(),this.videoSendingBalancer.unsubscribe(),this.isBalancingActive=!1,this.events.trigger("balancing-stopped",{})}async balance(){return this.videoSendingBalancer.balance()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleCallStarted),this.callManager.on("ended",this.handleCallEnded),this.callManager.on("failed",this.handleCallEnded)}handleCallStarted=()=>{this.scheduleBalancingStart()};handleCallEnded=()=>{this.stopBalancing()};scheduleBalancingStart(){this.clearStartTimer(),this.startBalancingTimer=setTimeout(()=>{this.startBalancingTimer=void 0,this.startBalancing().catch(e=>{E("startBalancing: error",e)})},this.balancingStartDelay),this.events.trigger("balancing-scheduled",{delay:this.balancingStartDelay})}clearStartTimer(){this.startBalancingTimer&&(clearTimeout(this.startBalancingTimer),this.startBalancingTimer=void 0)}}const Xt=1e6,Jt=ge.map(n=>`connection:${n}`),Kt=ie.map(n=>`call:${n}`),jt=ne.map(n=>`api:${n}`),Zt=Te.map(n=>`incoming-call:${n}`),en=he.map(n=>`presentation:${n}`),tn=Se.map(n=>`stats:${n}`),nn=_e.map(n=>`video-balancer:${n}`),sn=[...Jt,...Kt,...jt,...Zt,...en,...tn,...nn];class rn{events;connectionManager;connectionQueueManager;callManager;apiManager;incomingCallManager;presentationManager;statsManager;videoSendingBalancerManager;transceiverManager;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor({JsSIP:e},{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:s,videoBalancerOptions:r}={}){this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=s,this.events=new O.Events(sn),this.connectionManager=new ht({JsSIP:e}),this.connectionQueueManager=new lt({connectionManager:this.connectionManager}),this.callManager=new Ve,this.apiManager=new De({connectionManager:this.connectionManager,callManager:this.callManager}),this.incomingCallManager=new Tt(this.connectionManager),this.presentationManager=new tt({callManager:this.callManager,maxBitrate:Xt}),this.statsManager=new _t({callManager:this.callManager,apiManager:this.apiManager}),this.transceiverManager=new ft({callManager:this.callManager,apiManager:this.apiManager}),this.videoSendingBalancerManager=new zt(this.callManager,this.apiManager,r),this.subscribe()}get requestedConnection(){return this.connectionManager.requested}get isPendingConnect(){return this.connectionManager.isPendingConnect}get isPendingInitUa(){return this.connectionManager.isPendingInitUa}get connectionState(){return this.connectionManager.connectionState}get isRegistered(){return this.connectionManager.isRegistered}get isRegisterConfig(){return this.connectionManager.isRegisterConfig}get socket(){return this.connectionManager.socket}get requestedCall(){return this.callManager.requested}get connection(){return this.callManager.connection}get establishedRTCSession(){return this.callManager.establishedRTCSession}get isCallActive(){return this.callManager.isCallActive}get remoteCallerData(){return this.incomingCallManager.remoteCallerData}get isAvailableIncomingCall(){return this.incomingCallManager.isAvailableIncomingCall}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}connect=async(...e)=>this.connectionQueueManager.connect(...e);set=async(...e)=>this.connectionQueueManager.set(...e);disconnect=async()=>this.connectionQueueManager.disconnect();register=async()=>this.connectionQueueManager.register();unregister=async()=>this.connectionQueueManager.unregister();tryRegister=async()=>this.connectionQueueManager.tryRegister();sendOptions=async(e,t,s)=>this.connectionQueueManager.sendOptions(e,t,s);ping=async(e,t)=>this.connectionQueueManager.ping(e,t);checkTelephony=async e=>this.connectionQueueManager.checkTelephony(e);isConfigured=()=>this.connectionManager.isConfigured();getConnectionConfiguration=()=>this.connectionManager.getConnectionConfiguration();getSipServerUrl=e=>this.connectionManager.getSipServerUrl(e);call=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.startCall(this.connectionManager.getUaProtected(),this.getSipServerUrl,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};hangUp=async()=>this.callManager.endCall();answerToIncomingCall=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.answerToIncomingCall(this.incomingCallManager.extractIncomingRTCSession,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};declineToIncomingCall=async(...e)=>this.incomingCallManager.declineToIncomingCall(...e);getEstablishedRTCSession=()=>this.callManager.getEstablishedRTCSession();getCallConfiguration=()=>this.callManager.getCallConfiguration();getRemoteStreams=()=>this.callManager.getRemoteStreams();replaceMediaStream=async(...e)=>this.callManager.replaceMediaStream(...e);async startPresentation(e,t={}){const{isP2P:s,callLimit:r,onAddedTransceiver:i,...a}=t;return this.presentationManager.startPresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...a,onAddedTransceiver:this.resolveHandleAddTransceiver(i)},r===void 0?void 0:{callLimit:r})}async stopPresentation(e={}){const{isP2P:t}=e;return this.presentationManager.stopPresentation(async()=>{await(t===!0?this.apiManager.sendMustStopPresentationP2P():this.apiManager.sendStoppedPresentation())})}async updatePresentation(e,t={}){const{isP2P:s,onAddedTransceiver:r,...i}=t;return this.presentationManager.updatePresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...i,onAddedTransceiver:this.resolveHandleAddTransceiver(r)})}async waitChannels(...e){return this.apiManager.waitChannels(...e)}async waitSyncMediaState(...e){return this.apiManager.waitSyncMediaState(...e)}async sendDTMF(...e){return this.apiManager.sendDTMF(...e)}async sendChannels(...e){return this.apiManager.sendChannels(...e)}async sendMediaState(...e){return this.apiManager.sendMediaState(...e)}async sendRefusalToTurnOn(...e){return this.apiManager.sendRefusalToTurnOn(...e)}async sendRefusalToTurnOnMic(...e){return this.apiManager.sendRefusalToTurnOnMic(...e)}async sendRefusalToTurnOnCam(...e){return this.apiManager.sendRefusalToTurnOnCam(...e)}async sendMustStopPresentationP2P(...e){return this.apiManager.sendMustStopPresentationP2P(...e)}async sendStoppedPresentationP2P(...e){return this.apiManager.sendStoppedPresentationP2P(...e)}async sendStoppedPresentation(...e){return this.apiManager.sendStoppedPresentation(...e)}async askPermissionToStartPresentationP2P(...e){return this.apiManager.askPermissionToStartPresentationP2P(...e)}async askPermissionToStartPresentation(...e){return this.apiManager.askPermissionToStartPresentation(...e)}async askPermissionToEnableCam(...e){return this.apiManager.askPermissionToEnableCam(...e)}setCodecPreferences(e){vt(e,{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs})}subscribe(){this.bridgeEvents("connection",this.connectionManager),this.bridgeEvents("call",this.callManager),this.bridgeEvents("api",this.apiManager),this.bridgeEvents("incoming-call",this.incomingCallManager),this.bridgeEvents("presentation",this.presentationManager),this.bridgeEvents("stats",this.statsManager),this.bridgeEvents("video-balancer",this.videoSendingBalancerManager)}bridgeEvents=(e,t)=>{t.events.eachTriggers((s,r)=>{t.on(r,i=>{this.events.trigger(`${e}:${r}`,i)})})};resolveHandleAddTransceiver=e=>async(t,s,r)=>{this.setCodecPreferences(t),await e?.(t,s,r)}}exports.ECallCause=G;exports.EStatsTypes=S;exports.EUseLicense=te;exports.Originator=se;exports.SipConnector=rn;exports.StatsPeerConnection=Ee;exports.disableDebug=pe;exports.enableDebug=Me;exports.getCodecFromSender=Ne;exports.hasCanceledStartPresentationError=et;exports.logger=E;exports.prepareMediaStream=U;exports.setEncodingsToSender=Q;exports.setParametersToSender=de;