sip-connector 19.8.3 → 19.9.1
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.
- package/README.md +0 -101
- package/dist/@SipConnector-DhKRV_I3.cjs +1 -0
- package/dist/{@SipConnector-BmkeKEDD.js → @SipConnector-LWYRHYnw.js} +597 -714
- package/dist/ApiManager/@ApiManager.d.ts +0 -1
- package/dist/ApiManager/constants.d.ts +3 -8
- package/dist/ApiManager/eventNames.d.ts +7 -5
- package/dist/ApiManager/index.d.ts +0 -1
- package/dist/ApiManager/types.d.ts +0 -6
- package/dist/AutoConnectorManager/@AutoConnectorManager.d.ts +3 -0
- package/dist/AutoConnectorManager/NotActiveCallSubscriber.d.ts +15 -0
- package/dist/AutoConnectorManager/PingServerIfNotActiveCallRequester.d.ts +1 -3
- package/dist/AutoConnectorManager/RegistrationFailedOutOfCallSubscriber.d.ts +1 -1
- package/dist/CallManager/@CallManager.d.ts +30 -15
- package/dist/CallManager/MCUSession.d.ts +0 -1
- package/dist/CallManager/RecvSession.d.ts +29 -0
- package/dist/CallManager/index.d.ts +0 -1
- package/dist/CallManager/types.d.ts +13 -31
- package/dist/SipConnector/@SipConnector.d.ts +1 -2
- package/dist/SipConnector/eventNames.d.ts +4 -2
- package/dist/__fixtures__/RTCPeerConnectionMock.d.ts +13 -17
- package/dist/doMock.cjs +1 -1
- package/dist/doMock.js +131 -130
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/package.json +13 -5
- package/dist/@SipConnector-BHakZWEK.cjs +0 -1
- package/dist/CallManager/AbstractCallStrategy.d.ts +0 -54
- package/dist/CallManager/MCUCallStrategy.d.ts +0 -31
- package/dist/TransceiverManager/@TransceiverManager.d.ts +0 -70
- package/dist/TransceiverManager/index.d.ts +0 -1
- package/dist/TransceiverManager/types.d.ts +0 -11
package/README.md
CHANGED
|
@@ -31,8 +31,6 @@ SDK предоставляет комплексное решение для:
|
|
|
31
31
|
- **Обработка смены треков**: Автоматическая адаптация балансировки при изменении видеотреков
|
|
32
32
|
- **Улучшенная статистика**: Расширенные возможности сбора и анализа WebRTC статистики
|
|
33
33
|
- **Автоматический перезапуск ICE**: Обработка событий `restart` от сервера с автоматическим вызовом `restartIce`
|
|
34
|
-
- **Управление transceiver'ами**: Новый `TransceiverManager` для отслеживания и управления RTCRtpTransceiver'ами
|
|
35
|
-
- **Автоматическое добавление transceiver'ов**: Умное добавление презентационных transceiver'ов при событиях restart
|
|
36
34
|
|
|
|
37
35
|
|
|
38
36
|
### 🏗️ Архитектура
|
|
@@ -428,100 +426,6 @@ sipConnector.on('api:restart', (data) => {
|
|
|
428
426
|
|
|
429
427
|
---
|
|
430
428
|
|
|
431
|
-
## 🎛️ Управление RTCRtpTransceiver'ами
|
|
432
|
-
|
|
433
|
-
### Обзор TransceiverManager
|
|
434
|
-
|
|
435
|
-
SDK автоматически отслеживает и управляет RTCRtpTransceiver'ами через новый класс `TransceiverManager`:
|
|
436
|
-
|
|
437
|
-
```typescript
|
|
438
|
-
// Получение текущих transceiver'ов
|
|
439
|
-
const transceivers = sipConnector.callManager.getTransceivers();
|
|
440
|
-
|
|
441
|
-
console.log('Основной аудио transceiver:', transceivers.mainAudio);
|
|
442
|
-
console.log('Основной видео transceiver:', transceivers.mainVideo);
|
|
443
|
-
console.log('Презентационный видео transceiver:', transceivers.presentationVideo);
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### Типы transceiver'ов
|
|
447
|
-
|
|
448
|
-
SDK автоматически классифицирует transceiver'ы по их `mid` значению:
|
|
449
|
-
|
|
450
|
-
| Тип transceiver'а | mid | Назначение |
|
|
451
|
-
| ------------------- | --- | --------------------------- |
|
|
452
|
-
| `mainAudio` | '0' | Основной аудио поток |
|
|
453
|
-
| `mainVideo` | '1' | Основной видео поток |
|
|
454
|
-
| `presentationVideo` | '2' | Презентационный видео поток |
|
|
455
|
-
|
|
456
|
-
### Автоматическое добавление transceiver'ов
|
|
457
|
-
|
|
458
|
-
При получении события `restart` с `videoTrackCount === 2`, SDK автоматически добавляет презентационный transceiver если он отсутствует:
|
|
459
|
-
|
|
460
|
-
```typescript
|
|
461
|
-
// SDK автоматически обрабатывает события restart
|
|
462
|
-
sipConnector.on('api:restart', (data) => {
|
|
463
|
-
if (data.videoTrackCount === 2) {
|
|
464
|
-
// SDK проверит наличие presentationVideo transceiver'а
|
|
465
|
-
// и добавит его автоматически если необходимо
|
|
466
|
-
console.log('Будет добавлен презентационный transceiver');
|
|
467
|
-
}
|
|
468
|
-
});
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### Ручное управление transceiver'ами
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
// Добавление нового transceiver'а
|
|
475
|
-
try {
|
|
476
|
-
const audioTransceiver = await sipConnector.callManager.addTransceiver('audio', {
|
|
477
|
-
direction: 'sendrecv',
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
const videoTransceiver = await sipConnector.callManager.addTransceiver('video', {
|
|
481
|
-
direction: 'sendonly',
|
|
482
|
-
sendEncodings: [
|
|
483
|
-
{ rid: 'low', maxBitrate: 500_000, scaleResolutionDownBy: 4 },
|
|
484
|
-
{ rid: 'high', maxBitrate: 2_000_000, scaleResolutionDownBy: 1 },
|
|
485
|
-
],
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
console.log('Transceiver'ы добавлены:', { audioTransceiver, videoTransceiver });
|
|
489
|
-
} catch (error) {
|
|
490
|
-
console.error('Ошибка добавления transceiver'а:', error);
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Мониторинг transceiver'ов
|
|
495
|
-
|
|
496
|
-
```typescript
|
|
497
|
-
// Проверка состояния transceiver'ов
|
|
498
|
-
const checkTransceivers = () => {
|
|
499
|
-
const transceivers = sipConnector.callManager.getTransceivers();
|
|
500
|
-
|
|
501
|
-
console.log('Статус transceiver'ов:', {
|
|
502
|
-
hasAudio: transceivers.mainAudio !== undefined,
|
|
503
|
-
hasVideo: transceivers.mainVideo !== undefined,
|
|
504
|
-
hasPresentation: transceivers.presentationVideo !== undefined,
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
// Детальная информация
|
|
508
|
-
if (transceivers.mainVideo) {
|
|
509
|
-
console.log('Основное видео:', {
|
|
510
|
-
mid: transceivers.mainVideo.mid,
|
|
511
|
-
direction: transceivers.mainVideo.direction,
|
|
512
|
-
currentDirection: transceivers.mainVideo.currentDirection,
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
// Проверка после установки соединения
|
|
518
|
-
sipConnector.on('call:confirmed', () => {
|
|
519
|
-
checkTransceivers();
|
|
520
|
-
});
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
---
|
|
524
|
-
|
|
525
429
|
## 📡 События и их обработка
|
|
526
430
|
|
|
527
431
|
### Архитектура событий
|
|
@@ -924,7 +828,6 @@ import {
|
|
|
924
828
|
SipConnector, // Низкоуровневый API
|
|
925
829
|
SipConnectorFacade, // Высокоуровневый фасад
|
|
926
830
|
StatsPeerConnection, // Сбор статистики
|
|
927
|
-
TransceiverManager, // Управление transceiver'ами
|
|
928
831
|
// ... другие экспорты
|
|
929
832
|
} from 'sip-connector';
|
|
930
833
|
```
|
|
@@ -941,10 +844,6 @@ await facade.replaceMediaStream(mediaStream, options);
|
|
|
941
844
|
// Получение удаленных потоков
|
|
942
845
|
const streams = facade.getRemoteStreams();
|
|
943
846
|
|
|
944
|
-
// Управление transceiver'ами (низкоуровневый API)
|
|
945
|
-
const transceivers = sipConnector.callManager.getTransceivers();
|
|
946
|
-
await sipConnector.callManager.addTransceiver('video', { direction: 'sendrecv' });
|
|
947
|
-
|
|
948
847
|
// Перезапуск ICE-соединения (низкоуровневый API)
|
|
949
848
|
await sipConnector.callManager.restartIce(options);
|
|
950
849
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const O=require("events-constructor"),G=require("debug"),k=require("@krivega/cancelable-promise"),y=require("@krivega/timeout-requester"),Q=require("repeated-calls"),re=require("xstate"),Y=require("stack-promises");require("ua-parser-js");require("sequent-promises");const z="sip-connector",c=G(z),De=()=>{G.enable(z)},ye=()=>{G.enable(`-${z}`)},we="Error decline with 603",Ue=1006,Le=n=>typeof n=="object"&&n!==null&&"code"in n&&n.code===Ue,Be=n=>n.message===we;var u=(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.AUDIO_ID="X-WEBRTC-AUDIOID",n))(u||{}),F=(n=>(n.AVAILABLE_SECOND_REMOTE_STREAM="YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="CONTENTEND",n.MUST_STOP_PRESENTATION="YOUMUSTSTOPSENDCONTENT",n))(F||{}),V=(n=>(n.SPECTATOR="SPECTATOR",n.PARTICIPANT="PARTICIPANT",n))(V||{}),b=(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))(b||{}),p=(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))(p||{}),v=(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))(v||{}),H=(n=>(n.ADMIN_STOP_MIC="ADMINSTOPMIC",n.ADMIN_START_MIC="ADMINSTARTMIC",n))(H||{}),x=(n=>(n.ADMIN_SYNC_FORCED="1",n.ADMIN_SYNC_NOT_FORCED="0",n))(x||{}),ae=(n=>(n.AUDIO="AUDIO",n.VIDEO="VIDEO",n.AUDIOPLUSPRESENTATION="AUDIOPLUSPRESENTATION",n))(ae||{}),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_SPECTATORS_WITH_AUDIO_ID="participant:move-request-to-spectators-with-audio-id",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))(g||{});const oe=["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-spectators-with-audio-id","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"];var I=(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))(I||{});class Fe{events;connectionManager;callManager;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.callManager=t,this.events=new O.TypedEvents(oe),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 i;try{i=this.getEstablishedRTCSessionProtected()}catch(r){s(r)}i&&(this.callManager.once("newDTMF",({originator:r})=>{r==="local"&&t()}),i.sendDTMF(e,{duration:120,interToneGap:600}))})}async sendChannels({inputChannels:e,outputChannels:t}){const s=this.getEstablishedRTCSessionProtected(),i=`${u.INPUT_CHANNELS}: ${e}`,r=`${u.OUTPUT_CHANNELS}: ${t}`,a=[i,r];return s.sendInfo(p.CHANNELS,void 0,{extraHeaders:a})}async sendMediaState({cam:e,mic:t},s={}){const i=this.getEstablishedRTCSessionProtected(),r=`${u.MEDIA_STATE}: currentstate`,a=`${u.MAIN_CAM_STATE}: ${Number(e)}`,o=`${u.MIC_STATE}: ${Number(t)}`,h=[r,a,o];return i.sendInfo(p.MEDIA_STATE,void 0,{noTerminateWhenError:!0,...s,extraHeaders:h})}async sendStats({availableIncomingBitrate:e}){const t=this.getEstablishedRTCSessionProtected(),i=[`${u.AVAILABLE_INCOMING_BITRATE}: ${e}`];return t.sendInfo(p.STATS,void 0,{noTerminateWhenError:!0,extraHeaders:i})}async sendRefusalToTurnOn(e,t={}){const s=this.getEstablishedRTCSessionProtected(),a=e==="mic"?0:1,h=[`${u.MEDIA_TYPE}: ${a}`];return s.sendInfo(p.REFUSAL,void 0,{noTerminateWhenError:!0,...t,extraHeaders:h})}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(p.SHARE_STATE,void 0,{extraHeaders:[u.MUST_STOP_PRESENTATION_P2P]})}async sendStoppedPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(p.SHARE_STATE,void 0,{extraHeaders:[u.STOP_PRESENTATION_P2P]})}async sendStoppedPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(p.SHARE_STATE,void 0,{extraHeaders:[u.STOP_PRESENTATION]})}async askPermissionToStartPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(p.SHARE_STATE,void 0,{extraHeaders:[u.START_PRESENTATION_P2P]})}async askPermissionToStartPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(p.SHARE_STATE,void 0,{extraHeaders:[u.START_PRESENTATION]})}async askPermissionToEnableCam(e={}){const t=this.getEstablishedRTCSessionProtected(),s=[u.ENABLE_MAIN_CAM];return t.sendInfo(p.MAIN_CAM,void 0,{noTerminateWhenError:!0,...e,extraHeaders:s}).catch(i=>{if(Be(i))throw i})}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(u.NOTIFY);if(t){const s=JSON.parse(t);this.handleNotify(s)}}catch(t){c("error parse notify",t)}};handleNotify=e=>{switch(e.cmd){case I.CHANNELS:{const t=e;this.triggerChannelsNotify(t);break}case I.WEBCAST_STARTED:{const t=e;this.triggerWebcastStartedNotify(t);break}case I.WEBCAST_STOPPED:{const t=e;this.triggerWebcastStoppedNotify(t);break}case I.ADDED_TO_LIST_MODERATORS:{const t=e;this.triggerAddedToListModeratorsNotify(t);break}case I.REMOVED_FROM_LIST_MODERATORS:{const t=e;this.triggerRemovedFromListModeratorsNotify(t);break}case I.ACCEPTING_WORD_REQUEST:{const t=e;this.triggerParticipationAcceptingWordRequest(t);break}case I.CANCELLING_WORD_REQUEST:{const t=e;this.triggerParticipationCancellingWordRequest(t);break}case I.MOVE_REQUEST_TO_STREAM:{const t=e;this.triggerParticipantMoveRequestToStream(t);break}case I.ACCOUNT_CHANGED:{this.triggerAccountChangedNotify();break}case I.ACCOUNT_DELETED:{this.triggerAccountDeletedNotify();break}case I.CONFERENCE_PARTICIPANT_TOKEN_ISSUED:{const t=e;this.triggerConferenceParticipantTokenIssued(t);break}default:c("unknown cmd",e)}};handleNewInfo=e=>{const{originator:t}=e;if(t!=="remote")return;const{request:s}=e,i=s,r=i.getHeader(u.CONTENT_TYPE);if(r!==void 0)switch(r){case b.ENTER_ROOM:{this.triggerEnterRoom(i),this.maybeTriggerChannels(i);break}case b.NOTIFY:{this.maybeHandleNotify(i);break}case b.SHARE_STATE:{this.triggerShareState(i);break}case b.MAIN_CAM:{this.triggerMainCamControl(i);break}case b.MIC:{this.triggerMicControl(i);break}case b.USE_LICENSE:{this.triggerUseLicense(i);break}case b.PARTICIPANT_STATE:{this.maybeTriggerParticipantMoveRequest(i);break}}};triggerChannelsNotify=e=>{const t=e.input,s=e.output,i={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS_NOTIFY,i)};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,{})};triggerAccountDeletedNotify=()=>{this.events.trigger(g.ACCOUNT_DELETED,{})};triggerConferenceParticipantTokenIssued=({body:{conference:e,participant:t,jwt:s}})=>{const i={conference:e,participant:t,jwt:s};this.events.trigger(g.CONFERENCE_PARTICIPANT_TOKEN_ISSUED,i)};maybeTriggerChannels=e=>{const t=e.getHeader(u.INPUT_CHANNELS),s=e.getHeader(u.OUTPUT_CHANNELS);if(t&&s){const i={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS,i)}};triggerEnterRoom=e=>{const t=e.getHeader(u.CONTENT_ENTER_ROOM),s=e.getHeader(u.PARTICIPANT_NAME);this.events.trigger(g.ENTER_ROOM,{room:t,participantName:s})};triggerShareState=e=>{const t=e.getHeader(u.CONTENT_SHARE_STATE);if(t!==void 0)switch(t){case F.AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.AVAILABLE_SECOND_REMOTE_STREAM,{});break}case F.NOT_AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.NOT_AVAILABLE_SECOND_REMOTE_STREAM,{});break}case F.MUST_STOP_PRESENTATION:{this.events.trigger(g.MUST_STOP_PRESENTATION,{});break}}};maybeTriggerParticipantMoveRequest=e=>{const t=e.getHeader(u.CONTENT_PARTICIPANT_STATE),s=e.getHeader(u.AUDIO_ID);t===V.SPECTATOR&&(s?this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS_WITH_AUDIO_ID,{audioId:s}):this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,{})),t===V.PARTICIPANT&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS,{})};triggerMainCamControl=e=>{const t=e.getHeader(u.MAIN_CAM),s=e.getHeader(u.MEDIA_SYNC),i=s===x.ADMIN_SYNC_FORCED;if(t===v.ADMIN_START_MAIN_CAM){this.events.trigger(g.ADMIN_START_MAIN_CAM,{isSyncForced:i});return}if(t===v.ADMIN_STOP_MAIN_CAM){this.events.trigger(g.ADMIN_STOP_MAIN_CAM,{isSyncForced:i});return}(t===v.RESUME_MAIN_CAM||t===v.PAUSE_MAIN_CAM)&&s!==void 0&&this.events.trigger(g.ADMIN_FORCE_SYNC_MEDIA_STATE,{isSyncForced:i});const r=e.getHeader(u.MAIN_CAM_RESOLUTION);this.events.trigger(g.MAIN_CAM_CONTROL,{mainCam:t,resolutionMainCam:r})};triggerMicControl=e=>{const t=e.getHeader(u.MIC),i=e.getHeader(u.MEDIA_SYNC)===x.ADMIN_SYNC_FORCED;t===H.ADMIN_START_MIC?this.events.trigger(g.ADMIN_START_MIC,{isSyncForced:i}):t===H.ADMIN_STOP_MIC&&this.events.trigger(g.ADMIN_STOP_MIC,{isSyncForced:i})};triggerUseLicense=e=>{const t=e.getHeader(u.CONTENT_USE_LICENSE);this.events.trigger(g.USE_LICENSE,t)}}function ke(n){return e=>`sip:${e}@${n}`}const $e=(n,e)=>()=>Math.floor(Math.random()*(e-n))+n,ce=n=>n.trim().replaceAll(" ","_"),qe=$e(1e5,99999999),We=n=>n.some(t=>{const{kind:s}=t;return s==="video"});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.CALL_STATUS_CHANGED="call-status-changed",n))(N||{}),he=(n=>(n.LOCAL="local",n.REMOTE="remote",n.SYSTEM="system",n))(he||{});const de=["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"],Ve=["peerconnection:confirmed","peerconnection:ontrack","ended:fromserver","call-status-changed"],le=[...de,...Ve],He=(n,e)=>{n.getVideoTracks().forEach(s=>{"contentHint"in s&&s.contentHint!==e&&(s.contentHint=e)})},L=(n,{directionVideo:e,directionAudio:t,contentHint:s}={})=>{if(!n||e==="recvonly"&&t==="recvonly")return;const i=t==="recvonly"?[]:n.getAudioTracks(),r=e==="recvonly"?[]:n.getVideoTracks(),a=[...i,...r],o=new MediaStream(a);return o.getTracks=()=>[...o.getAudioTracks(),...o.getVideoTracks()],s&&s!=="none"&&He(o,s),o};var X=(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))(X||{});class xe{events;rtcSession;disposers=new Set;onReset;constructor(e,{onReset:t}){this.events=e,this.onReset=t,e.on(N.FAILED,this.handleEnded),e.on(N.ENDED,this.handleEnded)}get connection(){return this.rtcSession?.connection}get isCallActive(){return this.rtcSession?.isEstablished()===!0}getEstablishedRTCSession=()=>this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0;startCall=async(e,t,{number:s,mediaStream:i,extraHeaders:r=[],ontrack:a,iceServers:o,directionVideo:h,directionAudio:d,contentHint:T,offerToReceiveAudio:S=!0,offerToReceiveVideo:l=!0,degradationPreference:A,sendEncodings:m,onAddedTransceiver:R})=>new Promise((M,$)=>{this.handleCall({ontrack:a}).then(M).catch(q=>{$(q)}),this.rtcSession=e.call(t(s),{mediaStream:L(i,{directionVideo:h,directionAudio:d,contentHint:T}),pcConfig:{iceServers:o},rtcOfferConstraints:{offerToReceiveAudio:S,offerToReceiveVideo:l},eventHandlers:this.events.triggers,extraHeaders:r,directionVideo:h,directionAudio:d,degradationPreference:A,sendEncodings:m,onAddedTransceiver:R})});async endCall(){const{rtcSession:e}=this;if(e&&!e.isEnded())return e.terminateAsync({cause:X.CANCELED}).finally(()=>{this.reset()});this.reset()}answerToIncomingCall=async(e,{mediaStream:t,ontrack:s,extraHeaders:i=[],iceServers:r,directionVideo:a,directionAudio:o,offerToReceiveAudio:h,offerToReceiveVideo:d,contentHint:T,degradationPreference:S,sendEncodings:l,onAddedTransceiver:A})=>new Promise((m,R)=>{try{this.rtcSession=e,this.subscribeToSessionEvents(e),this.handleCall({ontrack:s}).then(m).catch(M=>{R(M)}),e.answer({pcConfig:{iceServers:r},rtcOfferConstraints:{offerToReceiveAudio:h,offerToReceiveVideo:d},mediaStream:L(t,{directionVideo:a,directionAudio:o,contentHint:T}),extraHeaders:i,directionVideo:a,directionAudio:o,degradationPreference:S,sendEncodings:l,onAddedTransceiver:A})}catch(M){R(M)}});getRemoteTracks(){return this.connection?this.connection.getReceivers().map(({track:s})=>s):void 0}async replaceMediaStream(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");const{contentHint:s}=t??{},i=L(e,{contentHint:s});if(i===void 0)throw new Error("No preparedMediaStream");return this.rtcSession.replaceMediaStream(i,t)}async restartIce(e){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.restartIce(e)}handleCall=async({ontrack:e})=>new Promise((t,s)=>{const i=()=>{this.events.on(N.PEER_CONNECTION,T),this.events.on(N.CONFIRMED,S)},r=()=>{this.events.off(N.PEER_CONNECTION,T),this.events.off(N.CONFIRMED,S)},a=()=>{this.events.on(N.FAILED,h),this.events.on(N.ENDED,h)},o=()=>{this.events.off(N.FAILED,h),this.events.off(N.ENDED,h)},h=l=>{r(),o(),s(l)};let d;const T=({peerconnection:l})=>{d=l;const A=m=>{this.events.trigger(N.PEER_CONNECTION_ONTRACK,m),e&&e(m)};l.addEventListener("track",A),this.disposers.add(()=>{l.removeEventListener("track",A)})},S=()=>{d!==void 0&&this.events.trigger(N.PEER_CONNECTION_CONFIRMED,d),r(),o(),t(d)};i(),a()});subscribeToSessionEvents(e){this.events.eachTriggers((t,s)=>{const i=de.find(r=>r===s);i&&(e.on(i,t),this.disposers.add(()=>{e.off(i,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.unsubscribeFromSessionEvents(),this.onReset()}}class Ge{remoteStreams={};reset(){this.remoteStreams={}}generateStream(e,t){const{id:s}=e,i=this.remoteStreams[s]??new MediaStream;return t&&i.addTrack(t),i.addTrack(e),this.remoteStreams[s]=i,i}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,i)=>{if(s.kind==="audio")return;const r=s,a=e[i-1];let o;a?.kind==="audio"&&(o=a);const h=this.generateStream(r,o);t.push(h)}),t}generateAudioStreams(e){return e.map(t=>this.generateAudioStream(t))}}class Qe{events;isPendingCall=!1;isPendingAnswer=!1;rtcSession;remoteStreams={};callConfiguration={};remoteStreamsManager=new Ge;mcuSession;constructor(){this.events=new O.TypedEvents(le),this.mcuSession=new xe(this.events,{onReset:this.reset}),this.subscribeCallStatusChange()}get requested(){return this.isPendingCall||this.isPendingAnswer}get connection(){return this.mcuSession.connection}get isCallActive(){return this.mcuSession.isCallActive}getEstablishedRTCSession=()=>this.mcuSession.getEstablishedRTCSession();on(e,t){return this.events.on(e,t)}onRace(e,t){return this.events.onRace(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)}startCall=async(e,t,s)=>(this.isPendingCall=!0,this.callConfiguration.number=s.number,this.callConfiguration.answer=!1,this.mcuSession.startCall(e,t,s).finally(()=>{this.isPendingCall=!1}));async endCall(){return this.mcuSession.endCall()}answerToIncomingCall=async(e,t)=>{this.isPendingAnswer=!0;const s=e();return this.callConfiguration.answer=!0,this.callConfiguration.number=s.remote_identity.uri.user,this.mcuSession.answerToIncomingCall(s,t).finally(()=>{this.isPendingAnswer=!1})};getCallConfiguration(){return{...this.callConfiguration}}getRemoteStreams(){const e=this.mcuSession.getRemoteTracks();if(e)return We(e)?this.remoteStreamsManager.generateStreams(e):this.remoteStreamsManager.generateAudioStreams(e)}async replaceMediaStream(e,t){return this.mcuSession.replaceMediaStream(e,t)}async restartIce(e){return this.mcuSession.restartIce(e)}reset=()=>{this.remoteStreamsManager.reset(),this.callConfiguration.number=void 0,this.callConfiguration.answer=!1};subscribeCallStatusChange(){let{isCallActive:e}=this;const{ACCEPTED:t,CONFIRMED:s,ENDED:i,FAILED:r}=N;this.onRace([t,s,i,r],()=>{e=this.maybeTriggerCallStatus(e)})}maybeTriggerCallStatus(e){const t=this.isCallActive;return t!==e&&this.events.trigger(N.CALL_STATUS_CHANGED,{isCallActive:t}),t}}const Ye=(n,e)=>(n.degradationPreference=e.degradationPreference,n),ze=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},ue=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,Xe=ue(),Je=(n,e)=>{if(Xe(n,e))return n},Ke=(n,e)=>{const t=n.maxBitrate,s=Je(e,t);return s!==void 0&&(n.maxBitrate=s),n},ge=1,je=ue(ge),Ze=(n,e)=>{const t=n===void 0?void 0:Math.max(n,ge);if(t!==void 0&&je(t,e))return t},et=(n,e)=>{const t=n.scaleResolutionDownBy,s=Ze(e,t);return s!==void 0&&(n.scaleResolutionDownBy=s),n},tt=(n,e)=>{const t=e.encodings?.length??0;return ze(n,t),n.encodings.forEach((s,i)=>{const r=(e?.encodings??[])[i],a=r?.maxBitrate,o=r?.scaleResolutionDownBy;Ke(s,a),et(s,o)}),n},nt=(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},Te=async(n,e)=>{const t=n.getParameters(),s=JSON.parse(JSON.stringify(t));tt(t,e),Ye(t,e);const i=nt(s,t);return i&&await n.setParameters(t),{parameters:t,isChanged:i}},J=async(n,e,t)=>{const{isChanged:s,parameters:i}=await Te(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return s&&t&&t(i),{isChanged:s,parameters:i}},st=(n,e)=>n.find(t=>t.track!==null&&e.getTracks().includes(t.track)),it=async(n,e,t)=>{const s=st(n,e);if(s)return J(s,{maxBitrate:t})};var P=(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))(P||{});const Se=["presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed"],rt=1,at=n=>Q.hasCanceledError(n);class ot{events;promisePendingStartPresentation;promisePendingStopPresentation;streamPresentationCurrent;maxBitrate;cancelableSendPresentationWithRepeatedCalls;callManager;constructor({callManager:e,maxBitrate:t}){this.callManager=e,this.maxBitrate=t,this.events=new O.TypedEvents(Se),this.subscribe()}get isPendingPresentation(){return!!this.promisePendingStartPresentation||!!this.promisePendingStopPresentation}async startPresentation(e,t,{isNeedReinvite:s,contentHint:i,sendEncodings:r,onAddedTransceiver:a}={},o){const h=this.getRtcSessionProtected();if(this.streamPresentationCurrent)throw new Error("Presentation is already started");return this.sendPresentationWithDuplicatedCalls(e,{rtcSession:h,stream:t,presentationOptions:{isNeedReinvite:s,contentHint:i,sendEncodings:r,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 i=this.callManager.getEstablishedRTCSession();return i&&t?s=e().then(async()=>i.stopPresentation(t)).catch(r=>{const a=r instanceof Error?r:new Error(String(r));throw this.events.trigger(P.FAILED_PRESENTATION,a),r}):t&&this.events.trigger(P.ENDED_PRESENTATION,t),this.promisePendingStopPresentation=s,s.finally(()=>{this.resetPresentation()})}async updatePresentation(e,t,{contentHint:s,sendEncodings:i,onAddedTransceiver:r}={}){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:i,onAddedTransceiver:r}).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(P.START_PRESENTATION,e)}),this.callManager.on("presentation:started",e=>{this.events.trigger(P.STARTED_PRESENTATION,e)}),this.callManager.on("presentation:end",e=>{this.events.trigger(P.END_PRESENTATION,e)}),this.callManager.on("presentation:ended",e=>{this.events.trigger(P.ENDED_PRESENTATION,e)}),this.callManager.on("presentation:failed",e=>{this.events.trigger(P.FAILED_PRESENTATION,e)}),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded)}async sendPresentationWithDuplicatedCalls(e,{rtcSession:t,stream:s,presentationOptions:i,options:r={callLimit:rt}}){const a=async()=>this.sendPresentation(e,t,s,i),o=()=>!!this.streamPresentationCurrent;return this.cancelableSendPresentationWithRepeatedCalls=Q.repeatedCallsAsync({targetFunction:a,isComplete:o,isRejectAsValid:!0,...r}),this.cancelableSendPresentationWithRepeatedCalls.then(h=>h)}async sendPresentation(e,t,s,{isNeedReinvite:i=!0,contentHint:r="detail",degradationPreference:a,sendEncodings:o,onAddedTransceiver:h}){const d=L(s,{contentHint:r});if(d===void 0)throw new Error("No streamPresentationTarget");this.streamPresentationCurrent=d;const T=e().then(async()=>t.startPresentation(d,i,{degradationPreference:a,sendEncodings:o,onAddedTransceiver:h})).then(this.setMaxBitrate).then(()=>s).catch(S=>{this.removeStreamPresentationCurrent();const l=S instanceof Error?S:new Error(String(S));throw this.events.trigger(P.FAILED_PRESENTATION,l),S});return this.promisePendingStartPresentation=T,T.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 i=e.getSenders();await it(i,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 ct{data;getUa;constructor(e){this.getUa=e.getUa}isConfigured(){return this.getUa()!==void 0}get(){if(this.data!==void 0)return{...this.data}}set(e){if(e===void 0){this.data=void 0;return}this.data={...e}}update(e,t){if(this.data===void 0)throw new Error("data is not exist");this.data[e]=t}clear(){this.data=void 0}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 C=(n=>(n.CONNECTING="connecting",n.CONNECTED="connected",n.DISCONNECTED="disconnected",n.DISCONNECTING="disconnecting",n.NEW_RTC_SESSION="newRTCSession",n.REGISTERED="registered",n.UNREGISTERED="unregistered",n.REGISTRATION_FAILED="registrationFailed",n.NEW_MESSAGE="newMessage",n.SIP_EVENT="sipEvent",n.CONNECT_STARTED="connect-started",n.CONNECT_SUCCEEDED="connect-succeeded",n.CONNECT_FAILED="connect-failed",n.CONNECT_PARAMETERS_RESOLVE_SUCCESS="connect-parameters-resolve-success",n.CONNECT_PARAMETERS_RESOLVE_FAILED="connect-parameters-resolve-failed",n.CONNECTED_WITH_CONFIGURATION="connected-with-configuration",n))(C||{});const Ce=["connecting","connected","disconnected","newRTCSession","registered","unregistered","registrationFailed","newMessage","sipEvent"],ht=["disconnecting","connect-started","connect-succeeded","connect-failed","connect-parameters-resolve-success","connect-parameters-resolve-failed","connected-with-configuration"],Ee=[...Ce,...ht],dt=3;class lt{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,this.proxyEvents()}connect=async(e,t)=>(this.cancelRequests(),this.connectWithDuplicatedCalls(e,t));set=async({displayName:e})=>new Promise((t,s)=>{const i=this.getUa();if(!i){s(new Error("this.ua is not initialized"));return}let r=!1;const a=this.getConnectionConfiguration();e!==void 0&&e!==a?.displayName&&(r=i.set("display_name",ce(e)),this.updateConnectionConfiguration("displayName",e));const o=r;o?t(o):s(new Error("nothing changed"))});disconnect=async()=>{this.events.trigger(C.DISCONNECTING,{});const e=new Promise(s=>{this.events.once(C.DISCONNECTED,()=>{s()})}),t=this.getUa();return t?t.stop():this.events.trigger(C.DISCONNECTED,{socket:{},error:!1}),e.finally(()=>{t?.removeAllListeners(),this.setUa(void 0),this.stateMachine.reset()})};cancelRequests(){this.cancelConnectWithRepeatedCalls()}connectWithDuplicatedCalls=async(e,{callLimit:t=dt}={})=>{const s=async()=>this.connectInner(e),i=r=>{const h=this.getUa()?.isConnected()===!0&&this.hasEqualConnectionConfiguration(e),d=r!=null&&!Le(r);return h||d};return this.stateMachine.startConnect(),this.cancelableConnectWithRepeatedCalls=Q.repeatedCallsAsync({targetFunction:s,isComplete:i,callLimit:t,isRejectAsValid:!0,isCheckBeforeCall:!1}),this.cancelableConnectWithRepeatedCalls.then(r=>{if("ua"in r&&r.ua instanceof this.JsSIP.UA)return r;throw r})};hasEqualConnectionConfiguration(e){const{configuration:t}=this.uaFactory.createConfiguration(e),i=this.getUa()?.configuration;return i?i.password===t.password&&i.register===t.register&&i.uri.toString()===t.uri&&i.display_name===t.display_name&&i.user_agent===t.user_agent&&i.sockets===t.sockets&&i.session_timers===t.session_timers&&i.register_expires===t.register_expires&&i.connection_recovery_min_interval===t.connection_recovery_min_interval&&i.connection_recovery_max_interval===t.connection_recovery_max_interval:!1}connectInner=async e=>this.initUa(e).then(async()=>this.start()).then(t=>{const s=this.getConnectionConfiguration();if(s===void 0)throw new Error("connectionConfiguration has not defined");return{...s,ua:t}});initUa=async({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:i,remoteAddress:r,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:h,connectionRecoveryMaxInterval:d,userAgent:T,displayName:S="",register:l=!1,extraHeaders:A=[]})=>{this.stateMachine.startInitUa(),this.setConnectionConfiguration({sipServerUrl:s,displayName:S,register:l,user:e,password:t}),this.getUa()&&await this.disconnect();const{ua:R,helpers:M}=this.uaFactory.createUAWithConfiguration({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:i,displayName:S,register:l,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:h,connectionRecoveryMaxInterval:d,userAgent:T,remoteAddress:r,extraHeaders:A},this.events);return this.setUa(R),this.setSipServerUrl(M.getSipServerUrl),this.setSocket(M.socket),R};start=async()=>new Promise((e,t)=>{const s=this.getUa();if(!s){t(new Error("this.ua is not initialized"));return}let i;i=((h,d)=>{if(this.getConnectionConfiguration()?.register===!0)return this.registrationManager.subscribeToStartEvents(h,d);const S=C.CONNECTED,l=[C.DISCONNECTED];return this.events.on(S,h),l.forEach(A=>{this.events.on(A,d)}),()=>{this.events.off(S,h),l.forEach(A=>{this.events.off(A,d)})}})(()=>{i?.(),e(s)},h=>{i?.(),t(h)}),s.start()});cancelConnectWithRepeatedCalls(){this.cancelableConnectWithRepeatedCalls?.cancel()}proxyEvents(){this.events.on(C.CONNECTED,()=>{const e=this.getConnectionConfiguration(),t=this.getUa();e!==void 0&&t!==void 0&&this.events.trigger(C.CONNECTED_WITH_CONFIGURATION,{...e,ua:t})})}}var Ae=(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))(Ae||{});const ut=re.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{c(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{c("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 gt{actor;stateChangeListeners=new Set;events;unsubscribeFromEvents;actorSubscription;constructor(e){this.events=e,this.actor=re.createActor(ut),this.actorSubscription=this.actor.subscribe(t=>{const s=t.value;this.stateChangeListeners.forEach(i=>{i(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(Ae).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)){c(`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 Tt{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(C.REGISTERED,t),e.on(C.REGISTRATION_FAILED,s),e.register()})}async unregister(){const e=this.getUaProtected();return new Promise(t=>{e.on(C.UNREGISTERED,t),e.unregister()})}async tryRegister(){try{await this.unregister()}catch(e){c("tryRegister",e)}return this.register()}subscribeToStartEvents(e,t){const s=C.REGISTERED,i=[C.REGISTRATION_FAILED,C.DISCONNECTED];return this.events.on(s,e),i.forEach(r=>{this.events.on(r,t)}),()=>{this.events.off(s,e),i.forEach(r=>{this.events.off(r,t)})}}}class St{uaFactory;getUaProtected;constructor(e){this.uaFactory=e.uaFactory,this.getUaProtected=e.getUaProtected}async sendOptions(e,t,s){const i=this.getUaProtected();return new Promise((r,a)=>{try{i.sendOptions(e,t,{extraHeaders:s,eventHandlers:{succeeded:()=>{r()},failed:a}})}catch(o){a(o)}})}async ping(e,t){const i=this.getUaProtected().configuration.uri;return this.sendOptions(i,e,t)}async checkTelephony({userAgent:e,displayName:t,sipServerUrl:s,sipWebSocketServerURL:i,remoteAddress:r,extraHeaders:a}){return new Promise((o,h)=>{const{configuration:d}=this.uaFactory.createConfiguration({sipWebSocketServerURL:i,displayName:t,userAgent:e,sipServerUrl:s}),T=this.uaFactory.createUA({...d,remoteAddress:r,extraHeaders:a}),S=()=>{const A=new Error("Telephony is not available");h(A)};T.once(C.DISCONNECTED,S);const l=()=>{T.removeAllListeners(),T.once(C.DISCONNECTED,()=>{o()}),T.stop()};T.once(C.CONNECTED,l),T.start()})}}const Ct=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 validateParametersConnection({register:e,password:t,user:s,sipServerUrl:i,sipWebSocketServerURL:r}){if(!i)throw new Error("sipServerUrl is required");if(!r)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():`${qe()}`}static buildExtraHeaders(e,t){const s=e!==void 0&&e!==""?Ct(e):[];return t===void 0?s:[...s,...t]}createConfiguration({user:e,password:t,sipWebSocketServerURL:s,displayName:i="",sipServerUrl:r,register:a=!1,sessionTimers:o=!1,registerExpires:h=300,connectionRecoveryMinInterval:d=2,connectionRecoveryMaxInterval:T=6,userAgent:S}){D.validateParametersConnection({register:a,password:t,user:e,sipServerUrl:r,sipWebSocketServerURL:s});const l=D.resolveAuthorizationUser(a,e),A=ke(r),m=A(l),R=new this.JsSIP.WebSocketInterface(s);return{configuration:{password:t,register:a,uri:m,display_name:ce(i),user_agent:S,sdpSemantics:"unified-plan",sockets:[R],session_timers:o,register_expires:h,connection_recovery_min_interval:d,connection_recovery_max_interval:T},helpers:{socket:R,getSipServerUrl:A}}}createUA({remoteAddress:e,extraHeaders:t,...s}){const i=new this.JsSIP.UA(s),r=D.buildExtraHeaders(e,t);return r.length>0&&i.registrator().setExtraHeaders(r),i}createUAWithConfiguration(e,t){const{configuration:s,helpers:i}=this.createConfiguration(e),r=this.createUA({...s,remoteAddress:e.remoteAddress,extraHeaders:e.extraHeaders});return t.eachTriggers((a,o)=>{const h=Ce.find(d=>d===o);h&&r.on(h,a)}),{ua:r,helpers:i}}}const Ne="Not ready for connection",Re=n=>n instanceof Error&&n.message===Ne,Et=()=>new Error(Ne),At=async n=>typeof n=="function"?n():n;class Nt{events;ua;socket;uaFactory;registrationManager;stateMachine;connectionFlow;sipOperations;configurationManager;JsSIP;constructor({JsSIP:e}){this.JsSIP=e,this.events=new O.TypedEvents(Ee),this.uaFactory=new D(e),this.registrationManager=new Tt({events:this.events,getUaProtected:this.getUaProtected}),this.stateMachine=new gt(this.events),this.configurationManager=new ct({getUa:this.getUa}),this.sipOperations=new St({uaFactory:this.uaFactory,getUaProtected:this.getUaProtected}),this.connectionFlow=new lt({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 isIdle(){return this.stateMachine.isIdle}get isDisconnected(){return this.stateMachine.isDisconnected}get isFailed(){return this.stateMachine.isFailed}get connectionState(){return this.stateMachine.state}get isRegistered(){return D.isRegisteredUA(this.ua)}get isRegisterConfig(){return this.configurationManager.isRegister()}connect=async(e,t)=>this.disconnect().catch(s=>{c("connect: disconnect error",s)}).then(async()=>this.connectWithProcessError(e,t));set=async({displayName:e})=>this.connectionFlow.set({displayName:e});disconnect=async()=>{if(this.isConfigured())return 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;connectWithProcessError=async(e,t)=>{if(!(t?.hasReadyForConnection?.()??!0))throw Et();return this.processConnect(e,t).catch(async i=>{const r=i;return this.disconnect().then(()=>{throw r}).catch(()=>{throw r})})};processConnect=async(e,t)=>(this.events.trigger(C.CONNECT_STARTED,{}),At(e).then(s=>(this.events.trigger(C.CONNECT_PARAMETERS_RESOLVE_SUCCESS,s),s)).catch(s=>{throw this.events.trigger(C.CONNECT_PARAMETERS_RESOLVE_FAILED,s),s}).then(async s=>this.connectionFlow.connect(s,t)).then(s=>(this.events.trigger(C.CONNECT_SUCCEEDED,{...s}),s)).catch(s=>{const i=s??new Error("Failed to connect to server");throw this.events.trigger(C.CONNECT_FAILED,i),i}))}class Rt{connectionManager;stackPromises=Y.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());stop(){this.stackPromises.stop()}}const Z=0,It=30;class mt{countInner=Z;initialCount=Z;limitInner=It;isInProgress=!1;onStatusChange;constructor({onStatusChange:e}){this.onStatusChange=e}get count(){return this.countInner}get limit(){return this.limitInner}get isAttemptInProgress(){return this.isInProgress}hasLimitReached(){return this.countInner>=this.limitInner}startAttempt(){this.isInProgress||(this.isInProgress=!0,this.onStatusChange({isInProgress:this.isInProgress}))}finishAttempt(){this.isInProgress&&(this.isInProgress=!1,this.onStatusChange({isInProgress:this.isInProgress}))}increment(){this.count<this.limit&&(this.countInner+=1)}reset(){this.countInner=this.initialCount,this.finishAttempt()}}class pt{connectionManager;interval;checkTelephonyByTimeout=void 0;cancelableBeforeRequest=void 0;constructor({connectionManager:e,interval:t}){this.connectionManager=e,this.interval=t}start({onBeforeRequest:e,onSuccessRequest:t,onFailRequest:s}){this.stop(),this.cancelableBeforeRequest=new k.CancelableRequest(e),this.checkTelephonyByTimeout=y.resolveRequesterByTimeout({isDontStopOnFail:!0,requestInterval:this.interval,request:async()=>{if(!this.cancelableBeforeRequest)throw new Error("cancelableBeforeRequest is not defined");const i=await this.cancelableBeforeRequest.request();return this.connectionManager.checkTelephony(i)}}),this.checkTelephonyByTimeout.start(void 0,{onFailRequest:s,onSuccessRequest:()=>{this.stop(),t()}})}stop(){this.checkTelephonyByTimeout?.stop(),this.checkTelephonyByTimeout=void 0,this.cancelableBeforeRequest?.cancelRequest(),this.cancelableBeforeRequest=void 0}}var _=(n=>(n.BEFORE_ATTEMPT="before-attempt",n.SUCCESS="success",n.FAILED_ALL_ATTEMPTS="failed-all-attempts",n.CANCELLED_ATTEMPTS="cancelled-attempts",n.CHANGED_ATTEMPT_STATUS="changed-attempt-status",n.STOP_ATTEMPTS_BY_ERROR="stop-attempts-by-error",n.LIMIT_REACHED_ATTEMPTS="limit-reached-attempts",n))(_||{});const Ie=["before-attempt","success","failed-all-attempts","cancelled-attempts","changed-attempt-status","stop-attempts-by-error","limit-reached-attempts"];class K{callManager;disposers=[];constructor({callManager:e}){this.callManager=e}subscribe(e){this.unsubscribe(),this.disposers.push(this.callManager.on("call-status-changed",()=>{this.handleCallStatusChange(e)})),this.handleCallStatusChange(e)}unsubscribe(){this.disposers.forEach(e=>{e()}),this.disposers=[]}handleCallStatusChange({onActive:e,onInactive:t}){this.callManager.isCallActive?e?.():t()}}const _t=15e3,Mt=2;class ft{connectionManager;pingServerByTimeoutWithFailCalls;constructor({connectionManager:e}){this.connectionManager=e,this.pingServerByTimeoutWithFailCalls=y.requesterByTimeoutsWithFailCalls(Mt,{whenPossibleRequest:async()=>{},requestInterval:_t,request:async()=>(c("ping"),this.connectionManager.ping().then(()=>{c("ping success")}))})}start({onFailRequest:e}){this.pingServerByTimeoutWithFailCalls.start(void 0,{onFailRequest:e}).catch(c)}stop(){this.pingServerByTimeoutWithFailCalls.stop()}}class vt{pingServerRequester;notActiveCallSubscriber;constructor({connectionManager:e,callManager:t}){this.pingServerRequester=new ft({connectionManager:e}),this.notActiveCallSubscriber=new K({callManager:t})}start({onFailRequest:e}){c("start"),this.notActiveCallSubscriber.subscribe({onActive:()=>{this.pingServerRequester.stop()},onInactive:()=>{this.pingServerRequester.start({onFailRequest:e})}})}stop(){c("stop"),this.pingServerRequester.stop(),this.unsubscribeCallStatusChange()}unsubscribeCallStatusChange(){this.notActiveCallSubscriber.unsubscribe()}}class Pt{connectionManager;isRegistrationFailed=!1;disposers=[];notActiveCallSubscriber;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.notActiveCallSubscriber=new K({callManager:t})}subscribe(e){this.unsubscribe(),this.disposers.push(this.connectionManager.on("registrationFailed",()=>{this.setIsRegistrationFailed()})),this.notActiveCallSubscriber.subscribe({onInactive:()=>{this.isRegistrationFailed&&e()}}),this.disposers.push(()=>{this.notActiveCallSubscriber.unsubscribe()})}unsubscribe(){this.disposers.forEach(e=>{e()}),this.disposers=[],this.resetIsRegistrationFailed()}setIsRegistrationFailed(){this.isRegistrationFailed=!0}resetIsRegistrationFailed(){this.isRegistrationFailed=!1}}const Ot=3e3,bt=15e3,ee={LIMIT_REACHED:"Limit reached",FAILED_TO_RECONNECT:"Failed to reconnect"},Dt=async()=>{},yt=n=>!0;class wt{events;connectionManager;connectionQueueManager;checkTelephonyRequester;pingServerIfNotActiveCallRequester;registrationFailedOutOfCallSubscriber;attemptsState;delayBetweenAttempts;cancelableRequestBeforeRetry;onBeforeRetry;canRetryOnError;networkInterfacesSubscriber;resumeFromSleepModeSubscriber;notActiveCallSubscriber;constructor({connectionQueueManager:e,connectionManager:t,callManager:s},i){const r=i?.onBeforeRetry??Dt,a=i?.canRetryOnError??yt;this.connectionQueueManager=e,this.connectionManager=t,this.onBeforeRetry=r,this.canRetryOnError=a,this.networkInterfacesSubscriber=i?.networkInterfacesSubscriber,this.resumeFromSleepModeSubscriber=i?.resumeFromSleepModeSubscriber,this.events=new O.TypedEvents(Ie),this.checkTelephonyRequester=new pt({connectionManager:t,interval:i?.checkTelephonyRequestInterval??bt}),this.pingServerIfNotActiveCallRequester=new vt({connectionManager:t,callManager:s}),this.registrationFailedOutOfCallSubscriber=new Pt({connectionManager:t,callManager:s}),this.attemptsState=new mt({onStatusChange:this.emitStatusChange}),this.cancelableRequestBeforeRetry=new k.CancelableRequest(r),this.delayBetweenAttempts=new y.DelayRequester(i?.timeoutBetweenAttempts??Ot),this.notActiveCallSubscriber=new K({callManager:s})}start(e){c("auto connector start"),this.restartConnectionAttempts(e),this.subscribeToNotActiveCall(e)}stop(){c("auto connector stop"),this.unsubscribeFromNotActiveCall(),this.unsubscribeFromHardwareTriggers(),this.stopConnectionFlow().catch(e=>{c("auto connector stop from stop method: error",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)}restartConnectionAttempts(e){c("auto connector restart connection attempts"),this.stopConnectionFlow().then(async()=>this.attemptConnection(e)).catch(t=>{c("auto connector failed to restart connection attempts:",t)})}async stopConnectionFlow(){c("stopConnectionFlow"),this.stopAttempts(),this.stopConnectTriggers(),await this.connectionQueueManager.disconnect()}stopAttempts(){this.attemptsState.isAttemptInProgress&&this.connectionQueueManager.stop(),this.delayBetweenAttempts.cancelRequest(),this.cancelableRequestBeforeRetry.cancelRequest(),this.attemptsState.reset()}stopConnectTriggers(){c("stopConnectTriggers"),this.stopPingRequester(),this.checkTelephonyRequester.stop(),this.registrationFailedOutOfCallSubscriber.unsubscribe()}startCheckTelephony(e){c("startCheckTelephony"),this.checkTelephonyRequester.start({onBeforeRequest:async()=>(await this.onBeforeRetry(),e.getParameters()),onSuccessRequest:()=>{c("startCheckTelephony: onSuccessRequest"),this.connectIfDisconnected(e)},onFailRequest:t=>{c("startCheckTelephony: onFailRequest",t.message)}})}async attemptConnection(e){if(c("attemptConnection: attempts.count",this.attemptsState.count),this.events.trigger(_.BEFORE_ATTEMPT,{}),this.stopConnectTriggers(),this.attemptsState.hasLimitReached()){c("attemptConnection: limit reached"),this.handleLimitReached(e);return}return this.attemptsState.startAttempt(),this.attemptsState.increment(),this.executeConnectionAttempt(e)}async executeConnectionAttempt(e){try{await this.connectionQueueManager.connect(e.getParameters,e.options),c("executeConnectionAttempt: success"),this.handleSucceededAttempt(e)}catch(t){this.handleConnectionError(t,e)}}handleConnectionError(e,t){if(Re(e)){this.attemptsState.finishAttempt(),this.events.trigger(_.STOP_ATTEMPTS_BY_ERROR,e);return}if(!this.canRetryOnError(e)){c("executeConnectionAttempt: error does not allow retry",e),this.attemptsState.finishAttempt(),this.events.trigger(_.STOP_ATTEMPTS_BY_ERROR,e);return}if(Y.isPromiseIsNotActualError(e)){c("executeConnectionAttempt: not actual error",e),this.attemptsState.finishAttempt(),this.events.trigger(_.CANCELLED_ATTEMPTS,e);return}c("executeConnectionAttempt: error",e),this.scheduleReconnect(t)}handleLimitReached(e){this.attemptsState.finishAttempt(),this.events.trigger(_.LIMIT_REACHED_ATTEMPTS,new Error(ee.LIMIT_REACHED)),this.startCheckTelephony(e)}handleSucceededAttempt(e){c("handleSucceededAttempt"),this.subscribeToConnectTriggers(e),this.events.trigger(_.SUCCESS)}subscribeToConnectTriggers(e){this.startPingRequester(e),this.registrationFailedOutOfCallSubscriber.subscribe(()=>{c("registrationFailedOutOfCallListener callback"),this.restartConnectionAttempts(e)})}subscribeToNotActiveCall(e){this.notActiveCallSubscriber.subscribe({onActive:()=>{c("subscribeToNotActiveCall onActive"),this.unsubscribeFromHardwareTriggers()},onInactive:()=>{c("subscribeToNotActiveCall onInactive"),this.subscribeToHardwareTriggers(e)}})}unsubscribeFromNotActiveCall(){this.notActiveCallSubscriber.unsubscribe()}subscribeToHardwareTriggers(e){this.unsubscribeFromHardwareTriggers(),c("subscribeToHardwareTriggers"),this.networkInterfacesSubscriber?.subscribe({onChange:()=>{c("networkInterfacesSubscriber onChange"),this.restartConnectionAttempts(e)},onUnavailable:()=>{c("networkInterfacesSubscriber onUnavailable"),this.stopConnectionFlow().catch(t=>{c("auto connector stop from networkInterfacesSubscriber onUnavailable: error",t)})}}),this.resumeFromSleepModeSubscriber?.subscribe({onResume:()=>{c("resumeFromSleepModeSubscriber onResume"),this.restartConnectionAttempts(e)}})}unsubscribeFromHardwareTriggers(){c("unsubscribeFromHardwareTriggers"),this.networkInterfacesSubscriber?.unsubscribe(),this.resumeFromSleepModeSubscriber?.unsubscribe()}stopPingRequester(){this.pingServerIfNotActiveCallRequester.stop()}startPingRequester(e){this.pingServerIfNotActiveCallRequester.start({onFailRequest:()=>{c("pingRequester: onFailRequest"),this.restartConnectionAttempts(e)}})}connectIfDisconnected(e){const t=this.isConnectionUnavailable();c("connectIfDisconnected: isUnavailable",t),t?this.restartConnectionAttempts(e):(this.stopConnectTriggers(),this.events.trigger(_.SUCCESS))}scheduleReconnect(e){c("scheduleReconnect"),this.delayBetweenAttempts.request().then(async()=>(c("scheduleReconnect: delayBetweenAttempts success"),this.cancelableRequestBeforeRetry.request())).then(async()=>(c("scheduleReconnect: onBeforeRetry success"),this.attemptConnection(e))).catch(t=>{const s=t instanceof Error?t:new Error(ee.FAILED_TO_RECONNECT);this.attemptsState.finishAttempt(),k.isCanceledError(t)||y.hasCanceledError(t)?this.events.trigger(_.CANCELLED_ATTEMPTS,s):this.events.trigger(_.FAILED_ALL_ATTEMPTS,s),c("scheduleReconnect: error",t)})}isConnectionUnavailable(){const{isFailed:e,isDisconnected:t,isIdle:s}=this.connectionManager;return e||t||s}emitStatusChange=({isInProgress:e})=>{this.events.trigger(_.CHANGED_ATTEMPT_STATUS,{isInProgress:e})}}var U=(n=>(n.INCOMING_CALL="incomingCall",n.DECLINED_INCOMING_CALL="declinedIncomingCall",n.TERMINATED_INCOMING_CALL="terminatedIncomingCall",n.FAILED_INCOMING_CALL="failedIncomingCall",n))(U||{});const me=["incomingCall","declinedIncomingCall","terminatedIncomingCall","failedIncomingCall"],Ut=486,Lt=487;class Bt{events;incomingRTCSession;connectionManager;constructor(e){this.connectionManager=e,this.events=new O.TypedEvents(me),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=Lt}={}){return new Promise((t,s)=>{try{const i=this.getIncomingRTCSession(),r=this.remoteCallerData;this.removeIncomingSession(),this.events.trigger(U.DECLINED_INCOMING_CALL,r),i.terminate({status_code:e}),t()}catch(i){s(i)}})}async busyIncomingCall(){return this.declineToIncomingCall({statusCode:Ut})}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(U.TERMINATED_INCOMING_CALL,t):this.events.trigger(U.FAILED_INCOMING_CALL,t)}),this.events.trigger(U.INCOMING_CALL,t)}removeIncomingSession(){delete this.incomingRTCSession}}const w=1e3;var E=(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))(E||{});const pe=["collected"],te=()=>"performance"in window?performance.now():Date.now(),B=n=>[...n.keys()].reduce((e,t)=>{const s=n.get(t);return s===void 0?e:{...e,[s.type]:s}},{}),Ft=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=B(n);return{outboundRtp:e[E.OUTBOUND_RTP],codec:e[E.CODEC],mediaSource:e[E.MEDIA_SOURCE],remoteInboundRtp:e[E.REMOTE_INBOUND_RTP]}},ne=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=B(n);return{outboundRtp:e[E.OUTBOUND_RTP],codec:e[E.CODEC],mediaSource:e[E.MEDIA_SOURCE],remoteInboundRtp:e[E.REMOTE_INBOUND_RTP]}},se=({videoReceiversStats:n,synchronizationSourcesVideo:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,synchronizationSources:e};const t=B(n);return{inboundRtp:t[E.INBOUND_RTP],codec:t[E.CODEC],synchronizationSources:e}},kt=({audioReceiverStats:n,synchronizationSourcesAudio:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,remoteOutboundRtp:void 0,synchronizationSources:e};const t=B(n);return{inboundRtp:t[E.INBOUND_RTP],codec:t[E.CODEC],remoteOutboundRtp:t[E.REMOTE_OUTBOUND_RTP],synchronizationSources:e}},_e=n=>{if(!n)return{candidatePair:void 0,certificate:void 0,localCandidate:void 0,remoteCandidate:void 0,transport:void 0};const e=B(n);return{candidatePair:e[E.CANDIDATE_PAIR],certificate:e[E.CERTIFICATE],localCandidate:e[E.LOCAL_CANDIDATE],remoteCandidate:e[E.REMOTE_CANDIDATE],transport:e[E.TRANSPORT]}},$t=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t})=>({video:ne(e),secondVideo:ne(t),audio:Ft(n),additional:_e(n??e??t)}),qt=({audioReceiverStats:n,videoReceiverFirstStats:e,videoReceiverSecondStats:t,synchronizationSources:s})=>({video:se({videoReceiversStats:e,synchronizationSourcesVideo:s.video}),secondVideo:se({videoReceiversStats:t,synchronizationSourcesVideo:s.video}),audio:kt({audioReceiverStats:n,synchronizationSourcesAudio:s.audio}),additional:_e(n??e??t)}),Wt=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t,audioReceiverStats:s,videoReceiverFirstStats:i,videoReceiverSecondStats:r,synchronizationSources:a})=>{const o=$t({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t}),h=qt({audioReceiverStats:s,videoReceiverFirstStats:i,videoReceiverSecondStats:r,synchronizationSources:a});return{outbound:o,inbound:h}},Vt=async n=>{const e="audio",t="video",s=n.getSenders(),i=s.find(l=>l.track?.kind===e),r=s.filter(l=>l.track?.kind===t),a=n.getReceivers(),o=a.find(l=>l.track.kind===e),h=a.filter(l=>l.track.kind===t),d={trackIdentifier:o?.track.id,item:o?.getSynchronizationSources()[0]},T={trackIdentifier:h[0]?.track.id,item:h[0]?.getSynchronizationSources()[0]},S={audio:d,video:T};return Promise.all([i?.getStats()??Promise.resolve(void 0),r[0]?.getStats()??Promise.resolve(void 0),r[1]?.getStats()??Promise.resolve(void 0),o?.getStats()??Promise.resolve(void 0),h[0]?.getStats()??Promise.resolve(void 0),h[1]?.getStats()??Promise.resolve(void 0)]).then(l=>{const[A,m,R,M,$,q]=l;return{synchronizationSources:S,audioSenderStats:A,videoSenderFirstStats:m,videoSenderSecondStats:R,audioReceiverStats:M,videoReceiverFirstStats:$,videoReceiverSecondStats:q}})},Ht=n=>{c(String(n))};class Me{events;setTimeoutRequest;requesterAllStatistics=new k.CancelableRequest(Vt);constructor(){this.events=new O.TypedEvents(pe),this.setTimeoutRequest=new y.SetTimeoutRequest}get requested(){return this.setTimeoutRequest.requested}start(e,{interval:t=w,onError:s=Ht}={}){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=te();this.requesterAllStatistics.request(e).then(i=>{this.events.trigger("collected",Wt(i));const a=te()-s;let o=w;a>48?o=w*4:a>32?o=w*3:a>16&&(o=w*2),this.start(e,{onError:t,interval:o})}).catch(i=>{t&&t(i)})}}class xt{availableIncomingBitrate;statsPeerConnection;callManager;apiManager;previousAvailableIncomingBitrate;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.statsPeerConnection=new Me,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=>{c("Failed to send stats",e)})}}const Gt=(n,e)=>n.filter(s=>e.some(i=>i.clockRate===s.clockRate&&i.mimeType===s.mimeType&&i.channels===s.channels&&i.sdpFmtpLine===s.sdpFmtpLine)),Qt=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),s=e===null?[]:e.codecs,i=t===null?[]:t.codecs;return Gt(s,i)},Yt=(n,e)=>e===void 0||e.length===0?n:n.sort((t,s)=>{const i=e.indexOf(t.mimeType),r=e.indexOf(s.mimeType),a=i===-1?Number.MAX_VALUE:i,o=r===-1?Number.MAX_VALUE:r;return a-o}),zt=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),Xt=(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=Qt("video"),i=zt(s,t),r=Yt(i,e);n.setCodecPreferences(r)}}catch(s){c("setCodecPreferences error",s)}},Jt=n=>[...n.keys()].map(e=>n.get(e)),Kt=(n,e)=>Jt(n).find(t=>t?.type===e),fe=async n=>n.getStats().then(e=>Kt(e,"codec")?.mimeType);class jt{async getCodecFromSender(e){return await fe(e)??""}}class Zt{stackPromises=Y.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{c("TaskQueue: error",e)})}}class en{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new Zt}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>J(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}const ve=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),tn=1e6,f=n=>n*tn,Pe=f(.06),Oe=f(4),nn=n=>n<=64?Pe:n<=128?f(.12):n<=256?f(.25):n<=384?f(.32):n<=426?f(.38):n<=640?f(.5):n<=848?f(.7):n<=1280?f(1):n<=1920?f(2):Oe,sn="av1",rn=n=>ve(n,sn),an=.6,j=(n,e)=>rn(e)?n*an:n,on=n=>j(Pe,n),cn=n=>j(Oe,n),ie=(n,e)=>{const t=nn(n);return j(t,e)},W=1,hn=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),s=t.width,i=t.height,r=s===void 0?W:s/e.width,a=i===void 0?W:i/e.height;return Math.max(r,a,W)};class dn{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:s},i){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=s,this.ignoreForCodec=i.ignoreForCodec}async balance(e,t){const s=e.getSenders(),i=this.senderFinder.findVideoSender(s);if(!i?.track)return{...this.resultNoChanged,sender:i};const r=await this.codecProvider.getCodecFromSender(i);if(ve(r,this.ignoreForCodec))return{...this.resultNoChanged,sender:i};const{mainCam:a,resolutionMainCam:o}=t??{};return this.processSender({mainCam:a,resolutionMainCam:o},{sender:i,codec:r,videoTrack:i.track}).then(h=>({...h,sender:i}))}async processSender(e,t){const{mainCam:s,resolutionMainCam:i}=e;switch(s){case v.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case v.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case v.MAX_MAIN_CAM_RESOLUTION:return i!==void 0?this.setResolutionSender(i,t):this.setBitrateByTrackResolution(t);case v.ADMIN_STOP_MAIN_CAM:case v.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,i={scaleResolutionDownBy:200,maxBitrate:on(s)};return this.parametersSetter.setEncodingsToSender(t,i)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:s,codec:i}=e,a=s.getSettings().width,o=a===void 0?cn(i):ie(a,i);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:o})}async setResolutionSender(e,t){const[s,i]=e.split("x"),{sender:r,videoTrack:a,codec:o}=t,h={width:Number(s),height:Number(i)},d=hn({videoTrack:a,targetSize:h}),T=ie(h.width,o),S={scaleResolutionDownBy:d,maxBitrate:T};return this.parametersSetter.setEncodingsToSender(r,S)}}const ln=n=>n.find(e=>e.track?.kind==="video");class un{findVideoSender(e){return ln(e)}}class gn{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 y.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 i=>{await s(i),this.attachTrack(t,i??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:i}=t.getSettings();this.lastWidth=s,this.lastHeight=i,this.currentPollIntervalMs=this.pollIntervalMs,this.schedulePoll(t,e)}schedulePoll(e,t){const s=()=>{const{width:i,height:r}=e.getSettings();i!==this.lastWidth||r!==this.lastHeight?(this.lastWidth=i,this.lastHeight=r,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 Tn{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 Sn{eventHandler;senderBalancer;parametersSetterWithQueue;getConnection;serverHeaders;trackMonitor;constructor(e,t,{ignoreForCodec:s,onSetParameters:i,pollIntervalMs:r}={}){this.getConnection=t,this.eventHandler=new Tn(e),this.parametersSetterWithQueue=new en(i),this.senderBalancer=new dn({senderFinder:new un,codecProvider:new jt,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:s}),this.trackMonitor=new gn({pollIntervalMs:r})}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=>{c("balance on track change: error",s)})}),t}handleMainCamControl=e=>{this.serverHeaders=e,this.balance().catch(t=>{c("handleMainCamControl: error",t)})}}const be=["balancing-scheduled","balancing-started","balancing-stopped","parameters-updated"];class Cn{isBalancingActive=!1;events;callManager;balancingStartDelay;videoSendingBalancer;startBalancingTimer;constructor(e,t,s={}){this.events=new O.TypedEvents(be),this.callManager=e,this.balancingStartDelay=s.balancingStartDelay??1e4,this.videoSendingBalancer=new Sn(t,()=>e.connection,{...s,onSetParameters:i=>{this.events.trigger("parameters-updated",i),s.onSetParameters?.(i)}}),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=>{c("startBalancing: error",e)})},this.balancingStartDelay),this.events.trigger("balancing-scheduled",{delay:this.balancingStartDelay})}clearStartTimer(){this.startBalancingTimer&&(clearTimeout(this.startBalancingTimer),this.startBalancingTimer=void 0)}}const En=1e6,An=Ie.map(n=>`auto-connect:${n}`),Nn=Ee.map(n=>`connection:${n}`),Rn=le.map(n=>`call:${n}`),In=oe.map(n=>`api:${n}`),mn=me.map(n=>`incoming-call:${n}`),pn=Se.map(n=>`presentation:${n}`),_n=pe.map(n=>`stats:${n}`),Mn=be.map(n=>`video-balancer:${n}`),fn=["disconnected-from-out-of-call"],vn=[...An,...Nn,...Rn,...In,...mn,...pn,..._n,...Mn,...fn];class Pn{events;connectionManager;connectionQueueManager;callManager;autoConnectorManager;apiManager;incomingCallManager;presentationManager;statsManager;videoSendingBalancerManager;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor({JsSIP:e},{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:s,videoBalancerOptions:i,autoConnectorOptions:r}={}){this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=s,this.events=new O.TypedEvents(vn),this.connectionManager=new Nt({JsSIP:e}),this.connectionQueueManager=new Rt({connectionManager:this.connectionManager}),this.callManager=new Qe,this.apiManager=new Fe({connectionManager:this.connectionManager,callManager:this.callManager}),this.incomingCallManager=new Bt(this.connectionManager),this.presentationManager=new ot({callManager:this.callManager,maxBitrate:En}),this.statsManager=new xt({callManager:this.callManager,apiManager:this.apiManager}),this.autoConnectorManager=new wt({connectionQueueManager:this.connectionQueueManager,connectionManager:this.connectionManager,callManager:this.callManager},r),this.videoSendingBalancerManager=new Cn(this.callManager,this.apiManager,i),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 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);disconnect=async()=>this.connectionQueueManager.disconnect();register=async()=>this.connectionManager.register();unregister=async()=>this.connectionManager.unregister();tryRegister=async()=>this.connectionManager.tryRegister();set=async(...e)=>this.connectionManager.set(...e);sendOptions=async(e,t,s)=>this.connectionManager.sendOptions(e,t,s);ping=async(e,t)=>this.connectionManager.ping(e,t);checkTelephony=async e=>this.connectionManager.checkTelephony(e);isConfigured=()=>this.connectionManager.isConfigured();getConnectionConfiguration=()=>this.connectionManager.getConnectionConfiguration();getSipServerUrl=e=>this.connectionManager.getSipServerUrl(e);startAutoConnect=(...e)=>{this.autoConnectorManager.start(...e)};stopAutoConnect=()=>{this.autoConnectorManager.stop()};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:i,onAddedTransceiver:r,...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(r)},i===void 0?void 0:{callLimit:i})}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:i,...r}=t;return this.presentationManager.updatePresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...r,onAddedTransceiver:this.resolveHandleAddTransceiver(i)})}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)}subscribeDisconnectedFromOutOfCall(){this.connectionManager.on("disconnected",()=>{this.isCallActive||this.events.trigger("disconnected-from-out-of-call",{})})}setCodecPreferences(e){Xt(e,{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs})}subscribe(){this.bridgeEvents("auto-connect",this.autoConnectorManager),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),this.subscribeDisconnectedFromOutOfCall()}bridgeEvents=(e,t)=>{t.events.eachTriggers((s,i)=>{t.on(i,r=>{this.events.trigger(`${e}:${i}`,r)})})};resolveHandleAddTransceiver=e=>async(t,s,i)=>{this.setCodecPreferences(t),await e?.(t,s,i)}}exports.ECallCause=X;exports.EStatsTypes=E;exports.EUseLicense=ae;exports.Originator=he;exports.SipConnector=Pn;exports.StatsPeerConnection=Me;exports.disableDebug=ye;exports.enableDebug=De;exports.getCodecFromSender=fe;exports.hasCanceledStartPresentationError=at;exports.hasNotReadyForConnectionError=Re;exports.logger=c;exports.prepareMediaStream=L;exports.setEncodingsToSender=J;exports.setParametersToSender=Te;
|