sip-connector 22.0.0 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ "use strict";const Z=require("debug"),I=require("events-constructor"),V=require("@krivega/cancelable-promise"),k=require("@krivega/timeout-requester"),ee=require("repeated-calls"),N=require("xstate"),te=require("stack-promises");require("ua-parser-js");require("sequent-promises");const tt=require("lodash"),ne="sip-connector",d=Z(ne),nt=()=>{Z.enable(ne)},st=()=>{Z.enable(`-${ne}`)},it="Error decline with 603",rt=1006,at=n=>typeof n=="object"&&n!==null&&"code"in n&&n.code===rt,ot=n=>n.message===it;var x=(n=>(n.SPECTATOR="SPECTATOR",n.PARTICIPANT="PARTICIPANT",n))(x||{}),y=(n=>(n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",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))(y||{}),_=(n=>(n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.CHANNELS="application/vinteo.webrtc.channels",n.MEDIA_STATE="application/vinteo.webrtc.mediastate",n.REFUSAL="application/vinteo.webrtc.refusal",n.STATS="application/vinteo.webrtc.stats",n))(_||{}),M=(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))(M||{}),Q=(n=>(n.ADMIN_STOP_MIC="ADMINSTOPMIC",n.ADMIN_START_MIC="ADMINSTARTMIC",n))(Q||{}),pe=(n=>(n.H264="H264",n.VP8="VP8",n.VP9="VP9",n.AV1="AV1",n))(pe||{}),h=(n=>(n.CONTENT_TYPE="content-type",n.CONTENT_ENTER_ROOM="x-webrtc-enter-room",n.CONTENT_USE_LICENSE="X-WEBRTC-USE-LICENSE",n.PARTICIPANT_NAME="X-WEBRTC-PARTICIPANT-NAME",n.INPUT_CHANNELS="X-WEBRTC-INPUT-CHANNELS",n.OUTPUT_CHANNELS="X-WEBRTC-OUTPUT-CHANNELS",n.MAIN_CAM="X-WEBRTC-MAINCAM",n.MIC="X-WEBRTC-MIC",n.MEDIA_SYNC="X-WEBRTC-SYNC",n.MAIN_CAM_RESOLUTION="X-WEBRTC-MAINCAM-RESOLUTION",n.MEDIA_STATE="X-WEBRTC-MEDIA-STATE",n.MEDIA_TYPE="X-Vinteo-Media-Type",n.MAIN_CAM_STATE="X-Vinteo-MainCam-State",n.MIC_STATE="X-Vinteo-Mic-State",n.CONTENT_PARTICIPANT_STATE="X-WEBRTC-PARTSTATE",n.NOTIFY="X-VINTEO-NOTIFY",n.CONTENT_ENABLE_MEDIA_DEVICE="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE",n.CONTENTED_STREAM_STATE="x-webrtc-share-state",n.CONTENTED_STREAM_CODEC="x-webrtc-share-codec",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))(h||{}),G=(n=>(n.AVAILABLE_CONTENTED_STREAM="YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_CONTENTED_STREAM="CONTENTEND",n.MUST_STOP_PRESENTATION="YOUMUSTSTOPSENDCONTENT",n))(G||{}),U=(n=>(n.AVAILABLE_CONTENTED_STREAM="x-webrtc-share-state: YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_CONTENTED_STREAM="x-webrtc-share-state: CONTENTEND",n.ACK_PERMISSION_TO_START_PRESENTATION="x-webrtc-share-state: LETMESTARTPRESENTATION",n.STOPPED_CLIENT_PRESENTATION="x-webrtc-share-state: STOPPRESENTATION",n.ENABLE_MAIN_CAM="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM",n))(U||{}),Y=(n=>(n.ADMIN_SYNC_FORCED="1",n.ADMIN_SYNC_NOT_FORCED="0",n))(Y||{}),se=(n=>(n.AUDIO="AUDIO",n.VIDEO="VIDEO",n.AUDIOPLUSPRESENTATION="AUDIOPLUSPRESENTATION",n))(se||{}),g=(n=>(n.ENTER_ROOM="enter-room",n.MAIN_CAM_CONTROL="main-cam-control",n.USE_LICENSE="use-license",n.NEW_DTMF="new-dtmf",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="conference:participant-token-issued",n.CONTENTED_STREAM_AVAILABLE="contented-stream:available",n.CONTENTED_STREAM_NOT_AVAILABLE="contented-stream:not-available",n.PRESENTATION_MUST_STOP="presentation:must-stop",n.CHANNELS_ALL="channels:all",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_SYNTHETIC="participant:move-request-to-spectators-synthetic",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.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))(g||{});const me=["enter-room","main-cam-control","use-license","new-dtmf","conference:participant-token-issued","contented-stream:available","contented-stream:not-available","presentation:must-stop","channels:all","channels:notify","participant:added-to-list-moderators","participant:removed-from-list-moderators","participant:move-request-to-stream","participant:move-request-to-spectators","participant:move-request-to-spectators-synthetic","participant:move-request-to-spectators-with-audio-id","participant:move-request-to-participants","participation:accepting-word-request","participation:cancelling-word-request","webcast:started","webcast:stopped","account:changed","account:deleted","admin:start-main-cam","admin:stop-main-cam","admin:start-mic","admin:stop-mic","admin:force-sync-media-state"],ct=()=>new I.TypedEvents(me),dt=n=>typeof n=="string"&&n.trim().length>0,L=(n,e)=>{const t=e.toLowerCase(),s=Object.entries(n).find(([,i])=>typeof i=="string"&&i.toLowerCase()===t);return s?s[1]:void 0},ht=n=>typeof n=="string"&&!Number.isNaN(Number(n))&&Number.isFinite(Number(n)),lt=n=>{if(ht(n))return Number(n)},A=(n,e)=>{const t=n.getHeader(e);if(!dt(t))return;const s=t.toLowerCase();switch(e){case h.CONTENT_ENTER_ROOM:case h.PARTICIPANT_NAME:case h.INPUT_CHANNELS:case h.OUTPUT_CHANNELS:case h.TRACKS_DIRECTION:case h.AUDIO_ID:case h.MAIN_CAM_RESOLUTION:case h.MEDIA_STATE:case h.NOTIFY:case h.CONTENT_ENABLE_MEDIA_DEVICE:return s;case h.MEDIA_TYPE:case h.MAIN_CAM_STATE:case h.MIC_STATE:case h.AVAILABLE_INCOMING_BITRATE:case h.AUDIO_TRACK_COUNT:case h.VIDEO_TRACK_COUNT:return lt(s);case h.CONTENTED_STREAM_CODEC:return L(pe,s);case h.CONTENT_TYPE:return L(y,s);case h.CONTENT_USE_LICENSE:return L(se,s);case h.MAIN_CAM:return L(M,s);case h.MIC:return L(Q,s);case h.MEDIA_SYNC:return L(Y,s);case h.CONTENT_PARTICIPANT_STATE:return L(x,s);case h.CONTENTED_STREAM_STATE:return L(G,s);default:return}};var v=(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))(v||{});class gt{events;callManager;constructor(){this.events=ct()}subscribe({connectionManager:e,callManager:t}){this.callManager=t,e.on("sipEvent",this.handleSipEvent),t.on("newInfo",this.handleNewInfo),t.on("newDTMF",({originator:s})=>{this.events.trigger(g.NEW_DTMF,{originator:s})})}async waitChannels(){return this.wait(g.CHANNELS_ALL)}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=`${h.INPUT_CHANNELS}: ${e}`,r=`${h.OUTPUT_CHANNELS}: ${t}`,a=[i,r];return s.sendInfo(_.CHANNELS,void 0,{extraHeaders:a})}async sendMediaState({cam:e,mic:t},s={}){const i=this.getEstablishedRTCSessionProtected(),r=`${h.MEDIA_STATE}: currentstate`,a=`${h.MAIN_CAM_STATE}: ${Number(e)}`,o=`${h.MIC_STATE}: ${Number(t)}`,c=[r,a,o];return i.sendInfo(_.MEDIA_STATE,void 0,{noTerminateWhenError:!0,...s,extraHeaders:c})}async sendStats({availableIncomingBitrate:e}){const t=this.getEstablishedRTCSessionProtected(),i=[`${h.AVAILABLE_INCOMING_BITRATE}: ${e}`];return t.sendInfo(_.STATS,void 0,{noTerminateWhenError:!0,extraHeaders:i})}async sendRefusalToTurnOn(e,t={}){const s=this.getEstablishedRTCSessionProtected(),a=e==="mic"?0:1,c=[`${h.MEDIA_TYPE}: ${a}`];return s.sendInfo(_.REFUSAL,void 0,{noTerminateWhenError:!0,...t,extraHeaders:c})}async sendRefusalToTurnOnMic(e={}){return this.sendRefusalToTurnOn("mic",{noTerminateWhenError:!0,...e})}async sendRefusalToTurnOnCam(e={}){return this.sendRefusalToTurnOn("cam",{noTerminateWhenError:!0,...e})}async sendAvailableContentedStream(){await this.getEstablishedRTCSessionProtected().sendInfo(_.SHARE_STATE,void 0,{extraHeaders:[U.AVAILABLE_CONTENTED_STREAM]})}async askPermissionToStartPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(_.SHARE_STATE,void 0,{extraHeaders:[U.ACK_PERMISSION_TO_START_PRESENTATION]})}async sendStoppedPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(_.SHARE_STATE,void 0,{extraHeaders:[U.STOPPED_CLIENT_PRESENTATION]})}async sendNotAvailableContentedStream(){await this.getEstablishedRTCSessionProtected().sendInfo(_.SHARE_STATE,void 0,{extraHeaders:[U.NOT_AVAILABLE_CONTENTED_STREAM]})}async askPermissionToEnableCam(e={}){const t=this.getEstablishedRTCSessionProtected(),s=[U.ENABLE_MAIN_CAM];return t.sendInfo(_.MAIN_CAM,void 0,{noTerminateWhenError:!0,...e,extraHeaders:s}).catch(i=>{if(ot(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};handleSipEvent=({request:e})=>{this.maybeHandleNotify(e)};maybeHandleNotify=e=>{try{const t=e.getHeader(h.NOTIFY);if(t){const s=JSON.parse(t);this.handleNotify(s)}}catch(t){d("error parse notify",t)}};handleNotify=e=>{switch(e.cmd){case v.CHANNELS:{const t=e;this.triggerChannelsNotify(t);break}case v.WEBCAST_STARTED:{const t=e;this.triggerWebcastStartedNotify(t);break}case v.WEBCAST_STOPPED:{const t=e;this.triggerWebcastStoppedNotify(t);break}case v.ADDED_TO_LIST_MODERATORS:{const t=e;this.triggerAddedToListModeratorsNotify(t);break}case v.REMOVED_FROM_LIST_MODERATORS:{const t=e;this.triggerRemovedFromListModeratorsNotify(t);break}case v.ACCEPTING_WORD_REQUEST:{const t=e;this.triggerParticipationAcceptingWordRequest(t);break}case v.CANCELLING_WORD_REQUEST:{const t=e;this.triggerParticipationCancellingWordRequest(t);break}case v.MOVE_REQUEST_TO_STREAM:{const t=e;this.triggerParticipantMoveRequestToStream(t);break}case v.ACCOUNT_CHANGED:{this.triggerAccountChangedNotify();break}case v.ACCOUNT_DELETED:{this.triggerAccountDeletedNotify();break}case v.CONFERENCE_PARTICIPANT_TOKEN_ISSUED:{const t=e;this.triggerConferenceParticipantTokenIssued(t);break}default:d("unknown cmd",e)}};handleNewInfo=e=>{const{originator:t}=e;if(t!=="remote")return;const{request:s}=e,i=s,r=A(i,h.CONTENT_TYPE);if(r!==void 0)switch(r){case y.ENTER_ROOM:{this.triggerEnterRoom(i),this.maybeTriggerChannels(i);break}case y.NOTIFY:{this.maybeHandleNotify(i);break}case y.SHARE_STATE:{this.triggerContentedStreamState(i);break}case y.MAIN_CAM:{this.triggerMainCamControl(i);break}case y.MIC:{this.triggerMicControl(i);break}case y.USE_LICENSE:{this.triggerUseLicense(i);break}case y.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=A(e,h.INPUT_CHANNELS),s=A(e,h.OUTPUT_CHANNELS);if(t!==void 0&&s!==void 0){const i={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS_ALL,i)}};triggerEnterRoom=e=>{const t=A(e,h.CONTENT_ENTER_ROOM),s=A(e,h.PARTICIPANT_NAME);t!==void 0&&this.events.trigger(g.ENTER_ROOM,{room:t,participantName:s})};triggerContentedStreamState=e=>{const t=A(e,h.CONTENTED_STREAM_STATE);if(t!==void 0)switch(t){case G.AVAILABLE_CONTENTED_STREAM:{const s=A(e,h.CONTENTED_STREAM_CODEC);this.events.trigger(g.CONTENTED_STREAM_AVAILABLE,{codec:s});break}case G.NOT_AVAILABLE_CONTENTED_STREAM:{this.events.trigger(g.CONTENTED_STREAM_NOT_AVAILABLE,{});break}case G.MUST_STOP_PRESENTATION:{this.events.trigger(g.PRESENTATION_MUST_STOP,{});break}}};maybeTriggerParticipantMoveRequest=e=>{const t=A(e,h.CONTENT_PARTICIPANT_STATE),s=A(e,h.AUDIO_ID);t===x.SPECTATOR&&(s===void 0?(this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS_SYNTHETIC,{}),this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,{isSynthetic:!0})):(this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS_WITH_AUDIO_ID,{audioId:s}),this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,{isSynthetic:!1,audioId:s}))),t===x.PARTICIPANT&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS,{})};triggerMainCamControl=e=>{const t=A(e,h.MAIN_CAM),s=A(e,h.MEDIA_SYNC),i=s===Y.ADMIN_SYNC_FORCED;if(t===M.ADMIN_START_MAIN_CAM){this.events.trigger(g.ADMIN_START_MAIN_CAM,{isSyncForced:i});return}if(t===M.ADMIN_STOP_MAIN_CAM){this.events.trigger(g.ADMIN_STOP_MAIN_CAM,{isSyncForced:i});return}(t===M.RESUME_MAIN_CAM||t===M.PAUSE_MAIN_CAM)&&s!==void 0&&this.events.trigger(g.ADMIN_FORCE_SYNC_MEDIA_STATE,{isSyncForced:i});const r=A(e,h.MAIN_CAM_RESOLUTION);this.events.trigger(g.MAIN_CAM_CONTROL,{mainCam:t,resolutionMainCam:r})};triggerMicControl=e=>{const t=A(e,h.MIC),i=A(e,h.MEDIA_SYNC)===Y.ADMIN_SYNC_FORCED;t===Q.ADMIN_START_MIC?this.events.trigger(g.ADMIN_START_MIC,{isSyncForced:i}):t===Q.ADMIN_STOP_MIC&&this.events.trigger(g.ADMIN_STOP_MIC,{isSyncForced:i})};triggerUseLicense=e=>{const t=A(e,h.CONTENT_USE_LICENSE);t!==void 0&&this.events.trigger(g.USE_LICENSE,t)}}class H{actor;subscriptions=[];stateChangeListeners=new Set;constructor(e){this.actor=N.createActor(e),this.actor.start(),this.addSubscription(this.subscribe(t=>{const s=t.value;this.stateChangeListeners.forEach(i=>{i(s)})}))}get actorRef(){return this.actor}get state(){return this.getSnapshot().value}send(e){this.actor.send(e)}getSnapshot(){return this.actor.getSnapshot()}subscribe(e){const t=this.actor.subscribe(e);return this.addSubscription(t),t}onStateChange(e){return this.stateChangeListeners.add(e),()=>{this.stateChangeListeners.delete(e)}}stop(){this.stateChangeListeners.clear(),this.subscriptions.forEach(e=>{e()}),this.subscriptions.length=0,this.actor.stop()}addSubscription(e){const t=typeof e=="function"?e:()=>{e.unsubscribe()};return this.subscriptions.push(t),t}}var Ne=(n=>(n.IDLE="call:idle",n.CONNECTING="call:connecting",n.ACCEPTED="call:accepted",n.IN_CALL="call:inCall",n.ENDED="call:ended",n.FAILED="call:failed",n))(Ne||{});const ut=N.setup({types:{context:{},events:{}},actions:{rememberError:N.assign(({event:n})=>"error"in n&&n.error!==void 0?{lastError:n.error instanceof Error?n.error:new Error(JSON.stringify(n.error))}:{lastError:void 0}),resetError:N.assign({lastError:void 0})}}).createMachine({id:"call",initial:"call:idle",context:{},states:{"call:idle":{on:{"CALL.CONNECTING":{target:"call:connecting",actions:"resetError"}}},"call:connecting":{on:{"CALL.ACCEPTED":"call:accepted","CALL.ENDED":"call:ended","CALL.FAILED":{target:"call:failed",actions:"rememberError"}}},"call:accepted":{on:{"CALL.CONFIRMED":"call:inCall","CALL.ENDED":"call:ended","CALL.FAILED":{target:"call:failed",actions:"rememberError"}}},"call:inCall":{on:{"CALL.ENDED":"call:ended","CALL.FAILED":{target:"call:failed",actions:"rememberError"}}},"call:ended":{on:{"CALL.RESET":{target:"call:idle",actions:"resetError"},"CALL.CONNECTING":{target:"call:connecting",actions:"resetError"}}},"call:failed":{on:{"CALL.RESET":{target:"call:idle",actions:"resetError"},"CALL.CONNECTING":{target:"call:connecting",actions:"resetError"},"CALL.ENDED":{target:"call:ended",actions:"resetError"}}}}});class Tt extends H{constructor(e){super(ut),this.subscribeToEvents(e)}get isIdle(){return this.state==="call:idle"}get isConnecting(){return this.state==="call:connecting"}get isAccepted(){return this.state==="call:accepted"}get isInCall(){return this.state==="call:inCall"}get isEnded(){return this.state==="call:ended"}get isFailed(){return this.state==="call:failed"}get isActive(){return this.isAccepted||this.isInCall}get isPending(){return this.isConnecting}get lastError(){return this.getSnapshot().context.lastError}reset(){this.send({type:"CALL.RESET"})}send(e){if(!this.getSnapshot().can(e)){console.warn(`[CallStateMachine] Invalid transition: ${e.type} from ${this.state}. Event cannot be processed in current state.`);return}super.send(e)}subscribeToEvents(e){this.addSubscription(e.on("connecting",()=>{this.send({type:"CALL.CONNECTING"})})),this.addSubscription(e.on("accepted",()=>{this.send({type:"CALL.ACCEPTED"})})),this.addSubscription(e.on("confirmed",()=>{this.send({type:"CALL.CONFIRMED"})})),this.addSubscription(e.on("ended",()=>{this.send({type:"CALL.ENDED"})})),this.addSubscription(e.on("failed",t=>{this.send({type:"CALL.FAILED",error:t})}))}}var S=(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.REMOTE_TRACKS_CHANGED="remote-tracks-changed",n.REMOTE_STREAMS_CHANGED="remote-streams-changed",n))(S||{}),Ae=(n=>(n.LOCAL="local",n.REMOTE="remote",n.SYSTEM="system",n))(Ae||{});const Re=["peerconnection","connecting","sending","progress","accepted","confirmed","ended","failed","hold","unhold","muted","unmuted","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"],Et=["peerconnection:confirmed","peerconnection:ontrack","ended:fromserver","call-status-changed","remote-tracks-changed","remote-streams-changed"],Ie=[...Re,...Et],St=()=>new I.TypedEvents(Ie),Ct=(n,e)=>{n.getVideoTracks().forEach(s=>{"contentHint"in s&&s.contentHint!==e&&(s.contentHint=e)})},q=(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"&&Ct(o,s),o};var ie=(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))(ie||{});class pt{events;rtcSession;disposers=new Set;onReset;constructor(e,{onReset:t}){this.events=e,this.onReset=t,e.on(S.FAILED,this.handleEnded),e.on(S.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;async renegotiate(){if(this.rtcSession===void 0)throw new Error("No rtcSession established");return this.rtcSession.renegotiate()}startCall=async(e,t,{number:s,mediaStream:i,extraHeaders:r=[],iceServers:a,directionVideo:o,directionAudio:c,contentHint:l,offerToReceiveAudio:T=!0,offerToReceiveVideo:u=!0,degradationPreference:E,sendEncodings:m,onAddedTransceiver:D})=>new Promise((R,w)=>{this.handleCall().then(R).catch(X=>{w(X)}),this.rtcSession=e.call(t(s),{mediaStream:q(i,{directionVideo:o,directionAudio:c,contentHint:l}),pcConfig:{iceServers:a},rtcOfferConstraints:{offerToReceiveAudio:T,offerToReceiveVideo:u},eventHandlers:this.events.triggers,extraHeaders:r,directionVideo:o,directionAudio:c,degradationPreference:E,sendEncodings:m,onAddedTransceiver:D})});async endCall(){const{rtcSession:e}=this;if(e&&!e.isEnded())return e.terminateAsync({cause:ie.CANCELED}).finally(()=>{this.reset()});this.reset()}answerToIncomingCall=async(e,{mediaStream:t,extraHeaders:s=[],iceServers:i,directionVideo:r,directionAudio:a,offerToReceiveAudio:o,offerToReceiveVideo:c,contentHint:l,degradationPreference:T,sendEncodings:u,onAddedTransceiver:E})=>new Promise((m,D)=>{try{this.rtcSession=e,this.subscribeToSessionEvents(e),this.handleCall().then(m).catch(R=>{D(R)}),e.answer({pcConfig:{iceServers:i},rtcOfferConstraints:{offerToReceiveAudio:o,offerToReceiveVideo:c},mediaStream:q(t,{directionVideo:r,directionAudio:a,contentHint:l}),extraHeaders:s,directionVideo:r,directionAudio:a,degradationPreference:T,sendEncodings:u,onAddedTransceiver:E})}catch(R){D(R)}});async replaceMediaStream(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");const{contentHint:s}=t??{},i=q(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()=>new Promise((e,t)=>{const s=()=>{this.events.on(S.PEER_CONNECTION,l),this.events.on(S.CONFIRMED,T)},i=()=>{this.events.off(S.PEER_CONNECTION,l),this.events.off(S.CONFIRMED,T)},r=()=>{this.events.on(S.FAILED,o),this.events.on(S.ENDED,o)},a=()=>{this.events.off(S.FAILED,o),this.events.off(S.ENDED,o)},o=u=>{i(),a(),t(u)};let c;const l=({peerconnection:u})=>{c=u;const E=m=>{this.events.trigger(S.PEER_CONNECTION_ONTRACK,m)};u.addEventListener("track",E),this.disposers.add(()=>{u.removeEventListener("track",E)})},T=()=>{c!==void 0&&this.events.trigger(S.PEER_CONNECTION_CONFIRMED,c),i(),a(),e(c)};s(),r()});subscribeToSessionEvents(e){this.events.eachTriggers((t,s)=>{const i=Re.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(S.ENDED_FROM_SERVER,e),this.reset()};reset=()=>{delete this.rtcSession,this.unsubscribeFromSessionEvents(),this.onReset()}}class mt{config;tools;connection;constructor(e,t){this.config=e,this.tools=t,this.connection=new RTCPeerConnection(e.pcConfig),this.addTransceivers()}get settings(){return this.config}get peerConnection(){return this.connection}close(){this.connection.close()}async call(e){const t=this.waitForTracks(),s=await this.createOffer(),i=await this.tools.sendOffer({conferenceNumber:e,quality:this.config.quality,audioChannel:this.config.audioChannel},s);await this.setRemoteDescription(i),await t}async createOffer(){const e=await this.connection.createOffer();return await this.connection.setLocalDescription(e),e}async setRemoteDescription(e){return this.connection.setRemoteDescription(e)}async waitForTracks(){return new Promise(e=>{const t=new Set,s=i=>{const{track:r}=i;t.add(r.kind),t.has("audio")&&t.has("video")&&(this.connection.removeEventListener("track",s),e())};this.connection.addEventListener("track",s)})}addTransceivers(){this.addRecvOnlyTransceiver("audio"),this.addRecvOnlyTransceiver("video"),this.addRecvOnlyTransceiver("video"),this.addRecvOnlyTransceiver("video"),this.addRecvOnlyTransceiver("video")}addRecvOnlyTransceiver(e){const t={direction:"recvonly"};return this.connection.addTransceiver(e,t)}}const ve=n=>n.getSettings(),Nt=(n,e)=>{const t=ve(n);let s=e;s??=n.label;let i=t?.msid;return i??=s,i??=n.id,i},At=(n,e)=>{const t=ve(n);let s=e;return s??=t?.msid,s??=n.label,(s&&s.length>0?s:void 0)??n.id};class ce{participantGroups=new Map;trackToGroup=new Map;trackDisposers=new Map;get mainStream(){const e=this.getStreams(),[t]=e;return t}reset(){this.participantGroups.clear(),this.trackToGroup.clear(),this.trackDisposers.forEach(e=>{e()}),this.trackDisposers.clear()}addTrack(e,{onRemoved:t,streamHint:s}={}){const i=At(e,s),r=Nt(e,s);if(this.trackToGroup.has(e.id))return{isAddedTrack:!1,isAddedStream:!1};const a=this.getParticipantGroups(i),o=a.get(r),c=!o;let l=o;l||(l={participantId:i,groupId:r,stream:new MediaStream,trackIds:new Set},a.set(r,l)),l.stream.addTrack(e),l.trackIds.add(e.id),this.trackToGroup.set(e.id,{participantId:i,groupId:r});const T=()=>{this.disposeTrackListener(e.id);const u=this.removeTrack(e.id);u.isRemovedTrack&&t?.({participantId:i,trackId:e.id,isRemovedStream:u.isRemovedStream})};return e.addEventListener("ended",T),this.trackDisposers.set(e.id,()=>{e.removeEventListener("ended",T)}),{isAddedTrack:!0,isAddedStream:c,participantId:i}}removeTrack(e){this.disposeTrackListener(e);const t=this.trackToGroup.get(e);if(!t)return{isRemovedTrack:!1,isRemovedStream:!1};const{participantId:s,groupId:i}=t,r=this.participantGroups.get(s),a=r?.get(i);if(!a)return this.trackToGroup.delete(e),{isRemovedTrack:!1,isRemovedStream:!1};const o=a.stream.getTracks().find(l=>l.id===e);o&&a.stream.removeTrack(o),a.trackIds.delete(e),this.trackToGroup.delete(e);const c=a.trackIds.size===0;return c&&(r?.delete(i),r?.size===0&&this.participantGroups.delete(s)),{isRemovedTrack:!0,isRemovedStream:c}}removeStaleTracks(e,t){const s=this.participantGroups.get(e);if(!s)return!1;let i=!1;return[...s.values()].forEach(a=>{[...a.trackIds].filter(c=>!t.includes(c)).forEach(c=>{const l=this.removeTrack(c);i||=l.isRemovedTrack})}),i}getStreams(e){if(e!==void 0){const t=this.participantGroups.get(e);return t?[...t.values()].map(s=>s.stream):[]}return[...this.participantGroups.values()].flatMap(t=>[...t.values()]).map(t=>t.stream)}disposeTrackListener(e){const t=this.trackDisposers.get(e);t&&(t(),this.trackDisposers.delete(e))}getParticipantGroups(e){const t=this.participantGroups.get(e);if(t)return t;const s=new Map;return this.participantGroups.set(e,s),s}}const J={type:"participant"},Rt={type:"spectator_synthetic"},It=n=>({type:"spectator",recvParams:n});class O{role=J;onRoleChanged;constructor(e){this.onRoleChanged=e}static hasParticipant(e){return e.type==="participant"}static hasSpectatorSynthetic(e){return e.type==="spectator_synthetic"}static hasSpectator(e){return e.type==="spectator"}getRole(){return this.role}setCallRoleParticipant(){this.changeRole(J)}setCallRoleSpectatorSynthetic(){this.changeRole(Rt)}setCallRoleSpectator(e){this.changeRole(It(e))}changeRole(e){const t=this.role;if(t.type!==e.type){this.setRole(e);return}O.hasSpectator(e)&&O.hasSpectator(t)&&t.recvParams.audioId!==e.recvParams.audioId&&this.setRole(e)}reset(){this.role=J}hasParticipant(){return O.hasParticipant(this.role)}hasSpectatorSynthetic(){return O.hasSpectatorSynthetic(this.role)}hasSpectator(){return O.hasSpectator(this.role)}setRole(e){const t=this.role;this.role=e,this.onRoleChanged?.({previous:t,next:e})}}const vt=(n,e)=>{if(!n||!e)return n===e;const t=n.mainStream?.id,s=e.mainStream?.id,i=n.contentedStream?.id,r=e.contentedStream?.id;return t===s&&i===r};class ft{lastEmittedStreams;hasChanged(e){return!vt(this.lastEmittedStreams,e)}updateLastEmittedStreams(e){this.lastEmittedStreams=e}getLastEmittedStreams(){return this.lastEmittedStreams}reset(){this.lastEmittedStreams=void 0}}const Mt="default",_t="dual",de=n=>[...n.getTracks()].some(e=>e.label.includes(_t));class bt{mainRemoteStreamsManager;recvRemoteStreamsManager;constructor(e,t){this.mainRemoteStreamsManager=e,this.recvRemoteStreamsManager=t}getActiveStreamsManagerTools({isSpectator:e,stateInfo:t}){return e?this.getRecvRemoteStreamsManagerTools({stateInfo:t}):this.getMainRemoteStreamsManagerTools({stateInfo:t})}getMainRemoteStreamsManagerTools({stateInfo:e}){const t=this.mainRemoteStreamsManager;return{manager:t,getRemoteStreams:()=>{const i=t.getStreams(),r=i.find(o=>!de(o)),a=e.isAvailable?i.find(o=>de(o)):void 0;return{mainStream:r,contentedStream:a}}}}getRecvRemoteStreamsManagerTools({stateInfo:e}){const t=this.recvRemoteStreamsManager;return{manager:t,getRemoteStreams:()=>{const i=t.getStreams(Mt);return{mainStream:i[0],contentedStream:e.isAvailable?i[1]:void 0}}}}}const he=n=>n.streams[0]?.id;class Ot{events;callStateMachine;isPendingCall=!1;isPendingAnswer=!1;rtcSession;conferenceStateManager;mainRemoteStreamsManager=new ce;recvRemoteStreamsManager=new ce;streamsManagerProvider;contentedStreamManager;roleManager=new O(e=>{this.onRoleChanged(e)});mcuSession;recvSession;disposeRecvSessionTrackListener;streamsChangeTracker=new ft;constructor(e,t){this.conferenceStateManager=e,this.contentedStreamManager=t,this.events=St(),this.mcuSession=new pt(this.events,{onReset:this.reset}),this.callStateMachine=new Tt(this.events),this.streamsManagerProvider=new bt(this.mainRemoteStreamsManager,this.recvRemoteStreamsManager),this.subscribeCallStatusChange(),this.subscribeMcuRemoteTrackEvents(),this.subscribeContentedStreamEvents()}get callActor(){return this.callStateMachine.actorRef}get requested(){return this.isPendingCall||this.isPendingAnswer}get connection(){return this.mcuSession.connection}get isCallActive(){return this.mcuSession.isCallActive}getStreamsManagerProvider(){return this.streamsManagerProvider}getContentedStreamManager(){return this.contentedStreamManager}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.conferenceStateManager.updateState({number:s.number,answer:!1}),this.mcuSession.startCall(e,t,s).finally(()=>{this.isPendingCall=!1}));async endCall(){return this.mcuSession.endCall()}async renegotiate(){return this.mcuSession.renegotiate()}answerToIncomingCall=async(e,t)=>{this.isPendingAnswer=!0;const s=e();return this.conferenceStateManager.updateState({answer:!0,number:s.remote_identity.uri.user}),this.mcuSession.answerToIncomingCall(s,t).finally(()=>{this.isPendingAnswer=!1})};getMainRemoteStream(){const{mainStream:e}=this.getRemoteStreams();return e}getRemoteStreams(){const{getRemoteStreams:e}=this.getActiveStreamsManagerTools();return e()}getActivePeerConnection=()=>this.roleManager.hasSpectator()?this.recvSession?.peerConnection:this.mcuSession.connection;setCallRoleParticipant(){this.roleManager.setCallRoleParticipant()}setCallRoleSpectatorSynthetic(){this.roleManager.setCallRoleSpectatorSynthetic()}setCallRoleSpectator(e){this.roleManager.setCallRoleSpectator(e)}async replaceMediaStream(e,t){return this.mcuSession.replaceMediaStream(e,t)}async restartIce(e){return this.mcuSession.restartIce(e)}reset=()=>{this.mainRemoteStreamsManager.reset(),this.conferenceStateManager.updateState({number:void 0,answer:!1}),this.roleManager.reset(),this.recvRemoteStreamsManager.reset(),this.stopRecvSession(),this.streamsChangeTracker.reset()};subscribeCallStatusChange(){let{isCallActive:e}=this;const{ACCEPTED:t,CONFIRMED:s,ENDED:i,FAILED:r}=S;this.onRace([t,s,i,r],()=>{e=this.maybeTriggerCallStatus(e)})}maybeTriggerCallStatus(e){const t=this.isCallActive;return t!==e&&this.events.trigger(S.CALL_STATUS_CHANGED,{isCallActive:t}),t}subscribeMcuRemoteTrackEvents(){this.on(S.PEER_CONNECTION_ONTRACK,e=>{this.addRemoteTrack(this.mainRemoteStreamsManager,e.track,he(e))})}addRemoteTrack(e,t,s){const i=e.addTrack(t,{streamHint:s,onRemoved:r=>{this.handleChangedRemoteTracks(e,"removed",{isRemovedStream:r.isRemovedStream,isAddedStream:!1,trackId:r.trackId,participantId:r.participantId})}});i.isAddedTrack&&this.handleChangedRemoteTracks(e,"added",{isRemovedStream:!1,isAddedStream:i.isAddedStream,trackId:t.id,participantId:i.participantId})}handleChangedRemoteTracks(e,t,{trackId:s,participantId:i,isRemovedStream:r,isAddedStream:a}){const o=this.getActiveStreamsManagerTools();if(e!==o.manager)return;const c=o.getRemoteStreams();this.emitEventChangedRemoteTracks(c,t,{trackId:s,participantId:i}),(a||r)&&this.emitEventChangedRemoteStreams(c)}emitEventChangedRemoteTracks(e,t,{trackId:s,participantId:i}){this.events.trigger(S.REMOTE_TRACKS_CHANGED,{streams:e,changeType:t,trackId:s,participantId:i})}emitEventChangedRemoteStreams(e){this.streamsChangeTracker.hasChanged(e)&&(this.streamsChangeTracker.updateLastEmittedStreams(e),this.events.trigger(S.REMOTE_STREAMS_CHANGED,{streams:e}))}getActiveStreamsManagerTools(){return this.streamsManagerProvider.getActiveStreamsManagerTools({isSpectator:this.roleManager.hasSpectator(),stateInfo:this.contentedStreamManager.getStateInfo()})}attachRecvSessionTracks(e){const{peerConnection:t}=e,s=i=>{this.addRemoteTrack(this.recvRemoteStreamsManager,i.track,he(i))};t.addEventListener("track",s),this.disposeRecvSessionTrackListener=()=>{t.removeEventListener("track",s)}}startRecvSession(e,t){const s=this.conferenceStateManager.getNumber();if(s===void 0)return;this.stopRecvSession();const i={quality:"high",audioChannel:e},r=new mt(i,{sendOffer:t});this.recvSession=r,this.recvRemoteStreamsManager.reset(),this.attachRecvSessionTracks(r),r.call(s).catch(()=>{this.stopRecvSession()})}stopRecvSession(){this.recvSession?.close(),this.recvSession=void 0,this.disposeRecvSessionTrackListener?.(),this.disposeRecvSessionTrackListener=void 0,this.recvRemoteStreamsManager.reset()}onRoleChanged=({previous:e,next:t})=>{if(O.hasSpectator(e)&&!O.hasSpectator(t)&&(this.stopRecvSession(),this.emitEventChangedRemoteStreams(this.getRemoteStreams())),O.hasSpectator(t)){const s=t.recvParams;this.startRecvSession(s.audioId,s.sendOffer)}};subscribeContentedStreamEvents(){this.contentedStreamManager.on("available",()=>{this.emitEventChangedRemoteStreams(this.getRemoteStreams())}),this.contentedStreamManager.on("not-available",()=>{this.emitEventChangedRemoteStreams(this.getRemoteStreams())})}}const Dt=(n,e)=>(n.degradationPreference=e.degradationPreference,n),Pt=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},fe=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,yt=fe(),Lt=(n,e)=>{if(yt(n,e))return n},wt=(n,e)=>{const t=n.maxBitrate,s=Lt(e,t);return s!==void 0&&(n.maxBitrate=s),n},Me=1,Ut=fe(Me),Ft=(n,e)=>{const t=n===void 0?void 0:Math.max(n,Me);if(t!==void 0&&Ut(t,e))return t},kt=(n,e)=>{const t=n.scaleResolutionDownBy,s=Ft(e,t);return s!==void 0&&(n.scaleResolutionDownBy=s),n},Bt=(n,e)=>{const t=e.encodings?.length??0;return Pt(n,t),n.encodings.forEach((s,i)=>{const r=(e?.encodings??[])[i],a=r?.maxBitrate,o=r?.scaleResolutionDownBy;wt(s,a),kt(s,o)}),n},$t=(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},_e=async(n,e)=>{const t=n.getParameters(),s=JSON.parse(JSON.stringify(t));Bt(t,e),Dt(t,e);const i=$t(s,t);return i&&await n.setParameters(t),{parameters:t,isChanged:i}},re=async(n,e,t)=>{const{isChanged:s,parameters:i}=await _e(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return s&&t&&t(i),{isChanged:s,parameters:i}},Gt=(n,e)=>n.find(t=>t.track!==null&&e.getTracks().includes(t.track)),qt=async(n,e,t)=>{const s=Gt(n,e);if(s)return re(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 be=["presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed"],Vt=()=>new I.TypedEvents(be);var Oe=(n=>(n.IDLE="presentation:idle",n.STARTING="presentation:starting",n.ACTIVE="presentation:active",n.STOPPING="presentation:stopping",n.FAILED="presentation:failed",n))(Oe||{});const Ht=N.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{d(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{d("PresentationStateMachine state changed",e.state)},setError:N.assign(({event:n})=>"error"in n&&n.error!==void 0?{lastError:n.error instanceof Error?n.error:new Error(JSON.stringify(n.error))}:{lastError:void 0}),clearError:N.assign({lastError:void 0})}}).createMachine({id:"presentation",initial:"presentation:idle",context:{},states:{"presentation:idle":{entry:{type:"logStateChange",params:{state:"presentation:idle"}},on:{"SCREEN.STARTING":{target:"presentation:starting",actions:["clearError",{type:"logTransition",params:{from:"presentation:idle",to:"presentation:starting",event:"SCREEN.STARTING"}}]}}},"presentation:starting":{entry:{type:"logStateChange",params:{state:"presentation:starting"}},on:{"SCREEN.STARTED":{target:"presentation:active",actions:{type:"logTransition",params:{from:"presentation:starting",to:"presentation:active",event:"SCREEN.STARTED"}}},"SCREEN.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:starting",to:"presentation:failed",event:"SCREEN.FAILED"}}]},"SCREEN.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:starting",to:"presentation:idle",event:"SCREEN.ENDED"}}]},"CALL.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:starting",to:"presentation:idle",event:"CALL.ENDED"}}]},"CALL.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:starting",to:"presentation:failed",event:"CALL.FAILED"}}]}}},"presentation:active":{entry:{type:"logStateChange",params:{state:"presentation:active"}},on:{"SCREEN.ENDING":{target:"presentation:stopping",actions:{type:"logTransition",params:{from:"presentation:active",to:"presentation:stopping",event:"SCREEN.ENDING"}}},"SCREEN.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:active",to:"presentation:idle",event:"SCREEN.ENDED"}}]},"SCREEN.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:active",to:"presentation:failed",event:"SCREEN.FAILED"}}]},"CALL.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:active",to:"presentation:idle",event:"CALL.ENDED"}}]},"CALL.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:active",to:"presentation:failed",event:"CALL.FAILED"}}]}}},"presentation:stopping":{entry:{type:"logStateChange",params:{state:"presentation:stopping"}},on:{"SCREEN.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:stopping",to:"presentation:idle",event:"SCREEN.ENDED"}}]},"SCREEN.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:stopping",to:"presentation:failed",event:"SCREEN.FAILED"}}]},"CALL.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:stopping",to:"presentation:idle",event:"CALL.ENDED"}}]},"CALL.FAILED":{target:"presentation:failed",actions:["setError",{type:"logTransition",params:{from:"presentation:stopping",to:"presentation:failed",event:"CALL.FAILED"}}]}}},"presentation:failed":{entry:{type:"logStateChange",params:{state:"presentation:failed"}},on:{"SCREEN.STARTING":{target:"presentation:starting",actions:["clearError",{type:"logTransition",params:{from:"presentation:failed",to:"presentation:starting",event:"SCREEN.STARTING"}}]},"SCREEN.ENDED":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:failed",to:"presentation:idle",event:"SCREEN.ENDED"}}]},"PRESENTATION.RESET":{target:"presentation:idle",actions:["clearError",{type:"logTransition",params:{from:"presentation:failed",to:"presentation:idle",event:"PRESENTATION.RESET"}}]}}}}});class Wt extends H{constructor(e){super(Ht),this.subscribeCallEvents(e)}get isIdle(){return this.state==="presentation:idle"}get isStarting(){return this.state==="presentation:starting"}get isActive(){return this.state==="presentation:active"}get isStopping(){return this.state==="presentation:stopping"}get isFailed(){return this.state==="presentation:failed"}get isPending(){return this.isStarting||this.isStopping}get isActiveOrPending(){return this.isActive||this.isPending}get lastError(){return this.getSnapshot().context.lastError}reset(){this.send({type:"PRESENTATION.RESET"})}send(e){if(!this.getSnapshot().can(e)){console.warn(`[PresentationStateMachine] Invalid transition: ${e.type} from ${this.state}. Event cannot be processed in current state.`);return}super.send(e)}subscribeCallEvents(e){this.addSubscription(e.on(S.START_PRESENTATION,()=>{this.send({type:"SCREEN.STARTING"})})),this.addSubscription(e.on(S.STARTED_PRESENTATION,()=>{this.send({type:"SCREEN.STARTED"})})),this.addSubscription(e.on(S.END_PRESENTATION,()=>{this.send({type:"SCREEN.ENDING"})})),this.addSubscription(e.on(S.ENDED_PRESENTATION,()=>{this.send({type:"SCREEN.ENDED"})})),this.addSubscription(e.on(S.FAILED_PRESENTATION,t=>{this.send({type:"SCREEN.FAILED",error:t})})),this.addSubscription(e.on(S.ENDED,()=>{this.send({type:"CALL.ENDED"})})),this.addSubscription(e.on(S.FAILED,t=>{this.send({type:"CALL.FAILED",error:t})}))}}const xt=1,Qt=n=>ee.hasCanceledError(n);class Yt{events;presentationStateMachine;promisePendingStartPresentation;promisePendingStopPresentation;streamPresentationCurrent;maxBitrate;cancelableSendPresentationWithRepeatedCalls;callManager;constructor({callManager:e,maxBitrate:t}){this.callManager=e,this.maxBitrate=t,this.events=Vt(),this.presentationStateMachine=new Wt(this.callManager.events),this.subscribe()}get presentationActor(){return this.presentationStateMachine.actorRef}get isPendingPresentation(){return!!this.promisePendingStartPresentation||!!this.promisePendingStopPresentation}get isPresentationInProcess(){return!!this.streamPresentationCurrent||this.isPendingPresentation}async startPresentation(e,t,{isNeedReinvite:s,contentHint:i,sendEncodings:r,onAddedTransceiver:a}={},o){const c=this.getRtcSessionProtected();if(this.streamPresentationCurrent)throw new Error("Presentation is already started");return this.sendPresentationWithDuplicatedCalls(e,{rtcSession:c,stream:t,presentationOptions:{isNeedReinvite:s,contentHint: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:xt}}){const a=async()=>this.sendPresentation(e,t,s,i),o=()=>!!this.streamPresentationCurrent;return this.cancelableSendPresentationWithRepeatedCalls=ee.repeatedCallsAsync({targetFunction:a,isComplete:o,isRejectAsValid:!0,...r}),this.cancelableSendPresentationWithRepeatedCalls.then(c=>c)}async sendPresentation(e,t,s,{isNeedReinvite:i=!0,contentHint:r="detail",degradationPreference:a,sendEncodings:o,onAddedTransceiver:c}){const l=q(s,{contentHint:r});if(l===void 0)throw new Error("No streamPresentationTarget");this.streamPresentationCurrent=l;const T=e().then(async()=>t.startPresentation(l,i,{degradationPreference:a,sendEncodings:o,onAddedTransceiver:c})).then(this.setMaxBitrate).then(()=>s).catch(u=>{this.removeStreamPresentationCurrent();const E=u instanceof Error?u:new Error(String(u));throw this.events.trigger(P.FAILED_PRESENTATION,E),u});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 qt(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 Xt{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}getSipServerIp(){return this.data?.sipServerIp}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 De=["connecting","connected","disconnected","newRTCSession","registered","unregistered","registrationFailed","newMessage","sipEvent"],Jt=["disconnecting","connect-started","connect-succeeded","connect-failed","connect-parameters-resolve-success","connect-parameters-resolve-failed","connected-with-configuration"],Pe=[...De,...Jt],zt=()=>new I.TypedEvents(Pe);function jt(n){return e=>`sip:${e}@${n}`}const Kt=(n,e)=>()=>Math.floor(Math.random()*(e-n))+n,ye=n=>n.trim().replaceAll(" ","_"),Zt=Kt(1e5,99999999),en=3;class tn{cancelableConnectWithRepeatedCalls;JsSIP;events;uaFactory;stateMachine;registrationManager;getUa;setUa;getConnectionConfiguration;setConnectionConfiguration;updateConnectionConfiguration;setGetUri;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.setGetUri=e.setGetUri,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",ye(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=en}={})=>{const s=async()=>this.connectInner(e),i=r=>{const c=this.getUa()?.isConnected()===!0&&this.hasEqualConnectionConfiguration(e),l=r!=null&&!at(r);return c||l};return this.stateMachine.startConnect(),this.cancelableConnectWithRepeatedCalls=ee.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,sipServerIp:s,sipServerUrl:i,remoteAddress:r,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:l,userAgent:T,displayName:u="",register:E=!1,extraHeaders:m=[]})=>{this.stateMachine.startInitUa(),this.setConnectionConfiguration({sipServerIp:s,sipServerUrl:i,displayName:u,register:E,user:e,password:t}),this.getUa()&&await this.disconnect();const{ua:R,helpers:w}=this.uaFactory.createUAWithConfiguration({user:e,password:t,sipServerIp:s,sipServerUrl:i,displayName:u,register:E,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:l,userAgent:T,remoteAddress:r,extraHeaders:m},this.events);return this.setUa(R),this.setGetUri(w.getUri),this.setSocket(w.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=((c,l)=>{if(this.getConnectionConfiguration()?.register===!0)return this.registrationManager.subscribeToStartEvents(c,l);const u=C.CONNECTED,E=[C.DISCONNECTED];return this.events.on(u,c),E.forEach(m=>{this.events.on(m,l)}),()=>{this.events.off(u,c),E.forEach(m=>{this.events.off(m,l)})}})(()=>{i?.(),e(s)},c=>{i?.(),t(c)}),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 Le=(n=>(n.IDLE="connection:idle",n.PREPARING="connection:preparing",n.CONNECTING="connection:connecting",n.CONNECTED="connection:connected",n.REGISTERED="connection:registered",n.ESTABLISHED="connection:established",n.DISCONNECTED="connection:disconnected",n.FAILED="connection:failed",n))(Le||{}),we=(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))(we||{});const nn=Object.values(we),sn=N.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{d(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{d("ConnectionStateMachine state changed",e.state)},setError:N.assign({error:({event:n})=>{if(n.type==="CONNECTION_FAILED"&&"error"in n)return n.error}}),clearError:N.assign({error:()=>{}})}}).createMachine({id:"connection",initial:"connection:idle",context:{},states:{"connection:idle":{entry:{type:"logStateChange",params:{state:"connection:idle"}},on:{START_CONNECT:{target:"connection:preparing",actions:{type:"logTransition",params:{from:"connection:idle",to:"connection:preparing",event:"START_CONNECT"}}}}},"connection:preparing":{entry:{type:"logStateChange",params:{state:"connection:preparing"}},on:{START_INIT_UA:{target:"connection:connecting",actions:{type:"logTransition",params:{from:"connection:preparing",to:"connection:connecting",event:"START_INIT_UA"}}},UA_DISCONNECTED:{target:"connection:disconnected",actions:{type:"logTransition",params:{from:"connection:preparing",to:"connection:disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"connection:failed",actions:[{type:"logTransition",params:{from:"connection:preparing",to:"connection:failed",event:"CONNECTION_FAILED"}},{type:"setError"}]}}},"connection:connecting":{entry:{type:"logStateChange",params:{state:"connection:connecting"}},on:{UA_CONNECTED:{target:"connection:connected",actions:{type:"logTransition",params:{from:"connection:connecting",to:"connection:connected",event:"UA_CONNECTED"}}},UA_REGISTERED:{target:"connection:registered",actions:{type:"logTransition",params:{from:"connection:connecting",to:"connection:registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"connection:disconnected",actions:{type:"logTransition",params:{from:"connection:connecting",to:"connection:disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"connection:failed",actions:[{type:"logTransition",params:{from:"connection:connecting",to:"connection:failed",event:"CONNECTION_FAILED"}},{type:"setError"}]}}},"connection:connected":{entry:{type:"logStateChange",params:{state:"connection:connected"}},always:{target:"connection:established",actions:{type:"logTransition",params:{from:"connection:connected",to:"connection:established",event:"always"}}},on:{UA_REGISTERED:{target:"connection:registered",actions:{type:"logTransition",params:{from:"connection:connected",to:"connection:registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"connection:disconnected",actions:{type:"logTransition",params:{from:"connection:connected",to:"connection:disconnected",event:"UA_DISCONNECTED"}}}}},"connection:registered":{entry:{type:"logStateChange",params:{state:"connection:registered"}},always:{target:"connection:established",actions:{type:"logTransition",params:{from:"connection:registered",to:"connection:established",event:"always"}}},on:{UA_UNREGISTERED:{target:"connection:connected",actions:{type:"logTransition",params:{from:"connection:registered",to:"connection:connected",event:"UA_UNREGISTERED"}}},UA_DISCONNECTED:{target:"connection:disconnected",actions:{type:"logTransition",params:{from:"connection:registered",to:"connection:disconnected",event:"UA_DISCONNECTED"}}}}},"connection:established":{entry:{type:"logStateChange",params:{state:"connection:established"}},on:{UA_DISCONNECTED:{target:"connection:disconnected",actions:{type:"logTransition",params:{from:"connection:established",to:"connection:disconnected",event:"UA_DISCONNECTED"}}},RESET:{target:"connection:idle",actions:{type:"logTransition",params:{from:"connection:established",to:"connection:idle",event:"RESET"}}}}},"connection:disconnected":{entry:{type:"logStateChange",params:{state:"connection:disconnected"}},on:{RESET:{target:"connection:idle",actions:{type:"logTransition",params:{from:"connection:disconnected",to:"connection:idle",event:"RESET"}}},START_CONNECT:{target:"connection:preparing",actions:{type:"logTransition",params:{from:"connection:disconnected",to:"connection:preparing",event:"START_CONNECT"}}}}},"connection:failed":{entry:{type:"logStateChange",params:{state:"connection:failed"}},on:{RESET:{target:"connection:idle",actions:[{type:"logTransition",params:{from:"connection:failed",to:"connection:idle",event:"RESET"}},{type:"clearError"}]},START_CONNECT:{target:"connection:preparing",actions:[{type:"logTransition",params:{from:"connection:failed",to:"connection:preparing",event:"START_CONNECT"}},{type:"clearError"}]}}}}});class rn extends H{events;unsubscribeFromEvents;constructor(e){super(sn),this.events=e,this.subscribeToEvents()}get isIdle(){return this.hasState("connection:idle")}get isPreparing(){return this.hasState("connection:preparing")}get isConnecting(){return this.hasState("connection:connecting")}get isConnected(){return this.hasState("connection:connected")}get isRegistered(){return this.hasState("connection:registered")}get isEstablished(){return this.hasState("connection:established")}get isDisconnected(){return this.hasState("connection:disconnected")}get isFailed(){return this.hasState("connection:failed")}get error(){return this.getSnapshot().context.error}get isPending(){return this.isPreparing||this.isConnecting}get isPendingConnect(){return this.isPreparing}get isPendingInitUa(){return this.isConnecting}get isActiveConnection(){return this.isEstablished||this.isConnected||this.isRegistered}startConnect(){this.toStartConnect()}startInitUa(){this.toStartInitUa()}reset(){this.toIdle()}destroy(){this.unsubscribeFromEvents?.(),this.stop()}canTransition(e){return this.getSnapshot().can({type:e})}getValidEvents(){return nn.filter(e=>this.canTransition(e))}hasState(e){return this.getSnapshot().matches(e)}sendEvent(e){if(!this.getSnapshot().can(e)){d(`Invalid transition: ${e.type} from ${this.state}. Event cannot be processed in current state.`);return}this.send(e)}toStartConnect=()=>{this.sendEvent({type:"START_CONNECT"})};toStartInitUa=()=>{this.sendEvent({type:"START_INIT_UA"})};toConnected=()=>{this.sendEvent({type:"UA_CONNECTED"})};toRegistered=()=>{this.sendEvent({type:"UA_REGISTERED"})};toUnregistered=()=>{this.sendEvent({type:"UA_UNREGISTERED"})};toDisconnected=()=>{this.sendEvent({type:"UA_DISCONNECTED"})};toFailed=e=>{this.sendEvent({type:"CONNECTION_FAILED",error:e})};toIdle=()=>{this.sendEvent({type:"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.handleRegistrationFailed),this.events.on("connect-failed",this.handleConnectFailed),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.handleRegistrationFailed),this.events.off("connect-failed",this.handleConnectFailed)}}handleRegistrationFailed=e=>{const t=e.response?.status_code??"Unknown",s=e.response?.reason_phrase??"Registration failed",i=new Error(`Registration failed: ${t} ${s}`);this.toFailed(i)};handleConnectFailed=e=>{this.toFailed(e instanceof Error?e:void 0)}}class an{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){d("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 on{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,sipServerIp:s,sipServerUrl:i,remoteAddress:r,extraHeaders:a}){return new Promise((o,c)=>{const{configuration:l}=this.uaFactory.createConfiguration({sipServerUrl:i,displayName:t,userAgent:e,sipServerIp:s}),T=this.uaFactory.createUA({...l,remoteAddress:r,extraHeaders:a}),u=()=>{const m=new Error("Telephony is not available");c(m)};T.once(C.DISCONNECTED,u);const E=()=>{T.removeAllListeners(),T.once(C.DISCONNECTED,()=>{o()}),T.stop()};T.once(C.CONNECTED,E),T.start()})}}const cn=n=>{const e=[];return n!==void 0&&n!==""&&e.push(`X-Vinteo-Remote: ${n}`),e};class F{JsSIP;constructor(e){this.JsSIP=e}static isRegisteredUA(e){return!!e&&e.isRegistered()}static validateParametersConnection({register:e,password:t,user:s,sipServerIp:i,sipServerUrl:r}){if(!i)throw new Error("sipServerIp is required");if(!r)throw new Error("sipServerUrl 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():`${Zt()}`}static buildExtraHeaders(e,t){const s=e!==void 0&&e!==""?cn(e):[];return t===void 0?s:[...s,...t]}createConfiguration({user:e,password:t,sipServerUrl:s,displayName:i="",sipServerIp:r,register:a=!1,sessionTimers:o=!1,registerExpires:c=300,connectionRecoveryMinInterval:l=2,connectionRecoveryMaxInterval:T=6,userAgent:u}){F.validateParametersConnection({register:a,password:t,user:e,sipServerIp:r,sipServerUrl:s});const E=F.resolveAuthorizationUser(a,e),m=jt(r),D=m(E),R=new this.JsSIP.WebSocketInterface(`wss://${s}/webrtc/wss/`);return{configuration:{password:t,register:a,uri:D,display_name:ye(i),user_agent:u,sdpSemantics:"unified-plan",sockets:[R],session_timers:o,register_expires:c,connection_recovery_min_interval:l,connection_recovery_max_interval:T},helpers:{socket:R,getUri:m}}}createUA({remoteAddress:e,extraHeaders:t,...s}){const i=new this.JsSIP.UA(s),r=F.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 c=De.find(l=>l===o);c&&r.on(c,a)}),{ua:r,helpers:i}}}const Ue="Not ready for connection",Fe=n=>n instanceof Error&&n.message===Ue,dn=()=>new Error(Ue),hn=async n=>typeof n=="function"?n():n;class ln{events;ua;socket;uaFactory;registrationManager;stateMachine;connectionFlow;sipOperations;configurationManager;JsSIP;constructor({JsSIP:e}){this.JsSIP=e,this.events=zt(),this.uaFactory=new F(e),this.registrationManager=new an({events:this.events,getUaProtected:this.getUaProtected}),this.stateMachine=new rn(this.events),this.configurationManager=new Xt({getUa:this.getUa}),this.sipOperations=new on({uaFactory:this.uaFactory,getUaProtected:this.getUaProtected}),this.connectionFlow=new tn({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},setGetUri:t=>{this.getUri=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 connectionActor(){return this.stateMachine.actorRef}get connectionState(){return this.stateMachine.state}get isRegistered(){return F.isRegisteredUA(this.ua)}get isRegisterConfig(){return this.configurationManager.isRegister()}connect=async(e,t)=>this.disconnect().catch(s=>{d("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()}getUri=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 dn();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,{}),hn(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 gn{connectionManager;stackPromises=te.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 le=0,un=30;class Tn{countInner=le;initialCount=le;limitInner=un;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 En{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 V.CancelableRequest(e),this.checkTelephonyByTimeout=k.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 f=(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))(f||{});const ke=["before-attempt","success","failed-all-attempts","cancelled-attempts","changed-attempt-status","stop-attempts-by-error","limit-reached-attempts"],Sn=()=>new I.TypedEvents(ke);class ae{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 Cn=15e3,pn=2;class mn{connectionManager;pingServerByTimeoutWithFailCalls;constructor({connectionManager:e}){this.connectionManager=e,this.pingServerByTimeoutWithFailCalls=k.requesterByTimeoutsWithFailCalls(pn,{whenPossibleRequest:async()=>{},requestInterval:Cn,request:async()=>(d("ping"),this.connectionManager.ping().then(()=>{d("ping success")}))})}start({onFailRequest:e}){this.pingServerByTimeoutWithFailCalls.start(void 0,{onFailRequest:e}).catch(d)}stop(){this.pingServerByTimeoutWithFailCalls.stop()}}class Nn{pingServerRequester;notActiveCallSubscriber;constructor({connectionManager:e,callManager:t}){this.pingServerRequester=new mn({connectionManager:e}),this.notActiveCallSubscriber=new ae({callManager:t})}start({onFailRequest:e}){d("start"),this.notActiveCallSubscriber.subscribe({onActive:()=>{this.pingServerRequester.stop()},onInactive:()=>{this.pingServerRequester.start({onFailRequest:e})}})}stop(){d("stop"),this.pingServerRequester.stop(),this.unsubscribeCallStatusChange()}unsubscribeCallStatusChange(){this.notActiveCallSubscriber.unsubscribe()}}class An{connectionManager;isRegistrationFailed=!1;disposers=[];notActiveCallSubscriber;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.notActiveCallSubscriber=new ae({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 Rn=3e3,In=15e3,ge={LIMIT_REACHED:"Limit reached",FAILED_TO_RECONNECT:"Failed to reconnect"},vn=async()=>{},fn=n=>!0;class Mn{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??vn,a=i?.canRetryOnError??fn;this.connectionQueueManager=e,this.connectionManager=t,this.onBeforeRetry=r,this.canRetryOnError=a,this.networkInterfacesSubscriber=i?.networkInterfacesSubscriber,this.resumeFromSleepModeSubscriber=i?.resumeFromSleepModeSubscriber,this.events=Sn(),this.checkTelephonyRequester=new En({connectionManager:t,interval:i?.checkTelephonyRequestInterval??In}),this.pingServerIfNotActiveCallRequester=new Nn({connectionManager:t,callManager:s}),this.registrationFailedOutOfCallSubscriber=new An({connectionManager:t,callManager:s}),this.attemptsState=new Tn({onStatusChange:this.emitStatusChange}),this.cancelableRequestBeforeRetry=new V.CancelableRequest(r),this.delayBetweenAttempts=new k.DelayRequester(i?.timeoutBetweenAttempts??Rn),this.notActiveCallSubscriber=new ae({callManager:s})}start(e){d("auto connector start"),this.restartConnectionAttempts(e),this.subscribeToNotActiveCall(e)}stop(){d("auto connector stop"),this.unsubscribeFromNotActiveCall(),this.unsubscribeFromHardwareTriggers(),this.stopConnectionFlow().catch(e=>{d("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){d("auto connector restart connection attempts"),this.stopConnectionFlow().then(async()=>this.attemptConnection(e)).catch(t=>{d("auto connector failed to restart connection attempts:",t)})}async stopConnectionFlow(){d("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(){d("stopConnectTriggers"),this.stopPingRequester(),this.checkTelephonyRequester.stop(),this.registrationFailedOutOfCallSubscriber.unsubscribe()}startCheckTelephony(e){d("startCheckTelephony"),this.checkTelephonyRequester.start({onBeforeRequest:async()=>(await this.onBeforeRetry(),e.getParameters()),onSuccessRequest:()=>{d("startCheckTelephony: onSuccessRequest"),this.connectIfDisconnected(e)},onFailRequest:t=>{d("startCheckTelephony: onFailRequest",t.message)}})}async attemptConnection(e){if(d("attemptConnection: attempts.count",this.attemptsState.count),this.events.trigger(f.BEFORE_ATTEMPT,{}),this.stopConnectTriggers(),this.attemptsState.hasLimitReached()){d("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),d("executeConnectionAttempt: success"),this.handleSucceededAttempt(e)}catch(t){this.handleConnectionError(t,e)}}handleConnectionError(e,t){if(Fe(e)){this.attemptsState.finishAttempt(),this.events.trigger(f.STOP_ATTEMPTS_BY_ERROR,e);return}if(!this.canRetryOnError(e)){d("executeConnectionAttempt: error does not allow retry",e),this.attemptsState.finishAttempt(),this.events.trigger(f.STOP_ATTEMPTS_BY_ERROR,e);return}if(te.isPromiseIsNotActualError(e)){d("executeConnectionAttempt: not actual error",e),this.attemptsState.finishAttempt(),this.events.trigger(f.CANCELLED_ATTEMPTS,e);return}d("executeConnectionAttempt: error",e),this.scheduleReconnect(t)}handleLimitReached(e){this.attemptsState.finishAttempt(),this.events.trigger(f.LIMIT_REACHED_ATTEMPTS,new Error(ge.LIMIT_REACHED)),this.startCheckTelephony(e)}handleSucceededAttempt(e){d("handleSucceededAttempt"),this.subscribeToConnectTriggers(e),this.events.trigger(f.SUCCESS)}subscribeToConnectTriggers(e){this.startPingRequester(e),this.registrationFailedOutOfCallSubscriber.subscribe(()=>{d("registrationFailedOutOfCallListener callback"),this.restartConnectionAttempts(e)})}subscribeToNotActiveCall(e){this.notActiveCallSubscriber.subscribe({onActive:()=>{d("subscribeToNotActiveCall onActive"),this.unsubscribeFromHardwareTriggers()},onInactive:()=>{d("subscribeToNotActiveCall onInactive"),this.subscribeToHardwareTriggers(e)}})}unsubscribeFromNotActiveCall(){this.notActiveCallSubscriber.unsubscribe()}subscribeToHardwareTriggers(e){this.unsubscribeFromHardwareTriggers(),d("subscribeToHardwareTriggers"),this.networkInterfacesSubscriber?.subscribe({onChange:()=>{d("networkInterfacesSubscriber onChange"),this.restartConnectionAttempts(e)},onUnavailable:()=>{d("networkInterfacesSubscriber onUnavailable"),this.stopConnectionFlow().catch(t=>{d("auto connector stop from networkInterfacesSubscriber onUnavailable: error",t)})}}),this.resumeFromSleepModeSubscriber?.subscribe({onResume:()=>{d("resumeFromSleepModeSubscriber onResume"),this.restartConnectionAttempts(e)}})}unsubscribeFromHardwareTriggers(){d("unsubscribeFromHardwareTriggers"),this.networkInterfacesSubscriber?.unsubscribe(),this.resumeFromSleepModeSubscriber?.unsubscribe()}stopPingRequester(){this.pingServerIfNotActiveCallRequester.stop()}startPingRequester(e){this.pingServerIfNotActiveCallRequester.start({onFailRequest:()=>{d("pingRequester: onFailRequest"),this.restartConnectionAttempts(e)}})}connectIfDisconnected(e){const t=this.isConnectionUnavailable();d("connectIfDisconnected: isUnavailable",t),t?this.restartConnectionAttempts(e):(this.stopConnectTriggers(),this.events.trigger(f.SUCCESS))}scheduleReconnect(e){d("scheduleReconnect"),this.delayBetweenAttempts.request().then(async()=>(d("scheduleReconnect: delayBetweenAttempts success"),this.cancelableRequestBeforeRetry.request())).then(async()=>(d("scheduleReconnect: onBeforeRetry success"),this.attemptConnection(e))).catch(t=>{const s=t instanceof Error?t:new Error(ge.FAILED_TO_RECONNECT);this.attemptsState.finishAttempt(),V.isCanceledError(t)||k.hasCanceledError(t)?this.events.trigger(f.CANCELLED_ATTEMPTS,s):this.events.trigger(f.FAILED_ALL_ATTEMPTS,s),d("scheduleReconnect: error",t)})}isConnectionUnavailable(){const{isFailed:e,isDisconnected:t,isIdle:s}=this.connectionManager;return e||t||s}emitStatusChange=({isInProgress:e})=>{this.events.trigger(f.CHANGED_ATTEMPT_STATUS,{isInProgress:e})}}var j=(n=>(n.STATE_CHANGED="state-changed",n.STATE_RESET="state-reset",n))(j||{});const Be=["state-changed","state-reset"],_n=()=>new I.TypedEvents(Be);class bn{events;state={};constructor(){this.events=_n()}getState(){return{...this.state}}updateState(e){const t={...this.state};this.state={...this.state,...e},this.events.trigger(j.STATE_CHANGED,{previous:t,current:this.state,updates:e})}reset(){this.state={},this.events.trigger(j.STATE_RESET,{})}getToken(){return this.state.token}getRoom(){return this.state.room}getParticipantName(){return this.state.participantName}getChannels(){return this.state.channels}getConference(){return this.state.conference}getParticipant(){return this.state.participant}getNumber(){return this.state.number}getAnswer(){return this.state.answer}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}off(e,t){this.events.off(e,t)}}const On=N.setup({types:{context:{},events:{}},actions:{setCodec:N.assign(({event:n})=>"codec"in n?{codec:n.codec}:{}),clearCodec:N.assign({codec:void 0})}}).createMachine({id:"contented-stream",initial:"contented-stream:not-available",context:{},states:{"contented-stream:not-available":{on:{"CONTENTED_STREAM.AVAILABLE":{target:"contented-stream:available",actions:"setCodec"}}},"contented-stream:available":{on:{"CONTENTED_STREAM.NOT_AVAILABLE":{target:"contented-stream:not-available",actions:"clearCodec"},"CONTENTED_STREAM.AVAILABLE":{target:"contented-stream:available",actions:"setCodec",reenter:!0},"CONTENTED_STREAM.RESET":{target:"contented-stream:not-available",actions:"clearCodec"}}}}});class Dn extends H{constructor(){super(On)}get isAvailable(){return this.state==="contented-stream:available"}get isNotAvailable(){return this.state==="contented-stream:not-available"}get codec(){return this.getSnapshot().context.codec}getStateInfo(){return{isAvailable:this.isAvailable,codec:this.codec}}reset(){this.send({type:"CONTENTED_STREAM.RESET"})}send(e){if(!this.getSnapshot().can(e)){console.warn(`[ContentedStreamStateMachine] Invalid transition: ${e.type} from ${this.state}. Event cannot be processed in current state.`);return}super.send(e)}subscribeToApiEvents(e){this.addSubscription(e.on("contented-stream:available",t=>{this.send({type:"CONTENTED_STREAM.AVAILABLE",codec:t.codec})})),this.addSubscription(e.on("contented-stream:not-available",()=>{this.send({type:"CONTENTED_STREAM.NOT_AVAILABLE"})}))}}var K=(n=>(n.AVAILABLE="available",n.NOT_AVAILABLE="not-available",n))(K||{});const Pn=["available","not-available"],yn=()=>new I.TypedEvents(Pn);class Ln{events;stateMachine;constructor(){this.events=yn(),this.stateMachine=new Dn,this.proxyEvents()}get isAvailable(){return this.stateMachine.isAvailable}get codec(){return this.stateMachine.codec}getStateInfo(){return this.stateMachine.getStateInfo()}reset(){this.stateMachine.reset()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}off(e,t){this.events.off(e,t)}subscribeToApiEvents(e){this.stateMachine.subscribeToApiEvents(e.events)}proxyEvents(){this.stateMachine.onStateChange(()=>{const e=this.getStateInfo();e.isAvailable?this.events.trigger(K.AVAILABLE,{codec:e.codec}):this.events.trigger(K.NOT_AVAILABLE,{})})}}var $=(n=>(n.RINGING="ringing",n.DECLINED_INCOMING_CALL="declinedIncomingCall",n.TERMINATED_INCOMING_CALL="terminatedIncomingCall",n.FAILED_INCOMING_CALL="failedIncomingCall",n))($||{});const $e=["ringing","declinedIncomingCall","terminatedIncomingCall","failedIncomingCall"],wn=()=>new I.TypedEvents($e);var Ge=(n=>(n.IDLE="incoming:idle",n.RINGING="incoming:ringing",n.CONSUMED="incoming:consumed",n.DECLINED="incoming:declined",n.TERMINATED="incoming:terminated",n.FAILED="incoming:failed",n))(Ge||{});const Un=N.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{d(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{d("IncomingCallStateMachine state changed",e.state)},rememberIncoming:N.assign(({event:n})=>{const{data:e}=n;return{remoteCallerData:e,lastReason:void 0}}),rememberReason:N.assign(({event:n,context:e})=>n.type==="INCOMING.CONSUMED"?{remoteCallerData:e.remoteCallerData,lastReason:"incoming:consumed"}:n.type==="INCOMING.DECLINED"?{remoteCallerData:n.data,lastReason:"incoming:declined"}:n.type==="INCOMING.TERMINATED"?{remoteCallerData:n.data,lastReason:"incoming:terminated"}:{remoteCallerData:n.data,lastReason:"incoming:failed"}),clearIncoming:N.assign(()=>({remoteCallerData:void 0,lastReason:void 0}))}}).createMachine({id:"incoming",initial:"incoming:idle",context:{},states:{"incoming:idle":{entry:{type:"logStateChange",params:{state:"incoming:idle"}},on:{"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:idle",to:"incoming:ringing",event:"INCOMING.RINGING"}}]},"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:idle",to:"incoming:idle",event:"INCOMING.CLEAR"}}]}}},"incoming:ringing":{entry:{type:"logStateChange",params:{state:"incoming:ringing"}},on:{"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:ringing",event:"INCOMING.RINGING"}}]},"INCOMING.CONSUMED":{target:"incoming:consumed",actions:["rememberReason",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:consumed",event:"INCOMING.CONSUMED"}}]},"INCOMING.DECLINED":{target:"incoming:declined",actions:["rememberReason",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:declined",event:"INCOMING.DECLINED"}}]},"INCOMING.TERMINATED":{target:"incoming:terminated",actions:["rememberReason",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:terminated",event:"INCOMING.TERMINATED"}}]},"INCOMING.FAILED":{target:"incoming:failed",actions:["rememberReason",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:failed",event:"INCOMING.FAILED"}}]},"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:ringing",to:"incoming:idle",event:"INCOMING.CLEAR"}}]}}},"incoming:consumed":{entry:{type:"logStateChange",params:{state:"incoming:consumed"}},on:{"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:consumed",to:"incoming:idle",event:"INCOMING.CLEAR"}}]},"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:consumed",to:"incoming:ringing",event:"INCOMING.RINGING"}}]}}},"incoming:declined":{entry:{type:"logStateChange",params:{state:"incoming:declined"}},on:{"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:declined",to:"incoming:idle",event:"INCOMING.CLEAR"}}]},"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:declined",to:"incoming:ringing",event:"INCOMING.RINGING"}}]}}},"incoming:terminated":{entry:{type:"logStateChange",params:{state:"incoming:terminated"}},on:{"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:terminated",to:"incoming:idle",event:"INCOMING.CLEAR"}}]},"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:terminated",to:"incoming:ringing",event:"INCOMING.RINGING"}}]}}},"incoming:failed":{entry:{type:"logStateChange",params:{state:"incoming:failed"}},on:{"INCOMING.CLEAR":{target:"incoming:idle",actions:["clearIncoming",{type:"logTransition",params:{from:"incoming:failed",to:"incoming:idle",event:"INCOMING.CLEAR"}}]},"INCOMING.RINGING":{target:"incoming:ringing",actions:["rememberIncoming",{type:"logTransition",params:{from:"incoming:failed",to:"incoming:ringing",event:"INCOMING.RINGING"}}]}}}}});class Fn extends H{constructor({incomingEvents:e,connectionEvents:t}){super(Un),this.subscribeIncomingEvents(e),this.subscribeConnectionEvents(t)}get isIdle(){return this.state==="incoming:idle"}get isRinging(){return this.state==="incoming:ringing"}get isConsumed(){return this.state==="incoming:consumed"}get isDeclined(){return this.state==="incoming:declined"}get isTerminated(){return this.state==="incoming:terminated"}get isFailed(){return this.state==="incoming:failed"}get isActive(){return this.isRinging}get isFinished(){return this.isConsumed||this.isDeclined||this.isTerminated||this.isFailed}get remoteCallerData(){return this.getSnapshot().context.remoteCallerData}get lastReason(){return this.getSnapshot().context.lastReason}reset(){this.send({type:"INCOMING.CLEAR"})}send(e){if(!this.getSnapshot().can(e)){console.warn(`[IncomingCallStateMachine] Invalid transition: ${e.type} from ${this.state}. Event cannot be processed in current state.`);return}super.send(e)}toConsumed(){this.send({type:"INCOMING.CONSUMED"})}subscribeIncomingEvents(e){this.addSubscription(e.on("ringing",t=>{this.send({type:"INCOMING.RINGING",data:t})})),this.addSubscription(e.on("declinedIncomingCall",t=>{this.send({type:"INCOMING.DECLINED",data:t})})),this.addSubscription(e.on("terminatedIncomingCall",t=>{this.send({type:"INCOMING.TERMINATED",data:t})})),this.addSubscription(e.on("failedIncomingCall",t=>{this.send({type:"INCOMING.FAILED",data:t})}))}subscribeConnectionEvents(e){this.addSubscription(e.on(C.DISCONNECTED,()=>{this.toClearIncoming()})),this.addSubscription(e.on(C.REGISTRATION_FAILED,()=>{this.toClearIncoming()})),this.addSubscription(e.on(C.CONNECT_FAILED,()=>{this.toClearIncoming()}))}toClearIncoming(){this.send({type:"INCOMING.CLEAR"})}}const kn=486,Bn=487;class $n{events;incomingStateMachine;incomingRTCSession;connectionManager;constructor(e){this.connectionManager=e,this.events=wn(),this.incomingStateMachine=new Fn({incomingEvents:this.events,connectionEvents:this.connectionManager.events}),this.start()}get incomingActor(){return this.incomingStateMachine.actorRef}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.incomingStateMachine.toConsumed(),this.removeIncomingSession(),e};async declineToIncomingCall({statusCode:e=Bn}={}){return new Promise((t,s)=>{try{const i=this.getIncomingRTCSession(),r=this.remoteCallerData;this.removeIncomingSession(),this.events.trigger($.DECLINED_INCOMING_CALL,r),i.terminate({status_code:e}),t()}catch(i){s(i)}})}async busyIncomingCall(){return this.declineToIncomingCall({statusCode:kn})}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($.TERMINATED_INCOMING_CALL,t):this.events.trigger($.FAILED_INCOMING_CALL,t)}),this.events.trigger($.RINGING,t)}removeIncomingSession(){delete this.incomingRTCSession}}var qe=(n=>(n.SNAPSHOT_CHANGED="snapshot-changed",n))(qe||{});const Ve=["snapshot-changed"],Gn=()=>new I.TypedEvents(Ve),qn=(n,e)=>Object.is(n,e),ue=n=>({connection:n.connection.getSnapshot(),call:n.call.getSnapshot(),incoming:n.incoming.getSnapshot(),presentation:n.presentation.getSnapshot()});class Vn{events;actors;currentSnapshot;subscribers=new Set;actorSubscriptions=[];constructor(e){this.events=Gn(),this.actors={connection:e.connectionManager.connectionActor,call:e.callManager.callActor,incoming:e.incomingCallManager.incomingActor,presentation:e.presentationManager.presentationActor},this.currentSnapshot=ue(this.actors),this.actorSubscriptions.push(this.actors.connection.subscribe(this.notifySubscribers),this.actors.call.subscribe(this.notifySubscribers),this.actors.incoming.subscribe(this.notifySubscribers),this.actors.presentation.subscribe(this.notifySubscribers))}getSnapshot(){return this.currentSnapshot}subscribe(e,t,s){const i=typeof t=="function",r=i?e:T=>T,a=i?t:e,o=(i?s:void 0)??qn,c=r(this.currentSnapshot),l={selector:r,listener:a,equals:o,current:c};return this.subscribers.add(l),()=>{this.subscribers.delete(l)}}stop(){this.subscribers.clear(),this.actorSubscriptions.forEach(e=>{e.unsubscribe()})}on(e,t){return this.events.on(e,t)}off(e,t){this.events.off(e,t)}notifySubscribers=()=>{const e=this.currentSnapshot;this.currentSnapshot=ue(this.actors);for(const t of this.subscribers){const s=t.selector(this.currentSnapshot);t.equals(t.current,s)||(t.current=s,t.listener(s))}this.events.trigger(qe.SNAPSHOT_CHANGED,{previous:e,current:this.currentSnapshot})}}const B=1e3;var p=(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))(p||{});const He=["collected"],Hn=()=>new I.TypedEvents(He),Wn="api/v2/rtp2webrtc/offer",We=async({serverUrl:n,conferenceNumber:e,quality:t,audio:s,offer:i,token:r})=>{const a=new URL(`https://${n.replace(/\/$/,"")}/${Wn}/${encodeURIComponent(e)}`);a.searchParams.set("quality",t),a.searchParams.set("audio",String(s));const o={"Content-Type":"application/json"};r!==void 0&&r!==""&&(o.Authorization=`Bearer ${r}`);const c=await fetch(a.toString(),{method:"POST",headers:o,credentials:"same-origin",body:JSON.stringify(i)});if(!c.ok)throw new Error(`sendOffer failed with status ${c.status}`);const l=await c.json();return{type:l.type,sdp:l.sdp,toJSON(){return l}}},Te=()=>"performance"in window?performance.now():Date.now(),W=n=>[...n.keys()].reduce((e,t)=>{const s=n.get(t);return s===void 0?e:{...e,[s.type]:s}},{}),xn=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=W(n);return{outboundRtp:e[p.OUTBOUND_RTP],codec:e[p.CODEC],mediaSource:e[p.MEDIA_SOURCE],remoteInboundRtp:e[p.REMOTE_INBOUND_RTP]}},Ee=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=W(n);return{outboundRtp:e[p.OUTBOUND_RTP],codec:e[p.CODEC],mediaSource:e[p.MEDIA_SOURCE],remoteInboundRtp:e[p.REMOTE_INBOUND_RTP]}},Se=({videoReceiversStats:n,synchronizationSourcesVideo:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,synchronizationSources:e};const t=W(n);return{inboundRtp:t[p.INBOUND_RTP],codec:t[p.CODEC],synchronizationSources:e}},Qn=({audioReceiverStats:n,synchronizationSourcesAudio:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,remoteOutboundRtp:void 0,synchronizationSources:e};const t=W(n);return{inboundRtp:t[p.INBOUND_RTP],codec:t[p.CODEC],remoteOutboundRtp:t[p.REMOTE_OUTBOUND_RTP],synchronizationSources:e}},xe=n=>{if(!n)return{candidatePair:void 0,certificate:void 0,localCandidate:void 0,remoteCandidate:void 0,transport:void 0};const e=W(n);return{candidatePair:e[p.CANDIDATE_PAIR],certificate:e[p.CERTIFICATE],localCandidate:e[p.LOCAL_CANDIDATE],remoteCandidate:e[p.REMOTE_CANDIDATE],transport:e[p.TRANSPORT]}},Yn=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t})=>({video:Ee(e),secondVideo:Ee(t),audio:xn(n),additional:xe(n??e??t)}),Xn=({audioReceiverStats:n,videoReceiverFirstStats:e,videoReceiverSecondStats:t,synchronizationSources:s})=>({video:Se({videoReceiversStats:e,synchronizationSourcesVideo:s.video}),secondVideo:Se({videoReceiversStats:t,synchronizationSourcesVideo:s.video}),audio:Qn({audioReceiverStats:n,synchronizationSourcesAudio:s.audio}),additional:xe(n??e??t)}),Jn=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t,audioReceiverStats:s,videoReceiverFirstStats:i,videoReceiverSecondStats:r,synchronizationSources:a})=>{const o=Yn({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t}),c=Xn({audioReceiverStats:s,videoReceiverFirstStats:i,videoReceiverSecondStats:r,synchronizationSources:a});return{outbound:o,inbound:c}},zn=async n=>{const e="audio",t="video",s=n.getSenders(),i=s.find(E=>E.track?.kind===e),r=s.filter(E=>E.track?.kind===t),a=n.getReceivers(),o=a.find(E=>E.track.kind===e),c=a.filter(E=>E.track.kind===t),l={trackIdentifier:o?.track.id,item:o?.getSynchronizationSources()[0]},T={trackIdentifier:c[0]?.track.id,item:c[0]?.getSynchronizationSources()[0]},u={audio:l,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),c[0]?.getStats()??Promise.resolve(void 0),c[1]?.getStats()??Promise.resolve(void 0)]).then(E=>{const[m,D,R,w,X,et]=E;return{synchronizationSources:u,audioSenderStats:m,videoSenderFirstStats:D,videoSenderSecondStats:R,audioReceiverStats:w,videoReceiverFirstStats:X,videoReceiverSecondStats:et}})},jn=n=>{d(String(n))};class Qe{events;setTimeoutRequest;requesterAllStatistics=new V.CancelableRequest(zn);constructor(){this.events=Hn(),this.setTimeoutRequest=new k.SetTimeoutRequest}get requested(){return this.setTimeoutRequest.requested}start(e,{interval:t=B,onError:s=jn}={}){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.requestAllStatistics(e).then(i=>{this.events.trigger("collected",Jn(i));const a=Te()-s;let o=B;a>48?o=B*4:a>32?o=B*3:a>16&&(o=B*2),this.start(e,{onError:t,interval:o})}).catch(i=>{t&&t(i)})};requestAllStatistics=async e=>{const t=e();if(t===void 0)throw new Error("failed to collect statistics: peerConnection is not defined");return this.requesterAllStatistics.request(t)}}const Kn=500;class Zn{statsPeerConnection;availableStats;previousAvailableStats;callManager;apiManager;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.statsPeerConnection=new Qe,this.subscribe()}get events(){return this.statsPeerConnection.events}get availableIncomingBitrate(){return this.availableStats?.inbound.additional.candidatePair?.availableIncomingBitrate}get isInvalidInboundFrames(){return this.isEmptyInboundFrames&&this.isReceivingPackets}get isEmptyInboundFrames(){return!this.isFramesReceived||!this.isFramesDecoded}get previousAvailableIncomingBitrate(){return this.previousAvailableStats?.inbound.additional.candidatePair?.availableIncomingBitrate}get previousInboundRtp(){return this.previousAvailableStats?.inbound.video.inboundRtp}get previousFramesReceived(){return this.previousInboundRtp?.framesReceived}get previousFramesDecoded(){return this.previousInboundRtp?.framesDecoded}get inboundRtp(){return this.availableStats?.inbound.video.inboundRtp}get framesReceived(){return this.inboundRtp?.framesReceived}get framesDecoded(){return this.inboundRtp?.framesDecoded}get isFramesReceived(){const e=this.framesReceived!==void 0&&this.framesReceived>0,t=this.framesReceived!==this.previousFramesReceived;return e&&t}get isFramesDecoded(){const e=this.framesDecoded!==void 0&&this.framesDecoded>0,t=this.framesDecoded!==this.previousFramesDecoded;return e&&t}get packetsReceived(){return this.inboundRtp?.packetsReceived}get previousPacketsReceived(){return this.previousInboundRtp?.packetsReceived}get isReceivingPackets(){const e=this.packetsReceived!==void 0&&this.packetsReceived>=Kn,t=this.packetsReceived!==this.previousPacketsReceived;return e&&t}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.previousAvailableStats=this.availableStats,this.availableStats=e,this.maybeSendStats()};handleStarted=()=>{this.statsPeerConnection.start(this.callManager.getActivePeerConnection)};handleEnded=()=>{this.statsPeerConnection.stop(),this.availableStats=void 0,this.previousAvailableStats=void 0};maybeSendStats(){this.availableIncomingBitrate!==void 0&&this.hasAvailableIncomingBitrateChangedQuarter()&&this.apiManager.sendStats({availableIncomingBitrate:this.availableIncomingBitrate}).catch(e=>{d("Failed to send stats",e)})}}const es=(n,e)=>n.filter(s=>e.some(i=>i.clockRate===s.clockRate&&i.mimeType===s.mimeType&&i.channels===s.channels&&i.sdpFmtpLine===s.sdpFmtpLine)),ts=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),s=e===null?[]:e.codecs,i=t===null?[]:t.codecs;return es(s,i)},ns=(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}),ss=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),is=(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=ts("video"),i=ss(s,t),r=ns(i,e);n.setCodecPreferences(r)}}catch(s){d("setCodecPreferences error",s)}},rs=n=>[...n.keys()].map(e=>n.get(e)),as=(n,e)=>rs(n).find(t=>t?.type===e),Ye=async n=>n.getStats().then(e=>as(e,"codec")?.mimeType);class os{async getCodecFromSender(e){return await Ye(e)??""}}class cs{stackPromises=te.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{d("TaskQueue: error",e)})}}class ds{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new cs}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>re(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}const Xe=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),hs=1e6,b=n=>n*hs,Je=b(.06),ze=b(4),ls=n=>n<=64?Je:n<=128?b(.12):n<=256?b(.25):n<=384?b(.32):n<=426?b(.38):n<=640?b(.5):n<=848?b(.7):n<=1280?b(1):n<=1920?b(2):ze,gs="av1",us=n=>Xe(n,gs),Ts=.6,oe=(n,e)=>us(e)?n*Ts:n,Es=n=>oe(Je,n),Ss=n=>oe(ze,n),Ce=(n,e)=>{const t=ls(n);return oe(t,e)},z=1,Cs=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),s=t.width,i=t.height,r=s===void 0?z:s/e.width,a=i===void 0?z:i/e.height;return Math.max(r,a,z)};class ps{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(Xe(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(c=>({...c,sender:i}))}async processSender(e,t){const{mainCam:s,resolutionMainCam:i}=e;switch(s){case M.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case M.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case M.MAX_MAIN_CAM_RESOLUTION:return i!==void 0?this.setResolutionSender(i,t):this.setBitrateByTrackResolution(t);case M.ADMIN_STOP_MAIN_CAM:case M.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:Es(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?Ss(i):Ce(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,c={width:Number(s),height:Number(i)},l=Cs({videoTrack:a,targetSize:c}),T=Ce(c.width,o),u={scaleResolutionDownBy:l,maxBitrate:T};return this.parametersSetter.setEncodingsToSender(r,u)}}const ms=n=>n.find(e=>e.track?.kind==="video");class Ns{findVideoSender(e){return ms(e)}}class As{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 k.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 Rs{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 Is{eventHandler;senderBalancer;parametersSetterWithQueue;getConnection;serverHeaders;trackMonitor;constructor(e,t,{ignoreForCodec:s,onSetParameters:i,pollIntervalMs:r}={}){this.getConnection=t,this.eventHandler=new Rs(e),this.parametersSetterWithQueue=new ds(i),this.senderBalancer=new ps({senderFinder:new Ns,codecProvider:new os,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:s}),this.trackMonitor=new As({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=>{d("balance on track change: error",s)})}),t}handleMainCamControl=e=>{this.serverHeaders=e,this.balance().catch(t=>{d("handleMainCamControl: error",t)})}}const je=["balancing-scheduled","balancing-started","balancing-stopped","parameters-updated"],vs=()=>new I.TypedEvents(je);class fs{isBalancingActive=!1;events;callManager;balancingStartDelay;videoSendingBalancer;startBalancingTimer;constructor(e,t,s={}){this.events=vs(),this.callManager=e,this.balancingStartDelay=s.balancingStartDelay??1e4,this.videoSendingBalancer=new Is(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=>{d("startBalancing: error",e)})},this.balancingStartDelay),this.events.trigger("balancing-scheduled",{delay:this.balancingStartDelay})}clearStartTimer(){this.startBalancingTimer&&(clearTimeout(this.startBalancingTimer),this.startBalancingTimer=void 0)}}const Ke="no-inbound-frames",Ze=[Ke],Ms=()=>new I.TypedEvents(Ze);class _s{events;statsManager;callManager;constructor(e,t){this.statsManager=e,this.callManager=t,this.events=Ms(),this.subscribe()}get mainVideoTrack(){return this.callManager.getMainRemoteStream()?.getVideoTracks()[0]}get isMutedMainVideoTrack(){const{mainVideoTrack:e}=this;return e===void 0?!1:e.muted}on(e,t){return this.events.on(e,t)}handleStatsCollected=()=>{this.hasNoIncomingFrames()&&this.events.trigger(Ke,{})};hasNoIncomingFrames=()=>this.statsManager.isInvalidInboundFrames&&this.isMutedMainVideoTrack;subscribe(){this.statsManager.on("collected",this.handleStatsCollected)}}const bs=3e3;class Os{renegotiateRequester;renegotiateThrottled;callManager;constructor(e,t=bs){this.callManager=e,this.renegotiateRequester=new V.CancelableRequest(e.renegotiate.bind(e)),this.renegotiateThrottled=tt.throttle(this.requestRenegotiate.bind(this),t),this.subscribe()}recover(){d("trying to recover main stream"),this.renegotiateThrottled()}requestRenegotiate=()=>{if(d("trying to renegotiate"),this.renegotiateRequester.requested){d("previous renegotiate is not finished yet");return}this.renegotiateRequester.request().then(()=>{d("renegotiate has successful")}).catch(e=>{d("failed to renegotiate main media stream",e)})};subscribe(){this.callManager.on("ended",()=>{this.cancel()})}cancel(){d("cancel recover main stream"),this.renegotiateThrottled.cancel(),this.renegotiateRequester.cancelRequest()}}const Ds=1e6,Ps=ke.map(n=>`auto-connect:${n}`),ys=Pe.map(n=>`connection:${n}`),Ls=Ie.map(n=>`call:${n}`),ws=Be.map(n=>`conference-state:${n}`),Us=me.map(n=>`api:${n}`),Fs=$e.map(n=>`incoming-call:${n}`),ks=be.map(n=>`presentation:${n}`),Bs=He.map(n=>`stats:${n}`),$s=je.map(n=>`video-balancer:${n}`),Gs=Ze.map(n=>`main-stream-health:${n}`),qs=Ve.map(n=>`session:${n}`),Vs=["disconnected-from-out-of-call","connected-with-configuration-from-out-of-call","stopped-presentation-by-server-command"],Hs=[...Ps,...ys,...Ls,...ws,...Us,...Fs,...ks,...Bs,...$s,...Gs,...qs,...Vs],Ws=()=>new I.TypedEvents(Hs);class xs{events;connectionManager;connectionQueueManager;conferenceStateManager;contentedStreamManager;callManager;autoConnectorManager;apiManager;incomingCallManager;presentationManager;statsManager;videoSendingBalancerManager;sessionManager;mainStreamHealthMonitor;mainStreamRecovery;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor({JsSIP:e},{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:s,videoBalancerOptions:i,autoConnectorOptions:r}={}){this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=s,this.events=Ws(),this.apiManager=new gt,this.connectionManager=new ln({JsSIP:e}),this.connectionQueueManager=new gn({connectionManager:this.connectionManager}),this.conferenceStateManager=new bn,this.contentedStreamManager=new Ln,this.callManager=new Ot(this.conferenceStateManager,this.contentedStreamManager),this.incomingCallManager=new $n(this.connectionManager),this.presentationManager=new Yt({callManager:this.callManager,maxBitrate:Ds}),this.statsManager=new Zn({callManager:this.callManager,apiManager:this.apiManager}),this.autoConnectorManager=new Mn({connectionQueueManager:this.connectionQueueManager,connectionManager:this.connectionManager,callManager:this.callManager},r),this.videoSendingBalancerManager=new fs(this.callManager,this.apiManager,i),this.mainStreamHealthMonitor=new _s(this.statsManager,this.callManager),this.mainStreamRecovery=new Os(this.callManager),this.sessionManager=new Vn({connectionManager:this.connectionManager,callManager:this.callManager,incomingCallManager:this.incomingCallManager,presentationManager:this.presentationManager}),this.contentedStreamManager.subscribeToApiEvents(this.apiManager),this.apiManager.subscribe({connectionManager:this.connectionManager,callManager:this.callManager}),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();getUri=e=>this.connectionManager.getUri(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.getUri,{...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=()=>{const e=this.conferenceStateManager.getState();return{number:e.number,answer:e.answer}};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()=>{await(s===!0?this.apiManager.sendAvailableContentedStream():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.sendNotAvailableContentedStream():this.apiManager.sendStoppedPresentation())})}async updatePresentation(e,t={}){const{isP2P:s,onAddedTransceiver:i,...r}=t;return this.presentationManager.updatePresentation(async()=>{await(s===!0?this.apiManager.sendAvailableContentedStream():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 askPermissionToEnableCam(...e){return this.apiManager.askPermissionToEnableCam(...e)}subscribeDisconnectedFromOutOfCall(){this.connectionManager.on("disconnected",()=>{this.isCallActive||this.events.trigger("disconnected-from-out-of-call",{})})}subscribeConnectedWithConfigurationFromOutOfCall(){this.connectionManager.on("connected-with-configuration",e=>{this.isCallActive||this.events.trigger("connected-with-configuration-from-out-of-call",e)})}mayBeStopPresentationAndNotify(){this.presentationManager.isPresentationInProcess&&(this.stopPresentation().catch(()=>{}),this.events.trigger("stopped-presentation-by-server-command",{}))}subscribeToApiEvents(){this.apiManager.on("participant:move-request-to-participants",()=>{this.callManager.setCallRoleParticipant()}),this.apiManager.on("participant:move-request-to-spectators-synthetic",()=>{this.callManager.setCallRoleSpectatorSynthetic(),this.mayBeStopPresentationAndNotify()}),this.apiManager.on("participant:move-request-to-spectators-with-audio-id",({audioId:e})=>{this.callManager.setCallRoleSpectator({audioId:e,sendOffer:this.sendOffer}),this.mayBeStopPresentationAndNotify()}),this.apiManager.on("presentation:must-stop",()=>{this.mayBeStopPresentationAndNotify()}),this.apiManager.on("enter-room",({room:e,participantName:t})=>{this.conferenceStateManager.updateState({room:e,participantName:t})}),this.apiManager.on("conference:participant-token-issued",({jwt:e,conference:t,participant:s})=>{this.conferenceStateManager.updateState({token:e,conference:t,participant:s})}),this.apiManager.on("channels:all",e=>{this.conferenceStateManager.updateState({channels:e})})}sendOffer=async(e,t)=>{const i=this.connectionManager.getConnectionConfiguration()?.sipServerUrl;if(i===void 0)throw new Error("No sipServerUrl for sendOffer");const r=this.conferenceStateManager.getToken();return We({serverUrl:i,offer:t,token:r,conferenceNumber:e.conferenceNumber,quality:e.quality,audio:e.audioChannel})};setCodecPreferences(e){is(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("conference-state",this.conferenceStateManager),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.bridgeEvents("main-stream-health",this.mainStreamHealthMonitor),this.bridgeEvents("session",this.sessionManager),this.subscribeToApiEvents(),this.subscribeDisconnectedFromOutOfCall(),this.subscribeConnectedWithConfigurationFromOutOfCall(),this.subscribeToMainStreamHealthMonitorEvents()}subscribeToMainStreamHealthMonitorEvents(){this.mainStreamHealthMonitor.on("no-inbound-frames",()=>{this.mainStreamRecovery.recover()})}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=ie;exports.EContentUseLicense=se;exports.EState=Le;exports.EState$1=Ne;exports.EState$2=Ge;exports.EState$3=Oe;exports.EStatsTypes=p;exports.Originator=Ae;exports.SipConnector=xs;exports.StatsPeerConnection=Qe;exports.disableDebug=st;exports.enableDebug=nt;exports.getCodecFromSender=Ye;exports.hasCanceledStartPresentationError=Qt;exports.hasNotReadyForConnectionError=Fe;exports.logger=d;exports.prepareMediaStream=q;exports.sendOffer=We;exports.setEncodingsToSender=re;exports.setParametersToSender=_e;
@@ -4,12 +4,12 @@ import { TEventMap, TEvents } from './events';
4
4
  import { TChannels, TMediaState, TOptionsInfoMediaState } from './types';
5
5
  declare class ApiManager {
6
6
  readonly events: TEvents;
7
- private readonly connectionManager;
8
- private readonly callManager;
9
- constructor({ connectionManager, callManager, }: {
7
+ private callManager?;
8
+ constructor();
9
+ subscribe({ connectionManager, callManager, }: {
10
10
  connectionManager: ConnectionManager;
11
11
  callManager: CallManager;
12
- });
12
+ }): void;
13
13
  waitChannels(): Promise<TChannels>;
14
14
  waitSyncMediaState(): Promise<{
15
15
  isSyncForced: boolean;
@@ -23,11 +23,10 @@ declare class ApiManager {
23
23
  sendRefusalToTurnOn(type: 'cam' | 'mic', options?: TOptionsInfoMediaState): Promise<void>;
24
24
  sendRefusalToTurnOnMic(options?: TOptionsInfoMediaState): Promise<void>;
25
25
  sendRefusalToTurnOnCam(options?: TOptionsInfoMediaState): Promise<void>;
26
- sendMustStopPresentationP2P(): Promise<void>;
27
- sendStoppedPresentationP2P(): Promise<void>;
28
- sendStoppedPresentation(): Promise<void>;
29
- askPermissionToStartPresentationP2P(): Promise<void>;
26
+ sendAvailableContentedStream(): Promise<void>;
30
27
  askPermissionToStartPresentation(): Promise<void>;
28
+ sendStoppedPresentation(): Promise<void>;
29
+ sendNotAvailableContentedStream(): Promise<void>;
31
30
  askPermissionToEnableCam(options?: TOptionsInfoMediaState): Promise<void>;
32
31
  on<T extends keyof TEventMap>(eventName: T, handler: (data: TEventMap[T]) => void): () => void;
33
32
  once<T extends keyof TEventMap>(eventName: T, handler: (data: TEventMap[T]) => void): () => void;
@@ -35,7 +34,6 @@ declare class ApiManager {
35
34
  wait<T extends keyof TEventMap>(eventName: T): Promise<TEventMap[T]>;
36
35
  off<T extends keyof TEventMap>(eventName: T, handler: (data: TEventMap[T]) => void): void;
37
36
  private readonly getEstablishedRTCSessionProtected;
38
- private subscribe;
39
37
  private readonly handleSipEvent;
40
38
  private readonly maybeHandleNotify;
41
39
  private readonly handleNotify;
@@ -53,7 +51,7 @@ declare class ApiManager {
53
51
  private readonly triggerConferenceParticipantTokenIssued;
54
52
  private readonly maybeTriggerChannels;
55
53
  private readonly triggerEnterRoom;
56
- private readonly triggerShareState;
54
+ private readonly triggerContentedStreamState;
57
55
  private readonly maybeTriggerParticipantMoveRequest;
58
56
  private readonly triggerMainCamControl;
59
57
  private readonly triggerMicControl;
@@ -1,4 +1,42 @@
1
- export declare enum EHeader {
1
+ export declare enum EContentParticipantType {
2
+ SPECTATOR = "SPECTATOR",
3
+ PARTICIPANT = "PARTICIPANT"
4
+ }
5
+ export declare enum EContentTypeReceived {
6
+ SHARE_STATE = "application/vinteo.webrtc.sharedesktop",
7
+ MAIN_CAM = "application/vinteo.webrtc.maincam",
8
+ ENTER_ROOM = "application/vinteo.webrtc.roomname",
9
+ MIC = "application/vinteo.webrtc.mic",
10
+ USE_LICENSE = "application/vinteo.webrtc.uselic",
11
+ PARTICIPANT_STATE = "application/vinteo.webrtc.partstate",
12
+ NOTIFY = "application/vinteo.webrtc.notify"
13
+ }
14
+ export declare enum EContentTypeSent {
15
+ SHARE_STATE = "application/vinteo.webrtc.sharedesktop",
16
+ MAIN_CAM = "application/vinteo.webrtc.maincam",
17
+ CHANNELS = "application/vinteo.webrtc.channels",
18
+ MEDIA_STATE = "application/vinteo.webrtc.mediastate",
19
+ REFUSAL = "application/vinteo.webrtc.refusal",
20
+ STATS = "application/vinteo.webrtc.stats"
21
+ }
22
+ export declare enum EContentMainCAM {
23
+ PAUSE_MAIN_CAM = "PAUSEMAINCAM",
24
+ RESUME_MAIN_CAM = "RESUMEMAINCAM",
25
+ MAX_MAIN_CAM_RESOLUTION = "MAXMAINCAMRESOLUTION",
26
+ ADMIN_STOP_MAIN_CAM = "ADMINSTOPMAINCAM",
27
+ ADMIN_START_MAIN_CAM = "ADMINSTARTMAINCAM"
28
+ }
29
+ export declare enum EContentMic {
30
+ ADMIN_STOP_MIC = "ADMINSTOPMIC",
31
+ ADMIN_START_MIC = "ADMINSTARTMIC"
32
+ }
33
+ export declare enum EContentedStreamCodec {
34
+ H264 = "H264",
35
+ VP8 = "VP8",
36
+ VP9 = "VP9",
37
+ AV1 = "AV1"
38
+ }
39
+ export declare enum EKeyHeader {
2
40
  CONTENT_TYPE = "content-type",
3
41
  CONTENT_ENTER_ROOM = "x-webrtc-enter-room",
4
42
  CONTENT_USE_LICENSE = "X-WEBRTC-USE-LICENSE",
@@ -16,62 +54,60 @@ export declare enum EHeader {
16
54
  CONTENT_PARTICIPANT_STATE = "X-WEBRTC-PARTSTATE",
17
55
  NOTIFY = "X-VINTEO-NOTIFY",
18
56
  CONTENT_ENABLE_MEDIA_DEVICE = "X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE",
19
- CONTENT_SHARE_STATE = "x-webrtc-share-state",
20
- MUST_STOP_PRESENTATION_P2P = "x-webrtc-share-state: YOUMUSTSTOPSENDCONTENT",
21
- START_PRESENTATION_P2P = "x-webrtc-share-state: YOUCANRECEIVECONTENT",
22
- STOP_PRESENTATION_P2P = "x-webrtc-share-state: CONTENTEND",
23
- STOP_PRESENTATION = "x-webrtc-share-state: STOPPRESENTATION",
24
- START_PRESENTATION = "x-webrtc-share-state: LETMESTARTPRESENTATION",
25
- ENABLE_MAIN_CAM = "X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM",
57
+ CONTENTED_STREAM_STATE = "x-webrtc-share-state",
58
+ CONTENTED_STREAM_CODEC = "x-webrtc-share-codec",
26
59
  AVAILABLE_INCOMING_BITRATE = "X-WEBRTC-AVAILABLE-INCOMING-BITRATE",
27
60
  AUDIO_TRACK_COUNT = "X-WEBRTC-AUDIO-TRACK-COUNT",
28
61
  VIDEO_TRACK_COUNT = "X-WEBRTC-VIDEO-TRACK-COUNT",
29
62
  TRACKS_DIRECTION = "X-WEBRTC-TRACKS-DIRECTION",
30
63
  AUDIO_ID = "X-WEBRTC-AUDIOID"
31
64
  }
32
- export declare enum EShareState {
33
- AVAILABLE_SECOND_REMOTE_STREAM = "YOUCANRECEIVECONTENT",
34
- NOT_AVAILABLE_SECOND_REMOTE_STREAM = "CONTENTEND",
65
+ export declare enum EContentedStreamSendAndReceive {
66
+ AVAILABLE_CONTENTED_STREAM = "YOUCANRECEIVECONTENT",
67
+ NOT_AVAILABLE_CONTENTED_STREAM = "CONTENTEND",
35
68
  MUST_STOP_PRESENTATION = "YOUMUSTSTOPSENDCONTENT"
36
69
  }
37
- export declare enum EParticipantType {
38
- SPECTATOR = "SPECTATOR",
39
- PARTICIPANT = "PARTICIPANT"
40
- }
41
- export declare enum EContentTypeReceived {
42
- ENTER_ROOM = "application/vinteo.webrtc.roomname",
43
- MIC = "application/vinteo.webrtc.mic",
44
- USE_LICENSE = "application/vinteo.webrtc.uselic",
45
- PARTICIPANT_STATE = "application/vinteo.webrtc.partstate",
46
- NOTIFY = "application/vinteo.webrtc.notify",
47
- SHARE_STATE = "application/vinteo.webrtc.sharedesktop",
48
- MAIN_CAM = "application/vinteo.webrtc.maincam"
49
- }
50
- export declare enum EContentTypeSent {
51
- CHANNELS = "application/vinteo.webrtc.channels",
52
- MEDIA_STATE = "application/vinteo.webrtc.mediastate",
53
- REFUSAL = "application/vinteo.webrtc.refusal",
54
- SHARE_STATE = "application/vinteo.webrtc.sharedesktop",
55
- MAIN_CAM = "application/vinteo.webrtc.maincam",
56
- STATS = "application/vinteo.webrtc.stats"
57
- }
58
- export declare enum EEventsMainCAM {
59
- PAUSE_MAIN_CAM = "PAUSEMAINCAM",
60
- RESUME_MAIN_CAM = "RESUMEMAINCAM",
61
- MAX_MAIN_CAM_RESOLUTION = "MAXMAINCAMRESOLUTION",
62
- ADMIN_STOP_MAIN_CAM = "ADMINSTOPMAINCAM",
63
- ADMIN_START_MAIN_CAM = "ADMINSTARTMAINCAM"
64
- }
65
- export declare enum EEventsMic {
66
- ADMIN_STOP_MIC = "ADMINSTOPMIC",
67
- ADMIN_START_MIC = "ADMINSTARTMIC"
70
+ export declare enum EHeader {
71
+ AVAILABLE_CONTENTED_STREAM = "x-webrtc-share-state: YOUCANRECEIVECONTENT",
72
+ NOT_AVAILABLE_CONTENTED_STREAM = "x-webrtc-share-state: CONTENTEND",
73
+ ACK_PERMISSION_TO_START_PRESENTATION = "x-webrtc-share-state: LETMESTARTPRESENTATION",
74
+ STOPPED_CLIENT_PRESENTATION = "x-webrtc-share-state: STOPPRESENTATION",
75
+ ENABLE_MAIN_CAM = "X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM"
68
76
  }
69
- export declare enum EEventsSyncMediaState {
77
+ export declare enum EContentSyncMediaState {
70
78
  ADMIN_SYNC_FORCED = "1",
71
79
  ADMIN_SYNC_NOT_FORCED = "0"
72
80
  }
73
- export declare enum EUseLicense {
81
+ export declare enum EContentUseLicense {
74
82
  AUDIO = "AUDIO",
75
83
  VIDEO = "VIDEO",
76
84
  AUDIOPLUSPRESENTATION = "AUDIOPLUSPRESENTATION"
77
85
  }
86
+ type THeaderValueMap = {
87
+ [EKeyHeader.CONTENT_ENTER_ROOM]: string;
88
+ [EKeyHeader.PARTICIPANT_NAME]: string;
89
+ [EKeyHeader.CONTENTED_STREAM_CODEC]: EContentedStreamCodec;
90
+ [EKeyHeader.CONTENT_TYPE]: EContentTypeReceived;
91
+ [EKeyHeader.CONTENT_USE_LICENSE]: EContentUseLicense;
92
+ [EKeyHeader.INPUT_CHANNELS]: string;
93
+ [EKeyHeader.OUTPUT_CHANNELS]: string;
94
+ [EKeyHeader.MAIN_CAM]: EContentMainCAM;
95
+ [EKeyHeader.MIC]: EContentMic;
96
+ [EKeyHeader.MEDIA_SYNC]: EContentSyncMediaState;
97
+ [EKeyHeader.MAIN_CAM_RESOLUTION]: string;
98
+ [EKeyHeader.MEDIA_STATE]: string;
99
+ [EKeyHeader.MEDIA_TYPE]: number;
100
+ [EKeyHeader.MAIN_CAM_STATE]: number;
101
+ [EKeyHeader.MIC_STATE]: number;
102
+ [EKeyHeader.CONTENT_PARTICIPANT_STATE]: EContentParticipantType;
103
+ [EKeyHeader.NOTIFY]: string;
104
+ [EKeyHeader.CONTENT_ENABLE_MEDIA_DEVICE]: string;
105
+ [EKeyHeader.CONTENTED_STREAM_STATE]: EContentedStreamSendAndReceive;
106
+ [EKeyHeader.AVAILABLE_INCOMING_BITRATE]: number;
107
+ [EKeyHeader.AUDIO_TRACK_COUNT]: number;
108
+ [EKeyHeader.VIDEO_TRACK_COUNT]: number;
109
+ [EKeyHeader.TRACKS_DIRECTION]: string;
110
+ [EKeyHeader.AUDIO_ID]: string;
111
+ };
112
+ export type EValueHeader<T extends EKeyHeader> = THeaderValueMap[T];
113
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { TypedEvents } from 'events-constructor';
2
- import { EUseLicense, EEventsMainCAM } from './constants';
2
+ import { EContentedStreamCodec, EContentUseLicense, EContentMainCAM } from './constants';
3
3
  import { TChannels, TParametersModeratorsList, TParametersWebcast, TParametersConferenceParticipantTokenIssued } from './types';
4
4
  export declare enum EEvent {
5
5
  ENTER_ROOM = "enter-room",
@@ -35,18 +35,20 @@ export declare const EVENT_NAMES: readonly ["enter-room", "main-cam-control", "u
35
35
  export type TEventMap = {
36
36
  'enter-room': {
37
37
  room: string;
38
- participantName: string;
38
+ participantName?: string;
39
39
  };
40
40
  'main-cam-control': {
41
- mainCam?: EEventsMainCAM;
41
+ mainCam?: EContentMainCAM;
42
42
  resolutionMainCam?: string;
43
43
  };
44
- 'use-license': EUseLicense;
44
+ 'use-license': EContentUseLicense;
45
45
  'new-dtmf': {
46
46
  originator: string;
47
47
  };
48
48
  'conference:participant-token-issued': TParametersConferenceParticipantTokenIssued;
49
- 'contented-stream:available': Record<string, never>;
49
+ 'contented-stream:available': {
50
+ codec?: EContentedStreamCodec;
51
+ };
50
52
  'contented-stream:not-available': Record<string, never>;
51
53
  'presentation:must-stop': Record<string, never>;
52
54
  'channels:all': TChannels;
@@ -0,0 +1,3 @@
1
+ import { EKeyHeader, EValueHeader } from './constants';
2
+ import { IncomingRequest } from '@krivega/jssip';
3
+ export declare const getHeader: <T extends EKeyHeader>(request: IncomingRequest, header: T) => EValueHeader<T> | undefined;
@@ -1,5 +1,6 @@
1
1
  export { default as ApiManager } from './@ApiManager';
2
- export { EContentTypeReceived, EContentTypeSent, EEventsMainCAM, EEventsMic, EEventsSyncMediaState, EHeader, EShareState, EUseLicense, } from './constants';
2
+ export { createEvents as createApiManagerEvents } from './events';
3
+ export { EContentTypeReceived, EContentTypeSent, EContentMainCAM, EContentMic, EContentSyncMediaState, EHeader, EKeyHeader, EContentedStreamSendAndReceive, EContentUseLicense, EContentedStreamCodec, } from './constants';
3
4
  export { EVENT_NAMES as API_MANAGER_EVENT_NAMES } from './events';
4
- export type { TEventMap as TApiManagerEventMap } from './events';
5
+ export type { TEventMap as TApiManagerEventMap, TEvents as TApiManagerEvents } from './events';
5
6
  export type { TChannels } from './types';
@@ -2,6 +2,7 @@ import { CallStateMachine, TCallActor } from './CallStateMachine';
2
2
  import { StreamsManagerProvider } from './StreamsManagerProvider';
3
3
  import { RTCSession } from '@krivega/jssip';
4
4
  import { ConferenceStateManager } from '../ConferenceStateManager';
5
+ import { ContentedStreamManager } from '../ContentedStreamManager';
5
6
  import { TEventMap, TEvents } from './events';
6
7
  import { TAnswerToIncomingCall, TCallRoleSpectator, TReplaceMediaStream, TStartCall, TRemoteStreams } from './types';
7
8
  declare class CallManager {
@@ -14,16 +15,19 @@ declare class CallManager {
14
15
  private readonly mainRemoteStreamsManager;
15
16
  private readonly recvRemoteStreamsManager;
16
17
  private readonly streamsManagerProvider;
18
+ private readonly contentedStreamManager;
17
19
  private readonly roleManager;
18
20
  private readonly mcuSession;
19
21
  private recvSession?;
20
22
  private disposeRecvSessionTrackListener?;
21
- constructor(conferenceStateManager: ConferenceStateManager);
23
+ private readonly streamsChangeTracker;
24
+ constructor(conferenceStateManager: ConferenceStateManager, contentedStreamManager: ContentedStreamManager);
22
25
  get callActor(): TCallActor;
23
26
  get requested(): boolean;
24
27
  get connection(): RTCPeerConnection | undefined;
25
28
  get isCallActive(): boolean;
26
29
  getStreamsManagerProvider(): StreamsManagerProvider;
30
+ getContentedStreamManager(): ContentedStreamManager;
27
31
  getEstablishedRTCSession: () => RTCSession | undefined;
28
32
  on<T extends keyof TEventMap>(eventName: T, handler: (data: TEventMap[T]) => void): () => void;
29
33
  onRace<T extends keyof TEventMap>(eventNames: T[], handler: (data: TEventMap[T], eventName: string) => void): () => void;
@@ -37,6 +41,7 @@ declare class CallManager {
37
41
  answerToIncomingCall: TAnswerToIncomingCall;
38
42
  getMainRemoteStream(): MediaStream | undefined;
39
43
  getRemoteStreams(): TRemoteStreams;
44
+ readonly getActivePeerConnection: () => RTCPeerConnection | undefined;
40
45
  setCallRoleParticipant(): void;
41
46
  setCallRoleSpectatorSynthetic(): void;
42
47
  setCallRoleSpectator(recvParams: TCallRoleSpectator['recvParams']): void;
@@ -61,5 +66,6 @@ declare class CallManager {
61
66
  private startRecvSession;
62
67
  private stopRecvSession;
63
68
  private readonly onRoleChanged;
69
+ private subscribeContentedStreamEvents;
64
70
  }
65
71
  export default CallManager;