opensips-js 0.1.47 → 0.1.48

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.
@@ -156,4 +156,4 @@ a=path:${t.getHeader("Use-Path")} msrp://${this._ua._configuration.authorization
156
156
  `),this._newMSRPSession("local",this._request),this._from_tag||(this._from_tag=this._request.from._parameters.tag),this._id=this._request.call_id+this._from_tag,new sl(this._ua,this._request,{onRequestTimeout:()=>{this.onRequestTimeout(),console.log("to")},onTransportError:n=>{this.onTransportError(),console.log(n)},onAuthenticated:n=>{this._request=n},onReceiveResponse:n=>{this._receiveInviteResponse(n),n.status_code===200&&(n.parseSDP(!0),this._status=Re.STATUS_CONFIRMED,this.target_addr=n.sdp.media[0].invalid[1].value.replaceAll("path:","").split(" ").reverse(),this.status="active",this.emit("active"),this.emit("confirmed"))}}).send(),this._status=Re.STATUS_INVITE_SENT}terminate(t={}){const s=t.cause||H.causes.BYE,i=Me.cloneArray(t.extraHeaders),a=t.body;let n,r=t.status_code,h=t.reason_phrase;if(this._status===Re.STATUS_TERMINATED)throw new qs.InvalidStateError(this._status);switch(this.status="terminated",this._status){case Re.STATUS_NULL:case Re.STATUS_INVITE_SENT:case Re.STATUS_1XX_RECEIVED:if(r&&(r<200||r>=700))throw new TypeError(`Invalid status_code: ${r}`);r&&(h=h||H.REASON_PHRASE[r]||"",n=`SIP ;cause=${r} ;text="${h}"`),this._status===Re.STATUS_NULL||this._status===Re.STATUS_INVITE_SENT?(this._is_canceled=!0,this._cancel_reason=n):this._status===Re.STATUS_1XX_RECEIVED&&this._request.cancel(n),this._status=Re.STATUS_CANCELED,this._failed("local",null,H.causes.CANCELED);break;case Re.STATUS_WAITING_FOR_ANSWER:case Re.STATUS_ANSWERED:if(r=r||480,r<300||r>=700)throw new TypeError(`Invalid status_code: ${r}`);this._request.reply(r,h,i,a),this._failed("local",null,H.causes.REJECTED);break;case Re.STATUS_WAITING_FOR_ACK:case Re.STATUS_CONFIRMED:if(h=t.reason_phrase||H.REASON_PHRASE[r]||"",r&&(r<200||r>=700))throw new TypeError(`Invalid status_code: ${r}`);if(r&&i.push(`Reason: SIP ;cause=${r}; text="${h}"`),this._status===Re.STATUS_WAITING_FOR_ACK&&this._direction==="incoming"&&this._request.server_transaction.state!==Wt.C.STATUS_TERMINATED){const d=this._dialog;this.receiveRequest=({method:_})=>{_===H.ACK&&(this.sendRequest(H.BYE,{extraHeaders:i,body:a}),d.terminate())},this._request.server_transaction.on("stateChanged",()=>{this._request.server_transaction.state===Wt.C.STATUS_TERMINATED&&(this.sendRequest(H.BYE,{extraHeaders:i,body:a}),d.terminate())}),this._ended("local",null,s),this._dialog=d,this._ua.newDialog(d)}else this.sendRequest(H.BYE,{extraHeaders:i,body:a}),this._ended("local",null,s)}}sendRequest(t,s){return this._dialog.sendRequest(t,s)}authenticate(t){this.status="auth";let s=new cr("");s.method="AUTH",s.addHeader("To-Path",`msrp://${this._ua._configuration.realm}:2856;ws`),s.addHeader("From-Path",`msrp://${this.credentials.username}.${this.credentials.realm}:2856/${this.auth_id};ws`),t&&s.addHeader("Authorization",t.toString());let i=s.toString(),a=[];for(var n=0;n<i.length;n++)a.push(i.charCodeAt(n).toString(16));this._connection.send(s.toString())}onmessage(t){const s=new cr(t.data);if(this.status==="auth"&&s.code===401){const i=this.parseAuth(s.getHeader("WWW-Authenticate")),a=new ng(this.credentials);a.authenticate({method:"AUTH",ruri:`msrp://${this._ua._configuration.realm}:2856;ws`,body:null},i,Me.createRandomToken(12)),this.authenticate(a)}this.status==="auth"&&s.code===200&&this._direction==="outgoing"?(this.my_addr.push(s.getHeader("To-Path")),this.my_addr.push(s.getHeader("Use-Path")),this.status="active",this.inviteParty(s)):this.status==="auth"&&s.code===200&&this._direction==="incoming"?(this.my_addr.push(s.getHeader("To-Path")),this.my_addr.push(s.getHeader("Use-Path")),this.status="active",this.acceptParty(s),this.emit("confirmed")):s.method==="SEND"&&(this._sendOk(s),this._sendReport(s),s.direction="incoming",this.emit("newMessage",s),this._msgHistory.push(s),this.emit("msgHistoryUpdate",this._msgHistory)),s.code===480&&this._close()}onclose(){console.log("close")}onopen(){const t=new RTCPeerConnection({iceServers:[]});t.createDataChannel(""),t.createOffer().then(t.setLocalDescription.bind(t)),t.onicecandidate=s=>{if(!s||!s.candidate||!s.candidate.candidate)return;const i=/([0-9]{1,3}(\.[0-9]{1,3}){3})/,a=s.candidate.candidate.match(i);this.my_ip=a&&a[1],t.onicecandidate=()=>{},this.authenticate(null)}}onerror(t){console.log(t)}_receiveInviteResponse(t){if(console.log("resp0000000000000",t),this._dialog&&t.status_code>=200&&t.status_code<=299)if(console.log("200000000000000"),this._dialog.id.call_id===t.call_id&&this._dialog.id.local_tag===t.from_tag&&this._dialog.id.remote_tag===t.to_tag){this.sendRequest(H.ACK);return}else{const s=new eo(this,t,"UAC");if(s.error!==void 0){console.log(s.error);return}this.sendRequest(H.ACK),this.sendRequest(H.BYE);return}if(this._is_canceled){t.status_code>=100&&t.status_code<200?this._request.cancel(this._cancel_reason):t.status_code>=200&&t.status_code<299&&this._acceptAndTerminate(t);return}if(!(this._status!==Re.STATUS_INVITE_SENT&&this._status!==Re.STATUS_1XX_RECEIVED))switch(console.log("start Switch"),!0){case/^100$/.test(t.status_code):this._status=Re.STATUS_1XX_RECEIVED;break;case/^1[0-9]{2}$/.test(t.status_code):{if(!t.to_tag){console.log("1xx response received without to tag");break}if(t.hasHeader("contact")&&!this._createDialog(t,"UAC",!0))break;if(this._status=Re.STATUS_1XX_RECEIVED,!t.body){this._progress("remote",t);break}const s={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",s);const i=new RTCSessionDescription({type:"answer",sdp:s.sdp});this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>this._connection.setRemoteDescription(i)).then(()=>this._progress("remote",t)).catch(a=>{console.log('emit "peerconnection:setremotedescriptionfailed" [error:%o]',a),this.emit("peerconnection:setremotedescriptionfailed",a)});break}case/^2[0-9]{2}$/.test(t.status_code):{if(console.log("maybe here???"),this._status=Re.STATUS_CONFIRMED,!t.body){this._acceptAndTerminate(t,400,H.causes.MISSING_SDP),console.log("failed 3"),this._failed("remote",t,H.causes.BAD_MEDIA_DESCRIPTION);break}if(!this._createDialog(t,"UAC"))break;const s={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",s),new RTCSessionDescription({type:"answer",sdp:s.sdp}),this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>{if(this._connection.signalingState==="stable")return this._connection.createOffer(this._rtcOfferConstraints).then(i=>this._connection.setLocalDescription(i)).catch(i=>{this._acceptAndTerminate(t,500,i.toString()),console.log("failed 4"),this._failed("local",t,H.causes.WEBRTC_ERROR)})}).then(()=>{this._handleSessionTimersInIncomingResponse(t),this._accepted("remote",t),this.sendRequest(H.ACK),this._confirmed("local",null)});break}default:{const s=Me.sipErrorCause(t.status_code);console.log("failed 5"),this._failed("remote",t,s)}}}sendMSRP(t){const s=new cr("");let i="";this.my_addr[1]&&(i=this.my_addr[1]),this.target_addr[1]&&(i+=" "+this.target_addr[1]),this.target_addr[0]&&(i+=" "+this.target_addr[0]),s.method="SEND",s.addHeader("To-Path",i),s.addHeader("From-Path",`${this.my_addr[0]}`),s.addHeader("Message-ID",Me.createRandomToken(10)),s.addHeader("Byte-Range","1-25/25"),s.addHeader("Content-Type","text/plain"),s.addHeader("Success-Report","yes"),s.addHeader("Failure-Report","yes"),s.body=t;let a=s.toString();console.log(a);let n=[];for(var r=0;r<a.length;r++)n.push(a.charCodeAt(r).toString(16));console.log(n),this._connection.send(s.toString()),s.direction="outgoing",this.emit("newMessage",s),this._msgHistory.push(s),this.emit("msgHistoryUpdate",this._msgHistory)}_sendOk(t){let s=t.ident,i=t.getHeader("Message-ID"),a=new cr("");a.method="200 OK",a.addHeader("To-Path",`${this.my_addr[1]}`),a.addHeader("From-Path",`${this.my_addr[0]}`),a.addHeader("Message-ID",i),a.ident=s;let n=a.toString();console.log(n);let r=[];for(var h=0;h<n.length;h++)r.push(n.charCodeAt(h).toString(16));console.log(r),this._connection.send(a.toString())}_sendReport(t){let s=t.ident,i=t.getHeader("Message-ID"),a=new cr("");a.method="REPORT",a.addHeader("To-Path",`${t.getHeader("From-Path")}`),a.addHeader("From-Path",`${this.my_addr[0]}`),a.addHeader("Message-ID",i),a.addHeader("Byte-Range","1-25/25"),a.addHeader("Status","000 200 OK"),a.ident=s;let n=a.toString();console.log(n);let r=[];for(var h=0;h<n.length;h++)r.push(n.charCodeAt(h).toString(16));console.log(r),this._connection.send(a.toString())}parseAuth(t){const s={},i=t.replace("Digest","").split(",");for(const a of i){const n=a.trim().split("=");s[n[0]]=n[1].match('^"(.+)"$')[1]}return s}init_incoming(t,s){let i;const a=t.hasHeader("Content-Type")?t.getHeader("Content-Type").toLowerCase():void 0;if(t.body&&a!=="application/sdp"){t.reply(415);return}if(this._status=Re.STATUS_INVITE_RECEIVED,this._from_tag=t.from_tag,this._id=t.call_id+this._from_tag,this._request=t,this._contact=this._ua.contact.toString(),t.hasHeader("expires")&&(i=t.getHeader("expires")*1e3),t.to_tag=Me.newTag(),!this._createDialog(t,"UAS",!0)){t.reply(500,"Missing Contact header field");return}t.body?this._late_sdp=!1:this._late_sdp=!0,this._status=Re.STATUS_WAITING_FOR_ANSWER,this._timers.userNoAnswerTimer=setTimeout(()=>{t.reply(408),console.log("failed 6"),this._failed("local",null,H.causes.NO_ANSWER)},this._ua.configuration.no_answer_timeout),i&&(this._timers.expiresTimer=setTimeout(()=>{this._status===Re.STATUS_WAITING_FOR_ANSWER&&(t.reply(487),console.log("failed 7"),this._failed("system",null,H.causes.EXPIRES))},i)),this._direction="incoming",this._local_identity=t.to,this._remote_identity=t.from,s&&s(this),t.parseSDP(!0),this.target_addr=t.sdp.media[0].invalid[1].value.replaceAll("path:","").split(" ").reverse(),this._newMSRPSession("remote",t),this._status!==Re.STATUS_TERMINATED&&(t.reply(180,null,[`Contact: ${this._ua._contact}`]),this._progress("local",null))}_failed(t,s,i){this.emit("_failed",{originator:t,message:s||null,cause:i}),this._close(),this.emit("failed",{originator:t,message:s||null,cause:i})}_close(){if(console.log("CLOSE SESSION"),this._status!==Re.STATUS_TERMINATED){if(this._status=Re.STATUS_TERMINATED,this._connection)try{this._connection.close()}catch(t){console.log("close() | error closing the RTCPeerConnection: %o",t)}for(const t in this._timers)Object.prototype.hasOwnProperty.call(this._timers,t)&&clearTimeout(this._timers[t]);clearTimeout(this._sessionTimers.timer),this._dialog&&(this._dialog.terminate(),delete this._dialog);for(const t in this._earlyDialogs)Object.prototype.hasOwnProperty.call(this._earlyDialogs,t)&&(this._earlyDialogs[t].terminate(),delete this._earlyDialogs[t]);for(const t in this._referSubscribers)Object.prototype.hasOwnProperty.call(this._referSubscribers,t)&&delete this._referSubscribers[t];this._ua.destroyMSRPSession(this)}}_createDialog(t,s,i){const a=s==="UAS"?t.to_tag:t.from_tag,n=s==="UAS"?t.from_tag:t.to_tag,r=t.call_id+a+n;let h=this._earlyDialogs[r];if(i)return h?!0:(h=new eo(this,t,s,eo.C.STATUS_EARLY),h.error?(console.log("failed 8"),this._failed("remote",t,H.causes.INTERNAL_ERROR),!1):(this._earlyDialogs[r]=h,!0));{if(this._from_tag=t.from_tag,this._to_tag=t.to_tag,h)return h.update(t,s),this._dialog=h,delete this._earlyDialogs[r],!0;const d=new eo(this,t,s);return d.error?(console.log("failed 9"),this._failed("remote",t,H.causes.INTERNAL_ERROR),!1):(this._dialog=d,!0)}}_newMSRPSession(t,s){this._ua.newMSRPSession(this,{originator:t,session:this,request:s})}_progress(t,s){this.emit("progress",{originator:t,response:s||null})}isEnded(){switch(this._status){case Re.STATUS_CANCELED:case Re.STATUS_TERMINATED:return!0;default:return!1}}_accepted(t,s){console.log("session accepted"),this._start_time=new Date,console.log('emit "accepted"'),this.emit("accepted",{originator:t,response:s||null})}_confirmed(t,s){console.log("session confirmed"),this._is_confirmed=!0,console.log('emit "confirmed"'),this.emit("confirmed",{originator:t,ack:s||null})}_ended(t,s,i){console.log("session ended"),this._end_time=new Date,this._close(),console.log('emit "ended"'),this.emit("ended",{originator:t,message:s||null,cause:i})}_runKeepAliveTimer(){if(!this._sessionTimers||!this._sessionTimers.enabled||this._sessionTimers.running)return;if(this._sessionTimers.currentExpires||(this._sessionTimers.currentExpires=this._sessionTimers.defaultExpires||30),!this._sessionTimers.refresher){console.log("Not the refresher; waiting for remote keep-alive");return}const t=this._sessionTimers.currentExpires;this._sessionTimers.running=!0,clearTimeout(this._sessionTimers.timer),this._sessionTimers.timer=setTimeout(()=>{if(this._connection.readyState===WebSocket.OPEN)try{this._sendKeepAlive(),console.log("Session timer: sending MSRP keep-alive")}catch(s){console.error("Failed to send keep-alive:",s)}this._sessionTimers.running=!1,this._runKeepAliveTimer()},t*1e3*.5)}_handleSessionTimersInIncomingResponse(t){if(!this._sessionTimers.enabled)return;let s;t.session_expires&&t.session_expires>=H.MIN_SESSION_EXPIRES?(this._sessionTimers.currentExpires=t.session_expires,s=t.session_expires_refresher||"uac"):(this._sessionTimers.currentExpires=this._sessionTimers.defaultExpires,s="uac"),this._sessionTimers.refresher=s==="uac",this._runKeepAliveTimer()}receiveRequest(t){if(console.log("receiveRequest()"),t.method===H.CANCEL)(this._status===Re.STATUS_WAITING_FOR_ANSWER||this._status===Re.STATUS_ANSWERED)&&(this._status=Re.STATUS_CANCELED,this._request.reply(487),console.log("failed 10"),this._failed("remote",t,H.causes.CANCELED));else switch(t.method){case H.ACK:if(this._status!==Re.STATUS_WAITING_FOR_ACK)return;if(this._status=Re.STATUS_CONFIRMED,clearTimeout(this._timers.ackTimer),clearTimeout(this._timers.invite2xxTimer),this._late_sdp){if(!t.body){this.terminate({cause:H.causes.MISSING_SDP,status_code:400});break}const s={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",s);const i=new RTCSessionDescription({type:"answer",sdp:s.sdp});this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>this._connection.setRemoteDescription(i)).then(()=>{this._is_confirmed||this._confirmed("remote",t)}).catch(a=>{this.terminate({cause:H.causes.BAD_MEDIA_DESCRIPTION,status_code:488}),console.log('emit "peerconnection:setremotedescriptionfailed" [error:%o]',a),this.emit("peerconnection:setremotedescriptionfailed",a)})}else this._is_confirmed||this._confirmed("remote",t);break;case H.BYE:this._status===Re.STATUS_CONFIRMED||this._status===Re.STATUS_WAITING_FOR_ACK?(t.reply(200),this._ended("remote",t,H.causes.BYE)):this._status===Re.STATUS_INVITE_RECEIVED||this._status===Re.STATUS_WAITING_FOR_ANSWER?(t.reply(200),this._request.reply(487,"BYE Received"),this._ended("remote",t,H.causes.BYE)):t.reply(403,"Wrong Status");break;case H.INVITE:this._status===Re.STATUS_CONFIRMED?t.hasHeader("replaces")?this._receiveReplaces(t):this._receiveReinvite(t):t.reply(403,"Wrong Status");break;case H.INFO:this._status===Re.STATUS_1XX_RECEIVED||this._status===Re.STATUS_WAITING_FOR_ANSWER||this._status===Re.STATUS_ANSWERED||this._status===Re.STATUS_WAITING_FOR_ACK||this._status===Re.STATUS_CONFIRMED?(t.hasHeader("Content-Type")?t.getHeader("Content-Type").toLowerCase():void 0)!==void 0?new Iu(this).init_incoming(t):t.reply(415):t.reply(403,"Wrong Status");break;case H.UPDATE:this._status===Re.STATUS_CONFIRMED?this._receiveUpdate(t):t.reply(403,"Wrong Status");break;case H.REFER:this._status===Re.STATUS_CONFIRMED?this._receiveRefer(t):t.reply(403,"Wrong Status");break;case H.NOTIFY:this._status===Re.STATUS_CONFIRMED?this._receiveNotify(t):t.reply(403,"Wrong Status");break;default:t.reply(501)}}onTransportError(){console.log("onTransportError()"),this._status!==Re.STATUS_TERMINATED&&this.terminate({status_code:500,reason_phrase:H.causes.CONNECTION_ERROR,cause:H.causes.CONNECTION_ERROR})}onRequestTimeout(){console.log("onRequestTimeout()"),this._status!==Re.STATUS_TERMINATED&&this.terminate({status_code:408,reason_phrase:H.causes.REQUEST_TIMEOUT,cause:H.causes.REQUEST_TIMEOUT})}onDialogError(){console.log("onDialogError()"),this._status!==Re.STATUS_TERMINATED&&this.terminate({status_code:500,reason_phrase:H.causes.DIALOG_ERROR,cause:H.causes.DIALOG_ERROR})}}var WT=es();const Du=Xe(WT),fo=new Yo("Parser"),KT=(c,t)=>{let s,i,a=c.indexOf(`\r
157
157
  `);if(a===-1){fo.warn("parseMessage() | no CRLF found, not a SIP message");return}const n=c.substring(0,a);let r=Du.parse(n,"Request_Response");if(r===-1){fo.warn(`parseMessage() | error parsing first line of SIP message: "${n}"`);return}else r.status_code?(s=new pr.IncomingResponse,s.status_code=r.status_code,s.reason_phrase=r.reason_phrase):(s=new pr.IncomingRequest(t),s.method=r.method,s.ruri=r.uri);s.data=c;let h=a+2;for(;;){if(a=YT(c,h),a===-2){i=h+2;break}else if(a===-1){fo.warn("parseMessage() | malformed message");return}if(r=JT(s,c,h,a),r!==!0){fo.warn("parseMessage() |",r.error);return}h=a+2}if(s.hasHeader("content-length")){const d=s.getHeader("content-length");s.body=c.substr(i,d)}else s.body=c.substring(i);return s};function YT(c,t){let s=t,i=0,a=0;if(c.substring(s,s+2).match(/(^\r\n)/))return-2;for(;i===0;){if(a=c.indexOf(`\r
158
158
  `,s),a===-1)return a;!c.substring(a+2,a+4).match(/(^\r\n)/)&&c.charAt(a+2).match(/(^\s+)/)?s=a+2:i=a}return i}function JT(c,t,s,i){let a;const n=t.indexOf(":",s),r=t.substring(s,n).trim(),h=t.substring(n+1,i).trim();switch(r.toLowerCase()){case"via":case"v":c.addHeader("via",h),c.getHeaders("via").length===1?(a=c.parseHeader("Via"),a&&(c.via=a,c.via_branch=a.branch)):a=0;break;case"from":case"f":c.setHeader("from",h),a=c.parseHeader("from"),a&&(c.from=a,c.from_tag=a.getParam("tag"));break;case"to":case"t":c.setHeader("to",h),a=c.parseHeader("to"),a&&(c.to=a,c.to_tag=a.getParam("tag"));break;case"record-route":if(a=Du.parse(h,"Record_Route"),a===-1)a=void 0;else for(const d of a)c.addHeader("record-route",h.substring(d.possition,d.offset)),c.headers["Record-Route"][c.getHeaders("record-route").length-1].parsed=d.parsed;break;case"call-id":case"i":c.setHeader("call-id",h),a=c.parseHeader("call-id"),a&&(c.call_id=h);break;case"contact":case"m":if(a=Du.parse(h,"Contact"),a===-1)a=void 0;else for(const d of a)c.addHeader("contact",h.substring(d.possition,d.offset)),c.headers.Contact[c.getHeaders("contact").length-1].parsed=d.parsed;break;case"content-length":case"l":c.setHeader("content-length",h),a=c.parseHeader("content-length");break;case"content-type":case"c":c.setHeader("content-type",h),a=c.parseHeader("content-type");break;case"cseq":c.setHeader("cseq",h),a=c.parseHeader("cseq"),a&&(c.cseq=a.value),c instanceof pr.IncomingResponse&&(c.method=a.method);break;case"max-forwards":c.setHeader("max-forwards",h),a=c.parseHeader("max-forwards");break;case"www-authenticate":c.setHeader("www-authenticate",h),a=c.parseHeader("www-authenticate");break;case"proxy-authenticate":c.setHeader("proxy-authenticate",h),a=c.parseHeader("proxy-authenticate");break;case"session-expires":case"x":c.setHeader("session-expires",h),a=c.parseHeader("session-expires"),a&&(c.session_expires=a.expires,c.session_expires_refresher=a.refresher);break;case"refer-to":case"r":c.setHeader("refer-to",h),a=c.parseHeader("refer-to"),a&&(c.refer_to=a);break;case"replaces":c.setHeader("replaces",h),a=c.parseHeader("replaces"),a&&(c.replaces=a);break;case"event":case"o":c.setHeader("event",h),a=c.parseHeader("event"),a&&(c.event=a);break;default:c.addHeader(r,h),a=0}return a===void 0?{error:`error parsing header "${r}"`}:!0}const zT={parseMessage:KT},Wi=new Yo("Registrator"),ho=10;class QT{constructor(t,s){this._reg_id=1,this._ua=t,this._transport=s,this._registrar=t.configuration.registrar_server,this._expires=t.configuration.register_expires,this._call_id=vs.createRandomToken(22),this._cseq=0,this._to_uri=t.configuration.uri,this._registrationTimer=null,this._registering=!1,this._registered=!1,this._contact=this._ua.contact.toString();const i=this._contact.indexOf(">");if(i!==-1){const a=this._contact.slice(0,i)+this._contact.slice(i+1,this._contact.length);this._contact=a}this._extra_contact="",this._extraContactParams="",this._extra_contact+=";+sip.ice",this._extraHeaders=[],this._sipInstance=`"<urn:uuid:${this._ua.configuration.instance_id}>"`,this._extra_contact+=`;reg-id=${this._reg_id}`,this._extra_contact+=`;+sip.instance=${this._sipInstance}`}get registered(){return this._registered}setExtraHeaders(t){Array.isArray(t)||(t=[]),this._extraHeaders=t.slice()}setExtraContactParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const s in t)if(Object.prototype.hasOwnProperty.call(t,s)){const i=t[s];this._extraContactParams+=`;${s}`,i&&(this._extraContactParams+=`=${i}`)}}setExtraContactUriParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const s in t)if(Object.prototype.hasOwnProperty.call(t,s)){const i=t[s];this._extraContactParams+=`;${s}`,i&&(this._extraContactParams+=`=${i}`)}}register(){if(this._registering){Wi.debug("Register request in progress...");return}const t=this._extraHeaders.slice();t.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=${this._expires}`),t.push(`Expires: ${this._expires}`);const s=new Ct.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},t),i=new sl(this._ua,s,{onRequestTimeout:()=>{this._registrationFailure(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._registrationFailure(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:a=>{if(a.cseq===this._cseq)switch(this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),!0){case/^1[0-9]{2}$/.test(a.status_code):break;case/^2[0-9]{2}$/.test(a.status_code):{if(this._registering=!1,!a.hasHeader("Contact")){Wi.debug("no Contact header in response to REGISTER, response ignored");break}const n=a.headers.Contact.reduce((_,g)=>_.concat(g.parsed),[]);let r=n.find(_=>this._sipInstance===_.getParam("+sip.instance")&&this._reg_id===parseInt(_.getParam("reg-id")));if(r||(r=n.find(_=>_.uri.user===this._ua.contact.uri.user)),!r){Wi.debug("no Contact header pointing to us, response ignored");break}this._ua.clearKeepAliveInterval(),this._ua.setLastRegisterTimestamp();let h=r.getParam("expires");!h&&a.hasHeader("expires")&&(h=a.getHeader("expires")),h||(h=this._expires),h=Number(h),h<ho&&(h=ho);const d=h>64?h*1e3/2+Math.floor((h/2-32)*1e3*Math.random()):Math.floor(h*1e3/2);this._registrationTimer=setTimeout(()=>{this._registrationTimer=null,this._ua.listeners("registrationExpiring").length===0?this.register():this._ua.emit("registrationExpiring")},d),r.hasParam("temp-gruu")&&(this._ua.contact.temp_gruu=r.getParam("temp-gruu").replace(/"/g,"")),r.hasParam("pub-gruu")&&(this._ua.contact.pub_gruu=r.getParam("pub-gruu").replace(/"/g,"")),this._registered||(this._registered=!0,this._ua.registered({response:a}));break}case/^423$/.test(a.status_code):{a.hasHeader("min-expires")?(this._expires=Number(a.getHeader("min-expires")),this._expires<ho&&(this._expires=ho),this.register()):(Wi.debug("423 response received for REGISTER without Min-Expires"),this._registrationFailure(a,H.causes.SIP_FAILURE_CODE));break}default:{const n=vs.sipErrorCause(a.status_code);this._registrationFailure(a,n)}}}});this._registering=!0,i.send()}unregister(t={}){if(!this._registered){Wi.debug("already unregistered");return}this._registered=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null);const s=this._extraHeaders.slice();t.all?s.push(`Contact: *${this._extraContactParams}`):s.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=0`),s.push("Expires: 0");const i=new Ct.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},s);new sl(this._ua,i,{onRequestTimeout:()=>{this._unregistered(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._unregistered(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:n=>{switch(!0){case/^1[0-9]{2}$/.test(n.status_code):break;case/^2[0-9]{2}$/.test(n.status_code):this._unregistered(n);break;default:{const r=vs.sipErrorCause(n.status_code);this._unregistered(n,r)}}}}).send()}close(){this._registered&&this.unregister()}onTransportClosed(){this._registering=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),this._registered&&(this._registered=!1,this._ua.unregistered({}))}_registrationFailure(t,s){this._registering=!1,this._ua.registrationFailed({response:t||null,cause:s}),this._registered&&(this._registered=!1,this._ua.unregistered({response:t||null,cause:s}))}_unregistered(t,s){this._registering=!1,this._registered=!1,this._ua.unregistered({response:t||null,cause:s||null})}}const nt=console,Bs={STATUS_INIT:0,STATUS_READY:1,STATUS_USER_CLOSED:2,STATUS_NOT_READY:3,CONFIGURATION_ERROR:1,NETWORK_ERROR:2},XT=$T;class ZT extends XT{constructor(t){super(t),this._msrp_sessions=[],this._transactions={nist:{},nict:{},ist:{},ict:{}},this._janus_sessions=[],this.newStreamPlugins=[],this.processStreamPlugins=[],this.optionsInterval=null,this.lastOptionsTimestamp=null,this.lastRegisterTimestamp=null,this._registrator=new QT(this)}setLastRegisterTimestamp(){this.lastRegisterTimestamp=Date.now()}call(t,s){return super.call(t,s)}joinVideoCall(t,s,i){nt.debug("call()");const a=new Vo(this);return a.configureMedia({audio:!0,video:!0}),a.connect(t,s,i),a}startScreenShare(){nt.debug("startScreenShare()");for(const t in this._janus_sessions)this._janus_sessions[t].connectScreenShare()}changeMediaConstraints(t){for(const s in this._janus_sessions)this._janus_sessions[s].changeMediaConstraints(t)}startBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].connectBlur()}stopBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].stopBlur()}_loadConfig(t){try{rl.load(this._configuration,t)}catch(n){throw n}this._configuration.display_name===0&&(this._configuration.display_name="0"),this._configuration.instance_id||(this._configuration.instance_id=vs.newUUID());let s;typeof window<"u"&&typeof window.document<"u"?s=window==null?void 0:window.navigator.userAgent:typeof self<"u"&&self.navigator&&(s=self.navigator.userAgent),s+=" "+De.USER_AGENT,this._configuration.user_agent=t.overrideUserAgent&&typeof t.overrideUserAgent=="function"?t.overrideUserAgent(s):s,t.onTransportCallback&&typeof t.onTransportCallback=="function"&&(this.onTransportCallback=t.onTransportCallback),this._configuration.jssip_id=vs.createRandomToken(5);const i=this._configuration.uri.clone();i.user=null,this._configuration.hostport_params=i.toString().replace(/^sip:/i,"");try{this._transport=new cT(this._configuration.sockets,{max_interval:this._configuration.connection_recovery_max_interval,min_interval:this._configuration.connection_recovery_min_interval}),this._transport.onconnecting=ev.bind(this),this._transport.onconnect=tv.bind(this),this._transport.ondisconnect=sv.bind(this),this._transport.ondata=nv.bind(this)}catch(n){throw nt.warn(n),new qs.ConfigurationError("sockets",this._configuration.sockets)}if(delete this._configuration.sockets,this._configuration.authorization_user||(this._configuration.authorization_user=this._configuration.uri.user),!this._configuration.registrar_server){const n=this._configuration.uri.clone();n.user=null,n.clearParams(),n.clearHeaders(),this._configuration.registrar_server=n}this._configuration.no_answer_timeout*=1e3,this._configuration.contact_uri?this._configuration.via_host=this._configuration.contact_uri.host:this._configuration.contact_uri=new In("sip",vs.createRandomToken(8),this._configuration.via_host,null,{transport:"ws"}),this._contact={pub_gruu:null,temp_gruu:null,uri:this._configuration.contact_uri,toString(n={}){const r=n.anonymous||null,h=n.outbound||null;let d="<";return r?d+=this.temp_gruu||"sip:anonymous@anonymous.invalid;transport=ws":d+=this.pub_gruu||this.uri.toString(),h&&(r?!this.temp_gruu:!this.pub_gruu)&&(d+=";ob"),d+=">",d}};const a=["authorization_user","password","realm","ha1","authorization_jwt","display_name","register"];for(const n in this._configuration)Object.prototype.hasOwnProperty.call(this._configuration,n)&&(a.indexOf(n)!==-1?Object.defineProperty(this._configuration,n,{writable:!0,configurable:!1}):Object.defineProperty(this._configuration,n,{writable:!1,configurable:!1}));nt.debug("configuration parameters after validation:");for(const n in this._configuration)if(Object.prototype.hasOwnProperty.call(rl.settings,n))switch(n){case"uri":case"registrar_server":nt.debug(`- ${n}: ${this._configuration[n]}`);break;case"password":case"ha1":case"authorization_jwt":nt.debug(`- ${n}: NOT SHOWN`);break;default:nt.debug(`- ${n}: ${JSON.stringify(this._configuration[n])}`)}}newMSRPSession(t,s){t.on("msgHistoryUpdate",i=>{console.log(i)}),this._msrp_sessions[t.id]=t,this.emit("newMSRPSession",s)}newJanusSession(t,s){this._janus_sessions[t.id]=t,this.newStreamPlugins.forEach(i=>{i.setSession(t)}),this.processStreamPlugins.forEach(i=>{i.setSession(t)}),this.emit("newJanusSession",s)}kill(){}destroyMSRPSession(t){delete this._msrp_sessions[t.id]}destroyJanusSession(t){delete this._janus_sessions[t.id]}clearKeepAliveInterval(){clearInterval(this.optionsInterval),this.optionsInterval=null}receiveRequest(t){var n,r,h,d;const s=t.method;if(t.ruri.user!==this._configuration.uri.user&&t.ruri.user!==this._contact.uri.user){nt.debug("Request-URI does not point to us"),t.method!==De.ACK&&t.reply_sl(404);return}if(t.ruri.scheme===De.SIPS){t.reply_sl(416);return}if(Wt.checkTransaction(this,t))return;if(s===De.INVITE?new Wt.InviteServerTransaction(this,this._transport,t):s!==De.ACK&&s!==De.CANCEL&&new Wt.NonInviteServerTransaction(this,this._transport,t),s===De.OPTIONS){if(this.lastOptionsTimestamp=Date.now(),this.optionsInterval||(this.emit("initKeepAliveInterval"),this.optionsInterval=setInterval(()=>{const g=Date.now(),T=this.lastOptionsTimestamp>g-35e3,S=this.lastRegisterTimestamp+this._configuration.register_expires*1e3>g;T&&S&&this.emit("keepAliveInterval")},35e3)),this.listeners("newOptions").length===0){t.reply(200);return}new sf.Options(this).init_incoming(t)}else if(s===De.MESSAGE){if(this.listeners("newMessage").length===0){t.reply(405);return}new sf.Message(this).init_incoming(t)}else if(s===De.INVITE&&!t.to_tag&&this.listeners("newRTCSession").length===0){t.reply(405);return}let i,a;if(t.to_tag)if(i=this._findDialog(t.call_id,t.from_tag,t.to_tag),i)i.receiveRequest(t);else if(s===De.NOTIFY)if(a=this._findSession(t),a)a.receiveRequest(t);else{if(t.body)try{const _=JSON.parse(t.body)||{};(r=(n=_.plugindata)==null?void 0:n.data)!=null&&r.publishers&&Object.values(this._janus_sessions)[0].receivePublishers(_),(d=(h=_.plugindata)==null?void 0:h.data)!=null&&d.unpublished&&Object.values(this._janus_sessions)[0].receiveUnpublished(_.plugindata.data.unpublished)}catch(_){console.error(_)}t.reply(200)}else s!==De.ACK&&t.reply(481);else switch(s){case De.INVITE:if(window.RTCPeerConnection)if(t.hasHeader("replaces")){const _=t.replaces;i=this._findDialog(_.call_id,_.from_tag,_.to_tag),i?(a=i.owner,a.isEnded()?t.reply(603):a.receiveRequest(t)):t.reply(481)}else t.body.search(/MSRP/ig)>-1?(a=new iu(this),a.init_incoming(t)):t.body.search(/JANUS/ig)>-1||(a=new Yg(this),a.init_incoming(t));else nt.warn("INVITE received but WebRTC is not supported"),t.reply(488);break;case De.BYE:t.reply(481);break;case De.CANCEL:a=this._findSession(t),a?a.receiveRequest(t):nt.debug("received CANCEL request for a non existent session");break;case De.ACK:break;case De.NOTIFY:this.emit("sipEvent",{event:t.event,request:t}),t.reply(200);break;default:t.reply(405);break}}startMSRP(t,s){nt.debug("startMSRP()",s);const i=new iu(this);return i.connect(t),i}startJanus(t,s){nt.debug("startJanus()",s);const i=new iu(this);return i.connect(t),i}terminateMSRPSessions(t){nt.debug("terminateSessions()");for(const s in this._msrp_sessions)this._msrp_sessions[s].isEnded()||this._msrp_sessions[s].terminate(t)}terminateJanusSessions(t){nt.debug("terminateSessions()");for(const s in this._janus_sessions)this._janus_sessions[s].isEnded()||this._janus_sessions[s].terminate(t)}enableJanusAudio(t){nt.debug("enableJanusAudio()");for(const s in this._janus_sessions)this._janus_sessions[s].isEnded()||(t?this._janus_sessions[s].startAudio():this._janus_sessions[s].stopAudio())}enableJanusVideo(t){nt.debug("enableJanusVideo()");for(const s in this._janus_sessions)this._janus_sessions[s].isEnded()||(t?this._janus_sessions[s].startVideo():this._janus_sessions[s].stopVideo())}terminateAllSessions(){for(const t in this._sessions)if(Object.prototype.hasOwnProperty.call(this._sessions,t)){nt.debug(`closing session ${t}`);try{this._sessions[t].terminate()}catch(s){console.error(s)}}}stop(t=!0){if(nt.debug("stop()"),this._dynConfiguration={},this._status===Bs.STATUS_USER_CLOSED){nt.debug("UA already closed");return}this._registrator.close();const s=Object.keys(this._sessions).length;t&&this.terminateAllSessions();for(const a in this._msrp_sessions)if(Object.prototype.hasOwnProperty.call(this._msrp_sessions,a)){nt.debug(`closing session ${a}`);try{this._msrp_sessions[a].terminate()}catch(n){console.error(n)}}for(const a in this._janus_sessions)if(Object.prototype.hasOwnProperty.call(this._janus_sessions,a)){nt.debug(`closing session ${a}`);try{this._janus_sessions[a].terminate()}catch(n){console.error(n)}}for(const a in this._applicants)if(Object.prototype.hasOwnProperty.call(this._applicants,a))try{this._applicants[a].close()}catch(n){console.error(n)}this._status=Bs.STATUS_USER_CLOSED,Object.keys(this._transactions.nict).length+Object.keys(this._transactions.nist).length+Object.keys(this._transactions.ict).length+Object.keys(this._transactions.ist).length===0&&s===0?this._transport.disconnect():this._closeTimer=setTimeout(()=>{this._closeTimer=null,this._transport.disconnect()},2e3)}}function ev(c){this.emit("connecting",c)}function tv(c){this._status!==Bs.STATUS_USER_CLOSED&&(this._status=Bs.STATUS_READY,this._error=null,this.emit("connected",c),this._dynConfiguration.register&&this._registrator.register())}function sv(c){const t=["nict","ict","nist","ist"];for(const s of t)for(const i in this._transactions[s])Object.prototype.hasOwnProperty.call(this._transactions[s],i)&&this._transactions[s][i].onTransportError();this.emit("disconnected",c),this._registrator.onTransportClosed(),this._status!==Bs.STATUS_USER_CLOSED&&(this._status=Bs.STATUS_NOT_READY,this._error=Bs.NETWORK_ERROR)}function nv(c){const t=c.transport;let s=c.message;const i=s;if(s=zT.parseMessage(s,this),this.onTransportCallback&&typeof this.onTransportCallback=="function"&&this.onTransportCallback(s,i),!!s&&!(this._status===Bs.STATUS_USER_CLOSED&&s instanceof pr.IncomingRequest)&&RT(s,this,t)){if(s instanceof pr.IncomingRequest)s.transport=t,this.receiveRequest(s);else if(s instanceof pr.IncomingResponse){let a;switch(s.method){case De.INVITE:if(a=this._transactions.ict[s.via_branch],a){const n=s.status_code;if((n===100||n===180||n===183)&&this.audio&&typeof this.audio.handleSipResponseForRingback=="function"){let r=null;if(a._session&&a._session.id)r=a._session.id;else if(s.call_id&&this._sessions){const d=Object.values(this._sessions).find(_=>_._id&&_._id.includes(s.call_id)||_.id&&_.id.includes(s.call_id)||_.call_id===s.call_id);d&&(d.id||d._id)&&(r=d.id||d._id)}else s.call_id&&(r=s.call_id);r&&this.audio.handleSipResponseForRingback(r,n)}a.receiveResponse(s)}break;case De.ACK:break;default:a=this._transactions.nict[s.via_branch],a&&a.receiveResponse(s);break}}}}const rv=["roomId","_audioMuted","_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","_localHold","_videoMuted","status","start_time","_remote_identity","audioTag","isOnHold","localMuted","autoAnswer","putOnHoldTimestamp","_remote_party_display_name","_remote_party_uri_user"],iv=["_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","status","start_time","_remote_identity","target_addr"];function Mf(c){const t={};return rv.forEach(s=>{c[s]!==void 0&&(t[s]=c[s])}),t.localHold=c._localHold,t}function Pf(c){const t={};return iv.forEach(s=>{c[s]!==void 0&&(t[s]=c[s])}),t}async function lu(c,t,s){const i=c.createMediaStreamSource(t),a=c.createMediaStreamDestination(),n=c.createGain();return i.connect(n),n.connect(a),n.gain.value=s,a.stream}function lv(c,t,s,i){if(Ld())return;const a=document.createElement("audio");a.id=t._id,a.className="audioTag",a.srcObject=c,a.setSinkId(s),a.volume=i,a.play(),t.audioTag=a}function Lf(c){if(!c)return null;const t=c.match(/^\s*"((?:[^"\\]|\\.)*)"/);return t?t[1].replace(/\\(.)/g,"$1"):null}function $f(c){if(!c)return null;const t=c.match(/<?sips?:([^@>\s;]+)@/i);return t?t[1]:null}function ov(c){if(c&&typeof c.log=="function"&&typeof c.warn=="function"&&typeof c.error=="function")return!0}function Ld(){return/Mobi|react-native|Android|iPhone/i.test(navigator.userAgent)}const av=ct,uv=es(),Nt=new av("WebSocketInterface");var cv=class{constructor(t){Nt.debug('new() [url:"%s"]',t),this._url=t,this._sip_uri=null,this._via_transport=null,this._ws=null;const s=uv.parse(t,"absoluteURI");if(s===-1)throw Nt.warn(`invalid WebSocket URI: ${t}`),new TypeError(`Invalid argument: ${t}`);if(s.scheme!=="wss"&&s.scheme!=="ws")throw Nt.warn(`invalid WebSocket URI scheme: ${s.scheme}`),new TypeError(`Invalid argument: ${t}`);this._sip_uri=`sip:${s.host}${s.port?`:${s.port}`:""};transport=ws`,this._via_transport=s.scheme.toUpperCase()}get via_transport(){return this._via_transport}set via_transport(t){this._via_transport=t.toUpperCase()}get sip_uri(){return this._sip_uri}get url(){return this._url}connect(){if(Nt.debug("connect()"),this.isConnected()){Nt.debug(`WebSocket ${this._url} is already connected`);return}else if(this.isConnecting()){Nt.debug(`WebSocket ${this._url} is connecting`);return}this._ws&&this.disconnect(),Nt.debug(`connecting to WebSocket ${this._url}`);try{this._ws=new WebSocket(this._url,"sip"),this._ws.binaryType="arraybuffer",this._ws.onopen=this._onOpen.bind(this),this._ws.onclose=this._onClose.bind(this),this._ws.onmessage=this._onMessage.bind(this),this._ws.onerror=this._onError.bind(this)}catch(t){this._onError(t)}}disconnect(){Nt.debug("disconnect()"),this._ws&&(this._ws.onopen=()=>{},this._ws.onclose=()=>{},this._ws.onmessage=()=>{},this._ws.onerror=()=>{},this._ws.close(),this._ws=null)}send(t){return Nt.debug("send()"),this.isConnected()?(this._ws.send(t),!0):(Nt.warn("unable to send message, WebSocket is not open"),!1)}isConnected(){return this._ws&&this._ws.readyState===this._ws.OPEN}isConnecting(){return this._ws&&this._ws.readyState===this._ws.CONNECTING}_onOpen(){Nt.debug(`WebSocket ${this._url} connected`),this.onconnect()}_onClose({wasClean:t,code:s,reason:i}){Nt.debug(`WebSocket ${this._url} closed`),t===!1&&Nt.debug("WebSocket abrupt disconnection"),this.ondisconnect(!t,s,i)}_onMessage({data:t}){Nt.debug("received WebSocket message"),this.ondata(t)}_onError(t){Nt.warn(`WebSocket ${this._url} error: `,t)}};const Nu=jo,fv=De,dv=As,hv=At(),_v=Pd,pv=Cs(),mv=ju(),gv=es(),Tv=cv,vv=gr("JsSIP");vv("version %s",Nu.version);var Sv={C:fv,Exceptions:dv,Utils:hv,UA:_v,URI:pv,NameAddrHeader:mv,WebSocketInterface:Tv,Grammar:gv,debug:gr,get name(){return Nu.title},get version(){return Nu.version}};const Ev=Xe(Sv);function ou(c){return c<10?`0${c}`:`${c}`}function yv(c){let t=c.hours||0,s=c.minutes||0,i=c.seconds||0;i++,i===60&&(i=0,s++,s===60&&(s=0,t++));const a=`${ou(t)}:${ou(s)}:${ou(i)}`;return{seconds:i,minutes:s,hours:t,formatted:a}}function Cv(c){let t=0;for(let s=0;s<c.length;s++)t+=c[s]*c[s];return Math.sqrt(t/c.length)}async function Av(c,t,s=150){const i=t.createMediaStreamSource(c),a=t.createDelay();a.delayTime.value=s/1e3;const n=t.createGain();n.gain.value=0;const r=t.createMediaStreamDestination();return i.connect(a).connect(n).connect(r),{stream:r.stream,setSpeaking:h=>{n.gain.value=h?1:0}}}var Rt={};Rt.forEach=async(c,t,s)=>{const i=[];for(let a=0;a<c.length;a++)if(a in c){const n=Promise.resolve(c[a]).then(r=>t.call(s||globalThis,r,a,c));i.push(n)}await Promise.all(i)};Rt.forEachSeries=async(c,t,s)=>{for(let i=0;i<c.length;i++)i in c&&await t.call(s||globalThis,await c[i],i,c)};Rt.map=async(c,t,s)=>{const i=[];for(let a=0;a<c.length;a++)a in c&&(i[a]=Promise.resolve(c[a]).then(n=>t.call(s||globalThis,n,a,c)));return Promise.all(i)};Rt.mapSeries=async(c,t,s)=>{const i=[];for(let a=0;a<c.length;a++)a in c&&(i[a]=await t.call(s||globalThis,await c[a],a,c));return i};Rt.find=(c,t,s)=>new Promise((i,a)=>{if(c.length===0)return i();let n=1;for(let r=0;r<c.length;r++){const h=d=>{d?i(c[r]):n===c.length&&i(),n++};Promise.resolve(c[r]).then(d=>t.call(s||globalThis,d,r,c)).then(h).catch(a)}});Rt.findSeries=async(c,t,s)=>{for(let i=0;i<c.length;i++)if(await t.call(s||globalThis,await c[i],i,c))return c[i]};Rt.findIndex=(c,t,s)=>new Promise((i,a)=>{if(c.length===0)return i(-1);let n=1;for(let r=0;r<c.length;r++){const h=d=>{d?i(r):n===c.length&&i(-1),n++};Promise.resolve(c[r]).then(d=>t.call(s||globalThis,d,r,c)).then(h).catch(a)}});Rt.findIndexSeries=async(c,t,s)=>{for(let i=0;i<c.length;i++)if(await t.call(s||globalThis,await c[i],i,c))return i};Rt.some=(c,t,s)=>new Promise((i,a)=>{if(c.length===0)return i(!1);let n=1;for(let r=0;r<c.length;r++){if(!(r in c)){n++;continue}const h=d=>{d?i(!0):n===c.length&&i(!1),n++};Promise.resolve(c[r]).then(d=>t.call(s||globalThis,d,r,c)).then(h).catch(a)}});Rt.someSeries=async(c,t,s)=>{for(let i=0;i<c.length;i++)if(i in c&&await t.call(s||globalThis,await c[i],i,c))return!0;return!1};Rt.every=(c,t,s)=>new Promise((i,a)=>{if(c.length===0)return i(!0);let n=1;for(let r=0;r<c.length;r++){if(!(r in c)){n++;continue}const h=d=>{d?n===c.length&&i(!0):i(!1),n++};Promise.resolve(c[r]).then(d=>t.call(s||globalThis,d,r,c)).then(h).catch(a)}});Rt.everySeries=async(c,t,s)=>{for(let i=0;i<c.length;i++)if(i in c&&!await t.call(s||globalThis,await c[i],i,c))return!1;return!0};Rt.filter=(c,t,s)=>new Promise(async(i,a)=>{const n=[];for(let h=0;h<c.length;h++)h in c&&(n[h]=Promise.resolve(c[h]).then(d=>t.call(s||globalThis,d,h,c)).catch(a));const r=[];for(let h=0;h<n.length;h++)await n[h]&&r.push(await c[h]);i(r)});Rt.filterSeries=async(c,t,s)=>{const i=[];for(let a=0;a<c.length;a++)a in c&&await t.call(s||globalThis,await c[a],a,c)&&i.push(await c[a]);return i};Rt.reduce=async(c,t,s)=>{if(c.length===0&&s===void 0)throw TypeError("Reduce of empty array with no initial value");let i,a;for(s!==void 0?(a=s,i=0):(a=c[0],i=1),i;i<c.length;i++)i in c&&(a=await t(await a,await c[i],i,c));return a};var $d={};(function(c){const t=Rt;Object.keys(t).forEach(s=>{const i=s.charAt(0).toUpperCase()+s.slice(1);c[`async${i}`]=async function(...a){return t[s](this,...a)}})})($d);const Rv=Rt,Iv=$d;var bv=Object.assign(Rv,{instanceMethods:Iv});const Xt={NEW_CALL:"new_call",CALL_CONFIRMED:"confirmed",CALL_FAILED:"failed",CALL_PROGRESS:"progress",CALL_ENDED:"ended"},au={TRYING:100,RINGING:180,SESSION_PROGRESS:183,OK:200,MOVED_TEMPORARILY:302,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,REQUEST_TIMEOUT:408,BUSY_HERE:486,REQUEST_TERMINATED:487,INTERNAL_SERVER_ERROR:500,SERVICE_UNAVAILABLE:503,BUSY_EVERYWHERE:600,DECLINE:603};var wv={exports:{}};(function(c){var t=function(s){var i=Object.prototype,a=i.hasOwnProperty,n=Object.defineProperty||function(X,W,G){X[W]=G.value},r,h=typeof Symbol=="function"?Symbol:{},d=h.iterator||"@@iterator",_=h.asyncIterator||"@@asyncIterator",g=h.toStringTag||"@@toStringTag";function T(X,W,G){return Object.defineProperty(X,W,{value:G,enumerable:!0,configurable:!0,writable:!0}),X[W]}try{T({},"")}catch{T=function(W,G,re){return W[G]=re}}function S(X,W,G,re){var pe=W&&W.prototype instanceof ie?W:ie,Ie=Object.create(pe.prototype),ke=new M(re||[]);return n(Ie,"_invoke",{value:Y(X,G,ke)}),Ie}s.wrap=S;function E(X,W,G){try{return{type:"normal",arg:X.call(W,G)}}catch(re){return{type:"throw",arg:re}}}var C="suspendedStart",A="suspendedYield",R="executing",F="completed",I={};function ie(){}function N(){}function $(){}var ve={};T(ve,d,function(){return this});var _e=Object.getPrototypeOf,U=_e&&_e(_e(B([])));U&&U!==i&&a.call(U,d)&&(ve=U);var x=$.prototype=ie.prototype=Object.create(ve);N.prototype=$,n(x,"constructor",{value:$,configurable:!0}),n($,"constructor",{value:N,configurable:!0}),N.displayName=T($,g,"GeneratorFunction");function q(X){["next","throw","return"].forEach(function(W){T(X,W,function(G){return this._invoke(W,G)})})}s.isGeneratorFunction=function(X){var W=typeof X=="function"&&X.constructor;return W?W===N||(W.displayName||W.name)==="GeneratorFunction":!1},s.mark=function(X){return Object.setPrototypeOf?Object.setPrototypeOf(X,$):(X.__proto__=$,T(X,g,"GeneratorFunction")),X.prototype=Object.create(x),X},s.awrap=function(X){return{__await:X}};function j(X,W){function G(Ie,ke,Ae,oe){var ye=E(X[Ie],X,ke);if(ye.type==="throw")oe(ye.arg);else{var rt=ye.arg,at=rt.value;return at&&typeof at=="object"&&a.call(at,"__await")?W.resolve(at.__await).then(function(Ee){G("next",Ee,Ae,oe)},function(Ee){G("throw",Ee,Ae,oe)}):W.resolve(at).then(function(Ee){rt.value=Ee,Ae(rt)},function(Ee){return G("throw",Ee,Ae,oe)})}}var re;function pe(Ie,ke){function Ae(){return new W(function(oe,ye){G(Ie,ke,oe,ye)})}return re=re?re.then(Ae,Ae):Ae()}n(this,"_invoke",{value:pe})}q(j.prototype),T(j.prototype,_,function(){return this}),s.AsyncIterator=j,s.async=function(X,W,G,re,pe){pe===void 0&&(pe=Promise);var Ie=new j(S(X,W,G,re),pe);return s.isGeneratorFunction(W)?Ie:Ie.next().then(function(ke){return ke.done?ke.value:Ie.next()})};function Y(X,W,G){var re=C;return function(Ie,ke){if(re===R)throw new Error("Generator is already running");if(re===F){if(Ie==="throw")throw ke;return Fe()}for(G.method=Ie,G.arg=ke;;){var Ae=G.delegate;if(Ae){var oe=V(Ae,G);if(oe){if(oe===I)continue;return oe}}if(G.method==="next")G.sent=G._sent=G.arg;else if(G.method==="throw"){if(re===C)throw re=F,G.arg;G.dispatchException(G.arg)}else G.method==="return"&&G.abrupt("return",G.arg);re=R;var ye=E(X,W,G);if(ye.type==="normal"){if(re=G.done?F:A,ye.arg===I)continue;return{value:ye.arg,done:G.done}}else ye.type==="throw"&&(re=F,G.method="throw",G.arg=ye.arg)}}}function V(X,W){var G=W.method,re=X.iterator[G];if(re===r)return W.delegate=null,G==="throw"&&X.iterator.return&&(W.method="return",W.arg=r,V(X,W),W.method==="throw")||G!=="return"&&(W.method="throw",W.arg=new TypeError("The iterator does not provide a '"+G+"' method")),I;var pe=E(re,X.iterator,W.arg);if(pe.type==="throw")return W.method="throw",W.arg=pe.arg,W.delegate=null,I;var Ie=pe.arg;if(!Ie)return W.method="throw",W.arg=new TypeError("iterator result is not an object"),W.delegate=null,I;if(Ie.done)W[X.resultName]=Ie.value,W.next=X.nextLoc,W.method!=="return"&&(W.method="next",W.arg=r);else return Ie;return W.delegate=null,I}q(x),T(x,g,"Generator"),T(x,d,function(){return this}),T(x,"toString",function(){return"[object Generator]"});function Q(X){var W={tryLoc:X[0]};1 in X&&(W.catchLoc=X[1]),2 in X&&(W.finallyLoc=X[2],W.afterLoc=X[3]),this.tryEntries.push(W)}function k(X){var W=X.completion||{};W.type="normal",delete W.arg,X.completion=W}function M(X){this.tryEntries=[{tryLoc:"root"}],X.forEach(Q,this),this.reset(!0)}s.keys=function(X){var W=Object(X),G=[];for(var re in W)G.push(re);return G.reverse(),function pe(){for(;G.length;){var Ie=G.pop();if(Ie in W)return pe.value=Ie,pe.done=!1,pe}return pe.done=!0,pe}};function B(X){if(X){var W=X[d];if(W)return W.call(X);if(typeof X.next=="function")return X;if(!isNaN(X.length)){var G=-1,re=function pe(){for(;++G<X.length;)if(a.call(X,G))return pe.value=X[G],pe.done=!1,pe;return pe.value=r,pe.done=!0,pe};return re.next=re}}return{next:Fe}}s.values=B;function Fe(){return{value:r,done:!0}}return M.prototype={constructor:M,reset:function(X){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(k),!X)for(var W in this)W.charAt(0)==="t"&&a.call(this,W)&&!isNaN(+W.slice(1))&&(this[W]=r)},stop:function(){this.done=!0;var X=this.tryEntries[0],W=X.completion;if(W.type==="throw")throw W.arg;return this.rval},dispatchException:function(X){if(this.done)throw X;var W=this;function G(oe,ye){return Ie.type="throw",Ie.arg=X,W.next=oe,ye&&(W.method="next",W.arg=r),!!ye}for(var re=this.tryEntries.length-1;re>=0;--re){var pe=this.tryEntries[re],Ie=pe.completion;if(pe.tryLoc==="root")return G("end");if(pe.tryLoc<=this.prev){var ke=a.call(pe,"catchLoc"),Ae=a.call(pe,"finallyLoc");if(ke&&Ae){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0);if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else if(ke){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0)}else if(Ae){if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else throw new Error("try statement without catch or finally")}}},abrupt:function(X,W){for(var G=this.tryEntries.length-1;G>=0;--G){var re=this.tryEntries[G];if(re.tryLoc<=this.prev&&a.call(re,"finallyLoc")&&this.prev<re.finallyLoc){var pe=re;break}}pe&&(X==="break"||X==="continue")&&pe.tryLoc<=W&&W<=pe.finallyLoc&&(pe=null);var Ie=pe?pe.completion:{};return Ie.type=X,Ie.arg=W,pe?(this.method="next",this.next=pe.finallyLoc,I):this.complete(Ie)},complete:function(X,W){if(X.type==="throw")throw X.arg;return X.type==="break"||X.type==="continue"?this.next=X.arg:X.type==="return"?(this.rval=this.arg=X.arg,this.method="return",this.next="end"):X.type==="normal"&&W&&(this.next=W),I},finish:function(X){for(var W=this.tryEntries.length-1;W>=0;--W){var G=this.tryEntries[W];if(G.finallyLoc===X)return this.complete(G.completion,G.afterLoc),k(G),I}},catch:function(X){for(var W=this.tryEntries.length-1;W>=0;--W){var G=this.tryEntries[W];if(G.tryLoc===X){var re=G.completion;if(re.type==="throw"){var pe=re.arg;k(G)}return pe}}throw new Error("illegal catch attempt")},delegateYield:function(X,W,G){return this.delegate={iterator:B(X),resultName:W,nextLoc:G},this.method==="next"&&(this.arg=r),I}},s}(c.exports);try{regeneratorRuntime=t}catch{typeof globalThis=="object"?globalThis.regeneratorRuntime=t:Function("r","regeneratorRuntime = r")(t)}})(wv);var Hd={exports:{}};(function(c){(function(t,s){c.exports?c.exports=s():t.log=s()})(Qd,function(){var t=function(){},s="undefined",i=typeof window!==s&&typeof window.navigator!==s&&/Trident\/|MSIE /.test(window.navigator.userAgent),a=["trace","debug","info","warn","error"];function n(A,R){var F=A[R];if(typeof F.bind=="function")return F.bind(A);try{return Function.prototype.bind.call(F,A)}catch{return function(){return Function.prototype.apply.apply(F,[A,arguments])}}}function r(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function h(A){return A==="debug"&&(A="log"),typeof console===s?!1:A==="trace"&&i?r:console[A]!==void 0?n(console,A):console.log!==void 0?n(console,"log"):t}function d(A,R){for(var F=0;F<a.length;F++){var I=a[F];this[I]=F<A?t:this.methodFactory(I,A,R)}this.log=this.debug}function _(A,R,F){return function(){typeof console!==s&&(d.call(this,R,F),this[A].apply(this,arguments))}}function g(A,R,F){return h(A)||_.apply(this,arguments)}function T(A,R,F){var I=this,ie;R=R??"WARN";var N="loglevel";typeof A=="string"?N+=":"+A:typeof A=="symbol"&&(N=void 0);function $(x){var q=(a[x]||"silent").toUpperCase();if(!(typeof window===s||!N)){try{window.localStorage[N]=q;return}catch{}try{window.document.cookie=encodeURIComponent(N)+"="+q+";"}catch{}}}function ve(){var x;if(!(typeof window===s||!N)){try{x=window.localStorage[N]}catch{}if(typeof x===s)try{var q=window.document.cookie,j=q.indexOf(encodeURIComponent(N)+"=");j!==-1&&(x=/^([^;]+)/.exec(q.slice(j))[1])}catch{}return I.levels[x]===void 0&&(x=void 0),x}}function _e(){if(!(typeof window===s||!N)){try{window.localStorage.removeItem(N);return}catch{}try{window.document.cookie=encodeURIComponent(N)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch{}}}I.name=A,I.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},I.methodFactory=F||g,I.getLevel=function(){return ie},I.setLevel=function(x,q){if(typeof x=="string"&&I.levels[x.toUpperCase()]!==void 0&&(x=I.levels[x.toUpperCase()]),typeof x=="number"&&x>=0&&x<=I.levels.SILENT){if(ie=x,q!==!1&&$(x),d.call(I,x,A),typeof console===s&&x<I.levels.SILENT)return"No console available for logging"}else throw"log.setLevel() called with invalid level: "+x},I.setDefaultLevel=function(x){R=x,ve()||I.setLevel(x,!1)},I.resetLevel=function(){I.setLevel(R,!1),_e()},I.enableAll=function(x){I.setLevel(I.levels.TRACE,x)},I.disableAll=function(x){I.setLevel(I.levels.SILENT,x)};var U=ve();U==null&&(U=R),I.setLevel(U,!1)}var S=new T,E={};S.getLogger=function(R){if(typeof R!="symbol"&&typeof R!="string"||R==="")throw new TypeError("You must supply a name when creating a logger.");var F=E[R];return F||(F=E[R]=new T(R,S.getLevel(),S.methodFactory)),F};var C=typeof window!==s?window.log:void 0;return S.noConflict=function(){return typeof window!==s&&window.log===S&&(window.log=C),S},S.getLoggers=function(){return E},S.default=S,S})})(Hd);var bt=Hd.exports;const Ss=()=>`${new Date().toISOString()} | metrics`,Es=(c,t,s)=>`${c} | ${t} | ${s}`;bt.setDefaultLevel(bt.levels.TRACE);const Ov=c=>{bt.info(Es(Ss(),"log ",`set log level to ${c?"verbose":"info"}`)),bt.setLevel(c?bt.levels.TRACE:bt.levels.INFO)},Dv=c=>{const t=[...Object.keys(bt.levels)];t.includes(c)?(bt.info(Es(Ss(),"log ",`update log level to ${c.toLowerCase()}`)),bt.setLevel(c)):bt.warn(Es(Ss(),"log ","Incorrect log level please choose one of "),t)},Ue=(c,t,s)=>{s?bt.debug(Es(Ss(),c,t),s):bt.debug(Es(Ss(),c,t))},uu=(c,t)=>{bt.info(Es(Ss(),c,t))},Rn=(c,t)=>{bt.info(Es(Ss(),c,t))},No=(c,t)=>{bt.warn(Es(Ss(),c,t))},hr=(c,t)=>{bt.error(Es(Ss(),c,t))};function Nv(c){return Math.floor(Math.random()*c).toString()}function Hf(c,t){let s=t;return c.forEach(i=>{s=s.replace(i,"")}),s}function xv(c,t){let s="";for(let i=0;i<t;i+=1)s+=c[Nv(c.length)];return s}function Uv({length:c=20,useLetters:t=!0,useNumbers:s=!0,includeSymbols:i=[],excludeSymbols:a=[]}={}){let n="abcdefghijklmnopqrstuvwxyz",r="0123456789",h=[],d=[],_=[];return t&&(a.length&&(n=Hf(a,n)),d=n.split("")),s&&(a.length&&(r=Hf(a,r)),_=r.split("")),h=[...d,..._,...i],xv(h,c)}var kv=Uv;const Xi=Xe(kv),Mv=()=>"WebRTCMetrics",Pv=()=>"5.0.3",He={INBOUND:"inbound",OUTBOUND:"outbound"},Ts={IDLE:"idle",RUNNING:"running",MUTED:"muted"},Ki={NEW:"new",CHECKING:"checking",CONNECTED:"connected",COMPLETED:"completed",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"},Lv=()=>({...{delta_time_to_measure_probes_ms:0,delta_time_consumed_to_measure_ms:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,total_time_decoded_in:0,total_time_encoded_out:0,probes:[]}}),Fd={level_in:0,codec_id_in:"",codec_in:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,mos_in:0,mos_emodel_in:0,ssrc:"",direction:He.INBOUND},Vd={level_out:0,codec_id_out:"",codec_out:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,timestamp_out:null,mos_out:0,mos_emodel_out:0,ssrc:"",direction:He.OUTBOUND},jd={codec_id_in:"",size_in:{width:null,height:null,framerate:null},codec_in:{mime_type:null,clock_rate:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,decoder_in:null,delta_ms_decode_frame_in:0,total_frames_decoded_in:0,total_time_decoded_in:0,delta_nack_sent_in:0,delta_pli_sent_in:0,total_nack_sent_in:0,total_pli_sent_in:0,ssrc:"",direction:He.INBOUND},qd={codec_id_out:"",size_out:{width:null,height:null,framerate:null},codec_out:{mime_type:null,clock_rate:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,encoder_out:null,delta_ms_encode_frame_out:0,total_time_encoded_out:0,total_frames_encoded_out:0,delta_nack_received_out:0,delta_pli_received_out:0,total_nack_received_out:0,total_pli_received_out:0,limitation_out:{reason:null,durations:null,resolutionChanges:0},timestamp_out:null,ssrc:"",direction:He.OUTBOUND},$v=c=>{const t={pname:"",call_id:"",user_id:"",timestamp:null,count:0,audio:{},video:{},network:{infrastructure:3,local_candidate_id:"",local_candidate_type:"",local_candidate_protocol:"",local_candidate_relay_protocol:"",remote_candidate_id:"",remote_candidate_type:"",remote_candidate_protocol:""},data:{total_KBytes_in:0,total_KBytes_out:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,delta_kbs_bandwidth_in:0,delta_kbs_bandwidth_out:0,delta_rtt_connectivity_ms:null,total_rtt_connectivity_ms:0,total_rtt_connectivity_measure:0},experimental:{time_to_measure_ms:0}};if(c){const s={...c,audio:{},video:{},data:{...c.data},network:{...c.network},experimental:{...c.experimental}};return Object.keys(c.audio).forEach(i=>{s.audio[i]={...c.audio[i]}}),Object.keys(c.video).forEach(i=>{s.video[i]={...c.video[i]}}),s}return{...t,audio:{},video:{},data:{...t.data},network:{...t.network},experimental:{...t.experimental}}},Hv={refreshEvery:2e3,startAfter:0,stopAfter:-1,verbose:!1,pname:`p-${Xi()}`,cid:`c-${Xi()}`,uid:`u-${Xi()}`,record:!1,ticket:!0},Qt={CANDIDATE_PAIR:"candidate-pair",CODEC:"codec",INBOUND_RTP:"inbound-rtp",LOCAL_CANDIDATE:"local-candidate",MEDIA_SOURCE:"media-source",OUTBOUND_RTP:"outbound-rtp",REMOTE_CANDIDATE:"remote-candidate",REMOTE_INBOUND_RTP:"remote-inbound-rtp",TRACK:"track"},K={AUDIO_LEVEL:"audioLevel",AVAILABLE_OUTGOING_BITRATE:"availableOutgoingBitrate",AVAILABLE_INCOMING_BITRATE:"availableIncomingBitrate",BYTES_RECEIVED:"bytesReceived",BYTES_SENT:"bytesSent",CANDIDATE_TYPE:"candidateType",CHANNELS:"channels",CLOCK_RATE:"clockRate",CODEC_ID:"codecId",CURRENT_ROUND_TRIP_TIME:"currentRoundTripTime",ROUND_TRIP_TIME:"roundTripTime",FRACTION_LOST:"fractionLost",FRAME_HEIGHT:"frameHeight",FRAME_WIDTH:"frameWidth",QUALITY_LIMITATION_REASON:"qualityLimitationReason",QUALITY_LIMITATION_DURATIONS:"qualityLimitationDurations",QUALITY_LIMITATION_RESOLUTION_CHANGES:"qualityLimitationResolutionChanges",ID:"id",JITTER:"jitter",KIND:"kind",MEDIA_TYPE:"mediaType",MIME_TYPE:"mimeType",LOCAL_CANDIDATE_ID:"localCandidateId",NETWORK_TYPE:"networkType",RELAY_PROTOCOL:"relayProtocol",NOMINATED:"nominated",PACKETS_LOST:"packetsLost",PACKETS_RECEIVED:"packetsReceived",PACKETS_SENT:"packetsSent",PROTOCOL:"protocol",PORT:"port",REMOTE_CANDIDATE_ID:"remoteCandidateId",REMOTE_SOURCE:"remoteSource",RESPONSES_RECEIVED:"responsesReceived",SDP_FMTP_LINE:"sdpFmtpLine",SSRC:"ssrc",SELECTED:"selected",STATE:"state",TIMESTAMP:"timestamp",TOTAL_ROUND_TRIP_TIME:"totalRoundTripTime",TOTAL_ROUND_TRIP_TIME_MEASUREMENTS:"roundTripTimeMeasurements",TYPE:"type",DECODER_IMPLEMENTATION:"decoderImplementation",ENCODER_IMPLEMENTATION:"encoderImplementation",FRAMES_DECODED:"framesDecoded",FRAMES_ENCODED:"framesEncoded",FRAMES_PER_SECOND:"framesPerSecond",TOTAL_DECODE_TIME:"totalDecodeTime",TOTAL_ENCODE_TIME:"totalEncodeTime",PLI:"pliCount",NACK:"nackCount"},P={SUCCEEDED:"succeeded",AUDIO:"audio",VIDEO:"video"},Yi={ETHERNET:0,CELLULAR_5G:2,WIFI:3,CELLULAR_4G:5,CELLULAR:10},cu={ETHERNET:"ethernet",CELLULAR_4G:"cellular",WIFI:"wifi"},ne={AUDIO:"audio",VIDEO:"video",NETWORK:"network",DATA:"data"},fu="config ",Fv=(c,t={},s)=>{const i={...s,...t};return t.pname||No(fu,`Argument [String] 'cfg.pname' for the peerConnection name or id is missing - use generated '${s.pname}'`),t.cid||No(fu,`Argument [String] 'cfg.cid' for the call name or id is missing - use generated '${s.cid}'`),t.uid||No(fu,`Argument [String] 'cfg.uid' for the user name or id is missing - use generated '${s.uid}'`),i.pc=c,i},Vv=(c={})=>{const t={...Hv,...c};return t.name=Mv(),t.version=Pv(),t},ml=(c,t,s,i=!1,a)=>{let n=c.map(r=>{if(!s)return r[t];if(!a)return r[t][s];const h=r[t][a];return h?h[s]:null});return n=n.filter(r=>i?Number.isFinite(r)&&r>0:Number.isFinite(r)),n.length===0?[]:n},Ws=c=>c.reduce((t,s)=>t+s,0)/c.length,jv=()=>`probe-${Xi()}`,qv=()=>`coltr-${Xi()}`,Ff=c=>new Promise(t=>setTimeout(t,c)),xu=(c,t,s)=>{t?c.call(t,s):c(s)},Je=(c,t,s,i)=>{const a=ml(c,t,s,!0,i);if(a.length===0)return null;const n=a.reduce((_,g)=>_+g,0)/a.length;return n===0?null:a.map(_=>Math.abs(n-_)).reduce((_,g)=>_+g,0)/a.length*100/n},Ze=(c,t,s,i=!1,a)=>{const n=ml(c,t,s,i,a);return n.length===0?null:n.reduce((r,h)=>r+h,0)/n.length},yn=(c,t,s)=>ml(c,t,s).reduce((a,n)=>a+n,0),ze=(c,t,s,i)=>{const a=ml(c,t,s,!0,i);return a.length===0?null:Math.min(...a)},Qe=(c,t,s,i)=>{const a=ml(c,t,s,!1,i);return a.length===0?null:Math.max(...a)},Tt=(c,t,s,i)=>{const a=c.slice().pop();if(!a)return null;if(!s)return a[t];if(!i)return a[t][s];const n=a[t][i];return n?n[s]:null},Bv=c=>c.slice().pop(),ft=(c,t,s)=>{if(!t)return null;const i={};let a=t[P.AUDIO][c];a||(a=s===He.INBOUND?{...Fd}:{...Vd}),i[P.AUDIO]=a;let n=t[P.VIDEO][c];return n||(n=s===He.INBOUND?{...jd}:{...qd}),i[P.VIDEO]=n,i},Ji="exporter ",Gv="2.0",Vf=(c,t,s)=>{if(!c||c.length===0)return 0;const i=c[c.length-1];if(!i)return 0;const a=i[t][s];if(a){const n=a.total_rtt_ms_out,r=a.total_rtt_measure_out;return!r||!n?Ze(c,t,"delta_rtt_ms_out",!1,s):Number(n/r)}return null},Wv=(c,t)=>{if(!c||c.length===0)return 0;const s=c[c.length-1];if(!s)return 0;const i=s[t].total_rtt_connectivity_ms,a=s[t].total_rtt_connectivity_measure;return!a||!i?Ze(c,t,"delta_rtt_connectivity_ms"):Number(i/a)},Kv=c=>Tt(c,"network","local_candidate_type")!=="relay"?`direct/${Tt(c,"network","local_candidate_protocol")}`:`turn/${Tt(c,"network","local_candidate_relay_protocol")}`,Yv=c=>{const t=Tt(c,"network","remote_candidate_type"),s=Tt(c,"network","remote_candidate_protocol");return t!=="relay"?`direct/${s}`:`turn/${s}`};class Jv{constructor(t){this._start=null,this._end=null,this._cfg=t,this._referenceReport=null,this._reports=[],this._events=[]}start(){uu(Ji,"start() - start exporter...");const t=new Date;return this._start=t.toJSON(),t}stop(){uu(Ji,"stop() - stop exporter...");const t=new Date;return this._end=t.toJSON(),t}saveReferenceReport(t){this._referenceReport=t}getReferenceReport(){return this._referenceReport}addReport(t){this._cfg.ticket&&(Ue(Ji,`addReport() - add report to exporter at ${t.timestamp}`),this._reports.push(t))}addCustomEvent(t){this._events.push(t)}reset(){uu(Ji,"resetReports() - reset reports"),this._reports=[],this._referenceReport=null,this._start=null,this._end=null}get ticket(){Ue(Ji,"ticket() - generate ticket");const t=Tt(this._reports,"audio","total_packets_lost_in"),s=Tt(this._reports,"audio","total_packets_in"),i=Tt(this._reports,"video","total_packets_lost_in"),a=Tt(this._reports,"video","total_packets_in"),n={},r=Bv(this._reports);return r&&(Object.keys(r[P.AUDIO]).forEach(h=>{const d=r[P.AUDIO][h];if(n[d.ssrc]={type:P.AUDIO,direction:d.direction},d.direction===He.INBOUND){const _={avg:Ze(this._reports,P.AUDIO,"delta_jitter_ms_in",!1,h),min:ze(this._reports,P.AUDIO,"delta_jitter_ms_in",h),max:Qe(this._reports,P.AUDIO,"delta_jitter_ms_in",h),volatility:Je(this._reports,P.AUDIO,"delta_jitter_ms_in",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},g={avg:Ze(this._reports,P.AUDIO,"delta_kbs_in",!1,h),min:ze(this._reports,P.AUDIO,"delta_kbs_in",h),max:Qe(this._reports,P.AUDIO,"delta_kbs_in",h),volatility:Je(this._reports,P.AUDIO,"delta_kbs_in",h),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Ze(this._reports,P.AUDIO,"delta_KBytes_in",!1,h),min:ze(this._reports,P.AUDIO,"delta_KBytes_in",h),max:Qe(this._reports,P.AUDIO,"delta_KBytes_in",h),volatility:Je(this._reports,P.AUDIO,"delta_KBytes_in",h),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={emodel:{avg:Ze(this._reports,P.AUDIO,"mos_emodel_in",!1,h),min:ze(this._reports,P.AUDIO,"mos_emodel_in",h),max:Qe(this._reports,P.AUDIO,"mos_emodel_in",h),volatility:Je(this._reports,P.AUDIO,"mos_emodel_in",h)},effective:{avg:Ze(this._reports,P.AUDIO,"mos_in",!1,h),min:ze(this._reports,P.AUDIO,"mos_in",h),max:Qe(this._reports,P.AUDIO,"mos_in",h),volatility:Je(this._reports,P.AUDIO,"mos_in",h)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}},E=Tt(this._reports,P.AUDIO,"total_packets_lost_in",h),C=Tt(this._reports,P.AUDIO,"total_packets_in",h),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};n[h].jitter=_,n[h].mos=S,n[h].traffic=T,n[h].bitrate=g,n[h].loss=A}else{const _={avg:Ze(this._reports,P.AUDIO,"delta_jitter_ms_out",!1,h),min:ze(this._reports,P.AUDIO,"delta_jitter_ms_out",h),max:Qe(this._reports,P.AUDIO,"delta_jitter_ms_out",h),volatility:Je(this._reports,P.AUDIO,"delta_jitter_ms_out",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},g={avg:Ze(this._reports,P.AUDIO,"delta_kbs_out",!1,h),min:ze(this._reports,P.AUDIO,"delta_kbs_out",h),max:Qe(this._reports,P.AUDIO,"delta_kbs_out",h),volatility:Je(this._reports,P.AUDIO,"delta_kbs_out",h),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Ze(this._reports,P.AUDIO,"delta_KBytes_out",!1,h),min:ze(this._reports,P.AUDIO,"delta_KBytes_out",h),max:Qe(this._reports,P.AUDIO,"delta_KBytes_out",h),volatility:Je(this._reports,P.AUDIO,"delta_KBytes_out",h),_unit:{avg:"KB",min:"KB",max:"KB",bitrate:"kbs",volatility:"percent"}},S={avg:Vf(this._reports,P.AUDIO,h),min:ze(this._reports,P.AUDIO,"delta_rtt_ms_out",h),max:Qe(this._reports,P.AUDIO,"delta_rtt_ms_out",h),volatility:Je(this._reports,P.AUDIO,"delta_rtt_ms_out",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Tt(this._reports,P.AUDIO,"total_packets_lost_out",h),C=Tt(this._reports,P.AUDIO,"total_packets_out",h),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}},R={emodel:{avg:Ze(this._reports,P.AUDIO,"mos_emodel_out",!1,h),min:ze(this._reports,P.AUDIO,"mos_emodel_out",h),max:Qe(this._reports,P.AUDIO,"mos_emodel_out",h),volatility:Je(this._reports,P.AUDIO,"mos_emodel_out",h)},effective:{avg:Ze(this._reports,P.AUDIO,"mos_out",!1,h),min:ze(this._reports,P.AUDIO,"mos_out",h),max:Qe(this._reports,P.AUDIO,"mos_out",h),volatility:Je(this._reports,P.AUDIO,"mos_out",h)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}};n[h].jitter=_,n[h].rtt=S,n[h].traffic=T,n[h].bitrate=g,n[h].loss=A,n[h].mos=R}}),Object.keys(r[P.VIDEO]).forEach(h=>{const d=r[P.VIDEO][h];if(n[h]={type:P.VIDEO,direction:d.direction},d.direction===He.INBOUND){const _={avg:Ze(this._reports,P.VIDEO,"delta_jitter_ms_in",!1,h),min:ze(this._reports,P.VIDEO,"delta_jitter_ms_in",h),max:Qe(this._reports,P.VIDEO,"delta_jitter_ms_in",h),volatility:Je(this._reports,P.VIDEO,"delta_jitter_ms_in",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},g={avg:Ze(this._reports,P.VIDEO,"delta_kbs_in",!1,h),min:ze(this._reports,P.VIDEO,"delta_kbs_in",h),max:Qe(this._reports,P.VIDEO,"delta_kbs_in",h),volatility:Je(this._reports,P.VIDEO,"delta_kbs_in",h),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Ze(this._reports,P.VIDEO,"delta_KBytes_in",!1,h),min:ze(this._reports,P.VIDEO,"delta_KBytes_in",h),max:Qe(this._reports,P.VIDEO,"delta_KBytes_in",h),volatility:Je(this._reports,P.VIDEO,"delta_KBytes_in",h),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S=Tt(this._reports,P.VIDEO,"total_packets_lost_in",h),E=Tt(this._reports,P.VIDEO,"total_packets_in",h),C={lost:S,avg:Math.round((S/(S+E)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};n[h].jitter=_,n[h].traffic=T,n[h].bitrate=g,n[h].loss=C}else{const _={avg:Ze(this._reports,P.VIDEO,"delta_jitter_ms_out",!1,h),min:ze(this._reports,P.VIDEO,"delta_jitter_ms_out",h),max:Qe(this._reports,P.VIDEO,"delta_jitter_ms_out",h),volatility:Je(this._reports,P.VIDEO,"delta_jitter_ms_out",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},g={avg:Ze(this._reports,P.VIDEO,"delta_kbs_out",!1,h),min:ze(this._reports,P.VIDEO,"delta_kbs_out",h),max:Qe(this._reports,P.VIDEO,"delta_kbs_out",h),volatility:Je(this._reports,P.VIDEO,"delta_kbs_out",h),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Ze(this._reports,P.VIDEO,"delta_KBytes_out",!1,h),min:ze(this._reports,P.VIDEO,"delta_KBytes_out",h),max:Qe(this._reports,P.VIDEO,"delta_KBytes_out",h),volatility:Je(this._reports,P.VIDEO,"delta_KBytes_out",h),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={avg:Vf(this._reports,P.VIDEO,h),min:ze(this._reports,P.VIDEO,"delta_rtt_ms_out",h),max:Qe(this._reports,P.VIDEO,"delta_rtt_ms_out",h),volatility:Je(this._reports,P.VIDEO,"delta_rtt_ms_out",h),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Tt(this._reports,P.VIDEO,"total_packets_lost_out",h),C=Tt(this._reports,P.VIDEO,"total_packets_out",h),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};n[h].jitter=_,n[h].rtt=S,n[h].traffic=T,n[h].bitrate=g,n[h].loss=A}})),{version:Gv,configuration:{frequency:this._cfg.refreshEvery},started:this._start,ended:this._end,ua:{agent:navigator.userAgent,pname:this._cfg.pname,user_id:this._cfg.uid},call:{call_id:this._cfg.cid,events:this._events},details:{count:this._reports.length,reports:this._cfg.record?this._reports:[],reference:this._referenceReport||null},ssrc:n,data:{rtt:{avg:Wv(this._reports,"data"),min:ze(this._reports,"data","delta_rtt_connectivity_ms"),max:Qe(this._reports,"data","delta_rtt_connectivity_ms"),volatility:Je(this._reports,"data","delta_rtt_connectivity_ms"),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},packetsLost:{audio:{in:{avg:Math.round((t/(t+s)*100||0)*100)/100}},video:{in:{avg:Math.round((i/(i+a)*100||0)*100)/100}},unit:{avg:"percent"}},bitrate:{in:{avg:Ze(this._reports,"data","delta_kbs_in"),min:ze(this._reports,"data","delta_kbs_in"),max:Qe(this._reports,"data","delta_kbs_in"),volatility:Je(this._reports,"data","delta_kbs_in")},out:{avg:Ze(this._reports,"data","delta_kbs_out"),min:ze(this._reports,"data","delta_kbs_out"),max:Qe(this._reports,"data","delta_kbs_out"),volatility:Je(this._reports,"data","delta_kbs_out")},unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},traffic:{in:{avg:Ze(this._reports,"data","delta_KBytes_in"),min:ze(this._reports,"data","delta_KBytes_in"),max:Qe(this._reports,"data","delta_KBytes_in"),volatility:Je(this._reports,"data","delta_KBytes_in")},out:{avg:Ze(this._reports,"data","delta_KBytes_out"),min:ze(this._reports,"data","delta_KBytes_out"),max:Qe(this._reports,"data","delta_KBytes_out"),volatility:Je(this._reports,"data","delta_KBytes_out")},unit:{avg:"KBytes",min:"KBytes",max:"KBytes",volatility:"percent"}},network:{localConnection:Kv(this._reports),remoteConnection:Yv(this._reports)}}}}updateConfig(t){this._cfg=t}getLastReport(){return this._reports.slice().pop()||null}getBeforeLastReport(){const t=this._reports.slice();return t.pop(),t.pop()||null}getReportsNumber(){return this._reports.length}}const js="extractor ",jf=(c,t,s,i)=>{let a=!1;const n=i[t].total_rtt_ms_out,r=i[t].total_rtt_measure_out,h=s?s[t].total_rtt_ms_out:0,d=s?s[t].total_rtt_measure_out:0,_={rtt:null,totalRTT:n,totalRTTMeasurements:r};if(c[K.TIMESTAMP]===i[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,K.ROUND_TRIP_TIME)||Object.prototype.hasOwnProperty.call(c,K.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS)&&(a=!0,Number(c[K.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])===0||Number(c[K.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d===r))return _;const g=1e3*Number(c[K.ROUND_TRIP_TIME]);let T=n+g,S=r+1;return a&&(T=1e3*Number(c[K.TOTAL_ROUND_TRIP_TIME])-h,S=Number(c[K.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d),{rtt:g,totalRTT:T,totalRTTMeasurements:S}},zv=(c,t,s,i)=>{if(!Object.prototype.hasOwnProperty.call(c,K.CURRENT_ROUND_TRIP_TIME))return{rtt:null,totalRTT:i[t].total_rtt_connectivity_ms,totalRTTMeasurements:i[t].total_rtt_connectivity_measure};const a=1e3*Number(c[K.CURRENT_ROUND_TRIP_TIME]);let n=i[t].total_rtt_connectivity_ms+a,r=i[t].total_rtt_connectivity_measure+1;return Object.prototype.hasOwnProperty.call(c,K.TOTAL_ROUND_TRIP_TIME)&&(n=1e3*Number(c[K.TOTAL_ROUND_TRIP_TIME])-(s?s[t].total_rtt_connectivity_ms:0)),Object.prototype.hasOwnProperty.call(c,K.RESPONSES_RECEIVED)&&(r=Number(c[K.RESPONSES_RECEIVED])-(s?s[t].total_rtt_connectivity_measure:0)),{rtt:a,totalRTT:n,totalRTTMeasurements:r}},_o=(c,t,s)=>c[K.TIMESTAMP]===s[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,K.JITTER)?null:1e3*(Number(c[K.JITTER])||0),Qv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,K.FRAMES_DECODED)||!Object.prototype.hasOwnProperty.call(c,K.TOTAL_DECODE_TIME))return{delta_ms_decode_frame:t[P.VIDEO].delta_ms_decode_frame_in,frames_decoded:t[P.VIDEO].total_frames_decoded_in,total_decode_time:t[P.VIDEO].total_time_decoded_in};const s=c[K.FRAMES_DECODED],i=c[K.TOTAL_DECODE_TIME],a=i-t[P.VIDEO].total_time_decoded_in,n=s-t[P.VIDEO].total_frames_decoded_in;return{delta_ms_decode_frame:n>0?a*1e3/n:0,frames_decoded:s,total_decode_time:i}},Xv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,K.FRAMES_ENCODED)||!Object.prototype.hasOwnProperty.call(c,K.TOTAL_ENCODE_TIME))return{delta_ms_encode_frame:t[P.VIDEO].delta_ms_encode_frame_out,frames_encoded:t[P.VIDEO].total_frames_encoded_out,total_encode_time:t[P.VIDEO].total_time_encoded_out};const s=c[K.FRAMES_ENCODED],i=c[K.TOTAL_ENCODE_TIME],a=i-t[P.VIDEO].total_time_encoded_out,n=s-t[P.VIDEO].total_frames_encoded_out;return{delta_ms_encode_frame:n>0&&a?a*1e3/n:0,frames_encoded:s,total_encode_time:i}},qf=(c,t,s,i)=>{if(!Object.prototype.hasOwnProperty.call(c,K.PACKETS_SENT)||!Object.prototype.hasOwnProperty.call(c,K.BYTES_SENT))return{packetsSent:s[t].total_packets_out,packetsLost:s[t].total_packets_lost_out,bytesSent:s[t].total_KBytes_out};const a=Number(c[K.PACKETS_SENT])||0-(i?i[t].total_packets_out:0),n=a-s[t].total_packets_out,r=Number(c[K.BYTES_SENT])/1024-(i?i[t].total_KBytes_out:0),h=r-s[t].total_KBytes_out,d=c[K.TIMESTAMP]||Date.now(),_=i?i.timestamp:null;let g=s.timestamp;!g&&_&&(g=_);const T=g?d-g:0,S=T>0?h*.008*1024/T*1e3:0;return{packetsSent:a,deltaPacketsSent:n,KBytesSent:r,deltaKBytesSent:h,kbsSent:S}},Bf=(c,t,s,i)=>{let a=s[t].total_packets_lost_out,n=0,r=0;return Object.prototype.hasOwnProperty.call(c,K.PACKETS_LOST)&&(a=Number(c[K.PACKETS_LOST])||0-(i?i[t].total_packets_lost_out:0),n=a-s[t].total_packets_lost_out),Object.prototype.hasOwnProperty.call(c,K.FRACTION_LOST)&&(r=Number(100*c[K.FRACTION_LOST])),{packetsLost:a,deltaPacketsLost:n,fractionLost:r}},Gf=(c,t,s,i)=>{if(!Object.prototype.hasOwnProperty.call(c,K.PACKETS_RECEIVED)||!Object.prototype.hasOwnProperty.call(c,K.PACKETS_LOST)||!Object.prototype.hasOwnProperty.call(c,K.BYTES_RECEIVED))return{percent_packets_lost:s[t].percent_packets_lost_in,packetsReceived:s[t].total_packets_in,packetsLost:s[t].total_packets_lost_in,bytesReceived:s[t].total_KBytes_in};const a=Number(c[K.PACKETS_RECEIVED])||0-(i?i[t].total_packets_in:0),n=Number(c[K.PACKETS_LOST])||0-(i?i[t].total_packets_lost_in:0),r=n-s[t].total_packets_lost_in,h=a-s[t].total_packets_in,d=a!==s[t].total_packets_in?r*100/(r+h):0,_=Number(c[K.BYTES_RECEIVED])/1024-(i?i[t].total_KBytes_in:0),g=_-s[t].total_KBytes_in,T=c[K.TIMESTAMP]||Date.now(),S=i?i.timestamp:null;let E=s.timestamp;!E&&S&&(E=S);const C=E?T-E:0,A=C>0?g*.008*1024/C*1e3:0;return{percentPacketsLost:d,packetsReceived:a,deltaPacketsReceived:h,packetsLost:n,deltaPacketsLost:r,KBytesReceived:_,deltaKBytesReceived:g,kbsReceived:A}},Zv=c=>c[K.CANDIDATE_TYPE]!=="relay"?"":c[K.RELAY_PROTOCOL]||"",eS=c=>{if(!Object.prototype.hasOwnProperty.call(c,K.NETWORK_TYPE))return Yi.WIFI;switch(c[K.NETWORK_TYPE]){case cu.ETHERNET:return Yi.ETHERNET;case cu.CELLULAR_4G:return Yi.CELLULAR_4G;case cu.WIFI:return Yi.WIFI;default:return Yi.CELLULAR}},Wf=c=>!Object.prototype.hasOwnProperty.call(c,K.FRAME_HEIGHT)||!Object.prototype.hasOwnProperty.call(c,K.FRAME_WIDTH)?{width:null,height:null,framerate:null}:{width:c[K.FRAME_WIDTH]||null,height:c[K.FRAME_HEIGHT]||null,framerate:c[K.FRAMES_PER_SECOND]},tS=c=>{const t=Object.prototype.hasOwnProperty.call(c,K.QUALITY_LIMITATION_REASON)?c[K.QUALITY_LIMITATION_REASON]:null,s=Object.prototype.hasOwnProperty.call(c,K.QUALITY_LIMITATION_RESOLUTION_CHANGES)?c[K.QUALITY_LIMITATION_RESOLUTION_CHANGES]:null,i=Object.prototype.hasOwnProperty.call(c,K.QUALITY_LIMITATION_DURATIONS)?c[K.QUALITY_LIMITATION_DURATIONS]:null;return i&&Object.keys(i).forEach(a=>{i[a]>1e3&&(i[a]=Number(i[a]/1e3))}),{reason:t,durations:i,resolutionChanges:s}},sS=(c,t,s)=>{if(!Object.prototype.hasOwnProperty.call(c,K.PLI)||!Object.prototype.hasOwnProperty.call(c,K.NACK))return{pliCount:t.total_pli_sent_in,nackCount:t.total_nack_sent_in,deltaPliCount:0,deltaNackCount:0};const i=(c[K.PLI]||0)-(s?s[P.VIDEO].total_pli_sent_in:0),a=(c[K.NACK]||0)-(s?s[P.VIDEO].total_nack_sent_in:0);return{pliCount:i,nackCount:a,deltaPliCount:i-t[P.VIDEO].total_pli_sent_in,deltaNackCount:a-t[P.VIDEO].total_nack_sent_in}},nS=(c,t,s)=>{if(!Object.prototype.hasOwnProperty.call(c,K.PLI)||!Object.prototype.hasOwnProperty.call(c,K.NACK))return{pliCount:t.total_pli_received_out,nackCount:t.total_nack_received_out,deltaPliCount:0,deltaNackCount:0};const i=(c[K.PLI]||0)-(s?s[P.VIDEO].total_pli_received_out:0),a=(c[K.NACK]||0)-(s?s[P.VIDEO].total_nack_received_out:0);return{pliCount:i,nackCount:a,deltaPliCount:i-t[P.VIDEO].total_pli_received_out,deltaNackCount:a-t[P.VIDEO].total_nack_received_out}},rS=c=>({channels:c[K.CHANNELS]||null,clock_rate:c[K.CLOCK_RATE]||null,mime_type:c[K.MIME_TYPE]||null,sdp_fmtp_line:c[K.SDP_FMTP_LINE]||null}),iS=c=>({clock_rate:c[K.CLOCK_RATE]||null,mime_type:c[K.MIME_TYPE]||null}),lS=(c,t,s)=>{const i=(c[K.BYTES_RECEIVED]||0)/1024-(s?s.data.total_KBytes_in:0),a=(c[K.BYTES_SENT]||0)/1024-(s?s.data.total_KBytes_out:0),n=c[K.TIMESTAMP]||Date.now(),r=i-t.data.total_KBytes_in,h=a-t.data.total_KBytes_out,d=s?s.timestamp:null;let _=t.timestamp;!_&&d&&(_=d);const g=_?n-_:0,T=g>0?r*.008*1024/g*1e3:0,S=g>0?h*.008*1024/g*1e3:0;return{total_KBytes_received:i,total_KBytes_sent:a,delta_KBytes_received:r,delta_KBytes_sent:h,kbs_speed_received:T,kbs_speed_sent:S}},oS=c=>{const t=c[K.AVAILABLE_INCOMING_BITRATE]/1024||0,s=c[K.AVAILABLE_OUTGOING_BITRATE]/1024||0;return{kbs_incoming_bandwidth:t,kbs_outgoing_bandwidth:s}},aS=(c,t,s,i)=>{if(!c)return[];switch(c[K.TYPE]){case Qt.CANDIDATE_PAIR:let a=!1;if(c[K.NOMINATED]&&c[K.STATE]===P.SUCCEEDED&&(a=!0,Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c),K.SELECTED in c&&!c[K.SELECTED]&&(a=!1)),a){const r=c[K.LOCAL_CANDIDATE_ID],h=c[K.REMOTE_CANDIDATE_ID],d=lS(c,t,i),_=oS(c),g=zv(c,"data",i,t);return[{type:ne.NETWORK,value:{local_candidate_id:r}},{type:ne.NETWORK,value:{remote_candidate_id:h}},{type:ne.DATA,value:{total_KBytes_in:d.total_KBytes_received}},{type:ne.DATA,value:{total_KBytes_out:d.total_KBytes_sent}},{type:ne.DATA,value:{delta_KBytes_in:d.delta_KBytes_received}},{type:ne.DATA,value:{delta_KBytes_out:d.delta_KBytes_sent}},{type:ne.DATA,value:{delta_kbs_in:d.kbs_speed_received}},{type:ne.DATA,value:{delta_kbs_out:d.kbs_speed_sent}},{type:ne.DATA,value:{delta_kbs_bandwidth_in:_.kbs_incoming_bandwidth}},{type:ne.DATA,value:{delta_kbs_bandwidth_out:_.kbs_outgoing_bandwidth}},{type:ne.DATA,value:{delta_rtt_connectivity_ms:g.rtt}},{type:ne.DATA,value:{total_rtt_connectivity_ms:g.totalRTT}},{type:ne.DATA,value:{total_rtt_connectivity_measure:g.totalRTTMeasurements}}]}break;case Qt.LOCAL_CANDIDATE:if(c[K.ID]===t.network.local_candidate_id)return[{type:ne.NETWORK,value:{infrastructure:eS(c)}},{type:ne.NETWORK,value:{local_candidate_type:c[K.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{local_candidate_protocol:c[K.PROTOCOL]||""}},{type:ne.NETWORK,value:{local_candidate_relay_protocol:Zv(c)}}];break;case Qt.REMOTE_CANDIDATE:if(c[K.ID]===t.network.remote_candidate_id)return[{type:ne.NETWORK,value:{remote_candidate_type:c[K.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{remote_candidate_protocol:c[K.PROTOCOL]||""}}];break;case Qt.INBOUND_RTP:{Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);const r=c[K.SSRC],h=ft(r,t,He.INBOUND);h&&(h.timestamp=t.timestamp);const d=ft(r,i,He.INBOUND);if(d&&(d.timestamp=i.timestamp),c[K.MEDIA_TYPE]===P.AUDIO){const _=Gf(c,P.AUDIO,h,d),g=_o(c,P.AUDIO,h),T=c[K.CODEC_ID]||"";return[{ssrc:r,type:ne.AUDIO,value:{codec_id_in:T}},{ssrc:r,type:ne.AUDIO,value:{total_packets_in:_.packetsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_in:_.deltaPacketsReceived}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_in:_.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_in:_.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_in:_.percentPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_in:_.KBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_in:_.deltaKBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_in:_.kbsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_in:g}}]}if(c[K.MEDIA_TYPE]===P.VIDEO){const _=Qv(c,h),g=Gf(c,P.VIDEO,h,d),T=_o(c,P.VIDEO,h),S=c[K.DECODER_IMPLEMENTATION]||null,E=c[K.CODEC_ID]||null,C=Wf(c),A=sS(c,h,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_in:E}},{ssrc:r,type:ne.VIDEO,value:{total_packets_in:g.packetsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_in:g.deltaPacketsReceived}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_in:g.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_in:g.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_in:g.percentPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_in:g.KBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_in:g.deltaKBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_in:g.kbsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_in:T}},{ssrc:r,type:ne.VIDEO,value:{decoder_in:S}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_decode_frame_in:_.delta_ms_decode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_decoded_in:_.frames_decoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_decoded_in:_.total_decode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_sent_in:A.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_sent_in:A.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_sent_in:A.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_sent_in:A.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_in:C}}]}break}case Qt.OUTBOUND_RTP:{Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);const r=c[K.SSRC],h=ft(r,t,He.OUTBOUND);h&&(h.timestamp=t.timestamp);const d=ft(r,i,He.OUTBOUND);if(d&&(d.timestamp=i.timestamp),c[K.MEDIA_TYPE]===P.AUDIO){const _=c[K.CODEC_ID]||null,g=qf(c,P.AUDIO,h,d);return[{ssrc:r,type:ne.AUDIO,value:{codec_id_out:_}},{ssrc:r,type:ne.AUDIO,value:{total_packets_out:g.packetsSent}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_out:g.deltaPacketsSent}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_out:g.KBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_out:g.deltaKBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_out:g.kbsSent}}]}if(c[K.MEDIA_TYPE]===P.VIDEO){const _=c[K.ENCODER_IMPLEMENTATION]||null,g=c[K.CODEC_ID]||null,T=Xv(c,h),S=Wf(c),E=tS(c),C=nS(c,h,d),A=qf(c,P.VIDEO,h,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_out:g}},{ssrc:r,type:ne.VIDEO,value:{total_packets_out:A.packetsSent}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_out:A.deltaPacketsSent}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_out:A.KBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_out:A.deltaKBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_out:A.kbsSent}},{ssrc:r,type:ne.VIDEO,value:{encoder_out:_}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_encode_frame_out:T.delta_ms_encode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_encoded_out:T.frames_encoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_encoded_out:T.total_encode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_received_out:C.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_received_out:C.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_received_out:C.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_received_out:C.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_out:S}},{ssrc:r,type:ne.VIDEO,value:{limitation_out:E}}]}break}case Qt.MEDIA_SOURCE:{Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);break}case Qt.TRACK:{Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);break}case Qt.CODEC:const n=[];return Object.keys(t[P.AUDIO]).forEach(r=>{const h=t[P.AUDIO][r];if(h.codec_id_in===c[K.ID]||h.codec_id_out===c[K.ID]){Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);const d=rS(c);c[K.ID]===h.codec_id_in?n.push({ssrc:h.ssrc,type:ne.AUDIO,value:{codec_in:d}}):n.push({ssrc:h.ssrc,type:ne.AUDIO,value:{codec_out:d}})}}),Object.keys(t[P.VIDEO]).forEach(r=>{const h=t[P.VIDEO][r];if(h.codec_id_in===c[K.ID]||h.codec_id_out===c[K.ID]){Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);const d=iS(c);c[K.ID]===h.codec_id_in?n.push({ssrc:h.ssrc,type:ne.VIDEO,value:{codec_in:d}}):n.push({ssrc:h.ssrc,type:ne.VIDEO,value:{codec_out:d}})}}),n;case Qt.REMOTE_INBOUND_RTP:{Ue(js,`analyze() - got stats ${c[K.TYPE]} for ${s}`,c);const r=c[K.SSRC],h=ft(r,t,He.OUTBOUND),d=ft(r,i,He.OUTBOUND);if(c[K.KIND]===P.AUDIO){const _=jf(c,P.AUDIO,d,h),g=_o(c,P.AUDIO,h),T=Bf(c,P.AUDIO,h,d);return[{ssrc:r,type:ne.AUDIO,value:{delta_rtt_ms_out:_.rtt}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_ms_out:_.totalRTT}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_measure_out:_.totalRTTMeasurements}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_out:g}},{ssrc:r,type:ne.AUDIO,value:{timestamp_out:c[K.TIMESTAMP]}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_out:T.fractionLost}}]}if(c[K.KIND]===P.VIDEO){const _=jf(c,P.VIDEO,d,h),g=_o(c,P.VIDEO,h),T=Bf(c,P.VIDEO,h,d);return[{ssrc:r,type:ne.VIDEO,value:{delta_rtt_ms_out:_.rtt}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_ms_out:_.totalRTT}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_measure_out:_.totalRTTMeasurements}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_out:g}},{ssrc:r,type:ne.VIDEO,value:{timestamp_out:c[K.TIMESTAMP]}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_out:T.fractionLost}}]}break}}return[]},zo=c=>c<0?1:c>100?4.5:1+.035*c+7/1e6*c*(c-60)*(100-c),uS=(c,t=P.AUDIO,s,i,a)=>{const n=ft(a,c,He.INBOUND),r=ft(a,s,He.INBOUND),h=ft(a,i,He.INBOUND),d=[],_=[],g=n[t].percent_packets_lost_in,T=n[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=h&&h[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=s&&s.data.delta_rtt_connectivity_ms||null,R=i&&i.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&_.push(T),s&&S&&_.push(S),i&&E&&_.push(E);const F=d.length>0?Ws(d):100,I=_.length>0?Ws(_):10,ie=93.2-g,N=.18*ie*ie-27.9*ie+1126.62,$=(F+I)/2,ve=$-177.3<0?0:1,_e=.024*$+.11*($-177.3)*ve,U=N-_e;return zo(U)},cS=(c,t=P.AUDIO,s,i,a)=>{const n=ft(a,c,He.OUTBOUND),r=ft(a,s,He.OUTBOUND),h=ft(a,i,He.OUTBOUND),d=[],_=[],g=n[t].percent_packets_lost_out,T=n[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=h&&h[t].delta_rtt_ms_out||null,C=n[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=h&&h[t].delta_jitter_ms_out||null,F=c.data.delta_rtt_connectivity_ms,I=s&&s.data.delta_rtt_connectivity_ms||null,ie=i&&i.data.delta_rtt_connectivity_ms||null;T?d.push(T):F&&d.push(F),S?d.push(S):I&&d.push(I),E?d.push(E):ie&&d.push(ie),C&&_.push(C),s&&A&&_.push(A),i&&R&&_.push(R);const N=d.length>0?Ws(d):100,$=_.length>0?Ws(_):10,ve=93.2-g,_e=.18*ve*ve-27.9*ve+1126.62,U=(N+$)/2,x=U-177.3<0?0:1,q=.024*U+.11*(U-177.3)*x,j=_e-q;return zo(j)},fS=(c,t=P.AUDIO,s,i,a)=>{const n=ft(a,c,He.INBOUND),r=ft(a,s,He.INBOUND),h=ft(a,i,He.INBOUND),d=[],_=[],g=n[t].percent_packets_lost_in/100,T=n[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=h&&h[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=s&&s.data.delta_rtt_connectivity_ms||null,R=i&&i.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&_.push(T),r&&S&&_.push(S),h&&E&&_.push(E);const F=d.length>0?Ws(d):100,I=_.length>0?Ws(_):10,ie=0,N=19.8,$=29.7,ve=30,_e=(F+I)/2+ve,U=_e-177.3<0?0:1,x=.024*_e+.11*(_e-177.3)*U,j=93.2-(ie+N*Math.log(1+$*g)+x);return zo(j)},dS=(c,t=P.AUDIO,s,i,a)=>{const n=ft(a,c,He.OUTBOUND),r=ft(a,s,He.OUTBOUND),h=ft(a,i,He.OUTBOUND),d=[],_=[],g=n[t].percent_packets_lost_out/100,T=n[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=h&&h[t].delta_rtt_ms_out||null,C=n[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=h&&h[t].delta_jitter_ms_out||null,F=c.data.delta_rtt_connectivity_ms,I=s&&s.data.delta_rtt_connectivity_ms||null,ie=i&&i.data.delta_rtt_connectivity_ms||null;T?d.push(T):F&&d.push(F),S?d.push(S):I&&d.push(I),E?d.push(E):ie&&d.push(ie),C&&_.push(C),r&&A&&_.push(A),h&&R&&_.push(R);const N=d.length>0?Ws(d):100,$=_.length>0?Ws(_):10,ve=0,_e=19.8,U=29.7,x=30,q=(N+$)/2+x,j=q-177.3<0?0:1,Y=.024*q+.11*(q-177.3)*j,Q=93.2-(ve+_e*Math.log(1+U*g)+Y);return zo(Q)};class hS{constructor(t,s){this._callbacks={onreport:null,onticket:null},this._id=qv(),this._moduleName=this._id,this._probeId=s,this._config=t,this._exporter=new Jv(t),this._state=Ts.IDLE,this.registerToPCEvents(),Rn(this._moduleName,`new collector created for probe ${this._probeId}`)}analyze(t,s,i,a){const n=(d,_)=>d===P.AUDIO?_===Qt.INBOUND_RTP?{...Fd}:{...Vd}:_===Qt.INBOUND_RTP?{...jd}:{...qd},r=$v(s);r.pname=this._config.pname,r.call_id=this._config.cid,r.user_id=this._config.uid,r.count=s?s.count+1:1;let h=null;return t.forEach(d=>{!h&&d.timestamp&&(h=d.timestamp),aS(d,r,r.pname,a).forEach(g=>{if(g.value&&g.type)if(g.ssrc){let T=r[g.type][g.ssrc];T||(T=n(g.type,d.type),T.ssrc=g.ssrc,r[g.type][g.ssrc]=T),Object.keys(g.value).forEach(S=>{T[S]=g.value[S]})}else Object.keys(g.value).forEach(T=>{r[g.type][T]=g.value[T]})})}),r.timestamp=h,Object.keys(r[P.AUDIO]).forEach(d=>{const _=r[P.AUDIO][d];_.direction===He.INBOUND?(_.mos_emodel_in=uS(r,P.AUDIO,s,i,_.ssrc),_.mos_in=fS(r,P.AUDIO,s,i,_.ssrc)):(_.mos_emodel_out=cS(r,P.AUDIO,s,i,_.ssrc),_.mos_out=dS(r,P.AUDIO,s,i,_.ssrc))}),r}async takeReferenceStats(){return new Promise((t,s)=>{const i=Date.now();setTimeout(async()=>{try{const a=Date.now()-i,n=Date.now(),r=await this._config.pc.getStats(),h=this.analyze(r,null,null,null),d=Date.now();h.experimental.time_to_measure_ms=d-n,h.experimental.time_to_wait_ms=a,this._exporter.saveReferenceReport(h),Ue(this._moduleName,`got reference report for probe ${this._probeId}`),t()}catch(a){s(a)}},this._config.startAfter)})}async collectStats(){try{if(this._state!==Ts.RUNNING||!this._config.pc)return Ue(this._moduleName,`report discarded (too late) for probe ${this._probeId}`),null;const t=Date.now(),s=await this._config.pc.getStats(),i=this.analyze(s,this._exporter.getLastReport(),this._exporter.getBeforeLastReport(),this._exporter.getReferenceReport()),a=Date.now();return i.experimental.time_to_measure_ms=a-t,this._exporter.addReport(i),Ue(this._moduleName,`got report for probe ${this._probeId}#${this._exporter.getReportsNumber()+1}`),this.fireOnReport(i),i}catch(t){return hr(this._moduleName,`got error ${t}`),null}}async start(){Ue(this._moduleName,"starting"),this.state=Ts.RUNNING,this._startedTime=this._exporter.start(),Ue(this._moduleName,"started")}async mute(){this.state=Ts.MUTED,Ue(this._moduleName,"muted")}async unmute(){this.state=Ts.RUNNING,Ue(this._moduleName,"unmuted")}async stop(t){if(Ue(this._moduleName,`stopping${t?" by watchdog":""}...`),this._stoppedTime=this._exporter.stop(),this.state=Ts.IDLE,this._config.ticket){const{ticket:s}=this._exporter;this.fireOnTicket(s)}this._exporter.reset(),Ue(this._moduleName,"stopped")}registerCallback(t,s,i){t in this._callbacks?(this._callbacks[t]={callback:s,context:i},Ue(this._moduleName,`registered callback '${t}'`)):hr(this._moduleName,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):hr(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReport(t){this._callbacks.onreport&&xu(this._callbacks.onreport.callback,this._callbacks.onreport.context,t)}fireOnTicket(t){this._callbacks.onticket&&xu(this._callbacks.onticket.callback,this._callbacks.onticket.context,t)}updateConfig(t){this._config=t,this._exporter.updateConfig(t)}get state(){return this._state}set state(t){this._state=t,Ue(this._moduleName,`state changed to ${t}`)}addCustomEvent(t,s,i,a){this._exporter.addCustomEvent({at:typeof t=="object"?t.toJSON():t,category:s,name:i,description:a})}async registerToPCEvents(){const{pc:t}=this._config;if(navigator.mediaDevices.ondevicechange=async()=>{try{const s=await navigator.mediaDevices.enumerateDevices();this.addCustomEvent(new Date().toJSON(),"device",`${s.length} devices found`,"Media Devices state")}catch{hr(this._moduleName,"can't get devices")}},t){t.oniceconnectionstatechange=()=>{const i=t.iceConnectionState;i===Ki.CONNECTED||i===Ki.COMPLETED?this.addCustomEvent(new Date().toJSON(),"call",i,"ICE connection state"):i===Ki.DISCONNECTED||i===Ki.FAILED?this.addCustomEvent(new Date().toJSON(),"call",i,"ICE connection state"):i===Ki.CLOSED&&this.addCustomEvent(new Date().toJSON(),"call","ended","ICE connection state")},t.onicegatheringstatechange=()=>{const i=t.iceGatheringState;this.addCustomEvent(new Date().toJSON(),"call",i,"ICE gathering state")},t.ontrack=i=>{this.addCustomEvent(new Date().toJSON(),"call",`${i.track.kind}track`,"MediaStreamTrack received")},t.onnegotiationneeded=()=>{this.addCustomEvent(new Date().toJSON(),"call","negotiation","Media changed")};const s=t.getReceivers();if(s&&s.length>0){const i=s[0],{transport:a}=i;if(a){const{iceTransport:n}=a;n&&(n.onselectedcandidatepairchange=()=>{this.addCustomEvent(new Date().toJSON(),"call","transport","Candidates Pair changed")})}}}}}class _S{constructor(t){this._id=t.pname&&t.pname.substr(0,12).padEnd(12," ")||jv(),this._moduleName=this._id,Rn(this._moduleName,"probe created"),this._config=t,this._collector=new hS(this._config,this._id)}set onreport(t){t?this._collector.registerCallback("onreport",t):this._collector.unregisterCallback("onreport")}set onticket(t){t?this._collector.registerCallback("onticket",t):this._collector.unregisterCallback("onticket")}get id(){return this._id}get pname(){return this._config.pname}get cid(){return this._config.cid}get uid(){return this._config.uid}get state(){return this._collector.state}set state(t){this._collector.state=t}addCustomEvent(t,s,i,a=new Date().toJSON()){this._collector.addCustomEvent(a,s,t,i)}get isRunning(){return this._collector.state===Ts.RUNNING}get isIdle(){return this._collector.state===Ts.IDLE}updateUserId(t){this._config.uid=t,this._collector.updateConfig(this._config)}updateCallId(t){this._config.cid=t,this._collector.updateConfig(this._config)}start(){if(!this.isIdle){No(this._moduleName,"probe is already running");return}this._collector.start()}stop(t=!1){this.isRunning&&this._collector.stop(t)}async takeReferenceStats(){return this._collector.takeReferenceStats()}async collectStats(){return this._collector.collectStats()}}const It="engine ";class pS{constructor(t){this._config=t,this._probes=[],this._startedTime=null,this._callbacks={onresult:null},Rn(It,`configured for probing every ${this._config.refreshEvery}ms`),Rn(It,`configured for starting after ${this._config.startAfter}ms`),Rn(It,`${!this._config.stopAfter||this._config.stopAfter!==-1?`configured for stopped after ${this._config.stopAfter}ms`:"configured for never stopped"}`),Ue(It,"engine initialized")}get probes(){return this._probes}get isRunning(){return this._probes.some(t=>t.isRunning)}get isIdle(){return this._probes.every(t=>t.isIdle)}addNewProbe(t,s){if(!t)throw new Error("undefined peer connection");const i=Fv(t,s,this._config),a=new _S(i);return this._probes.push(a),Ue(It,`${this._probes.length} probes registered`),a}removeExistingProbe(t){if(!t)throw new Error("undefined probe");t.state===Ts.RUNNING&&t.stop(),this._probes=this._probes.filter(s=>t.id!==s.id)}async start(){const t=()=>{this._probes.forEach(n=>n.start())},s=async()=>Promise.all(this._probes.map(n=>n.takeReferenceStats())),i=()=>this.isIdle?!1:!this._config.stopAfter||this._config.stopAfter<0?!0:Date.now()<this._startedTime+this._config.stopAfter,a=async()=>{const n=Lv(),r=this._probes.filter(h=>h.isRunning);for(const h of r){const d=await h.collectStats();d&&n.probes.push(d),Ue(It,`got probe ${h.id}`),await Ff(0)}return n.delta_time_to_measure_probes_ms=yn(n.probes,"experimental","time_to_measure_ms"),n.delta_KBytes_in=yn(n.probes,"data","delta_KBytes_in"),n.delta_KBytes_out=yn(n.probes,"data","delta_KBytes_out"),n.delta_kbs_in=yn(n.probes,"data","delta_kbs_in"),n.delta_kbs_out=yn(n.probes,"data","delta_kbs_out"),n.total_time_decoded_in=yn(n.probes,"video","total_time_decoded_in"),n.total_time_encoded_out=yn(n.probes,"video","total_time_encoded_out"),n};for(Ue(It,"starting to collect"),t(),Ue(It,"generating reference reports..."),await s(),Ue(It,"reference reports generated"),this._startedTime=Date.now();i();)if(Ue(It,`wait ${this._config.refreshEvery}ms before collecting`),await Ff(this._config.refreshEvery),i()){Ue(It,"collecting...");const n=Date.now(),r=await a(),h=Date.now();r.delta_time_consumed_to_measure_ms=h-n,this.fireOnReports(r),Ue(It,"collected")}Ue(It,"reaching end of the collecting period..."),this.isRunning&&setTimeout(()=>{this.stop()},0)}stop(t){const s=i=>{this._probes.forEach(a=>{a.stop(i)})};Rn(It,"stop collecting"),s(t)}registerCallback(t,s,i){t in this._callbacks?(this._callbacks[t]={callback:s,context:i},Ue(It,`registered callback '${t}'`)):hr(It,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):hr(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReports(t){this._callbacks.onresult&&t.probes.length>0&&xu(this._callbacks.onresult.callback,this._callbacks.onresult.context,t)}}const mS="interface ";class gS{constructor(t){this._config=Vv(t),Rn(mS,`welcome to ${this._config.name} version ${this._config.version}`),Ov(this._config.verbose||!1),this._engine=new pS(this._config)}setupLogLevel(t){Dv(t)}get version(){return this._config.version}get name(){return this._config.name}get probes(){return this._engine.probes}createProbe(t,s){return this._engine.addNewProbe(t,s)}startAllProbes(){this._engine.start()}stopAllProbes(){this._engine.stop()}get running(){return this._engine.isRunning}get idle(){return this._engine.isIdle}removeProbe(t){this._engine.removeExistingProbe(t)}set onresult(t){t?this._engine.registerCallback("onresult",t):this._engine.unregisterCallback("onresult")}}function TS(c,t){return Object.keys(c).filter(s=>t.includes(s)).reduce((s,i)=>{const a=i;return{...s,[a]:c[a]}},{})}const vS=["mos_in","codec_in","delta_KBytes_in","delta_kbs_in","delta_jitter_ms_in","delta_packets_lost_in"],SS={positiveSpeechThreshold:.6,negativeSpeechThreshold:.3,preSpeechPadMs:150,redemptionMs:1500,minSpeechMs:50};class ES{constructor(t){this.intervals={},this.analysers={},this.emitInterval=t.emitInterval||200,this.onChangeFunction=t.onChangeFunction}async start(t,s,i){s&&s.getTracks().length&&await this.beginCalculation(t,s,i)}stop(t){this.clearVolumeInterval(t),this.analysers[t]&&typeof this.analysers[t].disconnect=="function"&&(this.analysers[t].disconnect(),delete this.analysers[t])}clearVolumeInterval(t){this.intervals[t]&&(clearInterval(this.intervals[t]),delete this.intervals[t])}clearAllIntervals(){Object.keys(this.intervals).forEach(t=>{this.stop(t)}),this.intervals={},this.analysers={}}async beginCalculation(t,s,i){this.clearVolumeInterval(i);const a=t.createAnalyser(),n=t.createMediaStreamSource(s);a.smoothingTimeConstant=.8,a.fftSize=1024,n.connect(a),this.analysers[i]=a,this.intervals[i]=setInterval(()=>{const r=new Uint8Array(a.frequencyBinCount);a.getByteFrequencyData(r);let h=0;const d=r.length;for(let g=0;g<d;g++)h+=r[g];const _=h/d;this.onChangeFunction(i,_)},this.emitInterval)}}class yS{constructor(){this.resumePromise=null,this.context=new AudioContext,this.setupErrorHandling()}setupErrorHandling(){!this.context||typeof this.context.addEventListener!="function"||this.context.addEventListener("statechange",()=>{(this.context.state==="interrupted"||this.context.state==="closed")&&console.warn(`[ManagedAudioContext] AudioContext state changed to: ${this.context.state}`)})}createNewContext(){return console.log("[ManagedAudioContext] Creating new AudioContext instance"),this.context=new AudioContext,this.setupErrorHandling(),this.context}async getContext(){if(this.context.state==="closed")return console.warn("[ManagedAudioContext] AudioContext is closed, creating new instance"),this.createNewContext();if(this.context.state==="interrupted"){console.warn("[ManagedAudioContext] AudioContext is interrupted, attempting to resume");try{this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{console.error("[ManagedAudioContext] Failed to resume interrupted context:",t),this.resumePromise=null,this.createNewContext()})),await this.resumePromise}catch(t){return console.error("[ManagedAudioContext] Error resuming context, creating new one:",t),this.createNewContext()}}return this.context.state==="suspended"&&(this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{throw console.error("[ManagedAudioContext] Failed to resume suspended context:",t),this.resumePromise=null,t})),await this.resumePromise),this.context.state==="closed"?(console.warn("[ManagedAudioContext] Context closed after resume attempt, creating new instance"),this.createNewContext()):this.context}}const po={SELECTED_INPUT_DEVICE:"OpensipsJSInputDevice",SELECTED_OUTPUT_DEVICE:"OpensipsJSOutputDevice"},CS=0;function du(c,t){const s=new AudioContext,i=s.createMediaStreamSource(c),a=s.createMediaStreamSource(new MediaStream([t])),n=s.createMediaStreamDestination();return i.connect(n),a.connect(n),n.stream}class AS{constructor(t){var s;this.isAutoAnswer=!1,this.muteWhenJoinEnabled=!1,this.isDNDEnabled=!1,this.isCallWaitingEnabled=!0,this.muted=!1,this.microphoneInputLevelValue=1,this.speakerVolumeValue=1,this.activeRooms={},this.activeCalls={},this.extendedCalls={},this.conferenceNodes={},this.availableMediaDevices=[],this.selectedMediaDevices={input:"default",output:"default"},this.callStatus={},this.callTime={},this.callMetrics={},this.timeIntervals={},this.metricConfig={refreshEvery:1e3},this.activeStreamValue=null,this.initialStreamValue=null,this.vadSession=null,this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.vadInterval=null,this.vadMrsInterval=null,this.vadSessionGeneration=0,this.ringbackTimers={},this.ringbackAudioContexts={},this.ringbackSessionProgressReceived={},this.hangupBeepContext=null,this.managedAudioContext=new yS,this.context=t,this.context.on(this.context.newRTCSessionEventName,this.newRTCSessionCallback.bind(this)),this.VUMeter=new ES({onChangeFunction:this.emitVolumeChange.bind(this)}),this.initializeMediaDevices(),this.processVADConfiguration(((s=this.context.options.configuration)==null?void 0:s.noiseReductionOptions)||{}),this.setupVADInstance()}setVADConfiguration(t){if(!this.MicVAD)throw new Error("VAD module is not provided in the initial configuration");const s=Object.keys(t);for(const i of s)this.noiseReduction[i]=t[i];this.hasActiveCalls&&this.roomReconfigure(this.currentActiveRoomId)}setupVADInstance(){var s,i;const t=(i=(s=this.context.options.configuration)==null?void 0:s.noiseReductionOptions)==null?void 0:i.vadModule;t&&t.MicVAD?(this.MicVAD=t.MicVAD,console.log("✅ VAD module loaded successfully")):this.noiseReduction.mode!=="disabled"&&(console.warn("⚠️ Noise reduction is enabled but VAD module is not provided. To use VAD features, please install @ricky0123/vad-web and pass it via configuration.noiseReductionOptions.vadModule option."),this.noiseReduction.mode="disabled")}processVADConfiguration(t){this.noiseReduction={mode:t.mode||"disabled",checkEveryMs:t.checkEveryMs||500,noiseCheckInterval:t.noiseCheckInterval||2e3,noiseThreshold:t.noiseThreshold||.004,vadConfig:t.vadConfig||{},baseAssetPath:t.baseAssetPath||"https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.28/dist/",onnxWASMBasePath:t.onnxWASMBasePath||"https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/"}}get sipOptions(){return{...this.context.options.sipOptions,mediaConstraints:this.getUserMediaConstraints}}get currentActiveRoomId(){return this.currentActiveRoomIdValue}set currentActiveRoomId(t){this.currentActiveRoomIdValue=t,this.context.emit("currentActiveRoomChanged",t)}get autoAnswer(){return this.isAutoAnswer}get callAddingInProgress(){return this.isCallAddingInProgress}set callAddingInProgress(t){this.isCallAddingInProgress=t,this.context.emit("callAddingInProgressChanged",t)}get muteWhenJoin(){return this.muteWhenJoinEnabled}get isDND(){return this.isDNDEnabled}get isCallWaiting(){return this.isCallWaitingEnabled}get speakerVolume(){return this.speakerVolumeValue}get microphoneInputLevel(){return this.microphoneInputLevelValue}get getActiveCalls(){return this.activeCalls}get hasActiveCalls(){return Object.values(this.extendedCalls).length>0}get hasActiveAnsweredCalls(){return Object.values(this.activeRooms).filter(i=>!i.incomingInProgress).length>0}get getActiveRooms(){return this.activeRooms}get isMuted(){return this.muted}get getInputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audioinput")}get getOutputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audiooutput")}get getUserMediaConstraints(){return Ld()?{video:!1,audio:!0}:{audio:{deviceId:{exact:this.selectedMediaDevices.input},echoCancellation:!0,echoCancellationType:"system",noiseSuppression:!0,autoGainControl:!0,sampleRate:48e3,latency:.01},video:!1}}get selectedInputDevice(){return this.selectedMediaDevices.input}get selectedOutputDevice(){return this.selectedMediaDevices.output}get activeStream(){return this.activeStreamValue}setAvailableMediaDevices(t){this.availableMediaDevices=t,this.context.emit("changeAvailableDeviceList",t)}async updateDeviceList(){await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);const t=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(t)}async initializeMediaDevices(){const t=localStorage.getItem(po.SELECTED_INPUT_DEVICE)||"default",s=localStorage.getItem(po.SELECTED_OUTPUT_DEVICE)||"default";try{const i=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints),a=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(a),await this.setMicrophone(t),await this.setSpeaker(s),navigator.mediaDevices.addEventListener("devicechange",async()=>{const n=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(n)}),i.getTracks().forEach(n=>n.stop())}catch(i){console.error(i)}}async cleanupConferenceNodes(t){const s=this.conferenceNodes[t];if(!s)return;let i=0;s.sources.forEach((r,h)=>{var d;try{r.disconnect(),i++}catch(_){console.error(`[cleanupConferenceNodes] Error disconnecting source ${h}:`,_),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting source ${h}:`,_)}});let a=0;s.destinations.forEach((r,h)=>{var d;try{r.disconnect(),a++}catch(_){console.error(`[cleanupConferenceNodes] Error disconnecting destination ${h}:`,_),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting destination ${h}:`,_)}});let n=0;s.gains.forEach((r,h)=>{var d;try{r.disconnect(),n++}catch(_){console.error(`[cleanupConferenceNodes] Error disconnecting gain ${h}:`,_),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting gain ${h}:`,_)}}),delete this.conferenceNodes[t]}setCallTime(t){const s={...t};delete s.callId,this.callTime={...this.callTime,[t.callId]:s},this.context.emit("changeCallTime",this.callTime)}removeCallTime(t){const s={...this.callTime};delete s[t],this.callTime={...s},this.context.emit("changeCallTime",this.callTime)}setTimeInterval(t,s){this.timeIntervals={...this.timeIntervals,[t]:s}}removeTimeInterval(t){const s={...this.timeIntervals};s[t]&&(clearInterval(s[t]),delete s[t],this.timeIntervals={...s})}stopCallTimer(t){this.removeTimeInterval(t),this.removeCallTime(t)}emitVolumeChange(t,s){this.context.emit("changeCallVolume",{callId:t,volume:s})}getNoiseReductionMode(){return this.noiseReduction.mode}setMetricsConfig(t){this.metricConfig={...this.metricConfig,...t}}sendDTMF(t,s){if(!/^[A-D0-9*#]+$/g.test(s))throw new Error("Not allowed character used in the DTMF input");this.extendedCalls[t].sendDTMF(s)}setIsMuted(t){this.muted=t,this.context.emit("changeIsMuted",t)}processMute(t){const s=this.currentActiveRoomId;this.setIsMuted(t),this.initialStreamValue.getTracks().forEach(i=>i.enabled=!t),this.roomReconfigure(s)}mute(){this.processMute(!0)}unmute(){this.processMute(!1)}async processHold({callId:t,toHold:s,automatic:i}){const a=this.extendedCalls[t];if(!a)return;a._automaticHold=i??!1;const n=new Promise((r,h)=>{const d=setTimeout(()=>{h(new Error("Hold operation timeout"))},5e3),_=()=>{clearTimeout(d),a.putOnHoldTimestamp=s?Date.now():void 0,r()},g=T=>{clearTimeout(d),h(T)};try{s?(this.stopSessionVad(),a.hold({},_)):a.unhold({},_)}catch(T){g(T)}});try{await n,this.updateCall(a);const r=Object.values(this.extendedCalls).filter(h=>h.roomId===a.roomId&&(s?t!==h._id:!0));r.length>1&&await this.doConference(r)}catch(r){throw console.error("Hold operation failed:",r),r}}holdCall(t,s=!1){return this.processHold({callId:t,automatic:s,toHold:!0})}unholdCall(t){return this.processHold({callId:t,toHold:!1})}cancelAllOutgoingUnanswered(){Object.values(this.getActiveCalls).filter(t=>t.direction==="outgoing"&&t.status===CS).forEach(t=>this.terminateCall(t._id))}answerCall(t){const s=this.extendedCalls[t];this.cancelAllOutgoingUnanswered(),s.answer(this.sipOptions),this.updateCall(s),this.setActiveRoom(s.roomId),s.connection.addEventListener("track",i=>{this.triggerAddStream(i,s)})}async moveCall(t,s){this.updateCallStatus({callId:t,isMoving:!0}),await this.processRoomChange({callId:t,roomId:s}),this.updateCallStatus({callId:t,isMoving:!1})}updateCall(t){this.activeCalls[t._id]=Mf(t),this.context.emit("changeActiveCalls",this.activeCalls)}updateRoom(t){const i={...this.activeRooms[t.roomId],...t};this.activeRooms={...this.activeRooms,[t.roomId]:{...i}},this.context.emit("updateRoom",{room:i,roomList:this.activeRooms})}hasAutoAnswerHeaders(t){const s=/answer-after=0/,a=t.request.getHeader("Call-Info");return a&&s.test(a)}refreshRemotePartyId(t,s){const i=s.getHeader("Remote-Party-ID");if(!i)return!1;let a=!1;const n=Lf(i);n!==null&&t._remote_party_display_name!==n&&(t._remote_party_display_name=n,a=!0);const r=$f(i);return r!==null&&t._remote_party_uri_user!==r&&(t._remote_party_uri_user=r,a=!0),a}addCall(t,s=!0){this.activeCalls={...this.activeCalls,[t._id]:Mf(t)},this.extendedCalls[t._id]=t,s&&this.context.emit("changeActiveCalls",this.activeCalls)}addCallStatus(t){this.callStatus={...this.callStatus,[t]:{isMoving:!1,isTransferring:!1,isMerging:!1,isTransferred:!1}},this.context.emit("changeCallStatus",this.callStatus)}updateCallStatus(t){const i={...{...this.callStatus[t.callId]}};t.isMoving!==void 0&&(i.isMoving=t.isMoving),t.isTransferring!==void 0&&(i.isTransferring=t.isTransferring),t.isMerging!==void 0&&(i.isMerging=t.isMerging),t.isTransferred!==void 0&&(i.isTransferred=t.isTransferred),this.callStatus={...this.callStatus,[t.callId]:{...i}},this.context.emit("changeCallStatus",this.callStatus)}removeCallStatus(t){const s={...this.callStatus};delete s[t],this.callStatus={...s},this.context.emit("changeCallStatus",this.callStatus)}addRoom(t){this.activeRooms={...this.activeRooms,[t.roomId]:t},this.context.emit("addRoom",{room:t,roomList:this.activeRooms})}async setupActiveStream(){const t=await lu(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);t.getTracks().forEach(s=>s.enabled=!this.isMuted),await this.setActiveStream(t)}async getActiveStream(){const t=await lu(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);return t.getTracks().forEach(s=>s.enabled=!this.isMuted),await this.setActiveStream(t),t}async setMicrophone(t){if(!this.getInputDeviceList.find(({deviceId:i})=>i===t)||(this.setSelectedInputDevice(t),Object.keys(this.getActiveCalls).length===0))return;await this.setupStream();const s=Object.values(this.extendedCalls).filter(i=>i.roomId===this.currentActiveRoomId);s.length===1?Object.values(s).forEach(async i=>{await this.setupActiveStream();const a=this.activeStream;i.connection.getSenders()[0].replaceTrack(a.getTracks()[0]),this.updateCall(i)}):await this.doConference(s)}async setActiveStream(t){this.activeStream&&this.stopVUMeter("origin"),await this.setupVUMeter(t,"origin"),this.activeStreamValue=t,this.context.emit("changeActiveStream",t)}async setSpeaker(t){if(!this.getOutputDeviceList.find(({deviceId:a})=>a===t))return;this.setSelectedOutputDevice(t);const s=Object.values(this.extendedCalls);if(s.length===0)return;const i=s.filter(a=>a.roomId===this.currentActiveRoomId);i.length===1?s.forEach(a=>{var n;(n=a.audioTag)==null||n.setSinkId(t),this.updateCall(a)}):await this.doConference(i)}removeRoom(t){const s={...this.activeRooms},i={...s[t]};delete s[t],this.activeRooms={...s},this.context.emit("removeRoom",{room:i,roomList:this.activeRooms})}deleteRoomIfEmpty(t){t!==void 0&&Object.values(this.extendedCalls).filter(s=>s.roomId===t).length===0&&(this.removeRoom(t),this.currentActiveRoomId===t&&(this.currentActiveRoomId=void 0))}checkInitialized(){if(!this.context.initialized)throw new Error("[OpenSIPSJS] You must call `start` method first!")}muteReconfigure(t){this.muted?t.mute({audio:!0}):t.unmute({audio:!0})}async startNoiseMonitor({stream:t,onNoiseDetected:s,onNoiseStop:i}){var _,g,T;let a;try{a=await this.managedAudioContext.getContext()}catch(S){console.error("[startNoiseMonitor] Failed to get AudioContext:",S),(_=this.context.logger)==null||_.error("[startNoiseMonitor] Failed to get AudioContext:",S);return}let n,r;try{n=a.createMediaStreamSource(t.clone()),r=a.createAnalyser()}catch(S){console.error("[startNoiseMonitor] Failed to create audio nodes:",S),console.error("[startNoiseMonitor] AudioContext state:",a.state),(g=this.context.logger)==null||g.error("[startNoiseMonitor] Failed to create audio nodes:",S),(T=this.context.logger)==null||T.error("[startNoiseMonitor] AudioContext state:",a.state);return}r.fftSize=1024;const h=new Float32Array(r.fftSize);n.connect(r);const d=[];this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadMrsInterval=setInterval(()=>{r.getFloatTimeDomainData(h);const S=Cv(h);d.push(S);const E=Math.ceil(this.noiseReduction.noiseCheckInterval/this.noiseReduction.checkEveryMs);d.length>E&&d.shift()},this.noiseReduction.checkEveryMs),this.vadInterval=setInterval(()=>{var A;if(d.length===0)return;const S=d.reduce((R,F)=>R+F,0)/d.length,E=this.vadSessionState;if(!E){console.warn("[startNoiseMonitor] State not found, stopping interval"),(A=this.context.logger)==null||A.warn("[startNoiseMonitor] State not found, stopping interval"),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null);return}const C=S>this.noiseReduction.noiseThreshold;E.isSpeaking||(C&&E.currentMode==="clean"?(E.currentMode="noisy",console.log("Average noise high → enable VAD"),this.context.emit("changeNoiseReductionState",!0),s()):!C&&E.currentMode==="noisy"&&(E.currentMode="clean",console.log("Average noise low → disable VAD"),this.context.emit("changeNoiseReductionState",!1),i()))},this.noiseReduction.noiseCheckInterval)}async processVADForActiveStream(t={}){var g;const s=this.activeStream;this.stopSessionVad();const i=this.vadSessionGeneration,a=()=>i!==this.vadSessionGeneration;this.vadSessionState={currentMode:"clean",isSpeaking:!1};const n=await this.managedAudioContext.getContext();if(a())return;const r=await Av(s,n,150);if(a())return;let h=!1;const d=Object.values(this.extendedCalls).filter(T=>T.roomId===this.currentActiveRoomId),_=await this.MicVAD.new({getStream:()=>new Promise(T=>T(s)),pauseStream:async()=>{},resumeStream:async T=>T,...SS,...this.noiseReduction.vadConfig,baseAssetPath:this.noiseReduction.baseAssetPath,onnxWASMBasePath:this.noiseReduction.onnxWASMBasePath,onFrameProcessed:()=>{var T,S;if(!a()&&!h){if(h=!0,console.log("✅ VAD initialized, starting background noise monitoring"),this.noiseReduction.mode==="enabled"){if(t&&Object.keys(t).length)Object.keys(t).forEach(E=>{const C=this.extendedCalls[E];if(C&&C.connection.getSenders()[0]){const A=du(r.stream,t[E]);C.connection.getSenders()[0].replaceTrack(A.getAudioTracks()[0])}});else{const E=d[0],C=(T=E==null?void 0:E.connection)==null?void 0:T.getSenders()[0],A=r.stream.getAudioTracks()[0];C&&C.replaceTrack(A)}return}if(!this.vadSessionState){console.error("[processVAD] CRITICAL: State not found"),(S=this.context.logger)==null||S.error("[processVAD] CRITICAL: State not found");return}this.startNoiseMonitor({stream:s,onNoiseDetected:async()=>{var E;if(console.log("[processVad] - Replace track with Vad Controlled"),(E=this.context.logger)==null||E.log("[processVad] - Replace track with Vad Controlled"),t&&Object.keys(t).length)Object.keys(t).forEach(C=>{const A=this.extendedCalls[C];if(A&&A.connection.getSenders()[0]){const R=du(r.stream,t[C]);A.connection.getSenders()[0].replaceTrack(R.getAudioTracks()[0])}});else{const C=d[0];C.connection.getSenders()[0]&&C.connection.getSenders()[0].replaceTrack(r.stream.getAudioTracks()[0])}},onNoiseStop:async()=>{if(console.log("Replace track with Original"),t&&Object.keys(t).length)Object.keys(t).forEach(E=>{const C=this.extendedCalls[E];if(!C)return;const A=C.connection.getSenders()[0];if(A&&A.track&&A.transport&&A.transport.state!=="closed"&&A.transport.state!=="failed"){const R=du(s,t[E]);A.replaceTrack(R.getAudioTracks()[0])}});else{const E=d[0].connection.getSenders()[0];E&&E.track&&E.transport&&E.transport.state!=="closed"&&E.transport.state!=="failed"&&E.replaceTrack(s.getAudioTracks()[0])}}})}},onSpeechStart:()=>{a()||(console.log("🎤 Speech started"),r.setSpeaking(!0),this.vadSessionState.isSpeaking=!0)},onSpeechEnd:()=>{a()||(console.log("🛑 Speech end"),r.setSpeaking(!1),this.vadSessionState.isSpeaking=!1)}});if(a()){try{_.pause()}catch(T){(g=this.context.logger)==null||g.error("[processVADForActiveStream] Error pausing stale vadSession:",T)}return}this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadSession=_,_.start()}stopSessionVad(){this.vadSessionGeneration++,this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadSessionState&&(this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.context.emit("changeNoiseReductionState",!1))}async roomReconfigure(t){var a,n,r,h;if(t===void 0)return;const s=Object.values(this.extendedCalls).filter(d=>d.roomId===t),i=this.currentActiveRoomId===t;if(console.log("[roomReconfigure] - Calls In Room:",s),(a=this.context.logger)==null||a.log("[roomReconfigure] - Calls In Room:",s),s.forEach((d,_)=>{if(d.audioTag){d.connection.getReceivers().forEach(T=>{T.track.enabled=!d.localMuted}),i&&this.muteReconfigure(d);const g=!i;d.audioTag.muted=g,this.updateCall(d)}}),s.length===0){!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t),console.log("[roomReconfigure] - Delete empty room",t),(n=this.context.logger)==null||n.log("[roomReconfigure] - Delete empty room",t),this.deleteRoomIfEmpty(t);return}if(s.length===1&&!i){const d=s[0];d.isOnHold().local||await this.holdCall(d._id,!0),!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}if(s.length===1&&i){const d=s[0];d.isOnHold().local&&d._automaticHold&&await this.unholdCall(d._id);const T=(((r=d.connection)==null?void 0:r.getSenders())||[])[0];if(d.connection&&T)try{await this.setupActiveStream();const E=this.activeStream;["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[roomReconfigure] - Call processVAD from roomReconfigure"),(h=this.context.logger)==null||h.log("[roomReconfigure] - Call processVAD from roomReconfigure"),this.processVADForActiveStream());const C=E.getTracks();await T.replaceTrack(C[0]),this.muteReconfigure(d)}catch(E){console.error(E)}!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}s.length>1&&await this.doConference(s)}async doConference(t){var g,T,S,E,C,A,R,F;if(console.log("[doConference] - In doConference, sessions:",t),(g=this.context.logger)==null||g.log("[doConference] - In doConference, sessions:",t),t.length===0)return;const s=t[0].roomId,i=this.currentActiveRoomId===s;if(t.find(I=>I.roomId!==s))return;let n;try{n=await this.managedAudioContext.getContext()}catch(I){console.error("[doConference] Failed to get AudioContext:",I),(T=this.context.logger)==null||T.error("[doConference] Failed to get AudioContext:",I);return}const r=n.state;if(r!=="running")if(console.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),(S=this.context.logger)==null||S.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),r==="suspended"||r==="interrupted")try{await n.resume();const I=n.state;if(I!=="running"){console.error(`[doConference] Failed to resume AudioContext, state: ${I}`),(E=this.context.logger)==null||E.error(`[doConference] Failed to resume AudioContext, state: ${I}`);return}}catch(I){console.error("[doConference] Error resuming AudioContext:",I),(C=this.context.logger)==null||C.error("[doConference] Error resuming AudioContext:",I);return}else if(r==="closed"){console.error("[doConference] AudioContext is closed, cannot proceed"),(A=this.context.logger)==null||A.error("[doConference] AudioContext is closed, cannot proceed");return}else return;await this.cleanupConferenceNodes(s),this.conferenceNodes[s]={sources:new Map,destinations:new Map,gains:new Map};const h=this.conferenceNodes[s],d=new Map;console.log("[doConference] - Before sessions forEach, sessions:",t),(R=this.context.logger)==null||R.log("[doConference] - Before sessions forEach, sessions:",t),t.forEach((I,ie)=>{var N,$,ve;if(console.log("[doConference] - In sessions forEach, iteration for",I._id),(N=this.context.logger)==null||N.log("[doConference] - In sessions forEach, iteration for",I._id),I&&I.connection){const _e=I.connection.getReceivers();console.log("[doConference] - Receivers list length for",I._id,_e.length),($=this.context.logger)==null||$.log("[doConference] - Receivers list length for",I._id,_e.length),_e.forEach((U,x)=>{var Y,V,Q,k,M,B;U.track.enabled=!I.localMuted;const q=(Y=U.track)==null?void 0:Y.id;(V=U.track)==null||V.readyState,(Q=U.track)==null||Q.kind;const j=`${I._id}-${q}`;console.log("[doConference] - Gathering receiver tracks",I._id),console.log("[doConference] - Receiver track readyState",U.track.readyState),(k=this.context.logger)==null||k.log("[doConference] - Gathering receiver tracks",I._id),(M=this.context.logger)==null||M.log("[doConference] - Receiver track readyState",U.track.readyState),U.track&&U.track.readyState==="live"&&(console.log("[doConference] - Gathered receiver track",I._id),(B=this.context.logger)==null||B.log("[doConference] - Gathered receiver track",I._id),d.set(j,U.track))})}else console.log("[doConference] - No session or RTC connection, session:",I),(ve=this.context.logger)==null||ve.log("[doConference] - No session or RTC connection, session:",I)}),await this.setupActiveStream();const _={};await bv.forEach(t,async(I,ie)=>{var Y,V,Q,k,M;if(!I||!I.connection){console.log("[doConference] - Return because of no session or connection, session:",I),(Y=this.context.logger)==null||Y.log("[doConference] - Return because of no session or connection, session:",I);return}const N=n.createMediaStreamDestination(),$=n.createMediaStreamDestination();h.destinations.set(I._id,N),h.destinations.set(`${I._id}-others`,$);const ve=I.connection.getReceivers(),_e=ve.length>0;console.log(`[doConference] Session ${I._id} has ${ve.length} receivers`),(V=this.context.logger)==null||V.log(`[doConference] Session ${I._id} has ${ve.length} receivers`),_e||(console.warn(`[doConference] Session ${I._id} has no receivers yet. Will re-configure when track arrives.`),(Q=this.context.logger)==null||Q.warn(`[doConference] Session ${I._id} has no receivers yet. Will re-configure when track arrives.`)),d.forEach((B,Fe)=>{var X,W,G;if(console.log("[doConference] - In forEach receiverTracks for",I._id),(X=this.context.logger)==null||X.log("[doConference] - In forEach receiverTracks for",I._id),!Fe.startsWith(I._id)){if(!B||B.readyState!=="live"){console.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${I._id}`),(W=this.context.logger)==null||W.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${I._id}`);return}try{const re=n.createMediaStreamSource(new MediaStream([B])),pe=n.createGain(),Ie=`${I._id}-${Fe}`;re.connect(pe),pe.connect(N),pe.connect($),console.log("[doConference] - In forEach connect track for",I._id),(G=this.context.logger)==null||G.log("[doConference] - In forEach connect track for",I._id),h.sources.set(Ie,re),h.gains.set(Ie,pe)}catch(re){console.error(re)}}});const U=$.stream.getTracks();if(_[I._id]=U[0],i&&this.activeStreamValue)try{const B=this.activeStream,Fe=n.createMediaStreamSource(B),X=n.createGain(),W=`${I._id}-local`;Fe.connect(X),X.connect(N),h.sources.set(W,Fe),h.gains.set(W,X)}catch(B){console.error(B)}else i&&(console.error(`Host room but no activeStreamValue - skipping host microphone for session ${I._id}`),(k=this.context.logger)==null||k.error(`Host room but no activeStreamValue - skipping host microphone for session ${I._id}`));const q=I.connection.getSenders()[0],j=N.stream.getTracks();if(q&&j[0])try{console.log("[doConference] - Final replaceTrack for",I._id),(M=this.context.logger)==null||M.log("[doConference] - Final replaceTrack for",I._id),console.log("RIGHT 2 initial replace for ",I._id),await q.replaceTrack(j[0]),this.muteReconfigure(I)}catch(B){console.error(B)}}),["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[doConference] - Call processVAD from doConference"),(F=this.context.logger)==null||F.log("[doConference] - Call processVAD from doConference"),this.processVADForActiveStream(_))}processCallerMute(t,s){const i=this.extendedCalls[t];i&&i.connection.getReceivers().length&&(i.localMuted=s,i.connection.getReceivers().forEach(a=>{a.track.enabled=!s}),this.updateCall(i))}muteCaller(t){this.processCallerMute(t,!0)}unmuteCaller(t){this.processCallerMute(t,!1)}terminateCall(t){const s=this.extendedCalls[t];s._status===4?s.terminate({status_code:603,reason_phrase:"Decline"}):s._status!==8&&s.terminate()}handleSipResponseForRingback(t,s){var n,r,h,d,_,g;let i=null;if(this.extendedCalls[t])i=t;else{const T=Object.values(this.extendedCalls).find(S=>S.id===t||S._id===t||S.id&&S.id.includes(t)||S._id&&S._id.includes(t));T&&(i=T.id)}if(!i){(n=this.context.logger)==null||n.warn(`[handleSipResponseForRingback] Could not find session for identifier ${t}, status ${s}`);return}const a=this.extendedCalls[i];if(!a){(r=this.context.logger)==null||r.warn(`[handleSipResponseForRingback] Call not found in extendedCalls for ${i}`);return}if(a.direction==="outgoing"){if(a._is_confirmed){(h=this.context.logger)==null||h.log(`[handleSipResponseForRingback] Call ${i} is already confirmed, skipping ringback tone`);return}if(this.timeIntervals[i]||this.startCallTimer(i),s===au.TRYING||s===au.RINGING){if(this.ringbackTimers[i])return;this.ringbackSessionProgressReceived[i]=!1,this.ringbackTimers[i]=setTimeout(()=>{var S,E;const T=this.extendedCalls[i];T&&!T._is_confirmed&&!this.ringbackSessionProgressReceived[i]?(this.startLocalRingbackTone(i),(S=this.context.logger)==null||S.log(`[handleSipResponseForRingback] Started local ringback tone for call ${i} after 2 seconds without 183`)):T&&T._is_confirmed&&((E=this.context.logger)==null||E.log(`[handleSipResponseForRingback] Call ${i} was confirmed during 2-second wait, skipping ringback tone`)),delete this.ringbackTimers[i]},2e3),(d=this.context.logger)==null||d.log(`[handleSipResponseForRingback] Started 2-second timer for call ${i} after receiving ${s}`)}s===au.SESSION_PROGRESS&&(this.ringbackSessionProgressReceived[i]=!0,this.ringbackTimers[i]&&(clearTimeout(this.ringbackTimers[i]),delete this.ringbackTimers[i],(_=this.context.logger)==null||_.log(`[handleSipResponseForRingback] Cancelled ringback timer for call ${i} - 183 received`)),this.stopLocalRingbackTone(i),(g=this.context.logger)==null||g.log(`[handleSipResponseForRingback] Stopped local ringback tone for call ${i} - 183 received with SDP`))}}async startLocalRingbackTone(t){var s,i;if(!this.ringbackAudioContexts[t])try{const a=await this.managedAudioContext.getContext(),n=a.createOscillator(),r=a.createOscillator(),h=a.createGain();n.frequency.value=440,r.frequency.value=480,n.type="sine",r.type="sine",h.gain.value=0,n.connect(h),r.connect(h),h.connect(a.destination),n.start(),r.start();const d={context:a,oscillator1:n,oscillator2:r,gainNode:h,intervalId:null};this.ringbackAudioContexts[t]=d;const _=()=>{if(!this.ringbackAudioContexts[t])return;const T=a.currentTime;h.gain.cancelScheduledValues(T),h.gain.setValueAtTime(0,T),h.gain.linearRampToValueAtTime(.3,T+.05),h.gain.linearRampToValueAtTime(0,T+1)};_();const g=setInterval(()=>{if(!this.ringbackAudioContexts[t]){clearInterval(g);return}_()},4e3);d.intervalId=g,this.ringbackAudioContexts[t]=d,(s=this.context.logger)==null||s.log(`[startLocalRingbackTone] Started ringback tone for session ${t}`)}catch(a){(i=this.context.logger)==null||i.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a),console.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a)}}stopLocalRingbackTone(t){var i,a;const s=this.ringbackAudioContexts[t];if(s)try{s.intervalId&&clearInterval(s.intervalId),s.oscillator1&&s.oscillator1.stop(),s.oscillator2&&s.oscillator2.stop(),s.gainNode&&s.gainNode.disconnect(),delete this.ringbackAudioContexts[t],(i=this.context.logger)==null||i.log(`[stopLocalRingbackTone] Stopped ringback tone for session ${t}`)}catch(n){(a=this.context.logger)==null||a.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,n),console.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,n),delete this.ringbackAudioContexts[t]}}cleanupRingbackTone(t){this.ringbackTimers[t]&&(clearTimeout(this.ringbackTimers[t]),delete this.ringbackTimers[t]),this.stopLocalRingbackTone(t),delete this.ringbackSessionProgressReceived[t]}async playHangupBeep(){var t,s;if(!this.hangupBeepContext)try{const i=await this.managedAudioContext.getContext(),a=i.createOscillator(),n=i.createGain();a.frequency.value=800,a.type="sine",n.gain.value=0,a.connect(n),n.connect(i.destination),this.hangupBeepContext={context:i,oscillator:a,gainNode:n},a.start();const r=i.currentTime;n.gain.setValueAtTime(0,r),n.gain.linearRampToValueAtTime(.3,r+.01),n.gain.setValueAtTime(.3,r+.15),n.gain.linearRampToValueAtTime(0,r+.2),a.stop(r+.2),setTimeout(()=>{if(this.hangupBeepContext){try{this.hangupBeepContext.oscillator&&this.hangupBeepContext.oscillator.disconnect(),this.hangupBeepContext.gainNode&&this.hangupBeepContext.gainNode.disconnect()}catch(h){console.error("[playHangupBeep] Cleanup playing hangup beep error:",h)}this.hangupBeepContext=null}},250),(t=this.context.logger)==null||t.log("[playHangupBeep] Played hangup beep")}catch(i){(s=this.context.logger)==null||s.error("[playHangupBeep] Error playing hangup beep:",i),console.error("[playHangupBeep] Error playing hangup beep:",i),this.hangupBeepContext=null}}transferCall(t,s){if(s.toString().length===0)return new Error("Target must be passed");const i=this.extendedCalls[t];if(!i._is_confirmed&&!i._is_canceled){const a=`sip:${s}@${this.context.sipDomain}`;i.terminate({status_code:302,reason_phrase:"Moved Temporarily",extraHeaders:[`Contact: ${a}`]});return}this.updateCallStatus({callId:t,isTransferring:!0,isTransferred:!1}),i.refer(`sip:${s}@${this.context.sipDomain}`,{eventHandlers:{requestSucceeded:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!0})},requestFailed:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!1})}}}),this.updateCall(i)}mergeCall(t){const s=Object.values(this.extendedCalls).filter(n=>n.roomId===t);if(s.length!==2)return;const i=s[0],a=s[1];!i||!a||(this.updateCallStatus({callId:i._id,isMerging:!0}),this.updateCallStatus({callId:a._id,isMerging:!0}),i.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(i))}mergeCallByIds(t,s){const i=Object.values(this.extendedCalls).find(n=>n._id===t),a=Object.values(this.extendedCalls).find(n=>n._id===s);if(!i||!a)throw new Error("Call ID is not provided");this.updateCallStatus({callId:t,isMerging:!0}),this.updateCallStatus({callId:s,isMerging:!0}),i.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(i)}setDND(t){this.isDNDEnabled=t,this.context.emit("changeIsDND",t)}setCallWaiting(t){this.isCallWaitingEnabled=t,this.context.emit("changeIsCallWaiting",t)}startCallTimer(t){this.removeTimeInterval(t);const s={callId:t,hours:0,minutes:0,seconds:0,formatted:""};this.setCallTime(s);const i=setInterval(()=>{const a={...this.callTime[t]},n=yv(a);this.setCallTime({callId:t,...n})},1e3);this.setTimeInterval(t,i)}async setActiveRoom(t){const s=this.currentActiveRoomId;t!==s&&(this.currentActiveRoomId=t,await this.roomReconfigure(s),await this.roomReconfigure(t))}getNewRoomId(){const t=Object.keys(this.activeRooms);return t.length===0?1:parseInt(t.sort()[t.length-1])+1}async setupCall(t){var _,g;const s=t.session;if(this.getActiveCalls[s.id]!==void 0)return;const a=this.getNewRoomId(),n={started:new Date,incomingInProgress:!1,roomId:a};s.direction==="incoming"?(this.context.logger.log("New incoming call from",(g=(_=s._remote_identity)==null?void 0:_._uri)==null?void 0:g._user),n.incomingInProgress=!0,this.context.subscribe(Xt.CALL_CONFIRMED,T=>{s.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.startCallTimer(s.id))}),this.context.subscribe(Xt.CALL_FAILED,T=>{s.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.deleteRoomIfEmpty(a))})):s.direction==="outgoing"&&s.once("confirmed",()=>{this.startCallTimer(s.id)});const r=s,h=this.hasAutoAnswerHeaders(t),d=r.direction==="incoming"&&!this.hasActiveCalls&&(h||this.autoAnswer);r.roomId=a,r.localMuted=!1,r.autoAnswer=d,d?this.addCall(r,!1):this.addCall(r),this.addCallStatus(s.id),this.addRoom(n),d&&setTimeout(()=>{this.answerCall(r._id)},250)}removeCall(t){const s={...this.activeCalls};delete s[t],this.activeCalls={...s};const i={...this.extendedCalls};delete i[t],this.extendedCalls={...i},this.context.emit("changeActiveCalls",this.activeCalls)}activeCallListRemove(t){const s=this.extendedCalls[t._id];if(!s)return;this.stopVUMeter("origin"),this.stopVUMeter(t._id);const i=s.roomId;this.removeCall(t._id),this.roomReconfigure(i).then(()=>{}).catch(a=>{console.error("Error reconfiguring room after call removal:",a)})}shouldTerminateNewSession(t){if(t.session.direction==="outgoing")return!1;const i=!this.isCallWaiting&&this.hasActiveCalls;return this.isDND||i}async newRTCSessionCallback(t){const s=t.session,i=s.direction==="incoming"?t.request.getHeader("Remote-Party-ID"):null;if(s._remote_party_display_name=Lf(i),s._remote_party_uri_user=$f(i),this.shouldTerminateNewSession(t)){s.terminate({status_code:486,reason_phrase:"Do Not Disturb"});return}this.context.triggerListener({listenerType:Xt.NEW_CALL,session:s,event:t}),s.on("ended",r=>{var d,_,g;if(this.stopVUMeter(s.id),this.context.logger.log("Session ended for",(_=(d=s._remote_identity)==null?void 0:d._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_ENDED,session:s,event:r}),s._is_confirmed&&this.playHangupBeep(),s.connection){const T=s.connection.connectionState;(T==="closed"||T==="disconnected")&&this.context.emit("connectionStateChange",{session:s,connectionState:T})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(s.id);const h=this.getActiveCalls[s.id];h&&this.activeCallListRemove(h),this.stopCallTimer(s.id),this.removeCallStatus(s.id),this.removeCallMetrics(s.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(g=this.initialStreamValue)==null||g.getTracks().forEach(T=>T.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),s.on("progress",r=>{var h,d;this.context.logger.log("Session in progress for",(d=(h=s._remote_identity)==null?void 0:h._uri)==null?void 0:d._user),this.context.triggerListener({listenerType:Xt.CALL_PROGRESS,session:s,event:r})}),s.on("failed",r=>{var d,_,g;if(this.stopVUMeter(s.id),this.context.logger.log("Session failed for",(_=(d=s._remote_identity)==null?void 0:d._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_FAILED,session:s,event:r}),s.connection){const T=s.connection.connectionState;(T==="closed"||T==="disconnected")&&this.context.emit("connectionStateChange",{session:s,connectionState:T})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(s.id),s.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0);const h=this.getActiveCalls[s.id];h&&this.activeCallListRemove(h),this.stopCallTimer(s.id),this.removeCallStatus(s.id),this.removeCallMetrics(s.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(g=this.initialStreamValue)==null||g.getTracks().forEach(T=>T.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),s.on("confirmed",r=>{var h,d;this.context.logger.log("Session confirmed for",(d=(h=s._remote_identity)==null?void 0:h._uri)==null?void 0:d._user),this.context.triggerListener({listenerType:Xt.CALL_CONFIRMED,session:s,event:r}),this.updateCall(s),this.cleanupRingbackTone(s.id),s.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0)});const a=r=>{this.refreshRemotePartyId(s,r.request)&&this.updateCall(s)};s.on("reinvite",a),s.on("update",a);const n=r=>{r&&r.addEventListener("connectionstatechange",h=>{this.context.emit("connectionStateChange",{session:s,connectionState:r.connectionState})})};if(s.connection&&n(s.connection),s.on("peerconnection",({peerconnection:r})=>{n(r)}),await this.setupCall(t),s.direction==="outgoing"){const r=this.getActiveCalls[s.id].roomId;await this.setActiveRoom(r)}}setMuteWhenJoin(t){this.muteWhenJoinEnabled=t,this.context.emit("changeMuteWhenJoin",t)}setMicrophoneSensitivity(t){if(t<0||t>1)throw new Error("Value should be in range from 0 to 1!");this.microphoneInputLevelValue=t,this.roomReconfigure(this.currentActiveRoomId)}setSpeakerVolume(t){this.speakerVolumeValue=t,Object.values(this.extendedCalls).forEach(s=>{s.audioTag&&(s.audioTag.volume=t,this.updateCall(s))})}setAutoAnswer(t){this.isAutoAnswer=t}setSelectedInputDevice(t){localStorage.setItem(po.SELECTED_INPUT_DEVICE,t),this.selectedMediaDevices.input=t,this.context.emit("changeActiveInputMediaDevice",t)}setSelectedOutputDevice(t){localStorage.setItem(po.SELECTED_OUTPUT_DEVICE,t),this.selectedMediaDevices.output=t,this.context.emit("changeActiveOutputMediaDevice",t)}setCallMetrics(t){const s={...t};delete s.callId,this.callMetrics={...this.callMetrics,[t.callId]:s},this.context.emit("changeCallMetrics",this.callMetrics)}removeCallMetrics(t){const s={...this.callMetrics};delete s[t],this.callMetrics={...s},this.context.emit("changeCallMetrics",this.callMetrics)}getCallQuality(t){const s=new gS(this.metricConfig),i=s.createProbe(t.connection,{cid:t._id}),a=[];let n;i.onreport=r=>{Object.entries(r.audio).forEach(([_,g])=>{g.direction==="inbound"&&!a.includes(_)&&(a.push(_),n=_)});const h=r.audio[n];if(!h)return;const d=TS(h,vS);d.callId=t._id,this.setCallMetrics(d)},this.context.subscribe(Xt.CALL_ENDED,r=>{r._id===t._id&&s.stopAllProbes()}),s.startAllProbes()}async setupVUMeter(t,s){await this.VUMeter.start(await this.managedAudioContext.getContext(),t,s)}stopVUMeter(t){this.VUMeter.stop(t)}async setupStream(){try{const t=Date.now(),s=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);this.initialStreamValue&&(this.initialStreamValue.getTracks().forEach((a,n)=>{a.stop()}),this.initialStreamValue=null),this.initialStreamValue=s}catch(t){throw t}}async triggerAddStream(t,s){var S,E;console.log(`[triggerAddStream] - For ${s._id}`),(S=this.context.logger)==null||S.log(`[triggerAddStream] - For ${s._id}`);const i=this.muteWhenJoin||this.isMuted;this.setIsMuted(i),this.initialStreamValue||await this.setupStream();const a=await this.managedAudioContext.getContext(),n=await lu(a,this.initialStreamValue,this.microphoneInputLevel*2),r=this.isMuted||this.muteWhenJoin;n.getTracks().forEach(C=>{C.enabled=!r}),await this.setActiveStream(n),await s.connection.getSenders()[0].replaceTrack(n.getTracks()[0]);const _=new MediaStream([t.track]);!Object.values(this.extendedCalls).find(C=>C.audioTag&&C.audioTag.id===s._id)&&lv(_,s,this.selectedOutputDevice,this.speakerVolume);const T=s.roomId===this.currentActiveRoomId;s.audioTag&&(s.audioTag.muted=!T),await this.setupVUMeter(_,s._id),this.getCallQuality(s),this.updateCall(s),s.roomId!==void 0&&Object.values(this.extendedCalls).filter(A=>A.roomId===s.roomId).length>1&&(console.log(`[triggerAddStream] Re-configuring conference for room ${s.roomId} - track received for call ${s._id}`),(E=this.context.logger)==null||E.log(`[triggerAddStream] Re-configuring conference for room ${s.roomId} - track received for call ${s._id}`),setTimeout(()=>{this.roomReconfigure(s.roomId)},100)),["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.processVADForActiveStream()}initCall(t,s,i=!1){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`);const a=this.context.call(`sip:${t}@${this.context.sipDomain}`,this.sipOptions);if(this.callAddingInProgress=a.id,s&&this.currentActiveRoomId!==void 0&&(this.processRoomChange({callId:a.id,roomId:this.currentActiveRoomId}),i)){const n=Object.values(this.extendedCalls).filter(r=>r.roomId===this.currentActiveRoomId&&r._id!==a.id);for(const r of n)this.holdCall(r._id,!0)}a.connection.addEventListener("track",n=>{this.triggerAddStream(n,a)})}async processRoomChange({callId:t,roomId:s}){const i=this.extendedCalls[t];if(!i)return;const a=i.roomId;i.roomId=s,this.updateCall(i),await this.roomReconfigure(a),await this.roomReconfigure(s)}}class RS{constructor(t){this.context=t}get sipOptions(){return{...this.context.options.sipOptions}}initCall(t,s){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`),this.context.joinVideoCall(`sip:${t}@${this.context.sipDomain}`,s,this.sipOptions)}stop(t={}){this.context.terminateJanusSessions(t)}startAudio(){this.context.enableJanusAudio(!0)}stopAudio(){this.context.enableJanusAudio(!1)}startVideo(){this.context.enableJanusVideo(!0)}stopVideo(){this.context.enableJanusVideo(!1)}changeMediaConstraints(t){this.context.changeMediaConstraints(t)}startScreenShare(){this.context.startScreenShare()}startBlur(){this.context.startBlur()}stopBlur(){this.context.stopBlur()}}const Pe={CREATE:"m.conversation.create",MESSAGE:"m.conversation.message",MEMBER:"m.conversation.member",CLOSED:"m.conversation.closed",SYNC:"m.sync",UPLOAD_REQUEST:"m.upload.request",UPLOAD_RESPONSE:"m.upload.response",FILE_ACCESS_REQUEST:"m.file.access.request",FILE_ACCESS_RESPONSE:"m.file.access.response",REACTION:"m.reaction",TYPING:"m.typing",SENT:"m.sent",DELIVERED:"m.delivered",READ:"m.read",FAILED:"m.failed",SENDING:"m.sending"},Kf="m.conversation.member",IS="m.conversation.create",mo="m.conversation.closed";function Yf(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,c=>{const t=Math.random()*16|0;return(c==="x"?t:t&3|8).toString(16)})}function Jf(c="req"){return`${c}-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function Bd(c){return c&&(Array.isArray(c.attachments)||(c.attachments=[]),c)}function zf(c){return c&&(c.content&&Bd(c.content),c)}function bS(c){return c??{}}function wS(c){var t;return c?(Bd(c),!!(c.content||(t=c.attachments)!=null&&t.length)):!1}function OS(c){return c?c.startsWith("image/")?"image":c.startsWith("video/")?"video":c.startsWith("audio/")?"audio":"file":"file"}class DS{constructor(t){this.msrpSession=null,this.extendedSession=null,this.conversationsMap=new Map,this.pendingUploads=new Map,this.pendingFileAccessRequests=new Map,this.uploadRequestTimeoutMs=3e4,this.fileAccessTimeoutMs=3e4,this.typingKeepAliveInterval=null,this.typingKeepAliveConversationKey=null,this.typingKeepAliveIntervalMs=2e3,this.context=t,this.context.on(this.context.newMSRPSessionEventName,this.newMSRPSessionCallback.bind(this))}get isMSRPInitializing(){return this.isMSRPInitializingValue}get getMsrpSession(){return this.msrpSession}get hasActiveSession(){return this.extendedSession!==null}get conversations(){const t={};return this.conversationsMap.forEach((s,i)=>{t[i]=s}),t}msrpAnswer(t){this.extendedSession&&this.updateMSRPSession(this.extendedSession)}updateMSRPSession(t){this.msrpSession=Pf(t),this.context.emit("changeMsrpSession",this.msrpSession)}setMSRPSession(t){this.msrpSession=Pf(t),this.extendedSession=t,this.context.emit("changeMsrpSession",this.msrpSession)}addMSRPMessage(t,s){this.context.emit("newMSRPMessage",{message:t,session:s})}messageTerminate(t){this.extendedSession&&this.extendedSession._status!==8&&this.extendedSession.terminate()}addMessageSession(t){var s;t._id&&((s=this.extendedSession)==null?void 0:s._id)!==t._id&&this.setMSRPSession(t)}triggerMSRPListener({listenerType:t,session:s,event:i}){const a=this.context.listenersList[t];!a||!a.length||a.forEach(n=>{n(s,i)})}clearMSRPSession(){this.msrpSession=null,this.extendedSession=null,this.context.emit("changeMsrpSession",this.msrpSession)}newMSRPSessionCallback(t){t.session._id||(t.session._id=t.request.call_id+t.request.from._parameters.tag);const s=t.session;s.on("ended",i=>{var a;this.triggerMSRPListener({listenerType:Xt.CALL_ENDED,session:s,event:i}),((a=this.extendedSession)==null?void 0:a._id)===s._id&&this.clearMSRPSession()}),s.on("failed",i=>{var a;this.triggerMSRPListener({listenerType:Xt.CALL_FAILED,session:s,event:i}),((a=this.extendedSession)==null?void 0:a._id)===s._id&&this.clearMSRPSession()}),s.on("confirmed",i=>{this.triggerMSRPListener({listenerType:Xt.CALL_CONFIRMED,session:s,event:i}),this.updateMSRPSession(s)}),s.on("newMessage",i=>{this.addMSRPMessage(i,s),this.processIncomingMSRPMessage(i)}),this.addMessageSession(s)}setIsMSRPInitializing(t){this.isMSRPInitializingValue=t,this.context.emit("isMSRPInitializingChanged",t)}getUserUri(){var t;return(t=this.context.configuration)!=null&&t.uri?typeof this.context.configuration.uri=="string"?this.context.configuration.uri:this.context.configuration.uri.toString():""}initMSRP(t={}){const s=this.extractSipUser(this.getUserUri());if(!s)return console.error("Cannot init MSRP: current user SIP identity not available");const i=this.context.startMSRP(s,t);i.on("active",()=>{this.addMessageSession(i),i.sendMSRP(""),this.setIsMSRPInitializing(!1)}),this.setIsMSRPInitializing(!0)}initMSRPAndSendMessage(t,s,i={}){if(t.length===0)return console.error("Target must be a valid string");const a=this.context.startMSRP(t,i);a.on("active",()=>{this.addMessageSession(a),a.sendMSRP(s),this.setIsMSRPInitializing(!1)}),this.setIsMSRPInitializing(!0)}sendMSRP(t,s){if(!this.extendedSession)throw new Error("No active MSRP session");this.extendedSession.sendMSRP(s)}safeSendMSRP(t){if(!this.msrpSession||!this.extendedSession)return console.warn("safeSendMSRP: no active MSRP session - message dropped",t),!1;try{return this.extendedSession.sendMSRP(t),!0}catch(s){return console.error("safeSendMSRP error:",s),this.clearMSRPSession(),!1}}buildCreateConversationEvent(t){return{type:Pe.CREATE,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{creator:this.getUserUri(),invitee:t}}}buildTextMessageEvent(t,s){return{type:Pe.MESSAGE,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{message_type:"text",content:s,txn_id:Yf()}}}buildMediaMessageEvent(t,s,i=""){const a=s.media_type||OS(s.mime_type),n={kind:a,mime_type:s.mime_type,filename:s.filename};return s.preview_url&&(n.preview_url=s.preview_url),s.icon_url&&(n.icon_url=s.icon_url),s.transcription&&(n.transcription=s.transcription),{type:Pe.MESSAGE,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{message_type:a,content:i||s.filename||"",attachments:[n],txn_id:Yf()}}}buildMemberEvent(t,s,i,a){const n={type:Pe.MEMBER,conversationKey:t,sender:this.getUserUri(),state_key:s,origin_server_ts:Date.now(),content:{membership:i}};return a&&(n.content.role=a),n}buildCloseConversationEvent(t,s="Conversation resolved",i="resolved"){const a=Date.now();return{type:Pe.CLOSED,conversationKey:t,sender:this.getUserUri(),origin_server_ts:a,content:{reason:s,cause:i,closed_by:this.getUserUri(),closed_at:a}}}buildReactionEvent(t,s,i){return{type:Pe.REACTION,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{relates_to:{event_id:s,key:i}}}}buildTypingEvent(t,s){return{type:Pe.TYPING,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{typing:s}}}buildReadReceiptEvent(t,s){return{type:Pe.READ,event_id:s,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{ts:Date.now(),up_to:!0}}}sendCreateConversationMessage(t){if(!this.extendedSession)return console.warn("No MSRP session available for creating conversation"),!1;const i=(Array.isArray(t)?t:[t]).map(a=>(a??"").trim()).filter(a=>a.length>0).map(a=>a.startsWith("sip:")?a:`sip:${a}@${this.context.sipDomain}`);return i.length===0?(console.log("Room creation cancelled - invitee required"),!1):this.safeSendMSRP(JSON.stringify(this.buildCreateConversationEvent(i)))}sendTextMessage(t,s){const i=(s??"").trim();return!t||!i?!1:this.safeSendMSRP(JSON.stringify(this.buildTextMessageEvent(t,i)))}sendMediaMessage(t,s,i=""){return!t||!s?!1:this.safeSendMSRP(JSON.stringify(this.buildMediaMessageEvent(t,s,i)))}sendReaction(t,s,i){return!t||!s||!i?!1:this.safeSendMSRP(JSON.stringify(this.buildReactionEvent(t,s,i)))}sendTypingIndicator(t,s){return t?this.safeSendMSRP(JSON.stringify(this.buildTypingEvent(t,s))):!1}startTypingKeepAlive(t){t&&(this.stopTypingKeepAlive(!1),this.typingKeepAliveConversationKey=t,this.sendTypingIndicator(t,!0),this.typingKeepAliveInterval=setInterval(()=>{this.typingKeepAliveConversationKey&&this.hasActiveSession?this.sendTypingIndicator(this.typingKeepAliveConversationKey,!0):this.stopTypingKeepAlive(!0)},this.typingKeepAliveIntervalMs))}stopTypingKeepAlive(t=!0){this.typingKeepAliveInterval&&(clearInterval(this.typingKeepAliveInterval),this.typingKeepAliveInterval=null);const s=this.typingKeepAliveConversationKey;this.typingKeepAliveConversationKey=null,t&&s&&this.sendTypingIndicator(s,!1)}sendReadReceipt(t,s){return!t||!s||!this.hasActiveSession?!1:this.safeSendMSRP(JSON.stringify(this.buildReadReceiptEvent(t,s)))}closeConversation(t,s="Conversation resolved",i="resolved"){const a=this.conversationsMap.get(t);if(!a||this.isConversationClosed(a))return!1;const n=a.currentUserRole||"assigned";return n!=="in_charge"&&n!=="manager"?!1:this.safeSendMSRP(JSON.stringify(this.buildCloseConversationEvent(t,s,i)))}changeMemberRole(t,s,i){const a=this.conversationsMap.get(t),n=(a==null?void 0:a.currentUserRole)||"assigned";return n!=="in_charge"&&n!=="manager"?(console.warn("Not authorized to change roles (role:",n,")"),!1):this.safeSendMSRP(JSON.stringify(this.buildMemberEvent(t,s,"join",i)))}acceptInvite(t){return this.safeSendMSRP(JSON.stringify(this.buildMemberEvent(t,this.getUserUri(),"join")))}rejectInvite(t){const s=this.safeSendMSRP(JSON.stringify(this.buildMemberEvent(t,this.getUserUri(),"leave")));return s&&this.conversationsMap.delete(t)&&this.context.emit("msrpConversationRemoved",{conversationKey:t}),s}leaveConversation(t){const s=this.safeSendMSRP(JSON.stringify(this.buildMemberEvent(t,this.getUserUri(),"leave")));return s&&this.conversationsMap.delete(t)&&this.context.emit("msrpConversationRemoved",{conversationKey:t}),s}requestUploadUrl(t,s,i,a){return new Promise((n,r)=>{if(!this.hasActiveSession){r(new Error("No MSRP session available"));return}const h=Jf("upload"),d={type:Pe.UPLOAD_REQUEST,conversationKey:t,sender:this.getUserUri(),origin_server_ts:Date.now(),content:{request_id:h,filename:s,mime_type:i,file_size:a}};this.pendingUploads.set(h,{resolve:n,reject:r}),setTimeout(()=>{this.pendingUploads.has(h)&&(this.pendingUploads.delete(h),r(new Error("Upload request timeout")))},this.uploadRequestTimeoutMs),this.safeSendMSRP(JSON.stringify(d))||(this.pendingUploads.delete(h),r(new Error("Failed to send upload request")))})}requestFileAccess(t,s){return new Promise((i,a)=>{if(!this.hasActiveSession){a(new Error("No MSRP session available"));return}const n=Jf("file-access-req"),r={type:Pe.FILE_ACCESS_REQUEST,event_id:n,conversationKey:t,sender:this.getUserUri(),content:{request_id:n,event_id:s}};this.pendingFileAccessRequests.set(n,{resolve:i,reject:a}),setTimeout(()=>{this.pendingFileAccessRequests.has(n)&&(this.pendingFileAccessRequests.delete(n),a(new Error("File access request timed out")))},this.fileAccessTimeoutMs),this.safeSendMSRP(JSON.stringify(r))||(this.pendingFileAccessRequests.delete(n),a(new Error("Failed to send file access request")))})}async uploadFile(t,s,i=""){if(!t)throw new Error("conversationKey is required");if(!s)throw new Error("file is required");const a=await this.requestUploadUrl(t,s.name,s.type||"application/octet-stream",s.size),n=new FormData;n.append("file",s);const r=await fetch(a.upload_url,{method:"POST",body:n});if(!r.ok){const d=await r.json().catch(()=>({}));throw new Error((d==null?void 0:d.error)||`Upload failed: HTTP ${r.status}`)}const h=await r.json();return this.sendMediaMessage(t,h,i),h}processIncomingMSRPMessage(t){if(!t||t.direction==="outgoing")return;let s;try{s=JSON.parse(t.body)}catch{console.warn("Received non-JSON MSRP message",t.body);return}this.handleIncomingEvent(s)}handleIncomingEvent(t){const s=zf(t);if(!(!s||!s.type))switch(s.type){case Pe.SYNC:this.handleIncomingSync(s);break;case Pe.CREATE:this.handleIncomingConversationCreate(s);break;case Pe.MESSAGE:this.handleIncomingConversationMessage(s);break;case Pe.MEMBER:this.handleIncomingConversationMember(s);break;case Pe.CLOSED:this.handleIncomingConversationClosed(s);break;case Pe.REACTION:this.handleIncomingReaction(s);break;case Pe.TYPING:this.handleIncomingTyping(s);break;case Pe.SENT:case Pe.SENDING:case Pe.DELIVERED:case Pe.READ:case Pe.FAILED:this.handleIncomingReceipt(s);break;case Pe.UPLOAD_RESPONSE:this.handleIncomingUploadResponse(s);break;case Pe.FILE_ACCESS_RESPONSE:this.handleIncomingFileAccessResponse(s);break;default:console.warn("Unhandled MSRP event:",s.type,s)}}handleIncomingSync(t){if(!t.content)return;const s=t.content.conversations??[],i=this.getUserUri(),a=this.extractSipUser(i),n={};s.forEach(r=>{const h=this.conversationKeyOf(r);if(!h)return;const{creator:d,timeline:_,created_at:g,updated_at:T}=r,S=bS(r.state_events),E=new Set,C=new Map;let A=null,R="assigned";S[Kf]&&Object.entries(S[Kf]).forEach(([I,ie])=>{var _e,U;const N=(_e=ie.content)==null?void 0:_e.membership,$=((U=ie.content)==null?void 0:U.role)||"assigned";this.extractSipUser(I)===a&&(A=N??null,N==="join"&&(R=$)),N==="join"&&(E.add(I),C.set(I,$))});const F=(_||[]).filter(I=>I.type===Pe.MESSAGE).map(I=>zf({...I}));F.length>0&&(n[h]=F),this.upsertConversationState(h,{conversationKey:h,creator:d??null,members:E,memberRoles:C,currentUserRole:R,currentUserStatus:A,state_events:S,created_at:g||Date.now(),updated_at:T||Date.now(),status:r.status})}),this.context.emit("msrpSyncCompleted",{conversations:this.snapshotConversationsMap(),messagesByConversation:n})}handleIncomingConversationCreate(t){var a;const s=this.conversationKeyOf(t);if(!s||this.conversationsMap.has(s))return;const i=this.getUserUri();this.upsertConversationState(s,{conversationKey:s,creator:((a=t.content)==null?void 0:a.creator)||t.sender||null,members:new Set([i]),memberRoles:new Map([[i,"in_charge"]]),currentUserRole:"in_charge",state_events:{[IS]:{"":t}},created_at:t.origin_server_ts||Date.now(),updated_at:t.origin_server_ts||Date.now(),currentUserStatus:"join"}),this.context.emit("msrpConversationCreated",{conversationKey:s,conversation:this.snapshotConversation(this.conversationsMap.get(s))})}handleIncomingConversationMessage(t){const s=this.conversationKeyOf(t);if(!s||!wS(t.content))return;const i=this.conversationsMap.get(s);i&&(i.updated_at=t.origin_server_ts||Date.now(),this.context.emit("msrpMessageAdded",{conversationKey:s,message:t}))}handleIncomingConversationClosed(t){const s=this.conversationKeyOf(t);if(!s)return;const i=this.conversationsMap.get(s);i&&(i.state_events||(i.state_events={}),i.state_events[mo]=i.state_events[mo]||{},i.state_events[mo][""]=t,i.status="closed",i.updated_at=t.origin_server_ts||Date.now(),this.context.emit("msrpConversationUpdated",{conversationKey:s,patch:{status:i.status,state_events:{...i.state_events},updated_at:i.updated_at}}))}handleIncomingReceipt(t){const s=this.conversationKeyOf(t),i=t.event_id;if(!s||!i)return;const n={[Pe.SENDING]:"pending",[Pe.SENT]:"sent",[Pe.DELIVERED]:"delivered",[Pe.READ]:"read",[Pe.FAILED]:"failed"}[t.type];if(!n)return;const r=t.origin_server_ts||Date.now(),h=this.conversationsMap.get(s);h&&(h.updated_at=r),this.context.emit("msrpReceiptChanged",{conversationKey:s,eventId:i,status:n,updatedAt:r})}handleIncomingTyping(t){var i;const s=this.conversationKeyOf(t);s&&t.sender!==this.getUserUri()&&this.context.emit("msrpTyping",{conversationKey:s,sender:t.sender,isTyping:!!((i=t.content)!=null&&i.typing)})}handleIncomingReaction(t){var d,_;const s=this.conversationKeyOf(t),i=(d=t.content)==null?void 0:d.relates_to,a=(i==null?void 0:i.key)||(i==null?void 0:i.emoji);if(!s||!(i!=null&&i.event_id)||!a)return;const n=((_=t.content)==null?void 0:_.action)==="remove"?"remove":"add",r=t.origin_server_ts||Date.now(),h=this.conversationsMap.get(s);h&&(h.updated_at=r),this.context.emit("msrpReactionChanged",{conversationKey:s,eventId:i.event_id,emoji:a,action:n,sender:t.sender,updatedAt:r})}handleIncomingConversationMember(t){const s=this.conversationKeyOf(t);if(!s)return;const{state_key:i,content:a}=t,n=a==null?void 0:a.membership,r=(a==null?void 0:a.role)||"assigned",h=this.conversationsMap.has(s);let d=this.conversationsMap.get(s);d||(d={conversationKey:s,creator:null,members:new Set,memberRoles:new Map,currentUserRole:"assigned",state_events:{},created_at:t.origin_server_ts||Date.now(),updated_at:t.origin_server_ts||Date.now(),currentUserStatus:null},this.conversationsMap.set(s,d));const _=this.getUserUri(),g=this.extractSipUser(i),T=this.extractSipUser(_),S=i===_||!!g&&!!T&&g===T;let E=!1;if(n==="join")d.members.add(i),d.memberRoles.set(i,r),S&&(d.currentUserStatus="join",d.currentUserRole=r);else if(n==="leave"||n==="ban")d.members.delete(i),d.memberRoles.delete(i),S&&(d.currentUserStatus="leave",this.conversationsMap.delete(s),E=!0);else if(n==="invite"){if(!S)return;d.currentUserStatus="invite",d.memberRoles.set(i,r)}if(d.updated_at=t.origin_server_ts||Date.now(),E){this.context.emit("msrpConversationRemoved",{conversationKey:s});return}if(!h){this.context.emit("msrpConversationCreated",{conversationKey:s,conversation:this.snapshotConversation(d)});return}this.context.emit("msrpConversationUpdated",{conversationKey:s,patch:{members:new Set(d.members),memberRoles:new Map(d.memberRoles),currentUserRole:d.currentUserRole,currentUserStatus:d.currentUserStatus,updated_at:d.updated_at}})}handleIncomingUploadResponse(t){const s=t.content||{},i=s.request_id,a=this.pendingUploads.get(i);a&&(this.pendingUploads.delete(i),s.error?a.reject(new Error(s.error)):a.resolve({upload_url:s.upload_url,expires_in:s.expires_in,mime_type:s.mime_type,request_id:s.request_id,filename:s.filename,preview_url:s.preview_url,icon_url:s.icon_url,transcription:s.transcription,media_type:s.media_type}))}handleIncomingFileAccessResponse(t){const s=t.content||{},i=s.request_id,a=this.pendingFileAccessRequests.get(i);a&&(this.pendingFileAccessRequests.delete(i),s.error?a.reject(s.error):s.download_url?a.resolve(s.download_url):a.reject(new Error("No download URL in response")))}upsertConversationState(t,s){this.conversationsMap.set(t,{...s,conversationKey:t})}snapshotConversation(t){return{...t,members:new Set(t.members),memberRoles:new Map(t.memberRoles),state_events:{...t.state_events}}}snapshotConversationsMap(){const t={};return this.conversationsMap.forEach((s,i)=>{t[i]=this.snapshotConversation(s)}),t}isConversationClosed(t){var s,i;return!!((i=(s=t==null?void 0:t.state_events)==null?void 0:s[mo])!=null&&i[""])}conversationKeyOf(t){return t?typeof t=="string"?t:t.conversationKey??null:null}extractSipUser(t){if(!t)return null;const i=(typeof t=="string"?t:String(t)).match(/^sip:([^@]+)@/);return i?i[1]:null}extractDisplayName(t){if(!t)return"Unknown";const s=typeof t=="string"?t:String(t);if(s.startsWith("sip:")){const i=s.match(/^sip:([^@]+)@/);return i?i[1]:s}return s.startsWith("whatsapp:")?s.slice(9):s.startsWith("wa:")?s.slice(3):s.startsWith("greenapi:")?s.slice(9):s.startsWith("sms:")?s.slice(4):s}}const go={AUDIO:"audio",VIDEO:"video",MSRP:"msrp"};class Gd{constructor(t){this.opensips=null,this.session=null,this.name=null,this.name=t}setOpensips(t){this.opensips=t}setSession(t){this.session=t}kill(){this.opensips.kill(this.name)}}class Wd extends Gd{constructor(t,s){super(t),this._candidates=[],this._subscribeSent=!1,this._configureSent=!1,this._lastTrickleReceived=!1,this.type=s}connect(t={}){this.opaqueId=this.session.generateOpaqueId();const s=Me.cloneArray(t.extraHeaders),i={from_tag:this.session._from_tag};t.fromUserName&&(i.from_uri=new In("sip",t.fromUserName,this.session._ua.configuration.uri.host),s.push(`P-Preferred-Identity: ${this.session._ua.configuration.uri.toString()}`)),t.fromDisplayName&&(i.from_display_name=t.fromDisplayName),s.push(`Contact: ${this.session._contact}`),s.push("Content-Type: application/json"),this.session._sessionTimers.enabled&&s.push(`Session-Expires: ${this.session._sessionTimers.defaultExpires}${this.session._ua.configuration.session_timers_force_refresher?";refresher=uac":""}`),this._request=new Ct.InitialOutgoingInviteRequest(this.session.target,this.session._ua,i,s),this._createRTCConnection(),this._sendInitialRequest()}getStream(){return this.stream}getConnection(){return this._connection}_createRTCConnection(){this._connection=new RTCPeerConnection({iceServers:[{urls:"stun:turn.voicenter.co",credential:"kxsjahnsdjns3eds23esd",username:"turn2es21e"}]});let t;this._connection.onicecandidate=s=>{this._connection.signalingState!=="stable"&&this._connection.signalingState!=="have-local-offer"||s.candidate&&(this._candidates.push(s.candidate),clearTimeout(t),t=setTimeout(()=>{this._lastTrickleReceived=!0,this._subscribeSent&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})},500))}}addTracks(t){t.forEach(s=>{this._connection.addTrack(s)})}async _sendInitialRequest(){const t=new sl(this.session._ua,this._request,{onRequestTimeout:()=>{this.session.onRequestTimeout()},onTransportError:()=>{this.session.onTransportError()},onAuthenticated:n=>{this._request=n},onReceiveResponse:n=>{this._receiveInviteResponse(n)}});if(await this.generateStream(),!this.stream||!this.stream.getTracks().length)return;this.addTracks(this.stream.getTracks());const s={audio:!1,video:!0};this.jsep_offer=await this._connection.createOffer(s),await this._connection.setLocalDescription(this.jsep_offer);const i={janus:"attach",plugin:"janus.plugin.videoroom",opaque_id:this.opaqueId},a=JSON.stringify(i);this._request.body=a,t.send()}_receiveInviteResponse(t){if(this._publisherSubscribeSent||!t.body)return;const s=JSON.parse(t.body);this.handleId=s.data.id;const i={janus:"message",body:{request:"join",room:this.session.room_id,ptype:"publisher",display:this.session.display_name+" (Screen Share)",opaque_id:this.opaqueId},handle_id:this.handleId},a=[this.session.getPTypeHeader(kt.PUBLISHER)];this.session.sendRequest(H.SUBSCRIBE,{extraHeaders:a,body:JSON.stringify(i),eventHandlers:{onSuccessResponse:async n=>{var r,h,d,_;if(n.status_code===200){if(this._subscribeSent=!0,n.body)try{const g=JSON.parse(n.body)||{};((h=(r=g.plugindata)==null?void 0:r.data)==null?void 0:h.videoroom)==="joined"&&this.session.myFeedList.push(g.plugindata.data.id),(_=(d=g.plugindata)==null?void 0:d.data)!=null&&_.publishers&&this.session.receivePublishers(g)}catch(g){console.error(g)}this._lastTrickleReceived&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})}}}}),this._publisherSubscribeSent=!0}async _sendConfigureMessage(t){const s=this._candidates.map(r=>({janus:"trickle",candidate:r,handle_id:this.handleId,session_id:this.session.session_id})),a={configure:{janus:"message",body:{request:"configure",record:!0,filename:this.session.getRecordFileName(),...t},jsep:this.jsep_offer,handle_id:this.handleId,session_id:this.session.session_id},trickles:[...s]},n=["Content-Type: application/json",this.session.getPTypeHeader(kt.ICE)];this.session.sendRequest(H.INFO,{extraHeaders:n,body:JSON.stringify(a),eventHandlers:{onSuccessResponse:async r=>{this._configureSent=!0;const d=r.data.split(`\r
159
- `),_=d[d.length-1],g=JSON.parse(_);await this._connection.setRemoteDescription(g.jsep),this._candidates=[]}}})}_sendDetach(){const t={janus:"detach",handle_id:this.handleId,session_id:this.session.session_id},s=[this.session.getPTypeHeader(kt.DETACH)];this.session.sendRequest(H.INFO,{extraHeaders:s,body:JSON.stringify(t)}),this.session._ua.emit("pluginDetach",this.name)}async stopMedia(){this._connection&&(this._connection.close(),this._connection=null),this.stream&&(this.stream=null)}async stop(){await this.session.stopProcessPlugins(this.type);const t=this._connection.getSenders();t.forEach(s=>{const i=s.track;i&&i.stop()}),t.forEach(s=>{this._connection.removeTrack(s)}),await this.stopMedia(),this._sendDetach()}async generateStream(){throw new Error("generateStream method is not implemented")}}class Kd extends Gd{constructor(t,s,i={}){super(t),this.stream=null,this.running=!1,this.immediate=!1,this.type="video",this.immediate=i.immediate||!1,this.type=s}start(t){return t}stop(){throw new Error("stop method is not implemented")}async process(t){if(this.immediate){const s=await this.start(t);return this.running=!0,s}return t}async connect(){this.running=!0,await this.session.resyncPlugins(this.type)}terminate(){this.stop()}async kill(){this.stop(),this.running=!1,await this.session.resyncPlugins(this.type)}}class NS extends ZT{constructor(t,s){if(!t.modules.length)throw new Error("options.modules should include at least 1 module");const i={...t.configuration,sockets:t.socketInterfaces.map(a=>new Ev.WebSocketInterface(a))};super(i),this.initialized=!1,this.connected=!1,this.logger=console,this.newRTCSessionEventName="newRTCSession",this.registeredEventName="registered",this.unregisteredEventName="unregistered",this.disconnectedEventName="disconnected",this.connectedEventName="connected",this.newMSRPSessionEventName="newMSRPSession",this.isReconnecting=!1,this.activeConnection=!1,this.waitingForSessionHangup=!1,this.waitingForSessionTimeout=null,this.reconnectionAttemptsLimit=1/0,this.reconnectionAttemptsCounter=0,this.audio=null,this.msrp=null,this.video=null,this.listenersList={},this.modules=[],t.pnExtraHeaders&&Object.keys(t.pnExtraHeaders).length&&this.registrator().setExtraContactUriParams(t.pnExtraHeaders),this.options=t,this.modules=t.modules,t.configuration.reconnectionAttemptsLimit&&(this.reconnectionAttemptsLimit=t.configuration.reconnectionAttemptsLimit),s&&ov(s)&&(this.logger=s)}isWaitingForSessionHangup(){return this.waitingForSessionHangup}stopSessionAfterWaiting(){this.setInitialized(!1),this.waitingForSessionHangup=!1,clearTimeout(this.waitingForSessionTimeout),this.waitingForSessionTimeout=null,this.activeConnection&&this.reconnect()}get hasActiveSessions(){return this.modules.includes(go.AUDIO)?this.audio.hasActiveAnsweredCalls:!1}on(t,s){return super.on(t,s)}off(t,s){return super.off(t,s)}emit(t,s){return super.emit(t,s)}get sipDomain(){return this.options.sipDomain}use(t){if(this.newStreamPlugins.find(s=>s.name===t.name)||this.processStreamPlugins.find(s=>s.name===t.name))throw new Error(`Plugin with name ${t.name} already exists`);if(t instanceof Wd)t.setOpensips(this),this.newStreamPlugins.push(t);else if(t instanceof Kd)t.setOpensips(this),this.processStreamPlugins.push(t);else throw new Error("Wrong plugin instance")}getPlugin(t){return this.newStreamPlugins.find(s=>s.name===t)||this.processStreamPlugins.find(s=>s.name===t)}reconnect(){if(this.reconnectionAttemptsCounter<this.reconnectionAttemptsLimit){const s=5e3*Math.pow(2,this.reconnectionAttemptsCounter);this.reconnectionAttemptsCounter++,setTimeout(this.start.bind(this),s)}else this.emit("reconnectionAttemptsLimitReached",void 0)}begin(){if(this.isConnected()){console.error("Connection is already established");return}return this.modules.includes(go.AUDIO)&&(this.audio=new AS(this)),this.modules.includes(go.MSRP)&&(this.msrp=new DS(this)),this.modules.includes(go.VIDEO)&&(this.video=new RS(this)),this.on(this.registeredEventName,()=>{this.logger.log("Successfully registered to",this.options.socketInterfaces[0]),this.setInitialized(!0)}),this.on(this.unregisteredEventName,()=>{this.logger.log("Unregistered from",this.options.socketInterfaces[0]),this.setInitialized(!1)}),this.on(this.connectedEventName,()=>{this.logger.log("Connected to",this.options.socketInterfaces[0]),this.setConnected(!0),this.setReconnecting(!1),this.activeConnection=!0,this.waitingForSessionHangup=!1,this.reconnectionAttemptsCounter=0}),this.on(this.disconnectedEventName,()=>{this.setConnected(!1),!this.isReconnecting&&(this.setReconnecting(!0),this.logger.log("Disconnected from",this.options.socketInterfaces[0]),this.logger.log("Reconnecting to",this.options.socketInterfaces[0]),this.hasActiveSessions?(this.waitingForSessionHangup=!0,this.stop(!1),this.waitingForSessionTimeout=setTimeout(()=>{this.terminateAllSessions(),this.setInitialized(!1),this.waitingForSessionHangup=!1,this.activeConnection&&this.reconnect()},12e5)):(this.stop(),this.setInitialized(!1),this.activeConnection&&this.reconnect()))}),this.logger.log("Connecting to",this.options.socketInterfaces[0]),this.start(),this}disconnect(){this.activeConnection=!1,this.stop()}subscribe(t,s){const a=!this.listenersList[t]||!this.listenersList[t].length?[s]:[...this.listenersList[t],s];this.listenersList={...this.listenersList,[t]:a}}removeIListener(t){const s={...this.listenersList};delete s[t],this.listenersList={...s}}triggerListener({listenerType:t,session:s,event:i}){const a=this.listenersList[t];!a||!a.length||a.forEach(n=>{n(s,i)})}setInitialized(t){this.initialized=t,this.emit("ready",t)}setConnected(t){this.connected=t,this.emit("connection",t)}setReconnecting(t){this.isReconnecting=t,this.emit("reconnecting",t)}}exports.BaseNewStreamPlugin=Wd;exports.BaseProcessStreamPlugin=Kd;exports.default=NS;
159
+ `),_=d[d.length-1],g=JSON.parse(_);await this._connection.setRemoteDescription(g.jsep),this._candidates=[]}}})}_sendDetach(){const t={janus:"detach",handle_id:this.handleId,session_id:this.session.session_id},s=[this.session.getPTypeHeader(kt.DETACH)];this.session.sendRequest(H.INFO,{extraHeaders:s,body:JSON.stringify(t)}),this.session._ua.emit("pluginDetach",this.name)}async stopMedia(){this._connection&&(this._connection.close(),this._connection=null),this.stream&&(this.stream=null)}async stop(){await this.session.stopProcessPlugins(this.type);const t=this._connection.getSenders();t.forEach(s=>{const i=s.track;i&&i.stop()}),t.forEach(s=>{this._connection.removeTrack(s)}),await this.stopMedia(),this._sendDetach()}async generateStream(){throw new Error("generateStream method is not implemented")}}class Kd extends Gd{constructor(t,s,i={}){super(t),this.stream=null,this.running=!1,this.immediate=!1,this.type="video",this.immediate=i.immediate||!1,this.type=s}start(t){return t}stop(){throw new Error("stop method is not implemented")}async process(t){if(this.immediate){const s=await this.start(t);return this.running=!0,s}return t}async connect(){this.running=!0,await this.session.resyncPlugins(this.type)}terminate(){this.stop()}async kill(){this.stop(),this.running=!1,await this.session.resyncPlugins(this.type)}}class NS extends ZT{constructor(t,s){if(!t.modules.length)throw new Error("options.modules should include at least 1 module");const i={...t.configuration,sockets:t.socketInterfaces.map(a=>new Ev.WebSocketInterface(a))};super(i),this.initialized=!1,this.connected=!1,this.logger=console,this.newRTCSessionEventName="newRTCSession",this.registeredEventName="registered",this.unregisteredEventName="unregistered",this.disconnectedEventName="disconnected",this.connectedEventName="connected",this.newMSRPSessionEventName="newMSRPSession",this.isReconnecting=!1,this.activeConnection=!1,this.waitingForSessionHangup=!1,this.waitingForSessionTimeout=null,this.reconnectionAttemptsLimit=1/0,this.reconnectionAttemptsCounter=0,this.audio=null,this.msrp=null,this.video=null,this.listenersList={},this.modules=[],t.pnExtraHeaders&&Object.keys(t.pnExtraHeaders).length&&this.registrator().setExtraContactUriParams(t.pnExtraHeaders),this.options=t,this.modules=t.modules,t.configuration.reconnectionAttemptsLimit&&(this.reconnectionAttemptsLimit=t.configuration.reconnectionAttemptsLimit),s&&ov(s)&&(this.logger=s)}isWaitingForSessionHangup(){return this.waitingForSessionHangup}stopSessionAfterWaiting(){this.setInitialized(!1),this.waitingForSessionHangup=!1,clearTimeout(this.waitingForSessionTimeout),this.waitingForSessionTimeout=null,this.activeConnection&&this.reconnect()}get hasActiveSessions(){return this.modules.includes(go.AUDIO)?this.audio.hasActiveAnsweredCalls:!1}on(t,s){return super.on(t,s)}off(t,s){return super.off(t,s)}emit(t,s){return super.emit(t,s)}get sipDomain(){return this.options.sipDomain}use(t){if(this.newStreamPlugins.find(s=>s.name===t.name)||this.processStreamPlugins.find(s=>s.name===t.name))throw new Error(`Plugin with name ${t.name} already exists`);if(t instanceof Wd)t.setOpensips(this),this.newStreamPlugins.push(t);else if(t instanceof Kd)t.setOpensips(this),this.processStreamPlugins.push(t);else throw new Error("Wrong plugin instance")}getPlugin(t){return this.newStreamPlugins.find(s=>s.name===t)||this.processStreamPlugins.find(s=>s.name===t)}reconnect(){if(this.reconnectionAttemptsCounter<this.reconnectionAttemptsLimit){const s=5e3*Math.pow(2,this.reconnectionAttemptsCounter);this.reconnectionAttemptsCounter++,setTimeout(this.start.bind(this),s)}else this.emit("reconnectionAttemptsLimitReached",void 0)}begin(){if(this.isConnected()){console.error("Connection is already established");return}return this.modules.includes(go.AUDIO)&&(this.audio=new AS(this)),this.modules.includes(go.MSRP)&&(this.msrp=new DS(this)),this.modules.includes(go.VIDEO)&&(this.video=new RS(this)),this.on(this.registeredEventName,()=>{this.logger.log("Successfully registered to",this.options.socketInterfaces[0]),this.setInitialized(!0)}),this.on(this.unregisteredEventName,()=>{this.logger.log("Unregistered from",this.options.socketInterfaces[0]),this.setInitialized(!1)}),this.on(this.connectedEventName,()=>{this.logger.log("Connected to",this.options.socketInterfaces[0]),this.setConnected(!0),this.setReconnecting(!1),this.activeConnection=!0,this.waitingForSessionHangup=!1,this.reconnectionAttemptsCounter=0}),this.on(this.disconnectedEventName,()=>{this.setConnected(!1),!this.isReconnecting&&(this.setReconnecting(!0),this.logger.log("Disconnected from",this.options.socketInterfaces[0]),this.logger.log("Reconnecting to",this.options.socketInterfaces[0]),this.hasActiveSessions?(this.waitingForSessionHangup=!0,this.stop(!1),this.waitingForSessionTimeout=setTimeout(()=>{this.terminateAllSessions(),this.setInitialized(!1),this.waitingForSessionHangup=!1,this.activeConnection&&this.reconnect()},12e5)):(this.stop(),this.setInitialized(!1),this.activeConnection&&this.reconnect()))}),this.logger.log("Connecting to",this.options.socketInterfaces[0]),this.start(),this}disconnect(){this.activeConnection=!1,this.stop()}subscribe(t,s){const a=!this.listenersList[t]||!this.listenersList[t].length?[s]:[...this.listenersList[t],s];this.listenersList={...this.listenersList,[t]:a}}removeIListener(t){const s={...this.listenersList};delete s[t],this.listenersList={...s}}triggerListener({listenerType:t,session:s,event:i}){const a=this.listenersList[t];!a||!a.length||a.forEach(n=>{n(s,i)})}setInitialized(t){this.initialized=t,this.emit("ready",t)}setConnected(t){this.connected=t,this.emit("connection",t)}setReconnecting(t){this.isReconnecting=t,this.emit("reconnecting",t)}}exports.BaseNewStreamPlugin=Wd;exports.BaseProcessStreamPlugin=Kd;exports.MSRP_EVT=Pe;exports.default=NS;
@@ -25052,14 +25052,6 @@ class wS {
25052
25052
  var t;
25053
25053
  return (t = this.context.configuration) != null && t.uri ? typeof this.context.configuration.uri == "string" ? this.context.configuration.uri : this.context.configuration.uri.toString() : "";
25054
25054
  }
25055
- /**
25056
- * Open an MSRP session for the currently logged-in user. The SIP
25057
- * identity is resolved automatically from the OpenSIPSJS
25058
- * configuration, so the caller never has to pass it. Use this when
25059
- * the session is intended to act as a long-lived transport pipe and
25060
- * the first payload will be sent later through one of the higher-level
25061
- * actions (e.g. `sendCreateConversationMessage`).
25062
- */
25063
25055
  initMSRP(t = {}) {
25064
25056
  const s = this.extractSipUser(this.getUserUri());
25065
25057
  if (!s)
@@ -25069,12 +25061,6 @@ class wS {
25069
25061
  this.addMessageSession(i), i.sendMSRP(""), this.setIsMSRPInitializing(!1);
25070
25062
  }), this.setIsMSRPInitializing(!0);
25071
25063
  }
25072
- /**
25073
- * Open an MSRP session and push `body` as the first MSRP frame the
25074
- * moment the session goes active. Use this for the legacy
25075
- * "compose-and-send" flow where the first message is known at the
25076
- * time the session is opened.
25077
- */
25078
25064
  initMSRPAndSendMessage(t, s, i = {}) {
25079
25065
  if (t.length === 0)
25080
25066
  return console.error("Target must be a valid string");
@@ -25083,10 +25069,6 @@ class wS {
25083
25069
  this.addMessageSession(a), a.sendMSRP(s), this.setIsMSRPInitializing(!1);
25084
25070
  }), this.setIsMSRPInitializing(!0);
25085
25071
  }
25086
- /**
25087
- * Public raw send - kept for backward-compat with the old multi-session API.
25088
- * Ignores the passed callId/sessionId because we only ever hold one session.
25089
- */
25090
25072
  sendMSRP(t, s) {
25091
25073
  if (!this.extendedSession)
25092
25074
  throw new Error("No active MSRP session");
@@ -25095,8 +25077,7 @@ class wS {
25095
25077
  /**
25096
25078
  * Safe wrapper around session.sendMSRP. Returns true when the message was
25097
25079
  * handed off to the session; false when there is no active session or the
25098
- * underlying send threw. On failure the stored session is cleared so the
25099
- * next send attempt does not silently drop traffic on a half-dead session.
25080
+ * underlying send threw.
25100
25081
  */
25101
25082
  safeSendMSRP(t) {
25102
25083
  if (!this.msrpSession || !this.extendedSession)
@@ -25208,11 +25189,6 @@ class wS {
25208
25189
  };
25209
25190
  }
25210
25191
  // PUBLIC ACTIONS — outgoing requests
25211
- /**
25212
- * Create a new conversation by inviting one or more SIP URIs.
25213
- * Accepts plain numbers/usernames and rewrites them into full SIP URIs
25214
- * against the domain OpenSIPSJS was initialized with.
25215
- */
25216
25192
  sendCreateConversationMessage(t) {
25217
25193
  if (!this.extendedSession)
25218
25194
  return console.warn("No MSRP session available for creating conversation"), !1;
@@ -25232,13 +25208,6 @@ class wS {
25232
25208
  sendTypingIndicator(t, s) {
25233
25209
  return t ? this.safeSendMSRP(JSON.stringify(this.buildTypingEvent(t, s))) : !1;
25234
25210
  }
25235
- /**
25236
- * Start an automatic typing keep-alive loop for `conversationKey`. While
25237
- * active, a typing=true event is re-sent every `typingKeepAliveIntervalMs`
25238
- * so the remote side does not time out the indicator. Calling this with a
25239
- * different conversationKey or calling `stopTypingKeepAlive()` cancels
25240
- * any in-flight loop.
25241
- */
25242
25211
  startTypingKeepAlive(t) {
25243
25212
  t && (this.stopTypingKeepAlive(!1), this.typingKeepAliveConversationKey = t, this.sendTypingIndicator(t, !0), this.typingKeepAliveInterval = setInterval(() => {
25244
25213
  this.typingKeepAliveConversationKey && this.hasActiveSession ? this.sendTypingIndicator(this.typingKeepAliveConversationKey, !0) : this.stopTypingKeepAlive(!0);
@@ -25249,11 +25218,6 @@ class wS {
25249
25218
  const s = this.typingKeepAliveConversationKey;
25250
25219
  this.typingKeepAliveConversationKey = null, t && s && this.sendTypingIndicator(s, !1);
25251
25220
  }
25252
- /**
25253
- * Send a read receipt for `lastEventId` in `conversationKey`. The
25254
- * caller is responsible for resolving which event_id represents the
25255
- * "last seen" message because the module no longer stores chat history.
25256
- */
25257
25221
  sendReadReceipt(t, s) {
25258
25222
  return !t || !s || !this.hasActiveSession ? !1 : this.safeSendMSRP(JSON.stringify(this.buildReadReceiptEvent(t, s)));
25259
25223
  }
@@ -25374,11 +25338,6 @@ class wS {
25374
25338
  return this.sendMediaMessage(t, h, i), h;
25375
25339
  }
25376
25340
  // INCOMING EVENT PROCESSING
25377
- /**
25378
- * Parse a raw MSRP `newMessage` payload and dispatch it to the right
25379
- * conversation-state mutator. Outgoing messages and non-JSON payloads
25380
- * are ignored so the rest of the pipeline stays pure.
25381
- */
25382
25341
  processIncomingMSRPMessage(t) {
25383
25342
  if (!t || t.direction === "outgoing")
25384
25343
  return;
@@ -25625,15 +25584,6 @@ class wS {
25625
25584
  upsertConversationState(t, s) {
25626
25585
  this.conversationsMap.set(t, { ...s, conversationKey: t });
25627
25586
  }
25628
- /**
25629
- * Make a shallow snapshot of a conversation that is safe to hand off
25630
- * to an external consumer (e.g. a Vue composable).
25631
- *
25632
- * The mutable top-level collections (members, memberRoles,
25633
- * state_events) are cloned so subsequent internal mutations by the
25634
- * module cannot leak into the consumer's state. There is no
25635
- * `messages` field - chat history is owned by the consumer.
25636
- */
25637
25587
  snapshotConversation(t) {
25638
25588
  return {
25639
25589
  ...t,
@@ -25642,10 +25592,6 @@ class wS {
25642
25592
  state_events: { ...t.state_events }
25643
25593
  };
25644
25594
  }
25645
- /**
25646
- * Snapshot the whole conversations map - used only for the bulk
25647
- * `msrpSyncCompleted` emit.
25648
- */
25649
25595
  snapshotConversationsMap() {
25650
25596
  const t = {};
25651
25597
  return this.conversationsMap.forEach((s, i) => {
@@ -25656,25 +25602,15 @@ class wS {
25656
25602
  var s, i;
25657
25603
  return !!((i = (s = t == null ? void 0 : t.state_events) == null ? void 0 : s[mo]) != null && i[""]);
25658
25604
  }
25659
- /**
25660
- * Extract the conversationKey from either a string or an event/conversation object.
25661
- */
25662
25605
  conversationKeyOf(t) {
25663
25606
  return t ? typeof t == "string" ? t : t.conversationKey ?? null : null;
25664
25607
  }
25665
- /**
25666
- * Extract the user-part of a SIP URI, e.g. sip:103@example.com -> 103.
25667
- */
25668
25608
  extractSipUser(t) {
25669
25609
  if (!t)
25670
25610
  return null;
25671
25611
  const i = (typeof t == "string" ? t : String(t)).match(/^sip:([^@]+)@/);
25672
25612
  return i ? i[1] : null;
25673
25613
  }
25674
- /**
25675
- * Best-effort human-readable name for any URI we may encounter
25676
- * (SIP / WhatsApp / SMS / GreenAPI).
25677
- */
25678
25614
  extractDisplayName(t) {
25679
25615
  if (!t)
25680
25616
  return "Unknown";
@@ -27161,5 +27097,6 @@ class KS extends QT {
27161
27097
  export {
27162
27098
  OS as BaseNewStreamPlugin,
27163
27099
  DS as BaseProcessStreamPlugin,
27100
+ Pe as MSRP_EVT,
27164
27101
  KS as default
27165
27102
  };