samvyo-js-sdk 2.0.25 → 2.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/samvyo-js-sdk.js +1 -1
- package/package.json +1 -1
package/dest/samvyo-js-sdk.js
CHANGED
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
personMask = smoothstep(u_coverage.x, u_coverage.y, personMask);
|
|
229
229
|
outColor = vec4(frameColor * personMask + backgroundColor * (1.0 - personMask), 1.0);
|
|
230
230
|
}
|
|
231
|
-
`,{width:D,height:n}=B,o=D/n,s=Mi(A,A.VERTEX_SHADER,E),w=Mi(A,A.FRAGMENT_SHADER,i),a=Ki(A,s,w,I,g),y=A.getUniformLocation(a,"u_backgroundScale"),G=A.getUniformLocation(a,"u_backgroundOffset"),R=A.getUniformLocation(a,"u_inputFrame"),S=A.getUniformLocation(a,"u_personMask"),h=A.getUniformLocation(a,"u_background"),N=A.getUniformLocation(a,"u_coverage"),K=A.getUniformLocation(a,"u_lightWrapping"),M=A.getUniformLocation(a,"u_blendMode");A.useProgram(a),A.uniform2f(y,1,1),A.uniform2f(G,0,0),A.uniform1i(R,0),A.uniform1i(S,1),A.uniform2f(N,0,1),A.uniform1f(K,0),A.uniform1f(M,0);let F=null;function L(I){F=Fi(A,A.RGBA8,I.naturalWidth,I.naturalHeight,A.LINEAR,A.LINEAR),A.texSubImage2D(A.TEXTURE_2D,0,0,0,I.naturalWidth,I.naturalHeight,A.RGBA,A.UNSIGNED_BYTE,I);let g=0,C=0,Q=I.naturalWidth,B=I.naturalHeight;Q/B<o?(B=Q/o,C=(I.naturalHeight-B)/2):(Q=B*o,g=(I.naturalWidth-Q)/2);const E=Q/I.naturalWidth,i=B/I.naturalHeight;g/=I.naturalWidth,C/=I.naturalHeight,A.uniform2f(y,E,i),A.uniform2f(G,g,C)}return Q?.complete?L(Q):Q&&(Q.onload=()=>{L(Q)}),{render:function(){A.viewport(0,0,D,n),A.useProgram(a),A.activeTexture(A.TEXTURE1),A.bindTexture(A.TEXTURE_2D,C),null!==F&&(A.activeTexture(A.TEXTURE2),A.bindTexture(A.TEXTURE_2D,F),A.uniform1i(h,2)),A.bindFramebuffer(A.FRAMEBUFFER,null),A.drawArrays(A.TRIANGLE_STRIP,0,4)},updateCoverage:function(I){A.useProgram(a),A.uniform2f(N,I[0],I[1])},updateLightWrapping:function(I){A.useProgram(a),A.uniform1f(K,I)},updateBlendMode:function(I){A.useProgram(a),A.uniform1f(M,"screen"===I?0:1)},cleanUp:function(){A.deleteTexture(F),A.deleteProgram(a),A.deleteShader(w),A.deleteShader(s)}}}(a,R,S,K,I,Q);return{render:async function(){a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,h),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,A.htmlElement),a.bindVertexArray(G),await M.render(),i(),B._runInference(),i(),F.render(),L.render(),k.render()},updatePostProcessingConfig:function(A){if(L.updateSigmaSpace(A.jointBilateralFilter.sigmaSpace),L.updateSigmaColor(A.jointBilateralFilter.sigmaColor),"image"===g.type){const I=k;I.updateCoverage(A.coverage),I.updateLightWrapping(A.lightWrapping),I.updateBlendMode(A.blendMode)}else if("blur"===g.type){k.updateCoverage(A.coverage)}else{const A=k;A.updateCoverage([0,.9999]),A.updateLightWrapping(0)}},cleanUp:function(){k.cleanUp(),L.cleanUp(),F.cleanUp(),M.cleanUp(),a.deleteTexture(K),a.deleteTexture(N),a.deleteTexture(h),a.deleteBuffer(S),a.deleteBuffer(R),a.deleteVertexArray(G),a.deleteShader(y)}}}class Ui{constructor(){this.pipeline=null,this.backgroundImageRef=null,this.canvasRef=null,this.fps=0,this.durations=[],this.isRunning=!1,this.timerWorker=null,this.renderTimeoutId=null,this.previousTime=0,this.beginTime=0,this.eventCount=0,this.frameCount=0,this.frameDurations=[]}async initialize(A,I,g,C,Q,B=null,E=null){this.stop(),this.backgroundImageRef=B,this.canvasRef=E;const i=1e3/g.targetFps;this.previousTime=0,this.beginTime=0,this.eventCount=0,this.frameCount=0,this.frameDurations=[],this.timerWorker=function(){const A=new Map,I=new Blob(["\n const timeoutIds = new Map();\n \n addEventListener('message', (event) => {\n if (event.data.timeoutMs !== undefined) {\n const timeoutId = setTimeout(() => {\n postMessage({ callbackId: event.data.callbackId });\n timeoutIds.delete(event.data.callbackId);\n }, event.data.timeoutMs);\n timeoutIds.set(event.data.callbackId, timeoutId);\n } else {\n const timeoutId = timeoutIds.get(event.data.callbackId);\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n timeoutIds.delete(event.data.callbackId);\n }\n }\n });\n "],{type:"application/javascript"}),g=new Worker(URL.createObjectURL(I));g.onmessage=I=>{const g=A.get(I.data.callbackId);g&&(A.delete(I.data.callbackId),g())};let C=1;return{setTimeout:function(I,Q=0){const B=C++;return A.set(B,I),g.postMessage({callbackId:B,timeoutMs:Q}),B},clearTimeout:function(I){A.has(I)&&(g.postMessage({callbackId:I}),A.delete(I))},terminate:function(){A.clear(),g.terminate()}}}(),this.pipeline="webgl2"===g.pipeline?Ji(A,this.backgroundImageRef,I,g,this.canvasRef,Q,this.timerWorker,this.addFrameEvent.bind(this)):hi(A,I,g,this.canvasRef,C,Q,this.addFrameEvent.bind(this));const D=async()=>{if(!this.isRunning)return;const A=performance.now();this.beginFrame(),await this.pipeline.render(),this.endFrame(),this.renderTimeoutId=this.timerWorker.setTimeout(D,Math.max(0,i-(performance.now()-A)))};return this.isRunning=!0,D(),{pipeline:this.pipeline,backgroundImageRef:this.backgroundImageRef,canvasRef:this.canvasRef,fps:this.fps,durations:this.getProcessingDurations()}}beginFrame(){this.beginTime=Date.now()}addFrameEvent(){const A=Date.now();this.frameDurations[this.eventCount]=A-this.beginTime,this.beginTime=A,this.eventCount++}endFrame(){const A=Date.now();this.frameDurations[this.eventCount]=A-this.beginTime,this.frameCount++,A>=this.previousTime+1e3&&(this.fps=1e3*this.frameCount/(A-this.previousTime),this.durations=[...this.frameDurations],this.previousTime=A,this.frameCount=0),this.eventCount=0}getProcessingDurations(){return this.frameDurations.length>=3?[this.frameDurations[0]||0,this.frameDurations[1]||0,this.frameDurations[2]||0]:[0,0,0]}stop(){this.isRunning=!1,this.timerWorker&&this.renderTimeoutId&&this.timerWorker.clearTimeout(this.renderTimeoutId),this.timerWorker&&(this.timerWorker.terminate(),this.timerWorker=null),this.pipeline&&(this.pipeline.cleanUp(),this.pipeline=null),this.renderTimeoutId=null}getState(){return{pipeline:this.pipeline,backgroundImageRef:this.backgroundImageRef,canvasRef:this.canvasRef,fps:this.fps,durations:this.getProcessingDurations(),isRunning:this.isRunning}}getFps(){return this.fps}getDurations(){return this.durations}isActive(){return this.isRunning&&null!==this.pipeline}async updateConfig(A,I,g,C,Q){return this.initialize(A,I,g,C,Q,this.backgroundImageRef,this.canvasRef)}destroy(){this.stop(),this.backgroundImageRef=null,this.canvasRef=null,this.fps=0,this.durations=[]}}const qi=new qg("Room");const ti=new Set(["240p","360p","480p","720p","1080p","1440p","2160p"]);function ri(A){return!!Array.isArray(A)&&A.every(A=>ti.has(A))}const ci=new qg("utils-verifyFiles"),Hi=["mp4"];function Yi(A,I){try{const g=new URL(A).pathname;return g.split(".").pop().toLowerCase()===I.toLowerCase()}catch{return!1}}const ei=new TextEncoder,di=new TextDecoder;function bi(A){if(Uint8Array.fromBase64)return Uint8Array.fromBase64("string"==typeof A?A:di.decode(A),{alphabet:"base64url"});let I=A;I instanceof Uint8Array&&(I=di.decode(I)),I=I.replace(/-/g,"+").replace(/_/g,"/").replace(/\s/g,"");try{return function(A){if(Uint8Array.fromBase64)return Uint8Array.fromBase64(A);const I=atob(A),g=new Uint8Array(I.length);for(let C=0;C<I.length;C++)g[C]=I.charCodeAt(C);return g}(I)}catch{throw new TypeError("The input to be decoded is not correctly encoded.")}}class xi extends Error{static code="ERR_JOSE_GENERIC";code="ERR_JOSE_GENERIC";constructor(A,I){super(A,I),this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}}class ui extends xi{static code="ERR_JWT_CLAIM_VALIDATION_FAILED";code="ERR_JWT_CLAIM_VALIDATION_FAILED";claim;reason;payload;constructor(A,I,g="unspecified",C="unspecified"){super(A,{cause:{claim:g,reason:C,payload:I}}),this.claim=g,this.reason=C,this.payload=I}}class pi extends xi{static code="ERR_JWT_EXPIRED";code="ERR_JWT_EXPIRED";claim;reason;payload;constructor(A,I,g="unspecified",C="unspecified"){super(A,{cause:{claim:g,reason:C,payload:I}}),this.claim=g,this.reason=C,this.payload=I}}class Ti extends xi{static code="ERR_JOSE_ALG_NOT_ALLOWED";code="ERR_JOSE_ALG_NOT_ALLOWED"}class mi extends xi{static code="ERR_JOSE_NOT_SUPPORTED";code="ERR_JOSE_NOT_SUPPORTED"}class Oi extends xi{static code="ERR_JWS_INVALID";code="ERR_JWS_INVALID"}class li extends xi{static code="ERR_JWT_INVALID";code="ERR_JWT_INVALID"}class fi extends xi{static code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";constructor(A="signature verification failed",I){super(A,I)}}function Pi(A,I="algorithm.name"){return new TypeError(`CryptoKey does not support this operation, its ${I} must be ${A}`)}function Wi(A,I){return A.name===I}function zi(A){return parseInt(A.name.slice(4),10)}function ji(A,I,g){switch(I){case"HS256":case"HS384":case"HS512":{if(!Wi(A.algorithm,"HMAC"))throw Pi("HMAC");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"RS256":case"RS384":case"RS512":{if(!Wi(A.algorithm,"RSASSA-PKCS1-v1_5"))throw Pi("RSASSA-PKCS1-v1_5");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"PS256":case"PS384":case"PS512":{if(!Wi(A.algorithm,"RSA-PSS"))throw Pi("RSA-PSS");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"Ed25519":case"EdDSA":if(!Wi(A.algorithm,"Ed25519"))throw Pi("Ed25519");break;case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":if(!Wi(A.algorithm,I))throw Pi(I);break;case"ES256":case"ES384":case"ES512":{if(!Wi(A.algorithm,"ECDSA"))throw Pi("ECDSA");const g=function(A){switch(A){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}(I);if(A.algorithm.namedCurve!==g)throw Pi(g,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}!function(A,I){if(!A.usages.includes(I))throw new TypeError(`CryptoKey does not support this operation, its usages must include ${I}.`)}(A,g)}function Vi(A,I,...g){if((g=g.filter(Boolean)).length>2){const I=g.pop();A+=`one of type ${g.join(", ")}, or ${I}.`}else 2===g.length?A+=`one of type ${g[0]} or ${g[1]}.`:A+=`of type ${g[0]}.`;return null==I?A+=` Received ${I}`:"function"==typeof I&&I.name?A+=` Received function ${I.name}`:"object"==typeof I&&null!=I&&I.constructor?.name&&(A+=` Received an instance of ${I.constructor.name}`),A}function vi(A,I,...g){return Vi(`Key for the ${A} algorithm must be `,I,...g)}function Zi(A){return"CryptoKey"===A?.[Symbol.toStringTag]}function Xi(A){return"KeyObject"===A?.[Symbol.toStringTag]}const _i=A=>Zi(A)||Xi(A);const $i=A=>{if("object"!=typeof(I=A)||null===I||"[object Object]"!==Object.prototype.toString.call(A))return!1;var I;if(null===Object.getPrototypeOf(A))return!0;let g=A;for(;null!==Object.getPrototypeOf(g);)g=Object.getPrototypeOf(g);return Object.getPrototypeOf(A)===g};const AD=async A=>{if(!A.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');const{algorithm:I,keyUsages:g}=function(A){let I,g;switch(A.kty){case"AKP":switch(A.alg){case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":I={name:A.alg},g=A.priv?["sign"]:["verify"];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"RSA":switch(A.alg){case"PS256":case"PS384":case"PS512":I={name:"RSA-PSS",hash:`SHA-${A.alg.slice(-3)}`},g=A.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":I={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${A.alg.slice(-3)}`},g=A.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":I={name:"RSA-OAEP",hash:`SHA-${parseInt(A.alg.slice(-3),10)||1}`},g=A.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"EC":switch(A.alg){case"ES256":I={name:"ECDSA",namedCurve:"P-256"},g=A.d?["sign"]:["verify"];break;case"ES384":I={name:"ECDSA",namedCurve:"P-384"},g=A.d?["sign"]:["verify"];break;case"ES512":I={name:"ECDSA",namedCurve:"P-521"},g=A.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":I={name:"ECDH",namedCurve:A.crv},g=A.d?["deriveBits"]:[];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"OKP":switch(A.alg){case"Ed25519":case"EdDSA":I={name:"Ed25519"},g=A.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":I={name:A.crv},g=A.d?["deriveBits"]:[];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;default:throw new mi('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:I,keyUsages:g}}(A),C={...A};return"AKP"!==C.kty&&delete C.alg,delete C.use,crypto.subtle.importKey("jwk",C,I,A.ext??(!A.d&&!A.priv),A.key_ops??g)};function ID(A){return $i(A)&&"string"==typeof A.kty}let gD;const CD=async(A,I,g,C=!1)=>{gD||=new WeakMap;let Q=gD.get(A);if(Q?.[g])return Q[g];const B=await AD({...I,alg:g});return C&&Object.freeze(A),Q?Q[g]=B:gD.set(A,{[g]:B}),B},QD=async(A,I)=>{if(A instanceof Uint8Array)return A;if(Zi(A))return A;if(Xi(A)){if("secret"===A.type)return A.export();if("toCryptoKey"in A&&"function"==typeof A.toCryptoKey)try{return((A,I)=>{gD||=new WeakMap;let g=gD.get(A);if(g?.[I])return g[I];const C="public"===A.type,Q=!!C;let B;if("x25519"===A.asymmetricKeyType){switch(I){case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":break;default:throw new TypeError("given KeyObject instance cannot be used for this algorithm")}B=A.toCryptoKey(A.asymmetricKeyType,Q,C?[]:["deriveBits"])}if("ed25519"===A.asymmetricKeyType){if("EdDSA"!==I&&"Ed25519"!==I)throw new TypeError("given KeyObject instance cannot be used for this algorithm");B=A.toCryptoKey(A.asymmetricKeyType,Q,[C?"verify":"sign"])}switch(A.asymmetricKeyType){case"ml-dsa-44":case"ml-dsa-65":case"ml-dsa-87":if(I!==A.asymmetricKeyType.toUpperCase())throw new TypeError("given KeyObject instance cannot be used for this algorithm");B=A.toCryptoKey(A.asymmetricKeyType,Q,[C?"verify":"sign"])}if("rsa"===A.asymmetricKeyType){let g;switch(I){case"RSA-OAEP":g="SHA-1";break;case"RS256":case"PS256":case"RSA-OAEP-256":g="SHA-256";break;case"RS384":case"PS384":case"RSA-OAEP-384":g="SHA-384";break;case"RS512":case"PS512":case"RSA-OAEP-512":g="SHA-512";break;default:throw new TypeError("given KeyObject instance cannot be used for this algorithm")}if(I.startsWith("RSA-OAEP"))return A.toCryptoKey({name:"RSA-OAEP",hash:g},Q,C?["encrypt"]:["decrypt"]);B=A.toCryptoKey({name:I.startsWith("PS")?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:g},Q,[C?"verify":"sign"])}if("ec"===A.asymmetricKeyType){const g=new Map([["prime256v1","P-256"],["secp384r1","P-384"],["secp521r1","P-521"]]).get(A.asymmetricKeyDetails?.namedCurve);if(!g)throw new TypeError("given KeyObject instance cannot be used for this algorithm");"ES256"===I&&"P-256"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),"ES384"===I&&"P-384"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),"ES512"===I&&"P-521"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),I.startsWith("ECDH-ES")&&(B=A.toCryptoKey({name:"ECDH",namedCurve:g},Q,C?[]:["deriveBits"]))}if(!B)throw new TypeError("given KeyObject instance cannot be used for this algorithm");return g?g[I]=B:gD.set(A,{[I]:B}),B})(A,I)}catch(eD){if(eD instanceof TypeError)throw eD}let g=A.export({format:"jwk"});return CD(A,g,I)}if(ID(A))return A.k?bi(A.k):CD(A,A,I,!0);throw new Error("unreachable")},BD=A=>A?.[Symbol.toStringTag],ED=(A,I,g)=>{if(void 0!==I.use){let A;switch(g){case"sign":case"verify":A="sig";break;case"encrypt":case"decrypt":A="enc"}if(I.use!==A)throw new TypeError(`Invalid key for this operation, its "use" must be "${A}" when present`)}if(void 0!==I.alg&&I.alg!==A)throw new TypeError(`Invalid key for this operation, its "alg" must be "${A}" when present`);if(Array.isArray(I.key_ops)){let C;switch(!0){case"verify"===g:case"dir"===A:case A.includes("CBC-HS"):C=g;break;case A.startsWith("PBES2"):C="deriveBits";break;case/^A\d{3}(?:GCM)?(?:KW)?$/.test(A):C=!A.includes("GCM")&&A.endsWith("KW")?"unwrapKey":g;break;case"encrypt"===g:C="wrapKey";break;case"decrypt"===g:C=A.startsWith("RSA")?"unwrapKey":"deriveBits"}if(C&&!1===I.key_ops?.includes?.(C))throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${C}" when present`)}return!0},iD=(A,I,g)=>{A.startsWith("HS")||"dir"===A||A.startsWith("PBES2")||/^A(?:128|192|256)(?:GCM)?(?:KW)?$/.test(A)||/^A(?:128|192|256)CBC-HS(?:256|384|512)$/.test(A)?((A,I,g)=>{if(!(I instanceof Uint8Array)){if(ID(I)){if(function(A){return"oct"===A.kty&&"string"==typeof A.k}(I)&&ED(A,I,g))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!_i(I))throw new TypeError(vi(A,I,"CryptoKey","KeyObject","JSON Web Key","Uint8Array"));if("secret"!==I.type)throw new TypeError(`${BD(I)} instances for symmetric algorithms must be of type "secret"`)}})(A,I,g):((A,I,g)=>{if(ID(I))switch(g){case"decrypt":case"sign":if(function(A){return"oct"!==A.kty&&("AKP"===A.kty&&"string"==typeof A.priv||"string"==typeof A.d)}(I)&&ED(A,I,g))return;throw new TypeError("JSON Web Key for this operation be a private JWK");case"encrypt":case"verify":if(function(A){return"oct"!==A.kty&&void 0===A.d&&void 0===A.priv}(I)&&ED(A,I,g))return;throw new TypeError("JSON Web Key for this operation be a public JWK")}if(!_i(I))throw new TypeError(vi(A,I,"CryptoKey","KeyObject","JSON Web Key"));if("secret"===I.type)throw new TypeError(`${BD(I)} instances for asymmetric algorithms must not be of type "secret"`);if("public"===I.type)switch(g){case"sign":throw new TypeError(`${BD(I)} instances for asymmetric algorithm signing must be of type "private"`);case"decrypt":throw new TypeError(`${BD(I)} instances for asymmetric algorithm decryption must be of type "private"`)}if("private"===I.type)switch(g){case"verify":throw new TypeError(`${BD(I)} instances for asymmetric algorithm verifying must be of type "public"`);case"encrypt":throw new TypeError(`${BD(I)} instances for asymmetric algorithm encryption must be of type "public"`)}})(A,I,g)},DD=async(A,I,g)=>{if(I instanceof Uint8Array){if(!A.startsWith("HS"))throw new TypeError(((A,...I)=>Vi("Key must be ",A,...I))(I,"CryptoKey","KeyObject","JSON Web Key"));return crypto.subtle.importKey("raw",I,{hash:`SHA-${A.slice(-3)}`,name:"HMAC"},!1,[g])}return ji(I,A,g),I},nD=async(A,I,g,C)=>{const Q=await DD(A,I,"verify");((A,I)=>{if(A.startsWith("RS")||A.startsWith("PS")){const{modulusLength:g}=I.algorithm;if("number"!=typeof g||g<2048)throw new TypeError(`${A} requires key modulusLength to be 2048 bits or larger`)}})(A,Q);const B=((A,I)=>{const g=`SHA-${A.slice(-3)}`;switch(A){case"HS256":case"HS384":case"HS512":return{hash:g,name:"HMAC"};case"PS256":case"PS384":case"PS512":return{hash:g,name:"RSA-PSS",saltLength:parseInt(A.slice(-3),10)>>3};case"RS256":case"RS384":case"RS512":return{hash:g,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:g,name:"ECDSA",namedCurve:I.namedCurve};case"Ed25519":case"EdDSA":return{name:"Ed25519"};case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return{name:A};default:throw new mi(`alg ${A} is not supported either by JOSE or your javascript runtime`)}})(A,Q.algorithm);try{return await crypto.subtle.verify(B,Q,g,C)}catch{return!1}};async function oD(A,I,g){if(!$i(A))throw new Oi("Flattened JWS must be an object");if(void 0===A.protected&&void 0===A.header)throw new Oi('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==A.protected&&"string"!=typeof A.protected)throw new Oi("JWS Protected Header incorrect type");if(void 0===A.payload)throw new Oi("JWS Payload missing");if("string"!=typeof A.signature)throw new Oi("JWS Signature missing or incorrect type");if(void 0!==A.header&&!$i(A.header))throw new Oi("JWS Unprotected Header incorrect type");let C={};if(A.protected)try{const I=bi(A.protected);C=JSON.parse(di.decode(I))}catch{throw new Oi("JWS Protected Header is invalid")}if(!((...A)=>{const I=A.filter(Boolean);if(0===I.length||1===I.length)return!0;let g;for(const C of I){const A=Object.keys(C);if(g&&0!==g.size)for(const I of A){if(g.has(I))return!1;g.add(I)}else g=new Set(A)}return!0})(C,A.header))throw new Oi("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const Q={...C,...A.header},B=((A,I,g,C,Q)=>{if(void 0!==Q.crit&&void 0===C?.crit)throw new A('"crit" (Critical) Header Parameter MUST be integrity protected');if(!C||void 0===C.crit)return new Set;if(!Array.isArray(C.crit)||0===C.crit.length||C.crit.some(A=>"string"!=typeof A||0===A.length))throw new A('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let B;B=void 0!==g?new Map([...Object.entries(g),...I.entries()]):I;for(const E of C.crit){if(!B.has(E))throw new mi(`Extension Header Parameter "${E}" is not recognized`);if(void 0===Q[E])throw new A(`Extension Header Parameter "${E}" is missing`);if(B.get(E)&&void 0===C[E])throw new A(`Extension Header Parameter "${E}" MUST be integrity protected`)}return new Set(C.crit)})(Oi,new Map([["b64",!0]]),g?.crit,C,Q);let E=!0;if(B.has("b64")&&(E=C.b64,"boolean"!=typeof E))throw new Oi('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:i}=Q;if("string"!=typeof i||!i)throw new Oi('JWS "alg" (Algorithm) Header Parameter missing or invalid');const D=g&&((A,I)=>{if(void 0!==I&&(!Array.isArray(I)||I.some(A=>"string"!=typeof A)))throw new TypeError(`"${A}" option must be an array of strings`);if(I)return new Set(I)})("algorithms",g.algorithms);if(D&&!D.has(i))throw new Ti('"alg" (Algorithm) Header Parameter value not allowed');if(E){if("string"!=typeof A.payload)throw new Oi("JWS Payload must be a string")}else if("string"!=typeof A.payload&&!(A.payload instanceof Uint8Array))throw new Oi("JWS Payload must be a string or an Uint8Array instance");let n=!1;"function"==typeof I&&(I=await I(C,A),n=!0),iD(i,I,"verify");const o=function(...A){const I=A.reduce((A,{length:I})=>A+I,0),g=new Uint8Array(I);let C=0;for(const Q of A)g.set(Q,C),C+=Q.length;return g}(ei.encode(A.protected??""),ei.encode("."),"string"==typeof A.payload?ei.encode(A.payload):A.payload);let s;try{s=bi(A.signature)}catch{throw new Oi("Failed to base64url decode the signature")}const w=await QD(I,i);if(!(await nD(i,w,s,o)))throw new fi;let a;if(E)try{a=bi(A.payload)}catch{throw new Oi("Failed to base64url decode the payload")}else a="string"==typeof A.payload?ei.encode(A.payload):A.payload;const y={payload:a};return void 0!==A.protected&&(y.protectedHeader=C),void 0!==A.header&&(y.unprotectedHeader=A.header),n?{...y,key:w}:y}const sD=86400,wD=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i,aD=A=>{const I=wD.exec(A);if(!I||I[4]&&I[1])throw new TypeError("Invalid time period format");const g=parseFloat(I[2]);let C;switch(I[3].toLowerCase()){case"sec":case"secs":case"second":case"seconds":case"s":C=Math.round(g);break;case"minute":case"minutes":case"min":case"mins":case"m":C=Math.round(60*g);break;case"hour":case"hours":case"hr":case"hrs":case"h":C=Math.round(3600*g);break;case"day":case"days":case"d":C=Math.round(g*sD);break;case"week":case"weeks":case"w":C=Math.round(604800*g);break;default:C=Math.round(31557600*g)}return"-"===I[1]||"ago"===I[4]?-C:C},yD=A=>A.includes("/")?A.toLowerCase():`application/${A.toLowerCase()}`;function GD(A,I,g={}){let C;try{C=JSON.parse(di.decode(I))}catch{}if(!$i(C))throw new li("JWT Claims Set must be a top-level JSON object");const{typ:Q}=g;if(Q&&("string"!=typeof A.typ||yD(A.typ)!==yD(Q)))throw new ui('unexpected "typ" JWT header value',C,"typ","check_failed");const{requiredClaims:B=[],issuer:E,subject:i,audience:D,maxTokenAge:n}=g,o=[...B];void 0!==n&&o.push("iat"),void 0!==D&&o.push("aud"),void 0!==i&&o.push("sub"),void 0!==E&&o.push("iss");for(const S of new Set(o.reverse()))if(!(S in C))throw new ui(`missing required "${S}" claim`,C,S,"missing");if(E&&!(Array.isArray(E)?E:[E]).includes(C.iss))throw new ui('unexpected "iss" claim value',C,"iss","check_failed");if(i&&C.sub!==i)throw new ui('unexpected "sub" claim value',C,"sub","check_failed");if(D&&(s=C.aud,w="string"==typeof D?[D]:D,!("string"==typeof s?w.includes(s):Array.isArray(s)&&w.some(Set.prototype.has.bind(new Set(s))))))throw new ui('unexpected "aud" claim value',C,"aud","check_failed");var s,w;let a;switch(typeof g.clockTolerance){case"string":a=aD(g.clockTolerance);break;case"number":a=g.clockTolerance;break;case"undefined":a=0;break;default:throw new TypeError("Invalid clockTolerance option type")}const{currentDate:y}=g,G=(R=y||new Date,Math.floor(R.getTime()/1e3));var R;if((void 0!==C.iat||n)&&"number"!=typeof C.iat)throw new ui('"iat" claim must be a number',C,"iat","invalid");if(void 0!==C.nbf){if("number"!=typeof C.nbf)throw new ui('"nbf" claim must be a number',C,"nbf","invalid");if(C.nbf>G+a)throw new ui('"nbf" claim timestamp check failed',C,"nbf","check_failed")}if(void 0!==C.exp){if("number"!=typeof C.exp)throw new ui('"exp" claim must be a number',C,"exp","invalid");if(C.exp<=G-a)throw new pi('"exp" claim timestamp check failed',C,"exp","check_failed")}if(n){const A=G-C.iat;if(A-a>("number"==typeof n?n:aD(n)))throw new pi('"iat" claim timestamp check failed (too far in the past)',C,"iat","check_failed");if(A<0-a)throw new ui('"iat" claim timestamp check failed (it should be in the past)',C,"iat","check_failed")}return C}async function RD(A,I,g){const C=await async function(A,I,g){if(A instanceof Uint8Array&&(A=di.decode(A)),"string"!=typeof A)throw new Oi("Compact JWS must be a string or Uint8Array");const{0:C,1:Q,2:B,length:E}=A.split(".");if(3!==E)throw new Oi("Invalid Compact JWS");const i=await oD({payload:Q,protected:C,signature:B},I,g),D={payload:i.payload,protectedHeader:i.protectedHeader};return"function"==typeof I?{...D,key:i.key}:D}(A,I,g);if(C.protectedHeader.crit?.includes("b64")&&!1===C.protectedHeader.b64)throw new li("JWTs MUST NOT use unencoded payload");const Q={payload:GD(C.protectedHeader,C.payload,g),protectedHeader:C.protectedHeader};return"function"==typeof I?{...Q,key:C.key}:Q}const SD=new qg("Room"),hD={small:{width:{ideal:160},height:{ideal:120}},qvga:{width:{ideal:320},height:{ideal:240}},vga:{width:{ideal:640},height:{ideal:480}},hd:{width:{ideal:1280},height:{ideal:720}}};let ND;const KD=new class{constructor(){this.queue=new Map}push(A,I){this.queue.set(A,I)}get(A){return this.queue.get(A)}remove(A){this.queue.delete(A)}},MD=new class{constructor(){this._localVBStream=null,this._vbDetailsNew={},this._vbDetails=null,this._roomType=null,this._participants={},this._peerId=null,this._peerConnection=null,this._pipelineManager=null,this._updateInterval=null,this._pipelineManager=new Ui,this.initializeTFLite()}getVBDetails(){return this._vbDetailsNew}getVBStream(){return this._localVBStream}hasLiveVBTrack(){try{return this._localVBStream&&"function"==typeof this._localVBStream.getVideoTracks&&this._localVBStream.getVideoTracks().length>0&&"live"===this._localVBStream.getVideoTracks()[0].readyState}catch(A){return!1}}setPipelineManager(A){this._pipelineManager=A}async initializeTFLite(){try{const A=await Si(Gi);this._vbDetailsNew.tfLite=A.tflite,this._vbDetailsNew.isSIMDSupported=A.isSIMDSupported}catch(A){}}async initializePipeline(A,I){qi.debug("initializePipeline called with videoTrack and backgroundConfig:%O,%O",A,I);let g=null;try{const C=await this._createHiddenVideoElement(A);if(this._vbDetailsNew.hiddenCanvas=this._createHiddenCanvasElement(C),"image"===I.type){const A=await this._createHiddenImageElement(I);if(!A.success)return!1;g=A.hiddenImage}const Q=C.htmlElement;Q instanceof HTMLVideoElement&&Q.paused&&(qi.debug("🎬 Video is paused, starting playback..."),await Q.play());const B=await this._pipelineManager.initialize(C,I,Gi,null,this._vbDetailsNew.tfLite,g,this._vbDetailsNew.hiddenCanvas);qi.debug("Inside getUserMediaSuccess result",B),qi.debug("Pipeline manager active? :%s",this._pipelineManager.isActive()),qi.debug("camera stream live status:%s",A.readyState),B.pipeline.updatePostProcessingConfig(Ri),this._setupPeriodicUpdates(),this._vbDetailsNew.hiddenImage=g,this._vbDetailsNew.sourcePlayback=C;const E=B.canvasRef.captureStream(30);return this._localVBStream=E,{success:!0,vbStream:E}}catch(C){qi.error("Failed to initialize pipeline:%O",C)}}async _createHiddenVideoElement(A){return new Promise(I=>{const g=document.createElement("video");g.autoplay=!0,g.loop=!0,g.controls=!1,g.playsInline=!0,g.muted=!0,g.srcObject=new MediaStream([A]),g.style.cssText="position: fixed; top: 10px; right: 10px; width: 200px; height: 150px; border: 2px solid blue; z-index: 9999; ",document.body.appendChild(g),g.play(),g.onloadeddata=()=>{I({htmlElement:g,width:g.videoWidth,height:g.videoHeight})}})}async _createHiddenVideoElement(A){return new Promise(I=>{const g=document.createElement("video");g.style.display="none",g.autoplay=!0,g.loop=!0,g.controls=!1,g.playsInline=!0,g.muted=!0,g.srcObject=new MediaStream([A]),document.body.appendChild(g);const C=async()=>{try{await g.play()}catch(A){}g.readyState<2||!g.videoWidth||!g.videoHeight?requestAnimationFrame(C):I({htmlElement:g,width:g.videoWidth,height:g.videoHeight})};g.addEventListener("loadedmetadata",C,{once:!0}),C()})}_createHiddenCanvasElement(A){const I=document.createElement("canvas");return I.style.display="none",I.width=A.width,I.height=A.height,document.body.appendChild(I),I}_createHiddenImageElement(A){return new Promise(async I=>{const g=document.createElement("img");if(g.style.display="none",A?.url.includes("http"))try{(await this.testImageCORS(A?.url)).success?(g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})},g.src=A.url):(g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})})}catch(eD){g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})}}else g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})},g.src=A.url})}async testImageCORS(A,I=1e4){return new Promise((g,C)=>{const Q=new Image;Q.crossOrigin="anonymous";const B=setTimeout(()=>{Q.src="",C(new Error("CORS_TIMEOUT"))},I);Q.onload=()=>{clearTimeout(B);try{const I=document.createElement("canvas");I.width=Q.width||100,I.height=Q.height||100;const C=I.getContext("2d");C.drawImage(Q,0,0),C.getImageData(0,0,1,1),g({success:!0,url:A,width:Q.naturalWidth,height:Q.naturalHeight,message:"CORS allowed"})}catch(I){C(new Error("CORS_BLOCKED"))}},Q.onerror=A=>{clearTimeout(B),C(new Error("IMAGE_LOAD_FAILED"))},Q.src=A})}_setupPeriodicUpdates(){this._updateInterval&&clearInterval(this._updateInterval),this._updateInterval=setInterval(()=>{if(this._pipelineManager&&this._pipelineManager.isActive()){const A=this._pipelineManager.getState();this._vbDetailsNew.fps=A.fps;const[I,g,C]=A.durations||[0,0,0];this._vbDetailsNew.resizingDuration=I,this._vbDetailsNew.inferenceDuration=g,this._vbDetailsNew.postProcessingDuration=C}},1e3)}cleanup(){try{if(this._localVBStream&&"function"==typeof this._localVBStream.getVideoTracks)try{this._localVBStream.getVideoTracks().forEach(A=>{try{A.stop()}catch(I){}})}catch(A){}try{this._pipelineManager&&"function"==typeof this._pipelineManager.stop&&this._pipelineManager.stop()}catch(A){}if(this._updateInterval){try{clearInterval(this._updateInterval)}catch(A){}this._updateInterval=null}try{if(this._vbDetailsNew?.sourcePlayback?.htmlElement){try{this._vbDetailsNew.sourcePlayback.htmlElement.srcObject=null}catch(A){}try{this._vbDetailsNew.sourcePlayback.htmlElement.remove()}catch(A){}}}catch(A){}try{if(this._vbDetailsNew?.hiddenCanvas)try{this._vbDetailsNew.hiddenCanvas.remove()}catch(A){}}catch(A){}try{if(this._vbDetailsNew?.hiddenImage)try{this._vbDetailsNew.hiddenImage.remove()}catch(A){}}catch(A){}this._localVBStream=null,this._vbDetailsNew&&(this._vbDetailsNew.sourcePlayback=null,this._vbDetailsNew.hiddenCanvas=null,this._vbDetailsNew.hiddenImage=null)}catch(A){}}};class FD extends cg.EventEmitter{static async listDevices(){if(ND)return SD.info("Device list already exists:%O",ND),{success:!0,deviceList:ND};const A=await _E();return A.success?(ND=A.deviceList,{success:!0,deviceList:A.deviceList}):{success:!1,reason:A.reason}}static async changeVB({track:A,details:I}){if(SD.debug("changeVB Received details are:%O",I),SD.debug("changeVB Received track are:%O",A),!I)return SD.debug("VB details not provided. Skipping VB processing."),{success:!1};if(!0===A.active){SD.debug("Track is live, calling initializePipeline",A);const g=A.getVideoTracks()[0],C=await MD.initializePipeline(g,I);return SD.debug("response is :%o",C),C}throw SD.error("Track is not live"),new Error("Track is not live")}static async init({sessionToken:A,roomId:I,peerId:g,roomType:C}={}){if(!A)throw new Error("Session token is required to join the room.");try{let Q;SD.info("session token:%s",A);try{const I=(new TextEncoder).encode("samvyo_tech_321"),{payload:g}=await RD(A,I,{algorithms:["HS256"]});Q=g,SD.info("Decoded token:",Q)}catch(eD){throw SD.error("JWT verification failed:",eD),eD instanceof pi?new Error("Session token has expired"):eD instanceof ui?new Error("Session token not yet active"):new Error("Invalid session token: "+eD.message)}if(!Q||"object"!=typeof Q)throw new Error("Invalid token format");const{data:B,signallingServerUrl:E}=Q;if(!B||!E)throw new Error("Missing required token data");return g||(g=nQ()),I||(I=DQ()),new FD({peerId:g,roomId:I,outputData:{sessionToken:A,innerSessionToken:B,signallingServerUrl:E},roomType:C})}catch(Q){throw SD.error("Failed to initialize:",Q.message),Q}}constructor({peerId:A,roomId:I,outputData:g,roomType:C}){super(),this._closed=!1,this._roomStatus="initialised",this._roomDisplayName=null,this._running=!1,this._cignal=null,this._socket=null,this._sendTransport=null,this._recvTransport=null,this._device=new sg.Device,this._webCamProducer=null,this._micProducer=null,this._shareProducer=null,this._shareAudioProducer=null,this._producers=new Map,this._consumers=new Map,this._peers=new Map,this._data={...g,inputParams:{peerId:A,roomId:I,roomType:C||"conferencing"}},this._micStream=null,this._webCamStream=null,this._webcam={device:null,resolution:"hd"},this._mic={device:null},this._deviceList=ND||null,this._externalVideo=null,this._externalVideoStream=null,this._forceVP8=!1,this._forceH264=!1,this._forceVP9=!1,this._enableWebcamLayers=!0,this._numSimulcastStreams=3,this._enableSharingLayers=!0,this._client=kg.parse(window.navigator.userAgent),this._routerRtpCapabilities=null,this._recordingStartedByMe={},this._cignalConnected=!1,this._reconnectionInitiated=!1,this._restartIceInProgressSendTransport=!1,this._restartIceInProgressRecvTransport=!1,this._activeSpeaker=null,this._speechRecognition=null,this._transcriptStorage=new Map,this._audioContext=null,this._audioAnalyser=null,this._micMonitorStream=null,this._speakingWhileMutedInterval=null,this._speakingThreshold=-50,this._mutedSpeakingDetectionEnabled=!0,this._lastMutedSpeakingNotification=0,this._mutedSpeakingCooldown=3e3,this._audioTroubleShootData={lastDiagnostic:null,deviceTests:{},connectivityStatus:"unknown"},this._audioOutputDevices=[],this._currentSpeakerDevice=null,this._testAudioElements=new Map,this._speakerTestResults=new Map,this._remoteAudioElement=null,this._remoteCaption=null,this._transcriptionRecorder=null,this._transcriptionActive=!1,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,this.initLocal()}get peerId(){return this._peerId}set peerId(A){this._peerId=A}get roomType(){return this._roomType}set roomType(A){this._roomType=A}get closed(){return this._closed}get data(){return this._data}set data(A){throw new Error("Setting the whole data object is not possible!")}get peers(){return this._peers}set peers(A){throw new Error("Setting the whole peers object is not possible!")}get transports(){return{produce:this._sendTransport,consume:this._recvTransport}}set transports(A){throw new Error("Setting of transport is not possible!")}get videoStream(){return this._webCamStream}get audioStream(){return this._micStream}get clientAgent(){return this._client}get activeParameters(){return this._data.inputParams}get deviceList(){return this._deviceList?this._deviceList:{videoDevices:[],audioDevices:[],audioOutputDevices:[]}}set deviceList(A){throw new Error("Setting of deviceList is not possible!")}get currentlyActiveSpeaker(){return this._activeSpeaker}set currentlyActiveSpeaker(A){throw new Error("Setting of currentActivespeaker is not possible!")}get roomDisplayName(){return this._roomDisplayName}set roomDisplayName(A){throw new Error("Setting of roomDisplayName is not possible!")}async initLocal(){const A=sg.detectDevice();SD.debug("The device is:%O",A),await this._initSocket()}async _initSocket(){let A=this;const I=this.data.signallingServerUrl.replace(/^(http|https):\/\//,""),g=`wss://${I}/?sessionToken=${this.data.sessionToken}&roomId=${this.data.inputParams.roomId}&peerId=${this.data.inputParams.peerId}&roomType=${this.data.inputParams.roomType}`;SD.info(`Going to create a new socket! with address: ${I}`),this._socket=new iQ(g,!0),this._listenToSocket(),this._socket.on("notify",({type:A,title:I,message:g})=>{this.emit("notification",{eventType:A,eventText:`${I}: ${g}`,roomId:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId})}),this._socket.on("roomStartedP2p",A=>{SD.info("P2P room successfully started"),this._running=!0}),this._socket.on("userError",I=>{SD.error("User Error happened with message:%O",I),A.emit("notification",{eventType:I.title,eventText:`${I.text}`})}),this._socket.on("validationAlert",A=>{SD.info("Validation alert happened")}),this._socket.on("alreadyActive",({title:A,text:I})=>{this.emit("notification",{eventType:"alreadyActive",eventText:"This peer already has an active connection",roomId:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId})}),this._socket.on("passwordDisabled",()=>{SD.info("password disabled by moderator!"),this.emit("notification",{eventType:"passwordDisabled",eventText:"Password for this room has been disabled by moderator",roomId:this.data.inputParams.roomId})}),this._socket.on("close",({code:A,reason:I})=>{if(SD.info(`socket closed with code ${A}`),4500!==A&&4100!==A){let g=I||"Connection to server closed unexpectedly! Trying to reconnect.";SD.info(`socket close code is${A} with reason ${g}`)}else SD.info("Socket is now closed!"),this.close()}),this._socket.on("connected",async()=>{SD.info("Socket connected"),this.emit("initSuccess")}),this._socket.on("reconnected",async()=>{SD.info("Socket re-connected"),A.pc&&A._sendTransport&&A._recvTransport?roomType===YE.P2P&&A.pc?(SD.info("Socket seems to be reconnected in mid call! RestartIce needed for p2p call."),"failed"!==A.pc.iceConnectionState&&"disconnected"!==A.pc.iceConnectionState||A.restartICE()):(SD.debug("Ice restarts for mediasoup transports for a joined peer"),A._sendTransport&&["failed","disconnected"].includes(A._sendTransport.connectionState)?(SD.debug("Restart ice for sendtransport"),A.restartIce(A._sendTransport.id,"send")):SD.error("Send transport not available!"),A._recvTransport&&["failed","disconnected"].includes(A._recvTransport.connectionState)?(SD.debug("Restart ice for recvtransport"),A.restartIce(A._recvTransport.id,"recv")):SD.error("Recv transport not available!")):(SD.info("Connection getting connected for first time"),this.emit("initSuccess"))}),this._socket.on("defaultJoinStatus",async A=>{SD.info(" Socket defaultjoinstatus:%O",A)})}_sendMessage(A){this._socket.send({usageType:"sdk",...A})}_listenToSocket(){this._socket.on("message",A=>{try{switch("currentlyActiveSpeaker"===A.id||"allStats"===A.id||SD.info("message in Room is:%O",A),A.id){case"chatMessage":this.processChatMessage(A);break;case"customMessage":this.processCustomMessage(A);break;case"existingParticipants":this.onExistingParticipants(A);break;case"newPeerJoin":this.onNewPeer(A);break;case"recordingError":this.handleRecordingErrors(A);break;case"moderatorAuthentication":this.authenticateUser(A);break;case"authenticationRequested":this.authenticationRequested(A);break;case"toggleMyMic":this.toggleMyMic(A);break;case"toggleMyCamera":this.toggleMyCamera(A);break;case"logMeOut":this.logMeOutNew(A);break;case"userAlreadyAuthenticated":this.hideUserAuthenticationDialog(A);break;case"peerLeft":this.peerLeft(A);break;case"recordingStarted":this.setRecordingStatusStarted(A);break;case"recordingStopped":this.setRecordingStatusEnded(A);break;case"startDefaultRecording":this.startRecording(A);break;case"mediaToggled":this.mediaToggled(A);break;case"processingStarted":this.handleProcessingStart(A);break;case"processingCompleted":this.handleProcessingCompletion(A);break;case"processingError":this.handleProcessingError(A);break;case"createTransportResponse":this.handleCreateTransportRequest(A);break;case"connectTransportResponse":this.handleConnectTransportRequest(A);break;case"connectRecvTransportResponse":this.handleConnectRecvTransportRequest(A);break;case"sendTrackResponse":this.handleSendTrackRequest(A);break;case"recvTrackResponse":this.handleRecvTrackRequest(A);break;case"roomClosedByModerator":this.leaveRoomCommon(),this.roomClosed();break;case"currentlyActiveSpeaker":this.setCurrentlyActiveSpeaker(A);break;case"restartIceResponse":this.restartIceResponse(A);break;case"consumerClosed":this.closeConsumer(A);break;case"handRaise":this.handleHandRaise(A);break;case"updateCId":this.updateCId(A);break;case"upgradeParticipant":this.handleUpgradeParticipant(A);break;case"downgradeParticipant":this.handleDowngradeParticipant(A);break;case"switchMicOff":this.handleSwitchMicOff(A);break;case"screenShareLimitReached":this.handleScreenShareLimitReached(A);break;case"upgradeLimitReached":this.handleUpgradeLimitReached(A);break;case"modUpgradeReq":this.handleModUpgradeReq(A);break;case"lockUnlockRoom":this.handleLockUnlockRoom(A);break;case"peersWaiting":this.handlePeersWaiting(A);break;case"remotePeerJoin":this.handleRemotePeerJoin(A);break;case"offer":SD.debug("inside offer"),this.handleOffer(A);break;case"answer":SD.debug("inside answer"),this.handleAnswer(A);break;case"candidate":SD.debug("inside handle candidate"),this.handleCandidate(A.candidate);break;case"p2pRoomClosed":SD.debug("inside p2p room close"),this.leaveRoomNewP2p("leaveAndCloseRoom");break;case"p2pUserLeft":SD.debug("inside p2p user left"),this.userLeftRoom(A);break;case"iceRestart":this.handleIceRestart(A);break;case"iceRestarted":this.handleIceRestartResponse(A);break;case"screenShareP2p":this.handleScreenShareP2p(A);break;case"transcription":this._processTranscriptionMessage(A);break;default:SD.warn("Unrecognized message:%o",A)}}catch(eD){SD.error("listentomessage:%O",eD)}})}joinRoom=async({peerName:A=null,produce:I=!0,produceAudio:g=!0,produceVideo:C=!0,consume:Q=!0,videoResolution:B="hd",forceVp8:E=!1,forceVp9:i=!1,forceH264:D=!1,h264Profile:n="high",forcePCMU:o=!1,forcePCMA:s=!1,forceFPS:w=25,enableWebcamLayers:a=!0,numSimulcastStreams:y=3,autoGainControl:G=!0,echoCancellation:R=!0,noiseSuppression:S=!0,sampleRate:h=44e3,channelCount:N=1,videoBitRates:K=[700,250,75],share:M=!1,shareAudio:F=!1,enableSharingLayers:L=!0,shareBitRates:k=[2500,1250,500],audioDeviceId:J=null,videoDeviceId:U=null,peerType:q="participant",roomType:t=YE.CONFERENCING,authenticationRequired:r=!1,password:c=null,roomDisplayName:H=null,vbdetails:Y,enableTranscription:e=!1}={})=>{SD.info("Going to join room",e),["hd","vga","qvga"].includes(B)||(SD.warn("Invalid video resolution value. setting it to default value of 'hd' "),B="hd"),"boolean"!=typeof I&&(SD.warn("Produe should either be true or false"),I=Boolean(I)),"boolean"!=typeof g&&(SD.warn("ProduceAudio should either be true or false"),g=Boolean(g)),"boolean"!=typeof C&&(SD.warn("ProduceVideo should either be true or false"),C=Boolean(C)),"boolean"!=typeof Q&&(SD.warn("Consume should either be true or false"),Q=Boolean(Q)),"boolean"!=typeof E&&(SD.warn("forceVp8 should either be true or false"),E=Boolean(E)),"boolean"!=typeof i&&(SD.warn("forceVp9 should either be true or false"),i=Boolean(i)),"boolean"!=typeof D&&(SD.warn("forceH264 should either be true or false"),D=Boolean(D)),["high","low"].includes(n.toLowerCase())||(SD.warn("h264Profile should either be 'high' or 'low'"),n="high"),(!Number.isInteger(w)||Number.isInteger(w)&&(w>65||w<5))&&(SD.warn("forceFPS should be a number between 5 to 65, default value is 25 fps."),w=25),"boolean"!=typeof a&&(SD.warn("enableWebcamLayers should either be true or false"),a=Boolean(a)),(!Number.isInteger(y)||Number.isInteger(y)&&(y>3||y<1))&&(SD.warn("numSimulcastStreams should be a number between 1 to 3, default value is 3."),y=3),Array.isArray(K)&&K.length>=1&&K.length<=3&&K.every(A=>Number.isInteger(A)&&A>=75&&A<=800)?SD.debug("videoBitRates values are correct"):(SD.warn("videobitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[700,250,75]'"),K=[700,250,75]),"boolean"!=typeof o&&(SD.warn("forcePCMU should either be true or false"),o=Boolean(o)),"boolean"!=typeof s&&(SD.warn("forcePCMA should either be true or false"),s=Boolean(s)),"boolean"!=typeof G&&(SD.warn("autoGainControl should either be true or false"),G=Boolean(G)),"boolean"!=typeof R&&(SD.warn("echoCancellation should either be true or false"),R=Boolean(R)),"boolean"!=typeof S&&(SD.warn("noiseSuppression should either be true or false"),S=Boolean(S)),(!Number.isInteger(h)||Number.isInteger(h)&&(h>64e3||h<8e3))&&(SD.warn("sampleRate should be a number between 8000 to 64000, default value is 44000 Khz."),h=44e3),(!Number.isInteger(N)||Number.isInteger(N)&&(N>2||N<1))&&(SD.warn("sampleRate should be a number between 1 to 2, default value is 1, which is a mono audio."),N=1),"boolean"!=typeof M&&(SD.warn("share should either be true or false"),M=Boolean(M)),"boolean"!=typeof F&&(SD.warn("shareAudio should either be true or false"),F=Boolean(F)),"boolean"!=typeof L&&(SD.warn("enableSharingLayers should either be true or false"),L=Boolean(L)),Array.isArray(k)&&k.length>=1&&k.length<=3&&k.every(A=>Number.isInteger(A)&&A>=500&&A<=2500)?SD.debug("shareBitRates values are correct"):(SD.warn("sharebitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[2500,1250,500]'"),k=[2500,1250,500]),["moderator","participant","attendee"].includes(q)?SD.debug("peerType is valid:%s",q):(q="participant",SD.debug("peerType is invalid:%s. By default set to: participant",q)),await this.listDevicesInternal(),this._videoResolution=B,this._forceVP8=Boolean(E),this._forceH264=Boolean(D),this._forceVP9=Boolean(i),this._enableWebcamLayers=Boolean(a),this._numSimulcastStreams=y,this._enableSharingLayers=Boolean(L);try{A||(A=ZE()),this.data.inputParams={...this.data.inputParams,peerName:A,produce:I,produceAudio:g,produceVideo:C,consume:Q,videoResolution:B,forceVp8:E,forceVp9:i,forceH264:D,h264Profile:n,forceFPS:w,forcePCMU:o,forcePCMA:s,enableWebcamLayers:a,numSimulcastStreams:y,autoGainControl:G,echoCancellation:R,noiseSuppression:S,sampleRate:h,channelCount:N,videoBitRates:K,share:M,shareAudio:F,enableSharingLayers:L,shareBitRates:k,audioDeviceId:J,videoDeviceId:U,peerType:q,roomType:t,authenticationRequired:r,password:c,roomDisplayName:H,vbdetails:Y,enableTranscription:e},SD.info("input params are:%O",this.data.inputParams);const d={id:"joinRoom",type:"r",peerId:this.data.inputParams.peerId,participantType:"attendee"===q?"viewer":q,roomType:t,roomDisplayName:H||`room-${1e5+Math.round(9e5*Math.random())}`,browser:this._client,name:this.data.inputParams.peerName,room:this.data.inputParams.roomId,authenticationRequired:r,isRoomPassword:!!c,roomPassword:c||null,usageType:"sdk",enableTranscription:e};this._sendMessage(d)}catch(d){return SD.error("Failed to join room:",d.message),{success:!1,reason:d.message}}};authenticateUser=A=>{SD.info("Moderator authentication requested:%O",A),this.emit("moderatorAuthentication",{moderatorName:A.moderatorName,requesterName:A.requesterName,requesterPeerId:A.requesterPeerId,text:A.title})};authenticationRequested=A=>{SD.info("Moderator authentication requested:%O",A),this.emit("authenticationRequested",{requesterName:A.requesterName,requesterPeerId:this.data.inputParams.peerId,text:A.title})};allowRoomJoin=A=>{if(!A)return SD.error("peerId can't be undefined!"),{success:!1,reason:"PeerId can't be undefined"};SD.info("Allow user to join room:%O",A);let I={id:"userAuthenticated",peerId:A,roomName:this.data.inputParams.roomId,moderator:this.data.inputParams.peerId};this._sendMessage(I)};denyRoomJoin=A=>{if(!A)return SD.error("peerId can't be undefined!"),{success:!1,reason:"PeerId can't be undefined"};SD.info("Deny user to join room:%O",A);let I={id:"userDenied",peerId:A,roomName:this.data.inputParams.roomId,moderator:this.data.inputParams.peerId};this._sendMessage(I)};setSpeakingWhileMutedDetection(A=!0){this._mutedSpeakingDetectionEnabled=A,SD.debug("Speaking while muted detection "+(A?"enabled":"disabled"))}setSpeakingThreshold(A=-50){this._speakingThreshold=A,SD.debug(`Speaking threshold set to: ${A}dB`)}async _initializeAudioMonitoring(){if(this._micStream)try{this._audioContext=new AudioContext,this._audioAnalyser=this._audioContext.createAnalyser(),this._audioAnalyser.fftSize=512,this._audioAnalyser.smoothingTimeConstant=.3;const A={audio:{deviceId:this._mic.device?{exact:this._mic.device.deviceId}:void 0,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}};this._micMonitorStream=await navigator.mediaDevices.getUserMedia(A);this._audioContext.createMediaStreamSource(this._micMonitorStream).connect(this._audioAnalyser),SD.debug("Audio monitoring initialized successfully")}catch(A){SD.error("Error initializing audio monitoring:%o",A)}}_getAudioLevel(){if(!this._audioAnalyser)return-1/0;const A=this._audioAnalyser.frequencyBinCount,I=new Uint8Array(A);this._audioAnalyser.getByteFrequencyData(I);let g=0;for(let B=0;B<A;B++)g+=I[B];const C=g/A,Q=20*Math.log10(C/255);return isFinite(Q)?Q:-1/0}_startSpeakingWhileMutedDetection(){this._mutedSpeakingDetectionEnabled&&this._audioAnalyser&&(this._speakingWhileMutedInterval=setInterval(()=>{if(!this._micProducer||!this._micProducer.paused)return;const A=this._getAudioLevel();if(A>this._speakingThreshold){const I=Date.now();I-this._lastMutedSpeakingNotification>this._mutedSpeakingCooldown&&(this._lastMutedSpeakingNotification=I,this.data.inputParams.peerId===this.peerId&&(this.emit("speakingWhileMuted",{peerId:this.data.inputParams.peerId,audioLevel:A,timestamp:I,message:"You appear to be speaking while muted"}),SD.debug(`Speaking while muted detected - Audio level: ${A}dB`)))}},100))}_stopSpeakingWhileMutedDetection(){this._speakingWhileMutedInterval&&(clearInterval(this._speakingWhileMutedInterval),this._speakingWhileMutedInterval=null)}_cleanupAudioMonitoring(){this._stopSpeakingWhileMutedDetection(),this._micMonitorStream&&(this._micMonitorStream.getTracks().forEach(A=>A.stop()),this._micMonitorStream=null),this._audioContext&&"closed"!==this._audioContext.state&&(this._audioContext.close(),this._audioContext=null),this._audioAnalyser=null}async diagnoseAudio(){SD.debug("Starting comprehensive audio diagnostic...");const A={timestamp:Date.now(),browser:this._client,permissions:{},devices:{},connectivity:{},currentSetup:{},recommendations:[]};try{return A.permissions=await this._testAudioPermissions(),A.devices=await this._testAudioDevices(),A.currentSetup=await this._testCurrentMicSetup(),A.connectivity=await this._testWebRTCConnectivity(),A.recommendations=this._generateAudioRecommendations(A),this._audioTroubleShootData.lastDiagnostic=A,this.emit("audioDiagnosticComplete",{peerId:this.data.inputParams.peerId,diagnostic:A}),A}catch(I){return SD.error("Audio diagnostic failed:",I),A.error=I.message,A}}async _testAudioPermissions(){const A={granted:!1,state:"unknown",error:null};try{if(navigator.permissions){const I=await navigator.permissions.query({name:"microphone"});A.state=I.state,A.granted="granted"===I.state}const I=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});A.granted=!0,A.actuallyGranted=!0,I.getTracks().forEach(A=>A.stop())}catch(I){A.error=I.name,A.actuallyGranted=!1,SD.error("Permission test failed:",I)}return A}getSystemHealthStatus(){return{sdk:{roomStatus:this._roomStatus,isConnected:"connected"===this._roomStatus,micActive:!!this._micProducer&&!this._micProducer.closed,micMuted:this._micProducer?.paused,cameraActive:!!this._webcamProducer&&!this._webcamProducer.closed,screenSharing:!!this._shareProducer&&!this._shareProducer.closed},transports:{send:this._sendTransport?{id:this._sendTransport.id,connectionState:this._sendTransport.connectionState,iceState:this._sendTransport.iceState,dtlsState:this._sendTransport.dtlsState}:null,recv:this._recvTransport?{id:this._recvTransport.id,connectionState:this._recvTransport.connectionState,iceState:this._recvTransport.iceState,dtlsState:this._recvTransport.dtlsState}:null},audio:{context:this._audioContext?.state,analyser:!!this._audioAnalyser,currentLevel:this._getAudioLevel(),speaking:this._getAudioLevel()>this._speakingThreshold,monitorStream:!!this._micMonitorStream},streams:{mic:this._micStream?.active,camera:this._webCamStream?.active,micTracks:this._micStream?.getTracks()?.length||0,cameraTracks:this._webCamStream?.getTracks()?.length||0}}}async testNetworkConnectivity(){const A={timestamp:Date.now(),stun:{working:!1,latency:null},turn:{working:!1,latency:null},bandwidth:{upload:null,download:null},packetLoss:null};try{const I=Date.now(),g=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]}),C=(g.createDataChannel("test"),await g.createOffer());await g.setLocalDescription(C),await new Promise(A=>{g.onicecandidate=I=>{I.candidate||A()},setTimeout(A,5e3)}),A.stun.working="failed"!==g.iceConnectionState,A.stun.latency=Date.now()-I,g.close()}catch(I){}return A}async assessAudioQuality(A=5e3){if(!this._micStream)throw new Error("No active microphone stream");const I={duration:A,samples:[],averageLevel:0,peakLevel:-1/0,quietSamples:0,clipSamples:0,quality:"unknown"};try{const g=new AudioContext,C=g.createAnalyser();C.fftSize=1024;g.createMediaStreamSource(this._micStream).connect(C);const Q=C.frequencyBinCount,B=new Uint8Array(Q),E=Date.now(),i=100;return new Promise(D=>{const n=setInterval(()=>{C.getByteFrequencyData(B);let i=0;for(let A=0;A<Q;A++)i+=B[A];const o=i/Q,s=20*Math.log10(o/255);if(isFinite(s)&&(I.samples.push(s),I.peakLevel=Math.max(I.peakLevel,s),s<-70&&I.quietSamples++,s>-3&&I.clipSamples++),Date.now()-E>=A){clearInterval(n),g.close();const A=I.samples.filter(A=>isFinite(A));I.averageLevel=A.reduce((A,I)=>A+I,0)/A.length;const C=I.quietSamples/A.length*100;I.clipSamples/A.length*100>10?I.quality="poor-clipping":C>80?I.quality="poor-quiet":I.averageLevel>-30?I.quality="good":I.averageLevel>-50?I.quality="fair":I.quality="poor-low",D(I)}},i)})}catch(g){throw new Error(`Audio quality assessment failed: ${g.message}`)}}async attemptAutoRemediation(){const A=[],I=this.getSystemHealthStatus();try{"failed"===I.transports.send?.connectionState&&(await this.restartIce(I.transports.send.id,"send"),A.push("Restarted send transport")),"failed"===I.transports.recv?.connectionState&&(await this.restartIce(I.transports.recv.id,"recv"),A.push("Restarted receive transport")),!I.audio.analyser&&this._micStream&&(this._cleanupAudioMonitoring(),await this._initializeAudioMonitoring(),A.push("Restarted audio monitoring")),I.sdk.micActive&&!I.streams.mic&&(await this.disableMic(),await this.enableMic(),A.push("Restarted microphone"));const g=await this.diagnoseAudio();if(g.devices?.working?.length>0){const I=g.currentSetup?.deviceLabel,C=g.devices.working[0];I!==C.label&&(await this.changeAudioInput({deviceId:C.deviceId}),A.push(`Switched to working device: ${C.label}`))}return{success:!0,fixes:A}}catch(g){return{success:!1,error:g.message,fixes:A}}}async getEnhancedDeviceList(){try{const I=await navigator.mediaDevices.enumerateDevices(),g=[];for(const C of I){if("audioinput"!==C.kind)continue;const I={deviceId:C.deviceId,label:C.label,groupId:C.groupId,capabilities:null,testResult:null};try{const A=(await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:C.deviceId}}})).getAudioTracks()[0];I.capabilities=A.getCapabilities(),I.testResult=await this._testSpecificDevice(C.deviceId,1e3),A.stop()}catch(A){I.testResult={working:!1,error:A.message}}g.push(I)}return g}catch(A){throw new Error(`Enhanced device enumeration failed: ${A.message}`)}}async optimizeAudioSettings(){const A=this.getSystemHealthStatus(),I=[];try{const g=await this.assessAudioQuality(3e3);if("poor-clipping"===g.quality?(await this.changeAudioInput({autoGainControl:!1,echoCancellation:!0,noiseSuppression:!0}),I.push("Disabled auto-gain control to prevent clipping")):"poor-quiet"===g.quality&&(await this.changeAudioInput({autoGainControl:!0,echoCancellation:!0,noiseSuppression:!1}),I.push("Enabled auto-gain control for low input levels")),"connected"===A.transports.send?.connectionState){await this._sendTransport.getStats()}return{success:!0,recommendations:I,qualityAssessment:g}}catch(g){return{success:!1,error:g.message,recommendations:I}}}async _testAudioDevices(){const A={available:[],current:null,working:[],failed:[]};try{const g=await navigator.mediaDevices.enumerateDevices();A.available=g.filter(A=>"audioinput"===A.kind).map(A=>({deviceId:A.deviceId,label:A.label,groupId:A.groupId})),A.current=this._mic.device;for(const C of A.available)try{const I=await this._testSpecificDevice(C.deviceId);I.working?A.working.push({...C,audioLevel:I.audioLevel,testDuration:I.duration}):A.failed.push({...C,error:I.error})}catch(I){A.failed.push({...C,error:I.message})}}catch(I){A.error=I.message}return A}async _testSpecificDevice(A,I=2e3){return new Promise(g=>{const C={working:!1,audioLevel:-1/0,duration:I,error:null};let Q=null,B=null,E=null;const i=()=>{Q&&Q.getTracks().forEach(A=>A.stop()),B&&"closed"!==B.state&&B.close()},D=setTimeout(()=>{i(),g(C)},I);navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:A}}}).then(A=>{Q=A,B=new(window.AudioContext||window.webkitAudioContext),E=B.createAnalyser(),E.fftSize=256;B.createMediaStreamSource(Q).connect(E);const n=E.frequencyBinCount,o=new Uint8Array(n),s=setInterval(()=>{E.getByteFrequencyData(o);let A=0;for(let C=0;C<n;C++)A+=o[C];const I=A/n,g=20*Math.log10(I/255);isFinite(g)&&g>C.audioLevel&&(C.audioLevel=g),I>0&&(C.working=!0)},100);setTimeout(()=>{clearInterval(s),clearTimeout(D),i(),g(C)},I-100)}).catch(A=>{clearTimeout(D),C.error=A.message,i(),g(C)})})}async _testCurrentMicSetup(){const A={isActive:!1,isProducing:!1,isMuted:!1,audioLevel:-1/0,deviceLabel:null,streamActive:!1,producerStats:null};try{if(A.isActive=!!this._micProducer,A.isProducing=!(!this._micProducer||this._micProducer.closed),A.isMuted=!(!this._micProducer||!this._micProducer.paused),A.deviceLabel=this._mic.device?.label,A.streamActive=!(!this._micStream||!this._micStream.active),this._micStream){const I=this._micStream.getAudioTracks();I.length>0&&(A.trackEnabled=I[0].enabled,A.trackReadyState=I[0].readyState,A.trackSettings=I[0].getSettings())}if(this._audioAnalyser&&(A.audioLevel=this._getAudioLevel()),this._micProducer&&this._sendTransport)try{const I=await this._sendTransport.getStats();A.producerStats=I}catch(I){A.producerStatsError=I.message}}catch(I){A.error=I.message}return A}async _testWebRTCConnectivity(){const A={sendTransport:null,recvTransport:null,iceConnectionState:null,dtlsState:null,error:null};try{this._sendTransport&&(A.sendTransport={id:this._sendTransport.id,connectionState:this._sendTransport.connectionState,iceState:this._sendTransport.iceState,dtlsState:this._sendTransport.dtlsState}),this._recvTransport&&(A.recvTransport={id:this._recvTransport.id,connectionState:this._recvTransport.connectionState,iceState:this._recvTransport.iceState,dtlsState:this._recvTransport.dtlsState})}catch(I){A.error=I.message}return A}_generateAudioRecommendations(A){const I=[];return A.permissions.granted||I.push({type:"critical",title:"Microphone Permission Required",description:"Please allow microphone access in your browser",action:"Grant microphone permission in browser settings"}),0===A.devices.working.length&&I.push({type:"critical",title:"No Working Audio Devices",description:"No functioning microphone devices detected",action:"Check if microphone is connected and enabled in system settings"}),A.currentSetup.isActive&&!A.currentSetup.streamActive&&I.push({type:"warning",title:"Current Microphone Not Working",description:"The selected microphone device appears to be inactive",action:"Try switching to a different microphone device"}),"failed"===A.connectivity.sendTransport?.connectionState&&I.push({type:"critical",title:"Connection Failed",description:"Unable to establish audio connection to server",action:"Check internet connection and try rejoining the room"}),A.currentSetup.audioLevel<-60&&I.push({type:"info",title:"Low Audio Level",description:"Your microphone level appears to be very low",action:"Check microphone volume in system settings or move closer to microphone"}),I}async quickAudioTest(){const A={working:!1,issues:[],timestamp:Date.now()};try{if(!this._micProducer)return A.issues.push("Microphone not active"),A;if(this._micProducer.closed)return A.issues.push("Microphone producer is closed"),A;if(!this._micStream||!this._micStream.active)return A.issues.push("Microphone stream is not active"),A;const I=this._micStream.getAudioTracks();if(0===I.length)return A.issues.push("No audio tracks found"),A;if("live"!==I[0].readyState)return A.issues.push("Audio track is not live"),A;if("connected"!==this._sendTransport.connectionState)return A.issues.push(`Send transport not connected: ${this._sendTransport.connectionState}`),A;A.working=!0}catch(I){A.issues.push(`Test error: ${I.message}`)}return this.emit("quickAudioTestComplete",{peerId:this.data.inputParams.peerId,result:A}),A}async listAudioOutputDevices(){try{if(this._deviceList&&this._deviceList.audioOutputDevices)return SD.debug("Using cached audio output devices:",this._deviceList.audioOutputDevices),{success:!0,devices:this._deviceList.audioOutputDevices};const A=await navigator.mediaDevices.enumerateDevices();return this._audioOutputDevices=A.filter(A=>"audiooutput"===A.kind),SD.debug("Found audio output devices:",this._audioOutputDevices),{success:!0,devices:this._audioOutputDevices.map(A=>({deviceId:A.deviceId,label:A.label||`Speaker ${A.deviceId.slice(-4)}`,groupId:A.groupId}))}}catch(A){return SD.error("Failed to enumerate audio output devices:",A),{success:!1,error:A.message}}}async testSpeakerDevice(A,I={}){SD.debug("Testing speaker device",A);const{testDuration:g=3e3,testFrequencies:C=[440,1e3,2e3],volume:Q=.3,requireUserConfirmation:B=!0}=I,E=`speaker-test-${A}-${Date.now()}`;try{if(!HTMLAudioElement.prototype.setSinkId)throw new Error("setSinkId is not supported in this browser");const I={deviceId:A,testId:E,timestamp:Date.now(),success:!1,frequencies:[],volume:Q,duration:g,userConfirmed:!1,error:null},i=new Audio;i.volume=Q,i.loop=!1,await i.setSinkId(A),I.setSinkId=!0,this._testAudioElements.set(E,i);for(const A of C){const Q=await this._playTestTone(i,A,g/C.length);I.frequencies.push(Q)}if(B){const g=await this._requestUserConfirmation(A,I);I.userConfirmed=g,I.success=g}else I.success=I.frequencies.every(A=>A.played);return this._speakerTestResults.set(A,I),this.emit("speakerTestComplete",{deviceId:A,testResult:I}),{success:!0,testResult:I}}catch(i){SD.error(`Speaker test failed for device ${A}:`,i);const I={deviceId:A,testId:E,timestamp:Date.now(),success:!1,error:i.message};return this._speakerTestResults.set(A,I),this.emit("speakerTestComplete",{deviceId:A,testResult:I}),{success:!1,error:i.message,testResult:I}}finally{this._cleanupTestAudio(E)}}async _playTestTone(A,I,g){return new Promise((C,Q)=>{try{const Q=new window.AudioContext,B=Q.createOscillator(),E=Q.createGain(),i=Q.createMediaStreamDestination();B.connect(E),E.connect(i),B.frequency.setValueAtTime(I,Q.currentTime),B.type="sine",E.gain.setValueAtTime(0,Q.currentTime),E.gain.linearRampToValueAtTime(.1,Q.currentTime+.1),E.gain.linearRampToValueAtTime(.1,Q.currentTime+g/1e3-.1),E.gain.linearRampToValueAtTime(0,Q.currentTime+g/1e3),A.srcObject=i.stream,B.start(),B.stop(Q.currentTime+g/1e3);const D=A.play();void 0!==D&&D.then(()=>{setTimeout(()=>{B.disconnect(),E.disconnect(),Q.close(),C({frequency:I,duration:g,played:!0,timestamp:Date.now()})},g)}).catch(A=>{Q.close(),C({frequency:I,duration:g,played:!1,error:A.message,timestamp:Date.now()})})}catch(B){Q(B)}})}async _requestUserConfirmation(A,I){return new Promise(g=>{this.emit("speakerTestConfirmationRequired",{deviceId:A,testResult:I,onConfirm:A=>g(A)}),setTimeout(()=>g(!1),1e4)})}async testCurrentSpeakerOutput(){try{const I={timestamp:Date.now(),currentDevice:this._currentSpeakerDevice,remoteAudioPresent:!1,audioElementFound:!1,volumeLevel:0,success:!1},g=document.querySelectorAll("audio"),C=document.querySelectorAll("video");let Q=[];if(g.forEach(A=>{A.srcObject&&A.srcObject.getAudioTracks().length>0&&Q.push(A)}),C.forEach(A=>{A.srcObject&&A.srcObject.getAudioTracks().length>0&&Q.push(A)}),I.audioElementFound=Q.length>0,I.elementsCount=Q.length,Q.length>0){for(const g of Q)try{if(g.srcObject){const A=new AudioContext,C=A.createMediaStreamSource(g.srcObject),Q=A.createAnalyser();C.connect(Q),Q.fftSize=256;const B=Q.frequencyBinCount,E=new Uint8Array(B);Q.getByteFrequencyData(E);const i=E.reduce((A,I)=>A+I,0)/B;I.volumeLevel=Math.max(I.volumeLevel,i),I.remoteAudioPresent=i>0,A.close()}}catch(A){SD.debug("Could not analyze remote audio element:",A)}I.success=I.remoteAudioPresent}return this.emit("currentSpeakerTestComplete",I),{success:!0,testResult:I}}catch(A){return SD.error("Current speaker test failed:",A),{success:!1,error:A.message}}}async diagnoseSpeakers(){SD.debug("Starting comprehensive speaker diagnostic");const A={timestamp:Date.now(),browser:this._client,support:{},devices:{},currentOutput:{},remoteAudio:{},recommendations:[]};try{A.support={setSinkId:!!HTMLAudioElement.prototype.setSinkId,enumerateDevices:!!navigator.mediaDevices?.enumerateDevices,audioContext:!!window.AudioContext};const I=await this.listAudioOutputDevices();A.devices={available:I.devices||[],count:I.devices?.length||0,hasDefault:I.devices?.some(A=>"default"===A.deviceId)||!1};const g=await this.testCurrentSpeakerOutput();return A.currentOutput=g.testResult,A.remoteAudio=this._analyzeRemoteAudioSetup(),A.recommendations=this._generateSpeakerRecommendations(A),this.emit("speakerDiagnosticComplete",{diagnostic:A}),A}catch(I){return SD.error("Speaker diagnostic failed:",I),A.error=I.message,A}}_analyzeRemoteAudioSetup(){const A={consumers:0,activeStreams:0,audioElements:0,videoElements:0,totalTracks:0};try{this._consumers&&this._consumers.forEach(I=>{I&&"audio"===I.kind&&!I.closed&&A.consumers++});const I=document.querySelectorAll("audio"),g=document.querySelectorAll("video");I.forEach(I=>{A.audioElements++,I.srcObject&&I.srcObject.getAudioTracks().length>0&&(A.activeStreams++,A.totalTracks+=I.srcObject.getAudioTracks().length)}),g.forEach(I=>{A.videoElements++,I.srcObject&&I.srcObject.getAudioTracks().length>0&&(A.activeStreams++,A.totalTracks+=I.srcObject.getAudioTracks().length)}),0===A.activeStreams&&0===A.totalTracks&&A.consumers>0&&(A.activeStreams=A.consumers,A.totalTracks=A.consumers)}catch(I){SD.error("Remote audio analysis failed:",I),A.error=I.message}return A}_generateSpeakerRecommendations(A){const I=[];return A.support.setSinkId||I.push({type:"critical",title:"Audio Output Selection Not Supported",description:"Your browser does not support changing audio output devices",actions:["Use Chrome, Edge, or Firefox for audio output selection","Change system default audio device instead","Consider using a different browser"]}),0===A.devices.count&&I.push({type:"critical",title:"No Audio Output Devices Found",description:"No speakers or headphones detected",actions:["Check if speakers/headphones are connected","Verify audio drivers are installed","Try refreshing the page after connecting devices"]}),0===A.remoteAudio.consumers&&0===A.remoteAudio.activeStreams&&I.push({type:"warning",title:"No Remote Audio Detected",description:"Not receiving audio from other participants",actions:["Ask other participants to unmute their microphones","Check if you have muted remote participants","Verify your internet connection"]}),!A.currentOutput.success&&A.currentOutput.audioElementFound&&I.push({type:"warning",title:"Audio Output Issues",description:"Remote audio present but may not be playing correctly",actions:["Check system volume levels","Try switching to a different audio output device","Verify the selected output device is working"]}),0===I.length&&I.push({type:"success",title:"Audio Output System Healthy",description:"Speaker setup appears to be working correctly",actions:["Your audio output is configured properly","Run individual device tests if experiencing issues"]}),I}async progressiveTestAllSpeakers(A={}){SD.debug("Progressive speaker test started");const{testDuration:I=2e3,requireConfirmation:g=!0,volume:C=.2}=A;try{const A=await this.listAudioOutputDevices();if(!A.success)throw new Error("Could not enumerate audio devices");const Q=[];let B=0;this.emit("progressiveSpeakerTestStarted",{totalDevices:A.devices.length,testDuration:I,requireConfirmation:g});for(const E of A.devices){B++,this.emit("progressiveSpeakerTestProgress",{currentIndex:B,totalDevices:A.devices.length,currentDevice:E,progress:B/A.devices.length*100});const i=await this.testSpeakerDevice(E.deviceId,{testDuration:I,volume:C,requireUserConfirmation:g,testFrequencies:[1e3]});Q.push({device:E,...i}),await new Promise(A=>setTimeout(A,500))}return this.emit("progressiveSpeakerTestComplete",{results:Q,workingDevices:Q.filter(A=>A.success),failedDevices:Q.filter(A=>!A.success)}),{success:!0,results:Q,summary:{total:Q.length,working:Q.filter(A=>A.success).length,failed:Q.filter(A=>!A.success).length}}}catch(Q){return SD.error("Progressive speaker test failed:",Q),{success:!1,error:Q.message}}}_cleanupTestAudio(A){if(SD.debug("Cleaning up test audio"),this._testAudioElements.has(A)){const g=this._testAudioElements.get(A);try{g.pause(),g.srcObject=null,g.src=""}catch(I){SD.debug("Error cleaning up test audio:",I)}this._testAudioElements.delete(A)}}getCurrentSpeakerDevice(){return SD.debug("Getting current speaker device"),this._currentSpeakerDevice}async meetingSafeSpeakerTest(A){return SD.debug("Meeting safe speaker test started"),this.testSpeakerDevice(A,{testDuration:1500,testFrequencies:[800],volume:.1,requireUserConfirmation:!0})}hideUserAuthenticationDialog=A=>{SD.debug("authentication already done message:%o",A),this.emit("moderatorAuthStatus",{requesterId:A.requesterId,moderatorActed:A.peerId})};onNewPeer(A){const{peerId:I,displayName:g,participantType:C}=A;this._peers.set(I,{displayName:g,participantType:C,consumers:[]}),this.emit("newPeer",{peerId:I,peerName:g,type:this.data.inputParams.peerId===I?"local":"remote",peerRole:C})}async onExistingParticipants(A){if(SD.debug("Onexisting participant message:%O",A),this._routerRtpCapabilities=A.routerRtpCapabilities,this._roomStatus="connected",this._roomDisplayName=A.roomDisplayName,this._running=!0,this._socket.updateRoomJoinStatus(!0),this.emit("newPeer",{peerId:this.data.inputParams.peerId,peerName:this.data.inputParams.peerName,type:"local",peerRole:this.data.inputParams.peerType,screenSharing:A.screenSharing,userSettings:A.userSettings,participantType:A.participantType}),this.data.inputParams.produce?await this._createSendTransport():SD.debug("Produce is false!"),this.data.inputParams.consume){await this._createRecvTransport();let I=this;A.peers&&A.peers.length>0&&A.peers.forEach(A=>{I.emit("newPeer",{peerId:A.peerId,peerName:A.name,type:"remote",peerRole:A.participantType})})}else SD.debug("Consume is false!")}sendCustomMessage=(A,I="general",g=null,C,Q,B={})=>{const E={id:"customMessage",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,data:A,type:I,recieverPeerId:g,senderType:C,messageType:Q,customData:B};SD.debug("Room sendCustomMessage",E),this._sendMessage(E)};setCaptionPreference(A){try{const I={type:"captions_pref",show:!!A};return SD.debug("Room setCaptionPreference",I),this.sendCustomMessage(JSON.stringify(I),"custom",null,"participant","preference"),{success:!0}}catch(I){return SD.error("Failed to send caption preference",I),{success:!1,reason:I?.message}}}processCustomMessage=A=>{SD.debug("Room processCustomMessage",A),this.emit("customMessage",A)};updateCId=A=>{SD.debug("Received updateCId message",A),A.targetPeerId!==this.data.inputParams.peerId&&A.targetPeerId||this.emit("updateCId",{message:A,cId:A.cId,peerId:this.data.inputParams.peerId,isMyCId:A.targetPeerId===this.data.inputParams.peerId})};setCurrentlyActiveSpeaker(A){const{peerId:I,volume:g}=A.activeSpeaker;this._activeSpeaker=A.activeSpeaker,this.emit("activeSpeaker",{peerId:I,volume:g})}_createSendTransport=async()=>{SD.debug("Room _createSendTransport");try{this._device.loaded||(SD.debug("Room _createSendTransport","Going to load device with routerrtpcapabilities"),await this._device.load({routerRtpCapabilities:this._routerRtpCapabilities}));let A="send";this._sendTransport||this._sendMessage({id:"createTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,direction:A})}catch(eD){SD.error("Room _createSendTransport",eD)}};_createRecvTransport=async()=>{this._device.loaded||(SD.debug("loading device for creating recv transport"),await this._device.load({routerRtpCapabilities:this._routerRtpCapabilities}));this._recvTransport||(SD.debug("receive transport created"),this._sendMessage({id:"createTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,direction:"recv"}))};handleCreateTransportRequest=async A=>{SD.debug("Room handleCreateTransportRequest():%O",A);let I,{transportOptions:g,direction:C}=A;try{if("recv"===C)I=await this._device.createRecvTransport(g),SD.debug("Room",`handleCreateTransportRequest() recv transport created ${I.id}`),this._recvTransport=I,this.handleRecvTransportListeners();else{if("send"!==C)throw new Error(`bad transport 'direction': ${C}`);I=await this._device.createSendTransport(g),SD.debug("Room",`handleCreateTransportRequest() send transport created [id:%s]${I.id}`),this._sendTransport=I,this.handleSendTransportListeners(),this.produceMedia()}}catch(Q){SD.error("Room handleCreateTransportRequest() failed to create transport [error:%o]",Q)}};handleSendTransportListeners=()=>{this._sendTransport.on("connect",this.handleTransportConnectEvent),this._sendTransport.on("produce",this.handleTransportProduceEvent);let A=this;this._sendTransport.on("connectionstatechange",async I=>{if(SD.debug(`ConferenceRoom sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"disconnected"===I)setTimeout(async()=>{if("disconnected"===I)if(SD.debug("Connection state for Send Transport is:%s even after 5 seconds",I),SD.warn(`sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"connected"===A._socket.wsManager.connectionState)A.restartIce(A._sendTransport.id,"send");else{for(;"connected"!==A._socket.wsManager.connectionState;)SD.debug(`socket not yet ready with state- ${A._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._sendTransport.id,"send")}},5e3);else if("failed"===I)if(SD.warn(`sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"connected"===A._socket.wsManager.connectionState)A.restartIce(A._sendTransport.id,"send");else{for(;"connected"!==A._socket.wsManager.connectionState;)SD.debug(`handleSendTransportListeners() | socket not yet ready with state- ${A._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._sendTransport.id,"send")}SD.debug("ConferenceRoom",`send transport connection state change [state:%s]${I}`)})};handleTransportConnectEvent=({dtlsParameters:A},I,g)=>{try{const g=A=>{SD.debug("connect-transport action"),I(),KD.remove("connectTransport")};KD.push("connectTransport",g);let C={id:"connectTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,transportId:this._sendTransport.id,dtlsParameters:A,direction:"send"};this._sendMessage(C)}catch(C){SD.error("handleTransportConnectEvent() failed [error:%o]",C),g(C)}};handleTransportProduceEvent=({kind:A,rtpParameters:I,appData:g},C,Q)=>{try{const Q=A=>{SD.debug("handleTransportProduceEvent callback [data:%o]",A),C({id:A.producerId}),KD.remove("produce")};KD.push("produce",Q);let B="cam-audio"===g.mediaTag&&void 0!==this.data.inputParams.audioStatus&&!this.data.inputParams.audioStatus;SD.debug(`handleTransportProduceEvent() | pause status->${B}`);let E={id:"sendTrack",transportId:this._sendTransport.id,peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,kind:A,rtpParameters:I,paused:B,appData:g,clientOs:this._client.os.name,browser:this._client.browser};this._sendMessage(E)}catch(B){SD.error("handleTransportProduceEvent() failed [error:%o]",B),Q(B)}};produceMedia=async()=>{this.data.inputParams.produce?(this.data.inputParams.produceAudio?this.enableMic({deviceId:this.data.inputParams.audioDeviceId?this.data.inputParams.audioDeviceId:null}):SD.debug("No need to produce audio!"),this._device.canProduce("video")&&(this.data.inputParams.produceVideo?(SD.debug("going to enable cam with vbdetails",this.data.inputParams.vbdetails),this.enableCam({deviceId:this.data.inputParams.videoDeviceId?this.data.inputParams.videoDeviceId:null,vbdetails:this.data.inputParams.vbdetails})):SD.debug("No need to produce video!"),this.data.inputParams.share&&this.enableShare({shareAudio:this.data.inputParams.shareAudio,enableSharingLayers:this._enableSharingLayers,shareBitRates:this.data.inputParams.shareBitRates}))):SD.warn("produce is false!")};handleRecvTransportListeners=async()=>{this._recvTransport.on("connect",this.handleRecvTransportConnectEvent);let A=this;this._recvTransport.on("connectionstatechange",async I=>{if("disconnected"===I)setTimeout(async()=>{if("disconnected"===I)if(SD.warn("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState),"connected"===this._socket.wsManager.connectionState)A.restartIce(A._recvTransport.id,"recv");else{for(;"connected"!==this._socket.wsManager.connectionState;)SD.debug(`handleRecvTransportListeners() | socket not yet ready with state- ${this._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._recvTransport.id,"recv")}},5e3);else if("failed"===I)if(SD.warn("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState),"connected"===this._socket.wsManager.connectionState)A.restartIce(A._recvTransport.id,"recv");else{for(;"connected"!==this._socket.wsManager.connectionState;)SD.debug(`handleRecvTransportListeners() | socket not yet ready with state- ${this._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._recvTransport.id,"recv")}else SD.debug("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState)});let I={id:"transportsAvailable",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,rtpCapabilities:this._device.rtpCapabilities};this._sendMessage(I)};handleRecvTransportConnectEvent=({dtlsParameters:A},I,g)=>{try{const g=A=>{SD.debug("ConferenceRoom","connect-recv-transport action"),I(),KD.remove("connectRecvTransport")};KD.push("connectRecvTransport",g);let C={id:"connectTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,transportId:this._recvTransport.id,dtlsParameters:A,direction:"recv"};this._sendMessage(C)}catch(C){SD.error("handleTransportConnectEvent() failed [error:%o]",C),g(C)}};handleRecvTrackRequest=async A=>{if(SD.debug("Room handleRecvTrackRequest",A),!this.data.inputParams.consume)return void SD.warn("I do not want to consume");let{senderPeerId:I,mediaTag:g,sender:C,audioStatus:Q,videoStatus:B,senderParticipantType:E,type:i,producerPaused:D,...n}=A;SD.debug("New consumer created",n),n.id=n.consumerId,delete n.consumerId,SD.debug("ConferenceRoom",`senderPeerId is ->${I}`);let o=await this._recvTransport.consume({...n,streamId:`${I}-${"screen-video"===g||"screen-audio"===g?"share":"mic-webcam"}`,appData:{peerId:I,mediaTag:g}});for(;this._recvTransport&&"connected"!==this._recvTransport.connectionState;)SD.debug(`recv transport connstate${this._recvTransport.connectionState}`),await Qi(100);this._consumers.set(o.id,o),o.on("transportclose",()=>{this._consumers.delete(o.id)});const{spatialLayers:s,temporalLayers:w}=sg.parseScalabilityMode(o.rtpParameters.encodings[0].scalabilityMode),a=this._peers.get(this.data.inputParams.peerId);SD.debug(`Consumer created for sender peerId ${I} for kind ${o.kind} for receiver peerId ${this.data.inputParams.peerId}`),SD.info("The old peer data is :%O",a),a?(a["screen-video"===g||"screen-audio"===g?`ss${o.kind}`:o.kind]={consumerId:o.id,type:i,locallyPaused:!1,remotelyPaused:D,rtpParameters:o.rtpParameters,spatialLayers:s,temporalLayers:w,preferredSpatialLayer:s-1,preferredTemporalLayer:w-1,priority:1,codec:o.rtpParameters.codecs[0].mimeType.split("/")[1],track:o.track,share:"screen-video"===g||"screen-audio"===g},SD.info("The new peer data is :%O",a),this._peers.set(this.data.inputParams.peerId,a)):(SD.info("Peer not found!"),this._peers.set(this.data.inputParams.peerId,{["screen-video"===g||"screen-audio"===g?`ss${o.kind}`:o.kind]:{consumerId:o.id,type:i,locallyPaused:!1,remotelyPaused:D,rtpParameters:o.rtpParameters,spatialLayers:s,temporalLayers:w,preferredSpatialLayer:s-1,preferredTemporalLayer:w-1,priority:1,codec:o.rtpParameters.codecs[0].mimeType.split("/")[1],track:o.track,share:"screen-video"===g||"screen-audio"===g}})),await this.resumeConsumer(o),SD.debug("Going to emit mic start / videostart"),"audio"===o.kind?"screen-audio"===g?this.emit("ssAudioStart",{peerId:I,audioTrack:o.track,type:"remote"}):this.emit("micStart",{peerId:I,audioTrack:o.track,type:"remote"}):"video"===o.kind&&("screen-video"===g?this.emit("ssVideoStart",{peerId:I,videoTrack:o.track,type:"remote"}):this.emit("videoStart",{peerId:I,videoTrack:o.track,type:"remote"}))};resumeConsumer=async A=>{if(A){SD.debug("resume consumer",A.appData.peerId,A.appData.mediaTag);try{let I={id:"resumeConsumer",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,consumerId:A.id};this._sendMessage(I),await A.resume()}catch(I){SD.error("resumeConsumer error",I)}}};handleConnectTransportRequest=async A=>{SD.debug("handleTransportConnectRequest()");try{const I=KD.get("connectTransport");if(!I)throw new Error("transport-connect action was not found");await I(A)}catch(I){SD.error("handleTransportConnectRequest() failed [error:%o]",I)}};handleConnectRecvTransportRequest=async A=>{SD.debug("handleTransportConnectRequest()");try{const I=KD.get("connectRecvTransport");if(!I)throw new Error("recv transport-connect action was not found");await I(A)}catch(I){SD.error("handleRecvTransportConnectRequest() failed [error:%o]",I)}};handleSendTrackRequest=async A=>{SD.debug("ConferenceRoom","handleProduceRequest()");try{const I=KD.get("produce");if(!I)throw new Error("produce action was not found");await I(A)}catch(I){SD.error("handleProduceRequest() failed [error:%o]",I)}};mediaToggled=A=>{switch(SD.debug("Media Toggled message:%O",A),A.type){case"video":SD.debug(`mediaToggled() | inside case video${A.videoStatus}`);break;case"audio":SD.debug(`mediaToggled() | inside case audio${A.videoStatus}`),A.audioStatus?this.emit("peerUnMuted",{peerId:A.peerId,type:"remote"}):this.emit("peerMuted",{peerId:A.peerId,type:"remote"})}};closeConsumer=A=>{let{consumerId:I}=A;const g=this._consumers.get(I);if(!g)return void SD.warn("Consumer with id not found!:%s",I);const{peerId:C,mediaTag:Q}=g.appData;SD.debug("Consumer closed for consumerId:%s, type:%s, appData:%o",I,g?.kind,g.appData);let B="screen-audio"===Q||"screen-video"===Q?`ss${g.kind}`:g.kind;g.close(),this._consumers.delete(I);let E=this._peers.get(this.data.inputParams.peerId);SD.debug("Peer data before deletion:%O",E),E[B]&&E[B].consumerId===I&&delete E[B],SD.debug("Peer data after deletion:%O",E),this._peers.set(this.data.inputParams.peerId,E),"audio"===g?.kind?(SD.debug("Going to emit micEnd, consumer closed for audio"),"screen-audio"===Q?this.emit("ssAudioStop",{peerId:C,track:null,type:"remote"}):this.emit("micEnd",{peerId:C,track:null,type:"remote"})):"video"===g?.kind&&(SD.debug("Going to emit videoEnd, consumer closed for video"),"screen-video"===Q?this.emit("ssVideoStop",{peerId:C,track:null,type:"remote"}):this.emit("videoEnd",{peerId:C,track:null,type:"remote"}))};peerLeft=A=>{SD.debug("Peer Left message is:%o",A);let{peerId:I}=A;this._peers.delete(I),this.emit("peerLeft",{peerId:I})};roomClosed=()=>{SD.info("room closed by Moderator"),this._peers=null,this.emit("roomClosed",{roomId:this.data.inputParams.roomId})};close(){this._closed||(this._closed=!0,this._socket=null,this.data.inputParams={},SD.info("Room close()"),this._sendTransport&&this._sendTransport.close(),this._recvTransport&&this._recvTransport.close(),this._roomStatus="closed",this._running=!1)}async leaveRoom(){SD.debug("Leave room is called!!"),"connected"===this._roomStatus?(this._sendMessage({id:"leaveRoomNew",peerId:this.data.inputParams.peerId,roomLeaveType:"client"}),await this.leaveRoomCommon()):SD.error("The room state is:%s",this._roomStatus)}async closeRoom(){"connected"===this._roomStatus?(this._sendMessage({id:"leaveAndCloseRoom",peerId:this.data.inputParams.peerId,roomCloseType:"client"}),await this.leaveRoomCommon()):SD.error("The room state is:%s",this._roomStatus)}leaveRoomCommon=async()=>{try{SD.debug("Starting comprehensive room leave cleanup...");try{this._cleanupAudioMonitoring(),this._stopSpeakingWhileMutedDetection(),this._stopAutoAudioStreaming(),this._transcriptionActive&&this.stopTranscription(),MD&&"function"==typeof MD.cleanup&&MD.cleanup()}catch(A){}const C=new Set;this._webcamProducer?.track&&C.add(this._webcamProducer.track),this._micProducer?.track&&C.add(this._micProducer.track),this._shareProducer?.track&&C.add(this._shareProducer.track),this._shareAudioProducer?.track&&C.add(this._shareAudioProducer.track),this._producers&&this._producers.size>0&&this._producers.forEach(A=>{A?.track&&C.add(A.track)}),this._webCamStream&&this._webCamStream.getTracks().forEach(A=>C.add(A)),this._micStream&&this._micStream.getTracks().forEach(A=>C.add(A));try{const A=MD?.getVBStream?.()||MD?._localVBStream;A&&"function"==typeof A.getTracks&&A.getTracks().forEach(A=>C.add(A))}catch(A){}const Q=[];document.querySelectorAll("video, audio").forEach(A=>{if(A.srcObject&&"function"==typeof A.srcObject.getTracks){A.srcObject.getTracks().forEach(A=>C.add(A)),Q.push({element:A,stream:A.srcObject})}}),SD.debug(`Found ${C.size} total tracks to stop`);let B=0;for(const A of C)try{A&&"live"===A.readyState&&"function"==typeof A.stop&&(A.stop(),B++,SD.debug(`Stopped ${A.kind} track: ${A.label||A.id}`))}catch(I){SD.warn("Error stopping track:",I)}if(SD.debug(`Stopped ${B} tracks`),this._sendTransport){try{this._sendTransport.close()}catch(A){}this._sendTransport=null}if(this._recvTransport){try{this._recvTransport.close()}catch(A){}this._recvTransport=null}this._webcamProducer=null,this._micProducer=null,this._shareProducer=null,this._shareAudioProducer=null,this._webCamStream=null,this._micStream=null,this._producers&&this._producers.clear(),this._consumers&&this._consumers.clear(),this._roomStatus="closed",this._running=!1,this._routerRtpCapabilities=null,await new Promise(A=>setTimeout(A,100));let E=0;document.querySelectorAll("video, audio").forEach(A=>{try{A.srcObject&&(A.srcObject=null,"function"==typeof A.pause&&A.pause(),"function"==typeof A.load&&A.load(),E++,SD.debug(`Force cleared ${A.nodeName} element`))}catch(I){SD.warn("Error clearing element:",I)}}),SD.debug(`Cleared ${E} DOM elements`);try{C.forEach(A=>{A&&"function"==typeof A.removeEventListener&&(A.removeEventListener("ended",()=>{}),A.removeEventListener("mute",()=>{}),A.removeEventListener("unmute",()=>{}))})}catch(A){}if(window.gc&&"function"==typeof window.gc)try{window.gc()}catch(A){}await new Promise(A=>setTimeout(A,200));try{const A=await this.reportActiveMediaUse();SD.debug("Final media usage report:",A);const I=[],g=A.dom.mediaElements.filter(A=>A.hasSrcObject&&A.tracks.length>0);g.forEach(A=>{A.tracks.forEach(g=>{"live"===g.readyState&&I.push({kind:g.kind,label:g.label,id:g.id,element:A.nodeName})})}),(I.length>0||g.length>0)&&(SD.warn("WARNING: Media elements or live tracks still detected after cleanup:",{liveTracks:I,elementsWithTracks:g.length}),await this.emergencyTrackCleanup())}catch(g){SD.error("Failed to generate final media usage report:",g)}}catch(I){SD.error("Error during room leave cleanup:",I),await this.emergencyTrackCleanup()}};emergencyTrackCleanup=async()=>{SD.debug("Performing emergency track cleanup...");try{const A=[];document.querySelectorAll("video, audio").forEach(I=>{if(I.srcObject&&"function"==typeof I.srcObject.getTracks){A.push(...I.srcObject.getTracks()),I.srcObject=null,"function"==typeof I.pause&&I.pause(),"function"==typeof I.load&&I.load();try{I.src=""}catch(g){}}}),A.forEach(A=>{try{"live"===A.readyState&&(A.stop(),SD.debug(`Emergency stopped ${A.kind}: ${A.label||A.id}`))}catch(I){}}),SD.debug(`Emergency cleanup completed - stopped ${A.length} tracks`),await new Promise(A=>setTimeout(A,300))}catch(A){SD.error("Emergency cleanup failed:",A)}};reportActiveMediaUse=async(A=!1)=>{const I={sdk:{micStreamTracks:[],camStreamTracks:[],vbStreamTracks:[],shareTracks:[],producers:[],consumers:[]},dom:{mediaElements:[]},timestamp:Date.now()},g=A=>{try{return{kind:A?.kind,enabled:A?.enabled,readyState:A?.readyState,label:A?.label,id:A?.id,muted:A?.muted}}catch(I){return{error:!0}}};try{this._micStream&&"function"==typeof this._micStream.getTracks&&(I.sdk.micStreamTracks=this._micStream.getTracks().map(g))}catch(Q){}try{this._webCamStream&&"function"==typeof this._webCamStream.getTracks&&(I.sdk.camStreamTracks=this._webCamStream.getTracks().map(g))}catch(Q){}try{const A=MD?.getVBStream?.()||MD?._localVBStream;A&&"function"==typeof A.getTracks&&(I.sdk.vbStreamTracks=A.getTracks().map(g))}catch(Q){}try{this._shareProducer?.track&&I.sdk.shareTracks.push(g(this._shareProducer.track)),this._shareAudioProducer?.track&&I.sdk.shareTracks.push(g(this._shareAudioProducer.track))}catch(Q){}try{this._producers&&this._producers.size>0&&this._producers.forEach((A,C)=>{I.sdk.producers.push({key:C,track:A?.track?g(A.track):null,id:A?.id,paused:A?.paused})})}catch(Q){}try{this._consumers&&this._consumers.size>0&&this._consumers.forEach((A,C)=>{I.sdk.consumers.push({key:C,track:A?.track?g(A.track):null,id:A?.id,paused:A?.paused})})}catch(Q){}try{const A=Array.from(document.querySelectorAll("video, audio"));I.dom.mediaElements=A.map(A=>{let I=[],C=null;try{const Q=A.srcObject;Q&&"function"==typeof Q.getTracks&&(I=Q.getTracks().map(g),C=Q.id)}catch(Q){}return{nodeName:A.nodeName,muted:!!A.muted,paused:!!A.paused,hasSrcObject:!!A.srcObject,streamId:C,tracks:I,src:A.src||null,currentSrc:A.currentSrc||null}})}catch(Q){}const C=[...I.sdk.micStreamTracks,...I.sdk.camStreamTracks,...I.sdk.vbStreamTracks,...I.sdk.shareTracks,...I.sdk.producers.map(A=>A.track).filter(Boolean),...I.sdk.consumers.map(A=>A.track).filter(Boolean),...I.dom.mediaElements.flatMap(A=>A.tracks)].filter(A=>A&&"live"===A.readyState);return I.summary={totalLiveTracks:C.length,elementsWithSrcObject:I.dom.mediaElements.filter(A=>A.hasSrcObject).length,elementsWithTracks:I.dom.mediaElements.filter(A=>A.tracks.length>0).length},I};async listDevicesInternal(){if(navigator.mediaDevices.ondevicechange=async A=>{let I=await XE();SD.info("Media devices changed!:%O",I),I.audioDevices&&I.audioDevices.length>0&&(this._deviceList.audioDevices=I.audioDevices),I.videoDevices&&I.videoDevices.length>0&&(this._deviceList.videoDevices=I.videoDevices),I.audioDevices&&I.audioDevices.length>0&&(this._deviceList.audioOutputDevices=I.audioDevicesOutput),ND=this._deviceList,this.emit("deviceListUpdated")},!this._deviceList){const A=await _E();if(A.success)return this._deviceList=A.deviceList,void(ND=this._deviceList)}}restartIce=async(A,I)=>{if("send"===I&&"connected"===this._sendTransport.connectionState||"recv"===I&&"connected"===this._recvTransport.connectionState)return void SD.debug("no need to restart ICE as transport now connected");SD.debug("websocket is ready and connectionstate is still disconnected, therefore going to restart ICE");let g={id:"restartIce",transportId:A,roomName:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId};this._sendMessage(g)};restartIceResponse=A=>{SD.debug("restart ICE response:%o",A);let{transportId:I,iceParameters:g}=A;this._sendTransport&&this._sendTransport.id===I?this._sendTransport.restartIce({iceParameters:g}):this._recvTransport&&this._recvTransport.id===I&&this._recvTransport.restartIce({iceParameters:g})};startRecording=({recordingType:A=null,outputType:I=null,outputQualities:g=null}={})=>{SD.debug("recording type requested is:%s,outputType:%s, outputQualties:%o",A,I,g);const C=!A||"av"!==A?.toLowerCase()&&"audiovideo"!==A?.toLowerCase()?"mergedA":"mergedAV";if((!I||"hls"!==I.toLowerCase()&&"mp4"!==I.toLowerCase())&&I)return SD.error("Invalid outut type"),{success:!1,reason:`Invalid outputType: ${I}. `};if(I&&"hls"===I.toLowerCase()&&g&&!ri(g))return SD.error("Invalid outut qualities"),{success:!1,reason:`Invalid outputQualities: ${JSON.stringify(g)}. Allowed values are ${Array.from(ti).join(", ")}.`};let Q={id:"startRecording",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,url:window.location.hostname,type:uE,recordingStrategy:C,outputQualities:g,outputType:I?.toLowerCase()};this._sendMessage(Q),this._recordingStartedByMe={...this._recordingStartedByMe,"main-room":{recordingNo:null}}};stopRecording=()=>{SD.debug("going to stop recording for recordingStartedByMe:%o",this._recordingStartedByMe);let A="main-room";if(!this._recordingStartedByMe[A])return{success:!1,error:!0,code:"RRID001",text:"Error while trying to stop recording. Either the recording has not been started yet Or The same user need to stop recording who started it."};{let I={id:"stopRecording",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,recordingNo:this._recordingStartedByMe[A].recordingNo,type:uE};this._sendMessage(I),delete this._recordingStartedByMe[A],this.emit("recordingEnded",{peerId:this.data.inputParams.peerId})}};setRecordingStatusStarted=A=>{SD.debug("Recording/Streaming started by moderator!!:%O",A);let{breakOutRoom:I,recordingStartTime:g,recordingNo:C,type:Q}=A;[uE,pE].includes(Q)&&(this._recordingStartedByMe["main-room"]?(SD.debug("This recording has been started by me."),this._recordingStartedByMe["main-room"].recordingNo=C,this.emit("recordingStarted",{peerId:this.data.inputParams.peerId,startTime:g})):this.emit("recordingStarted",{startTime:g}))};setRecordingStatusEnded=A=>{SD.debug("Recording ended by moderator!!, data:%O",A);let{breakOutRoom:I,type:g}=A;"rtmpStream"===g||this.emit("recordingEnded",{})};startProcessing=async({inputFiles:A=[],outputQualities:I=null,bucket:g=null,cloud:C=null,region:Q=null}={})=>{SD.debug("Processing of Files requested for:%o",A);const B=Math.round(1e7*Math.random()),E=await async function(A){if(ci.info("The input files are:%o, length:%s",A,A.length),A.length>0){ci.info("Files array length is:%s",A.length);for(const{type:I,url:g}of A){if(ci.info("The file detais are type:%s, url:%s",I,g),!Hi.includes(I))return{success:!1,reason:`Type "${I}" is not allowed.`};if(!Yi(g,I))return{success:!1,reason:`Extension mismatch for ${g}; expected .${I}`}}return{success:!0}}return{success:!1,reason:"There are no files for processing!"}}(A);if(E.success){if(I&&!ri(I))return SD.error("Invalid outut qualities"),{success:!1,reason:`Invalid outputQualities: ${JSON.stringify(I)}. Allowed values are ${Array.from(ti).join(", ")}.`};this._processingStartedByMe={...this._processingStartedByMe,[B]:{}};for(const{type:I,url:g}of A)this._processingStartedByMe={...this._processingStartedByMe,[B]:{...this._processingStartedByMe[B],[g]:{type:I,url:g,status:"pending"}}};let E={id:"processVideos",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,inputFiles:A,outputQualities:I,bucket:g,cloud:C,region:Q,requestId:B,type:"process"};return this._sendMessage(E),{success:!0}}return E};checkProcessingStatus=({requestId:A})=>(SD.debug("Going to check processing status for request Id:%s",A),this._processingStartedByMe[A]?{success:!0,details:this._processingStartedByMe[A]}:{success:!0,details:this._processingStartedByMe});handleProcessingStart=A=>{const{processingStartTime:I,processingNo:g,requestId:C}=A;SD.debug("handleProcessingStart()| received message is:%o",A),this.emit("processingStarted",{processingStartTime:I,requestId:C})};handleProcessingCompletion=A=>{const{totalProcessingTime:I,hlsfileKey:g,size:C,originalFile:Q,lastFile:B,requestId:E}=A;if(SD.debug("handleProcessingCompletion()| received message is:%o",A),SD.debug("Before update, Total files to be processed are:%o",this._processingStartedByMe),this._processingStartedByMe[Q]&&(this._processingStartedByMe={...this._processingStartedByMe,[E]:{...this._processingStartedByMe[E],[Q]:{...this._processingStartedByMe[Q],status:"completed",hlsfileKey:g,size:C,totalProcessingTime:I}}}),SD.debug("After update, Total files to be processed are:%o",this._processingStartedByMe),this.emit("processingCompleted",A),B){SD.debug("The last file processing has been completed! Remove all the files that has been completed with the same requesterId");let A={...this._processingStartedByMe};delete A[E],SD.debug("After deleting the current requestId:%o",A),this._processingStartedByMe=A}};handleProcessingError=A=>{const{totalProcessingTime:I,hlsfileKey:g,size:C,originalFile:Q,lastFile:B,requestId:E,error:i}=A;SD.debug("handleProcessingCompletion()| received message is:%o",A),SD.debug("Before update, Total files to be processed are:%o",this._processingStartedByMe),this._processingStartedByMe[Q]&&(this._processingStartedByMe={...this._processingStartedByMe,[E]:{...this._processingStartedByMe[E],[Q]:{...this._processingStartedByMe[Q],status:"error",hlsfileKey:g,size:C,totalProcessingTime:I,error:i}}}),SD.debug("After update, Total files to be processed are:%o",this._processingStartedByMe),this.emit("processingError",A)};async enableMic({deviceId:A=null,autoGainControl:I,noiseSuppression:g,echoCancellation:C,channelCount:Q,sampleRate:B,forcePCMU:E,forcePCMA:i}={}){if(SD.debug("enableMic()"),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID007",text:"Error while trying to start Mic/Audio. Produce flag need to set to true while joining room in order to enable Mic/Audio."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID008",text:`Error while trying to start Mic/Audio as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling Mic? OR if you have already initiated the joinRoom process, then Mic will be enabled automatically once room join process completes."};if(this._micProducer)return SD.debug("Mic is already active!"),{success:!1,warning:!0,code:"RWID002",text:"Error while trying to start Mic/Audio. Mic/Audio is already active!"};if(!this._device.canProduce("audio"))return SD.error("enableMic() | cannot produce audio"),{success:!1,error:!0,code:"REID009",text:"Error while trying to start Mic/Audio. Mic/Audio couldnot be activated due to limitations on this device. If you think this device has a functional Mic and the problem persists even after multiple retries, please contact technical support with the error code."};let D,n;E&&"boolean"==typeof E&&(this.data.inputParams.forcePCMU=E),i&&"boolean"==typeof i&&(this.data.inputParams.forcePCMA=i),I&&"boolean"==typeof I&&(this.data.inputParams.autoGainControl=I),C&&"boolean"==typeof C&&(this.data.inputParams.echoCancellation=C),g&&"boolean"==typeof g&&(this.data.inputParams.noiseSuppression=g),B&&Number.isInteger(B)&&B<64e3&&B>8e3&&(this.data.inputParams.sampleRate=B),Q&&Number.isInteger(Q)&&Q>0&&Q<3&&(this.data.inputParams.channelCount=Q);try{if(this._externalVideo)this._micStream=await this._getExternalVideoStream(),D=this._micStream.getAudioTracks()[0].clone();else{if(A?(n=this._deviceList.audioDevices.find(I=>I.deviceId===A),n||(SD.warn("Selected audio input deviceId:%s not found",A),n=this._deviceList.audioDevices[0])):n=this._deviceList.audioDevices[0],this._mic.device=n,!n)return SD.error("No mic device found! Can't start audio!"),{success:!1,reason:"No mic available for starting audio!"};A&&this.data.inputParams.audioDeviceId!==A&&(this.data.inputParams.audioDeviceId=A),SD.debug("enableMic() | calling getUserMedia()");try{this._micStream=await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:n.deviceId},echoCancellation:this.data.inputParams.echoCancellation,noiseSuppression:this.data.inputParams.noiseSuppression,autoGainControl:this.data.inputParams.autoGainControl,sampleRate:this.data.inputParams.sampleRate,channelCount:this.data.inputParams.channelCount}}),D=this._micStream.getAudioTracks()[0]}catch(eD){throw new Error("Error while acquiring mic. Possible issue with audio constraint values",eD)}}this._micProducer=await this._sendTransport.produce({track:D,codecOptions:this.data.inputParams.forcePCMU||this.data.inputParams.forcePCMA?void 0:{opusStereo:!1,opusDtx:!0,opusFec:!0,opusNack:!0},codec:this.data.inputParams.forcePCMU?this._device.rtpCapabilities.codecs.find(A=>"audio/pcmu"===A.mimeType.toLowerCase()):this.data.inputParams.forcePCMA?this._device.rtpCapabilities.codecs.find(A=>"audio/pcma"===A.mimeType.toLowerCase()):void 0,appData:{mediaTag:"cam-audio"}}),this._producers.set("audio",{id:this._micProducer.id,paused:this._micProducer.paused,track:this._micProducer.track,rtpParameters:this._micProducer.rtpParameters,codec:this._micProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("micStart",{peerId:this.data.inputParams.peerId,audioTrack:this._micProducer.track,type:"local"}),this._micProducer.on("transportclose",()=>{this._micProducer=null}),this._micProducer.on("trackended",()=>{this.disableMic().catch(()=>{})}),await this._initializeAudioMonitoring(),this._startSpeakingWhileMutedDetection()}catch(o){SD.error("enableMic() | failed:%o",o),this.emit("error",{code:"EID002",text:"Error enabling microphone!"}),D&&D.stop()}}async disableMic(){if(SD.debug("disableMic()"),this._cleanupAudioMonitoring(),this._micStream&&this._micStream.getAudioTracks().forEach(A=>A.stop()),this._micProducer){this._micProducer.close(),this._producers.delete("audio");try{let A={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",producerId:this._micProducer.id};this._sendMessage(A),this.emit("micEnd",{peerId:this.data.inputParams.peerId,audioTrack:null,type:"local"})}catch(A){this.emit("error",{code:"EID003",text:"Error disabling microphone!"})}this._micProducer=null}}async muteMic(){SD.debug("muteMic()"),this._micProducer.pause();try{let A={id:"toggleMedia",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",audioStatus:!1,producerId:this._micProducer.id};this._sendMessage(A),this.emit("peerMuted",{peerId:this.data.inputParams.peerId,type:"local"})}catch(A){SD.error("muteMic() | failed: %o",A),this.emit("error",{code:"EID004",text:"Error muting local microphone!"})}}async unmuteMic(){SD.debug("unmuteMic()"),this._micProducer||(SD.debug("Mic is not active!"),await this.enableMic()),this._micProducer.resume();try{let A={id:"toggleMedia",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",audioStatus:!0,producerId:this._micProducer.id};this._sendMessage(A),this.emit("peerUnMuted",{peerId:this.data.inputParams.peerId,type:"local"})}catch(A){SD.error("unmuteMic() | failed: %o",A),this.emit("error",{code:"EID005",text:"Error unmuting local microphone!"})}}handleRoomSettingsGeneral=async({allowScreenShare:A,noOfScreenShare:I,noOfUpgradeRequests:g})=>{const C={type:"roomSetting:generalSettings",allowScreenShare:A,noOfScreenShare:I,noOfUpgradeRequests:g};return SD.debug("Room settings - General: %O",C),this.sendCustomMessage(JSON.stringify(C),"custom",null,"moderator","roomSetting:generalSettings",{}),{success:!0}};handleAuthSettings=async({moderatorApproval:A,passwordRequired:I})=>{const g={type:"roomSetting:authSettings",moderatorApproval:A,passwordRequired:I};return SD.debug("Room settings - Auth: %O",g),this.sendCustomMessage(JSON.stringify(g),"custom",null,"moderator","roomSetting:authSettings",{}),{success:!0}};handleRoomSettingsStage=A=>{if(A.stageStatus&&store.getState().conf.breakOutRoomsActive)return this.showNotification("danger","Not Available!","Stage mode is not available when breakout rooms are active"),{success:!1};const I={type:"roomSetting:stageSettings",stageStatus:!!A.stageStatus};return this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:stageSettings",{}),{success:!0}};handlePresenterSettings=async A=>{const I={type:"roomSetting:presenterSettings",presenterSettings:A};return SD.debug("presenter settings: %O",I),this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:presenterSettings",{}),{success:!0}};handleParticipantSettings=async A=>{SD.debug("Going to update participant settings with values:%s",A);const I={type:"roomSetting:participantSettings",participantSettings:A};return this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:participantSettings",{}),{success:!0}};startSpeechRecognition(A={}){const I={lang:"es-ES",continuous:!0,interimResults:!0,maxAlternatives:3,autoRestart:!0,restartDelayMs:250,...A},g=window.SpeechRecognition||window.webkitSpeechRecognition,C=window.SpeechGrammarList||window.webkitSpeechGrammarList;if(!g)return this.emit("sttError",{code:"UNSUPPORTED",message:"Web Speech API not supported"}),{success:!1,reason:"unsupported"};try{if(this._speechRecognition){try{this._speechRecognition.onend=null,this._speechRecognition.onresult=null,this._speechRecognition.onerror=null}catch{}try{this._speechRecognition.stop()}catch{}this._speechRecognition=null}const A=new g;if(A.lang=I.lang,A.continuous=!!I.continuous,A.interimResults=!!I.interimResults,A.maxAlternatives=I.maxAlternatives,I.grammars&&Array.isArray(I.grammars)&&C){const g=new C,Q=`#JSGF V1.0; grammar terms; public <term> = ${I.grammars.join(" | ")};`;g.addFromString&&g.addFromString(Q,1),A.grammars&&(A.grammars=g)}return this._sttShouldRun=!0,this._sttAutoRestart=!!I.autoRestart,this._sttRestartDelayMs=Number(I.restartDelayMs)||250,A.onstart=()=>this.emit("sttStart",{timestamp:Date.now(),lang:A.lang}),A.onresult=I=>{const g=I.results[I.results.length-1],C=g&&g[0]?g[0]:null,Q={transcript:C?C.transcript:"",confidence:C?C.confidence:0,isFinal:!!g&&g.isFinal,timestamp:Date.now(),lang:A.lang},B=Q.timestamp,E=this.data.inputParams.peerId||"local";this._transcriptStorage.has(B)||this._transcriptStorage.set(B,new Map);this._transcriptStorage.get(B).set(E,{transcript:Q.transcript,isFinal:Q.isFinal}),this.emit("sttResult",Q)},A.onerror=A=>{this.emit("sttError",{code:A.error||"UNKNOWN",message:A.message||"Speech recognition error"})},A.onend=()=>{if(this.emit("sttEnd",{timestamp:Date.now()}),this._sttShouldRun&&this._sttAutoRestart){const g=this._sttRestartDelayMs;try{setTimeout(()=>{if(this._sttShouldRun&&this._sttAutoRestart)try{A.start()}catch(I){}},g)}catch(I){}}},A.start(),this._speechRecognition=A,{success:!0}}catch(eD){return this.emit("sttError",{code:"INIT_FAILED",message:eD.message}),{success:!1,reason:eD.message}}}stopSpeechRecognition(){try{if(this._sttShouldRun=!1,this._sttAutoRestart=!1,this._speechRecognition){try{this._speechRecognition.onend=null,this._speechRecognition.onresult=null,this._speechRecognition.onerror=null}catch{}this._speechRecognition.stop(),this._speechRecognition=null}return{success:!0}}catch(eD){return this.emit("sttError",{code:"STOP_FAILED",message:eD.message}),{success:!1,reason:eD.message}}}startTranscription(){try{return this._transcriptionActive?(SD.debug("Transcription already active"),{success:!1,reason:"already_active"}):(this._transcriptionActive=!0,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,SD.debug("Transcription started - waiting for audio buffer from client"),this.emit("transcriptionStarted"),{success:!0})}catch(A){return SD.error("Failed to start transcription:",A),this.emit("transcriptionError",{error:A.message}),{success:!1,reason:A.message}}}stopTranscription(){try{return this._transcriptionActive?(this._transcriptionRecorder&&"inactive"!==this._transcriptionRecorder.state&&this._transcriptionRecorder.stop(),this._transcriptionRecorder=null,this._transcriptionActive=!1,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,SD.debug("Transcription stopped completely"),this.emit("transcriptionStopped"),{success:!0}):(SD.debug("Transcription not active"),{success:!1,reason:"not_active"})}catch(A){return SD.error("Failed to stop transcription:",A),this.emit("transcriptionError",{error:A.message}),{success:!1,reason:A.message}}}sendAudioForTranscription(A,I){try{return A?(this.sendCustomMessage({audioBuffer:A,timestamp:Date.now(),activeSpeakerPeerId:I},"general",null,"participant","deepgram:audio"),SD.debug(`Audio buffer sent for transcription from peer: ${I}`),{success:!0}):(SD.debug("No audio buffer provided"),{success:!1,reason:"no_audio_buffer"})}catch(g){return SD.error("Failed to send audio for transcription:",g),{success:!1,reason:g.message}}}isTranscriptionActive(){return this._transcriptionActive||!1}_processTranscriptionMessage=A=>{try{if("transcription"===A.type&&A.data){const I=A.data;this.emit("transcription",{transcript:I.transcript,confidence:I.confidence,isFinal:I.isFinal,timestamp:I.timestamp,speaker:I.speaker}),SD.debug("Transcription received:",I.transcript)}}catch(I){SD.error("Failed to process transcription message:",I)}};async enableCam({deviceId:A=null,videoResolution:I,forceVp8:g,forceVp9:C,forceH264:Q,h264Profile:B,forceFPS:E,enableWebcamLayers:i,numSimulcastStreams:D,videoBitRates:n,vbdetails:o}={}){if(SD.debug("enableWebcam()"),SD.debug("first vbdetails in enablecam",o),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID004",text:"Error while trying to start Camera. Produce flag need to set to true while joining room in order to enable Camera."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID005",text:`Error while trying to start Camera as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling Camera? OR if you have already initiated the joinRoom process, then Camera will be enabled automatically once room join process completes."};if(this._webcamProducer)return SD.debug("Camera is already active!"),{success:!1,warning:!0,code:"RWID003",text:"Error while trying to start Camera. Camera is already active!"};if(!this._device.canProduce("video"))return SD.error("enableWebcam() | cannot produce video"),{success:!1,error:!0,code:"REID006",text:"Error while trying to start Camera. Camera couldnot be activated due to limitations on this device. If you think this device has a functional camera and the problem persists even after multiple retries, please contact technical support with the error code."};let s,w;["hd","vga","qvga"].includes(I)&&(this.data.inputParams.videoResolution=I,this._webcam.resolution=I),g&&"boolean"==typeof g&&(this.data.inputParams.forceVp8=g),C&&"boolean"==typeof C&&(this.data.inputParams.forceVp9=C),Q&&"boolean"==typeof Q&&(this.data.inputParams.forceH264=Q),B&&["high","low"].includes(B.toLowerCase())&&(this.data.inputParams.h264Profile=B),E&&Number.isInteger(E)&&E<65&&E>5&&(this.data.inputParams.forceFPS=25),i&&"boolean"==typeof i&&(this.data.inputParams.enableWebcamLayers=i,this._enableWebcamLayers=i),D&&Number.isInteger(D)&&D<4&&D>0&&(this.data.inputParams.numSimulcastStreams=D,this._numSimulcastStreams=D),Array.isArray(n)&&n.length>=1&&n.length<=3&&n.every(A=>Number.isInteger(A)&&A>=75&&A<=800)?(SD.debug("videoBitRates values are correct"),this.data.inputParams.videoBitRates=n):SD.warn("videobitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[700,250,75]'");try{if(this._externalVideo)w={label:"external video"},this._webCamStream=await this._getExternalVideoStream(),s=this._webCamStream.getVideoTracks()[0].clone();else{A?(w=this._deviceList.videoDevices.find(I=>I.deviceId===A),w||(SD.warn("Selected deviceId:%s not found",A),w=this._deviceList.videoDevices[0])):w=this._deviceList.videoDevices[0],this._webcam.device=w;const{resolution:I}=this._webcam;if(!w)return SD.error("No wencam device found! Can't start video!"),{success:!1,reason:"No Webcam available for starting video!"};A&&this.data.inputParams.videoDeviceId!==A&&(this.data.inputParams.videoDeviceId=A),SD.debug("enableWebcam() | calling getUserMedia()"),this._webCamStream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:w.deviceId},...hD[I],frameRate:{ideal:this.data.inputParams.forceFPS}}}),s=this._webCamStream.getVideoTracks()[0]}let I,g;const C={videoGoogleStartBitrate:1e3};if(SD.debug("Current device codec options are:%O",this._device.rtpCapabilities.codecs),this._forceVP8){if(g=this._device.rtpCapabilities.codecs.find(A=>"video/vp8"===A.mimeType.toLowerCase()),!g)throw new Error("desired VP8 codec+configuration is not supported")}else if(this._forceH264){if("high"===this.data.inputParams.h264Profile?g=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"4d001f"===A.parameters["profile-level-id"]):"low"===this.data.inputParams.h264Profile&&(g=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"42e01f"===A.parameters["profile-level-id"])),!g)throw new Error("desired H264 codec+configuration is not supported");SD.debug("Selected h264 codec is:%O",g)}else if(this._forceVP9&&(g=this._device.rtpCapabilities.codecs.find(A=>"video/vp9"===A.mimeType.toLowerCase()),!g))throw new Error("desired VP9 codec+configuration is not supported");if(this._enableWebcamLayers){const A=this._device.rtpCapabilities.codecs.find(A=>"video"===A.kind);this._forceVP9&&g||"video/vp9"===A.mimeType.toLowerCase()?I=[{maxBitrate:5e6,scalabilityMode:this._webcamScalabilityMode||"L3T3_KEY"}]:(I=[{scaleResolutionDownBy:1,maxBitrate:1e3*this.data.inputParams.videoBitRates[0],scalabilityMode:this._webcamScalabilityMode||"L1T3"}],this._numSimulcastStreams>1&&I.unshift({scaleResolutionDownBy:2,maxBitrate:1e3*this.data.inputParams.videoBitRates[1],scalabilityMode:this._webcamScalabilityMode||"L1T3"}),this._numSimulcastStreams>2&&I.unshift({scaleResolutionDownBy:4,maxBitrate:1e3*this.data.inputParams.videoBitRates[2],scalabilityMode:this._webcamScalabilityMode||"L1T3"}))}if(o)try{const A=MD&&MD._localVBStream;let I=null;if(A&&"function"==typeof A.getVideoTracks&&A.getVideoTracks().length>0&&"live"===A.getVideoTracks()[0].readyState)I=A.getVideoTracks()[0],SD.debug("Using existing Virtual Background track");else{const A=await MD.initializePipeline(s,o);A&&A.vbStream&&"function"==typeof A.vbStream.getVideoTracks&&A.vbStream.getVideoTracks().length>0&&(I=A.vbStream.getVideoTracks()[0],SD.debug("Initialized new Virtual Background pipeline"))}I&&(s=I)}catch(a){SD.debug("VB init failed or skipped in enableCam")}this._webcamProducer=await this._sendTransport.produce({track:s,encodings:I,codecOptions:C,codec:g,appData:{mediaTag:"cam-video"}}),this._producers.set("video",{id:this._webcamProducer.id,deviceLabel:w.label,type:this._getWebcamType(w),paused:this._webcamProducer.paused,track:this._webcamProducer.track,rtpParameters:this._webcamProducer.rtpParameters,codec:this._webcamProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("videoStart",{peerId:this.data.inputParams.peerId,videoTrack:this._webcamProducer.track,type:"local"}),this._webcamProducer.on("transportclose",()=>{this._webcamProducer=null}),this._webcamProducer.on("trackended",()=>{this.disableCam().catch(()=>{})})}catch(y){SD.error("enableWebcam() | failed:%o",y),this.emit("error",{code:"EID011",text:"Enable Webcam failed!"}),s&&s.stop()}}async disableCam(){if(SD.debug("disableWebcam()"),this._webcamProducer){this._webcamProducer.close(),this._producers.delete("video");try{let A={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"video",producerId:this._webcamProducer.id};this._sendMessage(A),this.emit("videoEnd",{peerId:this.data.inputParams.peerId,videoTrack:null})}catch(A){this.emit("error",{code:"EID012",text:"Error while closing server side producer!"})}try{this._webCamStream&&"function"==typeof this._webCamStream.getTracks&&this._webCamStream.getTracks().forEach(A=>{try{A.stop()}catch(I){}})}catch(I){}this._webCamStream=null,this._webcamProducer=null}}async _updateWebcams(){SD.debug("_updateWebcams()"),this._webcams=new Map,SD.debug("_updateWebcams() | calling enumerateDevices()");const A=await navigator.mediaDevices.enumerateDevices();for(const Q of A)"videoinput"===Q.kind&&this._webcams.set(Q.deviceId,Q);const I=Array.from(this._webcams.values()),g=I.length,C=this._webcam.device?this._webcam.device.deviceId:void 0;SD.debug("_updateWebcams() [webcams:%o]",I),0===g?this._webcam.device=null:this._webcams.has(C)||(this._webcam.device=I[0])}async _getExternalVideoStream(){if(this._externalVideoStream)return this._externalVideoStream;if(this._externalVideo.readyState<3&&await new Promise(A=>this._externalVideo.addEventListener("canplay",A)),this._externalVideo.captureStream)this._externalVideoStream=this._externalVideo.captureStream();else{if(!this._externalVideo.mozCaptureStream)throw new Error("video.captureStream() not supported");this._externalVideoStream=this._externalVideo.mozCaptureStream()}return this._externalVideoStream}_getWebcamType(A){return/(back|rear)/i.test(A.label)?(SD.debug("_getWebcamType() | it seems to be a back camera"),"back"):(SD.debug("_getWebcamType() | it seems to be a front camera"),"front")}async changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C}){if(this._webcamProducer){return await this._changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C})}return SD.error("No webcam producer available!"),{success:!1,reason:"You are not sharing your camera yet. Camera Input can be changed to a new camera only when you are sharing an existing camera. "}}async _changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C}){SD.info("_changeVideoInput() | Inside"),A&&["hd","vga","qvga"].includes(A)?this._webcam.resolution=A:SD.warn("Invalid video resolution value "),g&&Number.isInteger(g)&&g<65&&g>5?this.data.inputParams.forceFPS=g:SD.warn("forceFPS should be a number between 5 to 65, default value is 25 fps.");let Q=this._deviceList.videoDevices.find(A=>I&&A.deviceId===I);if(!Q)return SD.error("The selected deviceId not found!"),{success:!1,reason:"Invalid deviceId!"};this._webcam.device=Q;try{this._webCamStream.getVideoTracks().forEach(A=>A.stop()),this._webCamStream=null,SD.debug("changeVideoInput() | calling getUserMedia()"),this._webCamStream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:Q.deviceId},...hD[this._webcam.resolution],frameRate:{ideal:this.data.inputParams.forceFPS}}});let A=this._webCamStream.getVideoTracks()[0];if(SD.debug("The new video track is:%O",A),C)try{const I=await MD.initializePipeline(A,C);I&&I.vbStream&&"function"==typeof I.vbStream.getVideoTracks&&I.vbStream.getVideoTracks()[0]&&(A=I.vbStream.getVideoTracks()[0],SD.debug("Reinitialized VB pipeline for changed camera"))}catch(B){SD.debug("VB init skipped/failed on changeVideoInput")}await this._webcamProducer.replaceTrack({track:A});let I=this._producers.get("video");return I.deviceLabel=Q.label,I.type=this._getWebcamType(Q),I.track=this._webcamProducer.track,SD.debug("Updated producer values are:%O",I),this._producers.set("video",I),this.emit("videoStart",{peerId:this.data.inputParams.peerId,videoTrack:A,type:"local"}),{success:!0}}catch(E){return SD.error("Error while changing input:%O",E),{success:!1,reason:"Couldn't change video input",error:E}}}async changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B}){if(this._micProducer){return await this._changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B})}return{success:!1,reason:"You are not sharing your mic yet. Mic Input can be changed to a new mic only when you are sharing an existing mic. "}}async _changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B}){A&&"boolean"==typeof A&&(this.data.inputParams.autoGainControl=A),I&&"boolean"==typeof I&&(this.data.inputParams.echoCancellation=Boolean(I)),g&&"boolean"==typeof g&&(this.data.inputParams.noiseSuppression=Boolean(g)),C&&Number.isInteger(C)&&C<64e3&&C>8e3&&(this.data.inputParams.sampleRate=C),Q&&Number.isInteger(Q)&&Q>0&&Q<3&&(this.data.inputParams.channelCount=Q);let E=this._deviceList.audioDevices.find(A=>B&&A.deviceId===B);if(!E)return{success:!1,reason:"Invalid deviceId!"};this._mic.device=E,this._micStream&&this._micStream.getAudioTracks().forEach(A=>A.stop()),this._micStream=null;try{this._micStream=await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:E.deviceId},echoCancellation:this.data.inputParams.echoCancellation,noiseSuppression:this.data.inputParams.noiseSuppression,autoGainControl:this.data.inputParams.autoGainControl,sampleRate:this.data.inputParams.sampleRate,channelCount:this.data.inputParams.channelCount}});const A=this._micStream.getAudioTracks()[0];this._micProducer.replaceTrack({track:A});let I=this._producers.get("audio");return I.deviceLabel=E.label,I.track=this._micProducer.track,SD.debug("Updated producer values are:%O",I),this._producers.set("audio",I),this.emit("micStart",{peerId:this.data.inputParams.peerId,audioTrack:this._micProducer.track,type:"local"}),{success:!0}}catch(eD){return SD.error("Error while changing input:%O",eD),{success:!1,reason:"Couldn't change audio input",err:eD}}}toggleVB=async A=>{if(A&&this._localCamVideo.getVideoTracks()[0]){const A=await this.initializePipeline(this._localCamVideo.getVideoTracks()[0],{type:"blur"});if(SD.debug("response is :%o, localVBTrack is:%O",A,this._localVBStream.getVideoTracks()[0]),A.success&&this._localVBStream.getVideoTracks()[0]){if(this._roomType===bE||this._roomType===xE)if(this._camVideoProducer&&store.getState().conf.joined){await this._camVideoProducer.replaceTrack({track:this._localVBStream.getVideoTracks()[0].clone()});let A={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localVBStream.getVideoTracks()[0]}};this._participants=A,store.dispatch(confActions.addParticipant(A))}else SD.debug("Camvideoproducer not available! virtual background changes in the landing page! ");else if(this._roomType===dE&&this._peerConnection){const A=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});if(SD.debug("found sender:%o",A),A&&this._localVBStream.getVideoTracks()[0]){A.replaceTrack(this._localVBStream.getVideoTracks()[0]);let I={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localVBStream.getVideoTracks()[0]}};this._participants=I,store.dispatch(confActions.addParticipant(I))}else this.showNotification("danger","Error!","Unable to switch off virtual background! Try again OR contact support with code:CM-FE-RC-VB-E04")}}else SD.error("Virtual background procesing can't be enabled")}else if(this._localVBStream?.getVideoTracks()[0].stop(),this._localVBStream=null,this._pipelineManager.stop(),this._vbDetailsNew.sourcePlayback&&(this._vbDetailsNew.sourcePlayback.htmlElement.srcObject=null),this._vbDetailsNew.sourcePlayback?.htmlElement.remove(),this._vbDetailsNew?.hiddenCanvas.remove(),this._vbDetailsNew?.hiddenImage?.remove(),this._vbDetailsNew.sourcePlayback=null,this._vbDetailsNew.hiddenCanvas=null,this._vbDetailsNew.hiddenImage=null,store.dispatch(confActions.setVBItemsStatus(A)),SD.debug("Garbage collection completed. Set the video to original video!"),store.getState().conf.videoStatus)if(this._roomType===bE||this._roomType===xE)if(this._camVideoProducer&&store.getState().conf.joined&&this._localCamVideo.getVideoTracks()[0]&&store.getState().conf.joined&&"live"===this._localCamVideo.getVideoTracks()[0].readyState){await this._camVideoProducer.replaceTrack({track:this._localCamVideo.getVideoTracks()[0].clone()});let A={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localCamVideo.getVideoTracks()[0]}};this._participants=A,store.dispatch(confActions.addParticipant(A))}else SD.debug("Camvideoproducer not available! virtual background changes in the landing page! ");else if(this._roomType===dE&&this._peerConnection){const A=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});if(SD.debug("found sender:%o",A),A&&this._localCamVideo.getVideoTracks()[0]&&"live"===this._localCamVideo.getVideoTracks()[0].readyState){A.replaceTrack(this._localCamVideo.getVideoTracks()[0]);let I={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localCamVideo.getVideoTracks()[0]}};this._participants=I,store.dispatch(confActions.addParticipant(I))}else this.showNotification("danger","Error!","Unable to switch off virtual background! Try again OR contact support with code:CM-FE-RC-VB-E04")}};setVBDetails=async A=>{if(this._vbDetails=A,this._roomType!==bE&&this._roomType!==xE||!store.getState().conf.joined){if(this._roomType===dE&&this._peerConnection){const I=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});SD.debug("found sender:%o",I),I?I.replaceTrack(A.stream.getVideoTracks()[0]):this.showNotification("danger","Error!","Unable to set virtual background! Try again OR contact support with code:CM-FE-RC-VB-E02")}}else if(this._camVideoProducer){SD.debug("Going to replace the video track for cam video producer!");try{await this._camVideoProducer.replaceTrack({track:A.stream.getVideoTracks()[0]})}catch(eD){SD.debug("vb set error",eD)}SD.debug("all participants",this._participants),SD.debug("this._localCamVideo",this._localCamVideo)}else SD.warn("Camvideo producer is not available yet!")};async enableShare({shareAudio:A=!1,enableSharingLayers:I=!0,shareBitRates:g=[2500,1250,500]}={}){if(SD.debug("enableShare()"),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID003",text:"Error while trying to start screen share. Produce flag need to set to true while joining room in order to enable screen share."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID001",text:`Error while trying to start screen share as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling screen share? OR if you have already initiated the joinRoom process, then try enabling screen share after some seconds."};if(this._shareProducer)return SD.debug("Screen share is already active!"),{success:!1,warning:!0,code:"RWID001",text:"Error while trying to start screen share. Screen share is already active!"};if(!this._device.canProduce("video"))return SD.error("enableShare() | cannot produce video"),{success:!1,error:!0,code:"REID002",text:"Error while trying to start screen share. Screen share couldnot be activated due to limitations on this device. If you think this device is capable of screen share and the problem persists even after multiple retries, please contact technical support with the error code."};let C,Q;this._enableSharingLayers="boolean"!=typeof I?Boolean(I):I,Array.isArray(g)&&g.length>=1&&g.length<=3&&g.every(A=>Number.isInteger(A)&&A>=500&&A<=2500)?this.data.inputParams.shareBitRates=g:this.data.inputParams.shareBitRates=[2500,1250,500];try{SD.debug("enableShare() | calling getDisplayMedia()");const I=await navigator.mediaDevices.getDisplayMedia({audio:!!A,video:{displaySurface:"monitor",logicalSurface:!0,cursor:!0,width:{max:1920},height:{max:1080},frameRate:{max:30}}});if(!I)return SD.error("Unable to capture screen."),void this.emit("error",{code:"EID013",text:"Error while trying to start screen share. Not able to capture screen!"});let g,B;Q=I.getAudioTracks()[0],Q&&(this._shareAudioProducer=await this._sendTransport.produce({track:Q,codecOptions:this.data.inputParams.forcePCMU?void 0:{opusStereo:!1,opusDtx:!0,opusFec:!0,opusNack:!0},codec:this.data.inputParams.forcePCMU?this._device.rtpCapabilities.codecs.find(A=>"audio/pcmu"===A.mimeType.toLowerCase()):void 0,appData:{mediaTag:"screen-audio"}}),this._producers.set("ssAudio",{id:this._shareAudioProducer.id,type:"shareAudio",paused:this._shareAudioProducer.paused,track:this._shareAudioProducer.track,rtpParameters:this._shareAudioProducer.rtpParameters,codec:this._shareAudioProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("ssAudioStart",{peerId:this.data.inputParams.peerId,audioTrack:this._shareAudioProducer.track,type:"local"})),C=I.getVideoTracks()[0];const E={videoGoogleStartBitrate:1e3};if(this._forceVP8){if(B=this._device.rtpCapabilities.codecs.find(A=>"video/vp8"===A.mimeType.toLowerCase()),!B)throw new Error("desired VP8 codec+configuration is not supported")}else if(this._forceH264){if("high"===this.data.inputParams.h264Profile?B=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"4d001f"===A.parameters["profile-level-id"]):"low"===this.data.inputParams.h264Profile&&(B=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"42e01f"===A.parameters["profile-level-id"])),!B)throw new Error("desired H264 codec+configuration is not supported");SD.debug("Selected h264 codec is:%O",B)}else if(this._forceVP9&&(B=this._device.rtpCapabilities.codecs.find(A=>"video/vp9"===A.mimeType.toLowerCase()),!B))throw new Error("desired VP9 codec+configuration is not supported");if(this._enableSharingLayers){const A=this._device.rtpCapabilities.codecs.find(A=>"video"===A.kind);this._forceVP9&&B||"video/vp9"===A.mimeType.toLowerCase()?g=[{maxBitrate:1e3*this.data.inputParams.shareBitRates[0],scalabilityMode:this._sharingScalabilityMode||"L3T3",dtx:!0}]:(g=[{scaleResolutionDownBy:1,maxBitrate:1e3*this.data.inputParams.shareBitRates[0],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}],this._numSimulcastStreams>1&&g.unshift({scaleResolutionDownBy:2,maxBitrate:1e3*this.data.inputParams.shareBitRates[1],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}),this._numSimulcastStreams>2&&g.unshift({scaleResolutionDownBy:4,maxBitrate:1e3*this.data.inputParams.shareBitRates[2],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}))}this._shareProducer=await this._sendTransport.produce({track:C,encodings:g,codecOptions:E,codec:B,appData:{mediaTag:"screen-video"}}),this._producers.set("ssVideo",{id:this._shareProducer.id,type:"shareVideo",paused:this._shareProducer.paused,track:this._shareProducer.track,rtpParameters:this._shareProducer.rtpParameters,codec:this._shareProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("ssVideoStart",{peerId:this.data.inputParams.peerId,videoTrack:this._shareProducer.track,type:"local"}),this._shareProducer.on("transportclose",()=>{this._shareProducer=null}),this._shareProducer.on("trackended",()=>{this.disableShare().catch(()=>{})})}catch(B){SD.error("enableShare() | failed:%o",B),"NotAllowedError"!==B.name&&this.emit("error",{code:"EID014",text:`Error while trying to start screen share. Error is: ${B}!`}),C&&C.stop()}}async disableShare(){if(SD.debug("disableShare()"),!this._shareProducer)return SD.warn("Screen share doesn't seem to be on!"),void this.emit("error",{code:"EID017",text:"Error while trying to stop screen share. Is the screen share on!"});if(this._shareProducer.close(),this._shareAudioProducer){this._shareAudioProducer.close();try{let I={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",producerId:this._shareAudioProducer.id};this._sendMessage(I),this.emit("ssAudioStop",{peerId:this.data.inputParams.peerId,videoTrack:null,type:"local"});try{this._shareAudioProducer.track&&this._shareAudioProducer.track.stop&&this._shareAudioProducer.track.stop()}catch(A){}}catch(I){this.emit("error",{code:"EID015",text:`Error while trying to stop screen share audio. Error is: ${I}!`})}}try{let I={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"video",producerId:this._shareProducer.id};this._sendMessage(I),this.emit("ssVideoStop",{peerId:this.data.inputParams.peerId,videoTrack:null,type:"local"});try{this._shareProducer.track&&this._shareProducer.track.stop&&this._shareProducer.track.stop()}catch(A){}}catch(I){this.emit("error",{code:"EID016",text:`Error while trying to stop screen share video. Error is: ${I}!`})}this._shareAudioProducer=null,this._shareProducer=null}upgradeParticipant=(A,I=!0,g=!1)=>{SD.debug("JsSdk upgradeParticipant()",`Upgrading ${A}`);const C={id:"upgradeParticipant",peerId:A,roomName:this.data.inputParams.roomId,audioStatus:I,videoStatus:g};this._sendMessage(C)};downgradeParticipant=A=>{SD.debug("JsSdk downgradeParticipant()",`Downgrading ${A}`);const I={id:"downgradeParticipant",peerId:A,roomName:this.data.inputParams.roomId,sendTransportId:null};this._sendMessage(I)};sendUpgradeRequest=(A,I=!0)=>{SD.debug("JsSdk sendUpgradeRequest()",`Sending upgrade request to ${A}, status: ${I}`);const g={id:"modUpgradeReq",peerId:A,status:I,moderator:this.data.inputParams.peerId};this._sendMessage(g),this.emit("upgradeRequestSent",{peerId:A,status:I})};acceptUpgradeRequest=(A=!0,I=!1)=>{SD.debug("JsSdk acceptUpgradeRequest()","Accepting upgrade request");const g={id:"upgradeReqAccepted",audioStatus:A,videoStatus:I};this._sendMessage(g)};rejectUpgradeRequest=A=>{SD.debug("JsSdk rejectUpgradeRequest()","Rejecting upgrade request");const I={id:"modUpgradeReq",peerId:this.data.inputParams.peerId,status:!1};this._sendMessage(I),this.emit("upgradeRequestRejected",{moderatorPeerId:A})};raiseHand=()=>{SD.debug("JsSdk raiseHand()");const A={id:"handRaise",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,status:!0,handRaised:!0};this._sendMessage(A),this.emit("handRaised",{peerId:this.data.inputParams.peerId})};dropHand=(A=null,I=!1)=>{const g=A||this.data.inputParams.peerId;SD.debug("JsSdk dropHand()",`Dropping hand for ${g}`);const C={id:"handRaise",peerId:g,roomName:this.data.inputParams.roomId,status:!1,handRaised:!1,moderator:I};this._sendMessage(C),this.emit("handDropped",{peerId:g,moderator:I})};requestUpgradeToPresenter=async()=>{try{const A={id:"handRaise",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,status:!0,handRaised:!0,upgradeRequest:!0};return this._sendMessage(A),this.emit("upgradeRequestSent",{status:"success",message:"Upgrade request sent"}),{success:!0}}catch(eD){return SD.error("requestUpgradeToPresenter failed",eD),{success:!1,reason:eD?.message||"unknown_error"}}};handleUpgradeParticipant=async A=>{const{peerId:I,audioStatus:g,videoStatus:C}=A;SD.debug("JsSdk handleUpgradeParticipant()",`Upgrade received for ${I}`),this.emit("participantUpgraded",{peerId:I,audioStatus:g,videoStatus:C,participantType:"presenter"}),I===this.data.inputParams.peerId&&(SD.debug("JsSdk handleUpgradeParticipant()","Current user upgraded to presenter"),this.data.inputParams.peerType="presenter",this.data.inputParams.produce=!0,this.data.inputParams.produceAudio=!0,this.data.inputParams.produceVideo=!0,this._sendTransport||await this._createSendTransport(),this.emit("upgraded",{audioStatus:g,videoStatus:C,participantType:"presenter"}))};handleDowngradeParticipant=async A=>{const{peerId:I}=A;if(SD.debug("JsSdk handleDowngradeParticipant()",`Downgrade received for ${I}`),this.emit("participantDowngraded",{peerId:I,participantType:"viewer"}),I===this.data.inputParams.peerId){if(SD.debug("JsSdk handleDowngradeParticipant()","Current user downgraded to viewer"),this.data.inputParams.peerType="viewer",this.data.inputParams.produce=!1,this.data.inputParams.produceAudio=!1,this.data.inputParams.produceVideo=!1,this._sendTransport&&(this._sendTransport.close(),this._sendTransport=null),this._camAudioProducer){try{this._camAudioProducer.track&&this._camAudioProducer.track.stop&&this._camAudioProducer.track.stop()}catch(g){}this._camAudioProducer.close(),this._camAudioProducer=null}if(this._camVideoProducer){try{this._camVideoProducer.track&&this._camVideoProducer.track.stop&&this._camVideoProducer.track.stop()}catch(g){}this._camVideoProducer.close(),this._camVideoProducer=null}if(this._shareProducer){try{this._shareProducer.track&&this._shareProducer.track.stop&&this._shareProducer.track.stop()}catch(g){}this._shareProducer.close(),this._shareProducer=null,this.emit("ssVideoStop",{peerId:this.data.inputParams.peerId,type:"local"})}if(this._shareAudioProducer){try{this._shareAudioProducer.track&&this._shareAudioProducer.track.stop&&this._shareAudioProducer.track.stop()}catch(g){}this._shareAudioProducer.close(),this._shareAudioProducer=null}this._localCamVideo&&(this._localCamVideo.stop(),this._localCamVideo=null),this._localMicAudio&&(this._localMicAudio.stop(),this._localMicAudio=null),this._webCamStream&&(this._webCamStream.getTracks().forEach(A=>A.stop()),this._webCamStream=null),this._micStream&&(this._micStream.getTracks().forEach(A=>A.stop()),this._micStream=null),this.emit("downgraded",{participantType:"viewer"})}};handleModUpgradeReq=A=>{const{peerId:I,status:g,moderator:C}=A;SD.debug("JsSdk handleModUpgradeReq()",`Moderator upgrade request received. Status: ${g}`),"moderator"!==this.data.inputParams.peerType||g?g?this.emit("upgradeRequestReceived",{peerId:this.data.inputParams.peerId,moderator:C,message:"Moderator requested Participant to Presenter upgrade"}):this.emit("upgradeRequestCancelled",{peerId:this.data.inputParams.peerId,moderator:C,message:"Moderator cancelled Participant to Presenter upgrade request"}):this.emit("upgradeRequestRejected",{peerId:I,moderator:C,message:"Participant rejected request for upgrade to Presenter"})};handleUpgradeLimitReached=A=>{SD.debug("JsSdk handleUpgradeLimitReached()",A),this.emit("upgradeLimitReached",{message:A.text||"Maximum number of presenters reached",limit:A.limit})};handleHandRaise=A=>{const{peerId:I,handRaised:g,peerName:C,upgradeRequest:Q}=A;SD.debug("JsSdk handleHandRaise()",`Hand raise status: ${g} for ${I}`),this.emit("handRaise",{peerId:I,handRaised:g,peerName:C,upgradeRequest:!!Q})};handleSwitchMicOff=A=>{SD.debug("JsSdk handleSwitchMicOff()",A),this.emit("micForcedOff",{message:A.text||"Moderator turned off your microphone"}),this._camAudioProducer&&!this._camAudioProducer.paused&&this.muteMic()};handleScreenShareLimitReached=A=>{SD.debug("JsSdk handleScreenShareLimitReached()",A),this.emit("screenShareLimitReached",{message:A.text||"Maximum number of screen shares reached",limit:A.limit})};handleLockUnlockRoom=A=>{const{locked:I}=A;SD.debug("JsSdk handleLockUnlockRoom()","Room "+(I?"locked":"unlocked")),this.emit("roomLockStatusChanged",{locked:I,message:I?"Room has been locked":"Room has been unlocked"})};handlePeersWaiting=A=>{const{peersWaiting:I}=A;SD.debug("JsSdk handlePeersWaiting()",`${I?.length||0} peers waiting`),this.emit("peersWaiting",{peersWaiting:I||[],count:I?.length||0})};logMeOutNew=async()=>{try{SD.debug("Room","inside log me out new"),this.emit("roomClosed",{roomId:this.data.inputParams.roomId,reason:"removed_by_moderator"})}catch(A){}await this.leaveRoom()};logThisUserOutOfMeeting=A=>{if(SD.debug("Room","inside log this user out of meeting"),A===this.data.inputParams.peerId)SD.debug("ConferenceRoom","logging myself Out"),this.leaveRoom();else try{var I={id:"logThisUserOut",peerId:A,moderatorPeerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId};this._sendMessage(I)}catch(g){SD.error("Room",g)}}}const LD="cp2p-client";class kD{constructor(A){A?(this._debug=Jg(`${LD}:${A}`),this._info=Jg(`${LD}:INFO:${A}`),this._warn=Jg(`${LD}:WARN:${A}`),this._error=Jg(`${LD}:ERROR:${A}`)):(this._debug=Jg(LD),this._info=Jg(`${LD}:INFO`),this._warn=Jg(`${LD}:WARN`),this._error=Jg(`${LD}:ERROR`)),this._debug.log=function(){}.bind(),this._info.log=function(){}.bind(),this._warn.log=function(){}.bind(),this._error.log=function(){}.bind()}get debug(){return this._debug}get info(){return this._info}get warn(){return this._warn}get error(){return this._error}}const JD={audio:{deviceId:{exact:void 0}},video:!1},UD={video:{deviceId:{exact:void 0},width:{min:320,ideal:640,max:1280},height:{min:240,ideal:480,max:720},frameRate:{min:15,max:30}}},qD={audio:!0,video:{width:{min:320,ideal:1280,max:1280},height:{min:240,ideal:720,max:720},aspectRatio:1.777777778,frameRate:{min:15,max:30}}},tD=new kD("socket");class rD extends cg.EventEmitter{constructor({url:A,roomId:I,peerId:g,peerName:C,role:Q}){super(),tD.debug("constructor():%o ",{url:A,roomId:I,peerId:g,peerName:C,role:Q}),this._closed=!1,this._params={url:A,roomId:I,peerId:g,peerName:C,role:Q},this._socket=null,this._connectionStatus=null,this._createSocket()}get closed(){return this._closed}get connectionStatus(){return this._connectionStatus}close(){if(!this._closed){tD.debug("close()"),this._closed=!0,this.emit("close");try{this._socket.disconnect()}catch(A){tD.error("close() | error closing the Socket:%o",A)}}}async send(A){if(this._closed)throw new Error("transport closed");try{this._socket.send(JSON.stringify(A))}catch(I){throw tD.warn("send() failed:%o",I),I}}async request({type:A,message:I}){return new Promise(g=>{if(this._closed)throw new Error("transport closed");try{this._socket.emit(A,JSON.stringify(I),A=>{g(A)})}catch(C){throw tD.warn("emit() failed:%o",C),C}})}async _createSocket(){let A=this;const I=io(this._params.url,{query:{roomId:this._params.roomId,peerId:this._params.peerId,peerName:this._params.peerName,role:this._params.role}});I.on("connect",()=>{tD.debug("Socket connected!!"),A._connectionStatus=!0,A.emit("connected")}),I.on("disconnect",()=>{tD.debug("Socket disconnected!!"),A._connectionStatus=!1,A.emit("disconnected")}),I.on("reconnect",()=>{tD.debug("Socket reconnected after disconnect!!"),I.emit("reconnected")}),I.on("message",I=>{const g=JSON.parse(I);tD.debug("New mesage received with id:%s",g.type),A.emit("message",g)}),this._socket=I}}
|
|
231
|
+
`,{width:D,height:n}=B,o=D/n,s=Mi(A,A.VERTEX_SHADER,E),w=Mi(A,A.FRAGMENT_SHADER,i),a=Ki(A,s,w,I,g),y=A.getUniformLocation(a,"u_backgroundScale"),G=A.getUniformLocation(a,"u_backgroundOffset"),R=A.getUniformLocation(a,"u_inputFrame"),S=A.getUniformLocation(a,"u_personMask"),h=A.getUniformLocation(a,"u_background"),N=A.getUniformLocation(a,"u_coverage"),K=A.getUniformLocation(a,"u_lightWrapping"),M=A.getUniformLocation(a,"u_blendMode");A.useProgram(a),A.uniform2f(y,1,1),A.uniform2f(G,0,0),A.uniform1i(R,0),A.uniform1i(S,1),A.uniform2f(N,0,1),A.uniform1f(K,0),A.uniform1f(M,0);let F=null;function L(I){F=Fi(A,A.RGBA8,I.naturalWidth,I.naturalHeight,A.LINEAR,A.LINEAR),A.texSubImage2D(A.TEXTURE_2D,0,0,0,I.naturalWidth,I.naturalHeight,A.RGBA,A.UNSIGNED_BYTE,I);let g=0,C=0,Q=I.naturalWidth,B=I.naturalHeight;Q/B<o?(B=Q/o,C=(I.naturalHeight-B)/2):(Q=B*o,g=(I.naturalWidth-Q)/2);const E=Q/I.naturalWidth,i=B/I.naturalHeight;g/=I.naturalWidth,C/=I.naturalHeight,A.uniform2f(y,E,i),A.uniform2f(G,g,C)}return Q?.complete?L(Q):Q&&(Q.onload=()=>{L(Q)}),{render:function(){A.viewport(0,0,D,n),A.useProgram(a),A.activeTexture(A.TEXTURE1),A.bindTexture(A.TEXTURE_2D,C),null!==F&&(A.activeTexture(A.TEXTURE2),A.bindTexture(A.TEXTURE_2D,F),A.uniform1i(h,2)),A.bindFramebuffer(A.FRAMEBUFFER,null),A.drawArrays(A.TRIANGLE_STRIP,0,4)},updateCoverage:function(I){A.useProgram(a),A.uniform2f(N,I[0],I[1])},updateLightWrapping:function(I){A.useProgram(a),A.uniform1f(K,I)},updateBlendMode:function(I){A.useProgram(a),A.uniform1f(M,"screen"===I?0:1)},cleanUp:function(){A.deleteTexture(F),A.deleteProgram(a),A.deleteShader(w),A.deleteShader(s)}}}(a,R,S,K,I,Q);return{render:async function(){a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,h),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,A.htmlElement),a.bindVertexArray(G),await M.render(),i(),B._runInference(),i(),F.render(),L.render(),k.render()},updatePostProcessingConfig:function(A){if(L.updateSigmaSpace(A.jointBilateralFilter.sigmaSpace),L.updateSigmaColor(A.jointBilateralFilter.sigmaColor),"image"===g.type){const I=k;I.updateCoverage(A.coverage),I.updateLightWrapping(A.lightWrapping),I.updateBlendMode(A.blendMode)}else if("blur"===g.type){k.updateCoverage(A.coverage)}else{const A=k;A.updateCoverage([0,.9999]),A.updateLightWrapping(0)}},cleanUp:function(){k.cleanUp(),L.cleanUp(),F.cleanUp(),M.cleanUp(),a.deleteTexture(K),a.deleteTexture(N),a.deleteTexture(h),a.deleteBuffer(S),a.deleteBuffer(R),a.deleteVertexArray(G),a.deleteShader(y)}}}class Ui{constructor(){this.pipeline=null,this.backgroundImageRef=null,this.canvasRef=null,this.fps=0,this.durations=[],this.isRunning=!1,this.timerWorker=null,this.renderTimeoutId=null,this.previousTime=0,this.beginTime=0,this.eventCount=0,this.frameCount=0,this.frameDurations=[]}async initialize(A,I,g,C,Q,B=null,E=null){this.stop(),this.backgroundImageRef=B,this.canvasRef=E;const i=1e3/g.targetFps;this.previousTime=0,this.beginTime=0,this.eventCount=0,this.frameCount=0,this.frameDurations=[],this.timerWorker=function(){const A=new Map,I=new Blob(["\n const timeoutIds = new Map();\n \n addEventListener('message', (event) => {\n if (event.data.timeoutMs !== undefined) {\n const timeoutId = setTimeout(() => {\n postMessage({ callbackId: event.data.callbackId });\n timeoutIds.delete(event.data.callbackId);\n }, event.data.timeoutMs);\n timeoutIds.set(event.data.callbackId, timeoutId);\n } else {\n const timeoutId = timeoutIds.get(event.data.callbackId);\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n timeoutIds.delete(event.data.callbackId);\n }\n }\n });\n "],{type:"application/javascript"}),g=new Worker(URL.createObjectURL(I));g.onmessage=I=>{const g=A.get(I.data.callbackId);g&&(A.delete(I.data.callbackId),g())};let C=1;return{setTimeout:function(I,Q=0){const B=C++;return A.set(B,I),g.postMessage({callbackId:B,timeoutMs:Q}),B},clearTimeout:function(I){A.has(I)&&(g.postMessage({callbackId:I}),A.delete(I))},terminate:function(){A.clear(),g.terminate()}}}(),this.pipeline="webgl2"===g.pipeline?Ji(A,this.backgroundImageRef,I,g,this.canvasRef,Q,this.timerWorker,this.addFrameEvent.bind(this)):hi(A,I,g,this.canvasRef,C,Q,this.addFrameEvent.bind(this));const D=async()=>{if(!this.isRunning)return;const A=performance.now();this.beginFrame(),await this.pipeline.render(),this.endFrame(),this.renderTimeoutId=this.timerWorker.setTimeout(D,Math.max(0,i-(performance.now()-A)))};return this.isRunning=!0,D(),{pipeline:this.pipeline,backgroundImageRef:this.backgroundImageRef,canvasRef:this.canvasRef,fps:this.fps,durations:this.getProcessingDurations()}}beginFrame(){this.beginTime=Date.now()}addFrameEvent(){const A=Date.now();this.frameDurations[this.eventCount]=A-this.beginTime,this.beginTime=A,this.eventCount++}endFrame(){const A=Date.now();this.frameDurations[this.eventCount]=A-this.beginTime,this.frameCount++,A>=this.previousTime+1e3&&(this.fps=1e3*this.frameCount/(A-this.previousTime),this.durations=[...this.frameDurations],this.previousTime=A,this.frameCount=0),this.eventCount=0}getProcessingDurations(){return this.frameDurations.length>=3?[this.frameDurations[0]||0,this.frameDurations[1]||0,this.frameDurations[2]||0]:[0,0,0]}stop(){this.isRunning=!1,this.timerWorker&&this.renderTimeoutId&&this.timerWorker.clearTimeout(this.renderTimeoutId),this.timerWorker&&(this.timerWorker.terminate(),this.timerWorker=null),this.pipeline&&(this.pipeline.cleanUp(),this.pipeline=null),this.renderTimeoutId=null}getState(){return{pipeline:this.pipeline,backgroundImageRef:this.backgroundImageRef,canvasRef:this.canvasRef,fps:this.fps,durations:this.getProcessingDurations(),isRunning:this.isRunning}}getFps(){return this.fps}getDurations(){return this.durations}isActive(){return this.isRunning&&null!==this.pipeline}async updateConfig(A,I,g,C,Q){return this.initialize(A,I,g,C,Q,this.backgroundImageRef,this.canvasRef)}destroy(){this.stop(),this.backgroundImageRef=null,this.canvasRef=null,this.fps=0,this.durations=[]}}const qi=new qg("Room");const ti=new Set(["240p","360p","480p","720p","1080p","1440p","2160p"]);function ri(A){return!!Array.isArray(A)&&A.every(A=>ti.has(A))}const ci=new qg("utils-verifyFiles"),Hi=["mp4"];function Yi(A,I){try{const g=new URL(A).pathname;return g.split(".").pop().toLowerCase()===I.toLowerCase()}catch{return!1}}const ei=new TextEncoder,di=new TextDecoder;function bi(A){if(Uint8Array.fromBase64)return Uint8Array.fromBase64("string"==typeof A?A:di.decode(A),{alphabet:"base64url"});let I=A;I instanceof Uint8Array&&(I=di.decode(I)),I=I.replace(/-/g,"+").replace(/_/g,"/").replace(/\s/g,"");try{return function(A){if(Uint8Array.fromBase64)return Uint8Array.fromBase64(A);const I=atob(A),g=new Uint8Array(I.length);for(let C=0;C<I.length;C++)g[C]=I.charCodeAt(C);return g}(I)}catch{throw new TypeError("The input to be decoded is not correctly encoded.")}}class xi extends Error{static code="ERR_JOSE_GENERIC";code="ERR_JOSE_GENERIC";constructor(A,I){super(A,I),this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}}class ui extends xi{static code="ERR_JWT_CLAIM_VALIDATION_FAILED";code="ERR_JWT_CLAIM_VALIDATION_FAILED";claim;reason;payload;constructor(A,I,g="unspecified",C="unspecified"){super(A,{cause:{claim:g,reason:C,payload:I}}),this.claim=g,this.reason=C,this.payload=I}}class pi extends xi{static code="ERR_JWT_EXPIRED";code="ERR_JWT_EXPIRED";claim;reason;payload;constructor(A,I,g="unspecified",C="unspecified"){super(A,{cause:{claim:g,reason:C,payload:I}}),this.claim=g,this.reason=C,this.payload=I}}class Ti extends xi{static code="ERR_JOSE_ALG_NOT_ALLOWED";code="ERR_JOSE_ALG_NOT_ALLOWED"}class mi extends xi{static code="ERR_JOSE_NOT_SUPPORTED";code="ERR_JOSE_NOT_SUPPORTED"}class Oi extends xi{static code="ERR_JWS_INVALID";code="ERR_JWS_INVALID"}class li extends xi{static code="ERR_JWT_INVALID";code="ERR_JWT_INVALID"}class fi extends xi{static code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";constructor(A="signature verification failed",I){super(A,I)}}function Pi(A,I="algorithm.name"){return new TypeError(`CryptoKey does not support this operation, its ${I} must be ${A}`)}function Wi(A,I){return A.name===I}function zi(A){return parseInt(A.name.slice(4),10)}function ji(A,I,g){switch(I){case"HS256":case"HS384":case"HS512":{if(!Wi(A.algorithm,"HMAC"))throw Pi("HMAC");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"RS256":case"RS384":case"RS512":{if(!Wi(A.algorithm,"RSASSA-PKCS1-v1_5"))throw Pi("RSASSA-PKCS1-v1_5");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"PS256":case"PS384":case"PS512":{if(!Wi(A.algorithm,"RSA-PSS"))throw Pi("RSA-PSS");const g=parseInt(I.slice(2),10);if(zi(A.algorithm.hash)!==g)throw Pi(`SHA-${g}`,"algorithm.hash");break}case"Ed25519":case"EdDSA":if(!Wi(A.algorithm,"Ed25519"))throw Pi("Ed25519");break;case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":if(!Wi(A.algorithm,I))throw Pi(I);break;case"ES256":case"ES384":case"ES512":{if(!Wi(A.algorithm,"ECDSA"))throw Pi("ECDSA");const g=function(A){switch(A){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}(I);if(A.algorithm.namedCurve!==g)throw Pi(g,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}!function(A,I){if(!A.usages.includes(I))throw new TypeError(`CryptoKey does not support this operation, its usages must include ${I}.`)}(A,g)}function Vi(A,I,...g){if((g=g.filter(Boolean)).length>2){const I=g.pop();A+=`one of type ${g.join(", ")}, or ${I}.`}else 2===g.length?A+=`one of type ${g[0]} or ${g[1]}.`:A+=`of type ${g[0]}.`;return null==I?A+=` Received ${I}`:"function"==typeof I&&I.name?A+=` Received function ${I.name}`:"object"==typeof I&&null!=I&&I.constructor?.name&&(A+=` Received an instance of ${I.constructor.name}`),A}function vi(A,I,...g){return Vi(`Key for the ${A} algorithm must be `,I,...g)}function Zi(A){return"CryptoKey"===A?.[Symbol.toStringTag]}function Xi(A){return"KeyObject"===A?.[Symbol.toStringTag]}const _i=A=>Zi(A)||Xi(A);const $i=A=>{if("object"!=typeof(I=A)||null===I||"[object Object]"!==Object.prototype.toString.call(A))return!1;var I;if(null===Object.getPrototypeOf(A))return!0;let g=A;for(;null!==Object.getPrototypeOf(g);)g=Object.getPrototypeOf(g);return Object.getPrototypeOf(A)===g};const AD=async A=>{if(!A.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');const{algorithm:I,keyUsages:g}=function(A){let I,g;switch(A.kty){case"AKP":switch(A.alg){case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":I={name:A.alg},g=A.priv?["sign"]:["verify"];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"RSA":switch(A.alg){case"PS256":case"PS384":case"PS512":I={name:"RSA-PSS",hash:`SHA-${A.alg.slice(-3)}`},g=A.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":I={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${A.alg.slice(-3)}`},g=A.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":I={name:"RSA-OAEP",hash:`SHA-${parseInt(A.alg.slice(-3),10)||1}`},g=A.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"EC":switch(A.alg){case"ES256":I={name:"ECDSA",namedCurve:"P-256"},g=A.d?["sign"]:["verify"];break;case"ES384":I={name:"ECDSA",namedCurve:"P-384"},g=A.d?["sign"]:["verify"];break;case"ES512":I={name:"ECDSA",namedCurve:"P-521"},g=A.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":I={name:"ECDH",namedCurve:A.crv},g=A.d?["deriveBits"]:[];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"OKP":switch(A.alg){case"Ed25519":case"EdDSA":I={name:"Ed25519"},g=A.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":I={name:A.crv},g=A.d?["deriveBits"]:[];break;default:throw new mi('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;default:throw new mi('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:I,keyUsages:g}}(A),C={...A};return"AKP"!==C.kty&&delete C.alg,delete C.use,crypto.subtle.importKey("jwk",C,I,A.ext??(!A.d&&!A.priv),A.key_ops??g)};function ID(A){return $i(A)&&"string"==typeof A.kty}let gD;const CD=async(A,I,g,C=!1)=>{gD||=new WeakMap;let Q=gD.get(A);if(Q?.[g])return Q[g];const B=await AD({...I,alg:g});return C&&Object.freeze(A),Q?Q[g]=B:gD.set(A,{[g]:B}),B},QD=async(A,I)=>{if(A instanceof Uint8Array)return A;if(Zi(A))return A;if(Xi(A)){if("secret"===A.type)return A.export();if("toCryptoKey"in A&&"function"==typeof A.toCryptoKey)try{return((A,I)=>{gD||=new WeakMap;let g=gD.get(A);if(g?.[I])return g[I];const C="public"===A.type,Q=!!C;let B;if("x25519"===A.asymmetricKeyType){switch(I){case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":break;default:throw new TypeError("given KeyObject instance cannot be used for this algorithm")}B=A.toCryptoKey(A.asymmetricKeyType,Q,C?[]:["deriveBits"])}if("ed25519"===A.asymmetricKeyType){if("EdDSA"!==I&&"Ed25519"!==I)throw new TypeError("given KeyObject instance cannot be used for this algorithm");B=A.toCryptoKey(A.asymmetricKeyType,Q,[C?"verify":"sign"])}switch(A.asymmetricKeyType){case"ml-dsa-44":case"ml-dsa-65":case"ml-dsa-87":if(I!==A.asymmetricKeyType.toUpperCase())throw new TypeError("given KeyObject instance cannot be used for this algorithm");B=A.toCryptoKey(A.asymmetricKeyType,Q,[C?"verify":"sign"])}if("rsa"===A.asymmetricKeyType){let g;switch(I){case"RSA-OAEP":g="SHA-1";break;case"RS256":case"PS256":case"RSA-OAEP-256":g="SHA-256";break;case"RS384":case"PS384":case"RSA-OAEP-384":g="SHA-384";break;case"RS512":case"PS512":case"RSA-OAEP-512":g="SHA-512";break;default:throw new TypeError("given KeyObject instance cannot be used for this algorithm")}if(I.startsWith("RSA-OAEP"))return A.toCryptoKey({name:"RSA-OAEP",hash:g},Q,C?["encrypt"]:["decrypt"]);B=A.toCryptoKey({name:I.startsWith("PS")?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:g},Q,[C?"verify":"sign"])}if("ec"===A.asymmetricKeyType){const g=new Map([["prime256v1","P-256"],["secp384r1","P-384"],["secp521r1","P-521"]]).get(A.asymmetricKeyDetails?.namedCurve);if(!g)throw new TypeError("given KeyObject instance cannot be used for this algorithm");"ES256"===I&&"P-256"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),"ES384"===I&&"P-384"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),"ES512"===I&&"P-521"===g&&(B=A.toCryptoKey({name:"ECDSA",namedCurve:g},Q,[C?"verify":"sign"])),I.startsWith("ECDH-ES")&&(B=A.toCryptoKey({name:"ECDH",namedCurve:g},Q,C?[]:["deriveBits"]))}if(!B)throw new TypeError("given KeyObject instance cannot be used for this algorithm");return g?g[I]=B:gD.set(A,{[I]:B}),B})(A,I)}catch(eD){if(eD instanceof TypeError)throw eD}let g=A.export({format:"jwk"});return CD(A,g,I)}if(ID(A))return A.k?bi(A.k):CD(A,A,I,!0);throw new Error("unreachable")},BD=A=>A?.[Symbol.toStringTag],ED=(A,I,g)=>{if(void 0!==I.use){let A;switch(g){case"sign":case"verify":A="sig";break;case"encrypt":case"decrypt":A="enc"}if(I.use!==A)throw new TypeError(`Invalid key for this operation, its "use" must be "${A}" when present`)}if(void 0!==I.alg&&I.alg!==A)throw new TypeError(`Invalid key for this operation, its "alg" must be "${A}" when present`);if(Array.isArray(I.key_ops)){let C;switch(!0){case"verify"===g:case"dir"===A:case A.includes("CBC-HS"):C=g;break;case A.startsWith("PBES2"):C="deriveBits";break;case/^A\d{3}(?:GCM)?(?:KW)?$/.test(A):C=!A.includes("GCM")&&A.endsWith("KW")?"unwrapKey":g;break;case"encrypt"===g:C="wrapKey";break;case"decrypt"===g:C=A.startsWith("RSA")?"unwrapKey":"deriveBits"}if(C&&!1===I.key_ops?.includes?.(C))throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${C}" when present`)}return!0},iD=(A,I,g)=>{A.startsWith("HS")||"dir"===A||A.startsWith("PBES2")||/^A(?:128|192|256)(?:GCM)?(?:KW)?$/.test(A)||/^A(?:128|192|256)CBC-HS(?:256|384|512)$/.test(A)?((A,I,g)=>{if(!(I instanceof Uint8Array)){if(ID(I)){if(function(A){return"oct"===A.kty&&"string"==typeof A.k}(I)&&ED(A,I,g))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!_i(I))throw new TypeError(vi(A,I,"CryptoKey","KeyObject","JSON Web Key","Uint8Array"));if("secret"!==I.type)throw new TypeError(`${BD(I)} instances for symmetric algorithms must be of type "secret"`)}})(A,I,g):((A,I,g)=>{if(ID(I))switch(g){case"decrypt":case"sign":if(function(A){return"oct"!==A.kty&&("AKP"===A.kty&&"string"==typeof A.priv||"string"==typeof A.d)}(I)&&ED(A,I,g))return;throw new TypeError("JSON Web Key for this operation be a private JWK");case"encrypt":case"verify":if(function(A){return"oct"!==A.kty&&void 0===A.d&&void 0===A.priv}(I)&&ED(A,I,g))return;throw new TypeError("JSON Web Key for this operation be a public JWK")}if(!_i(I))throw new TypeError(vi(A,I,"CryptoKey","KeyObject","JSON Web Key"));if("secret"===I.type)throw new TypeError(`${BD(I)} instances for asymmetric algorithms must not be of type "secret"`);if("public"===I.type)switch(g){case"sign":throw new TypeError(`${BD(I)} instances for asymmetric algorithm signing must be of type "private"`);case"decrypt":throw new TypeError(`${BD(I)} instances for asymmetric algorithm decryption must be of type "private"`)}if("private"===I.type)switch(g){case"verify":throw new TypeError(`${BD(I)} instances for asymmetric algorithm verifying must be of type "public"`);case"encrypt":throw new TypeError(`${BD(I)} instances for asymmetric algorithm encryption must be of type "public"`)}})(A,I,g)},DD=async(A,I,g)=>{if(I instanceof Uint8Array){if(!A.startsWith("HS"))throw new TypeError(((A,...I)=>Vi("Key must be ",A,...I))(I,"CryptoKey","KeyObject","JSON Web Key"));return crypto.subtle.importKey("raw",I,{hash:`SHA-${A.slice(-3)}`,name:"HMAC"},!1,[g])}return ji(I,A,g),I},nD=async(A,I,g,C)=>{const Q=await DD(A,I,"verify");((A,I)=>{if(A.startsWith("RS")||A.startsWith("PS")){const{modulusLength:g}=I.algorithm;if("number"!=typeof g||g<2048)throw new TypeError(`${A} requires key modulusLength to be 2048 bits or larger`)}})(A,Q);const B=((A,I)=>{const g=`SHA-${A.slice(-3)}`;switch(A){case"HS256":case"HS384":case"HS512":return{hash:g,name:"HMAC"};case"PS256":case"PS384":case"PS512":return{hash:g,name:"RSA-PSS",saltLength:parseInt(A.slice(-3),10)>>3};case"RS256":case"RS384":case"RS512":return{hash:g,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:g,name:"ECDSA",namedCurve:I.namedCurve};case"Ed25519":case"EdDSA":return{name:"Ed25519"};case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return{name:A};default:throw new mi(`alg ${A} is not supported either by JOSE or your javascript runtime`)}})(A,Q.algorithm);try{return await crypto.subtle.verify(B,Q,g,C)}catch{return!1}};async function oD(A,I,g){if(!$i(A))throw new Oi("Flattened JWS must be an object");if(void 0===A.protected&&void 0===A.header)throw new Oi('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==A.protected&&"string"!=typeof A.protected)throw new Oi("JWS Protected Header incorrect type");if(void 0===A.payload)throw new Oi("JWS Payload missing");if("string"!=typeof A.signature)throw new Oi("JWS Signature missing or incorrect type");if(void 0!==A.header&&!$i(A.header))throw new Oi("JWS Unprotected Header incorrect type");let C={};if(A.protected)try{const I=bi(A.protected);C=JSON.parse(di.decode(I))}catch{throw new Oi("JWS Protected Header is invalid")}if(!((...A)=>{const I=A.filter(Boolean);if(0===I.length||1===I.length)return!0;let g;for(const C of I){const A=Object.keys(C);if(g&&0!==g.size)for(const I of A){if(g.has(I))return!1;g.add(I)}else g=new Set(A)}return!0})(C,A.header))throw new Oi("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const Q={...C,...A.header},B=((A,I,g,C,Q)=>{if(void 0!==Q.crit&&void 0===C?.crit)throw new A('"crit" (Critical) Header Parameter MUST be integrity protected');if(!C||void 0===C.crit)return new Set;if(!Array.isArray(C.crit)||0===C.crit.length||C.crit.some(A=>"string"!=typeof A||0===A.length))throw new A('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let B;B=void 0!==g?new Map([...Object.entries(g),...I.entries()]):I;for(const E of C.crit){if(!B.has(E))throw new mi(`Extension Header Parameter "${E}" is not recognized`);if(void 0===Q[E])throw new A(`Extension Header Parameter "${E}" is missing`);if(B.get(E)&&void 0===C[E])throw new A(`Extension Header Parameter "${E}" MUST be integrity protected`)}return new Set(C.crit)})(Oi,new Map([["b64",!0]]),g?.crit,C,Q);let E=!0;if(B.has("b64")&&(E=C.b64,"boolean"!=typeof E))throw new Oi('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:i}=Q;if("string"!=typeof i||!i)throw new Oi('JWS "alg" (Algorithm) Header Parameter missing or invalid');const D=g&&((A,I)=>{if(void 0!==I&&(!Array.isArray(I)||I.some(A=>"string"!=typeof A)))throw new TypeError(`"${A}" option must be an array of strings`);if(I)return new Set(I)})("algorithms",g.algorithms);if(D&&!D.has(i))throw new Ti('"alg" (Algorithm) Header Parameter value not allowed');if(E){if("string"!=typeof A.payload)throw new Oi("JWS Payload must be a string")}else if("string"!=typeof A.payload&&!(A.payload instanceof Uint8Array))throw new Oi("JWS Payload must be a string or an Uint8Array instance");let n=!1;"function"==typeof I&&(I=await I(C,A),n=!0),iD(i,I,"verify");const o=function(...A){const I=A.reduce((A,{length:I})=>A+I,0),g=new Uint8Array(I);let C=0;for(const Q of A)g.set(Q,C),C+=Q.length;return g}(ei.encode(A.protected??""),ei.encode("."),"string"==typeof A.payload?ei.encode(A.payload):A.payload);let s;try{s=bi(A.signature)}catch{throw new Oi("Failed to base64url decode the signature")}const w=await QD(I,i);if(!(await nD(i,w,s,o)))throw new fi;let a;if(E)try{a=bi(A.payload)}catch{throw new Oi("Failed to base64url decode the payload")}else a="string"==typeof A.payload?ei.encode(A.payload):A.payload;const y={payload:a};return void 0!==A.protected&&(y.protectedHeader=C),void 0!==A.header&&(y.unprotectedHeader=A.header),n?{...y,key:w}:y}const sD=86400,wD=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i,aD=A=>{const I=wD.exec(A);if(!I||I[4]&&I[1])throw new TypeError("Invalid time period format");const g=parseFloat(I[2]);let C;switch(I[3].toLowerCase()){case"sec":case"secs":case"second":case"seconds":case"s":C=Math.round(g);break;case"minute":case"minutes":case"min":case"mins":case"m":C=Math.round(60*g);break;case"hour":case"hours":case"hr":case"hrs":case"h":C=Math.round(3600*g);break;case"day":case"days":case"d":C=Math.round(g*sD);break;case"week":case"weeks":case"w":C=Math.round(604800*g);break;default:C=Math.round(31557600*g)}return"-"===I[1]||"ago"===I[4]?-C:C},yD=A=>A.includes("/")?A.toLowerCase():`application/${A.toLowerCase()}`;function GD(A,I,g={}){let C;try{C=JSON.parse(di.decode(I))}catch{}if(!$i(C))throw new li("JWT Claims Set must be a top-level JSON object");const{typ:Q}=g;if(Q&&("string"!=typeof A.typ||yD(A.typ)!==yD(Q)))throw new ui('unexpected "typ" JWT header value',C,"typ","check_failed");const{requiredClaims:B=[],issuer:E,subject:i,audience:D,maxTokenAge:n}=g,o=[...B];void 0!==n&&o.push("iat"),void 0!==D&&o.push("aud"),void 0!==i&&o.push("sub"),void 0!==E&&o.push("iss");for(const S of new Set(o.reverse()))if(!(S in C))throw new ui(`missing required "${S}" claim`,C,S,"missing");if(E&&!(Array.isArray(E)?E:[E]).includes(C.iss))throw new ui('unexpected "iss" claim value',C,"iss","check_failed");if(i&&C.sub!==i)throw new ui('unexpected "sub" claim value',C,"sub","check_failed");if(D&&(s=C.aud,w="string"==typeof D?[D]:D,!("string"==typeof s?w.includes(s):Array.isArray(s)&&w.some(Set.prototype.has.bind(new Set(s))))))throw new ui('unexpected "aud" claim value',C,"aud","check_failed");var s,w;let a;switch(typeof g.clockTolerance){case"string":a=aD(g.clockTolerance);break;case"number":a=g.clockTolerance;break;case"undefined":a=0;break;default:throw new TypeError("Invalid clockTolerance option type")}const{currentDate:y}=g,G=(R=y||new Date,Math.floor(R.getTime()/1e3));var R;if((void 0!==C.iat||n)&&"number"!=typeof C.iat)throw new ui('"iat" claim must be a number',C,"iat","invalid");if(void 0!==C.nbf){if("number"!=typeof C.nbf)throw new ui('"nbf" claim must be a number',C,"nbf","invalid");if(C.nbf>G+a)throw new ui('"nbf" claim timestamp check failed',C,"nbf","check_failed")}if(void 0!==C.exp){if("number"!=typeof C.exp)throw new ui('"exp" claim must be a number',C,"exp","invalid");if(C.exp<=G-a)throw new pi('"exp" claim timestamp check failed',C,"exp","check_failed")}if(n){const A=G-C.iat;if(A-a>("number"==typeof n?n:aD(n)))throw new pi('"iat" claim timestamp check failed (too far in the past)',C,"iat","check_failed");if(A<0-a)throw new ui('"iat" claim timestamp check failed (it should be in the past)',C,"iat","check_failed")}return C}async function RD(A,I,g){const C=await async function(A,I,g){if(A instanceof Uint8Array&&(A=di.decode(A)),"string"!=typeof A)throw new Oi("Compact JWS must be a string or Uint8Array");const{0:C,1:Q,2:B,length:E}=A.split(".");if(3!==E)throw new Oi("Invalid Compact JWS");const i=await oD({payload:Q,protected:C,signature:B},I,g),D={payload:i.payload,protectedHeader:i.protectedHeader};return"function"==typeof I?{...D,key:i.key}:D}(A,I,g);if(C.protectedHeader.crit?.includes("b64")&&!1===C.protectedHeader.b64)throw new li("JWTs MUST NOT use unencoded payload");const Q={payload:GD(C.protectedHeader,C.payload,g),protectedHeader:C.protectedHeader};return"function"==typeof I?{...Q,key:C.key}:Q}const SD=new qg("Room"),hD={small:{width:{ideal:160},height:{ideal:120}},qvga:{width:{ideal:320},height:{ideal:240}},vga:{width:{ideal:640},height:{ideal:480}},hd:{width:{ideal:1280},height:{ideal:720}}};let ND;const KD=new class{constructor(){this.queue=new Map}push(A,I){this.queue.set(A,I)}get(A){return this.queue.get(A)}remove(A){this.queue.delete(A)}},MD=new class{constructor(){this._localVBStream=null,this._vbDetailsNew={},this._vbDetails=null,this._roomType=null,this._participants={},this._peerId=null,this._peerConnection=null,this._pipelineManager=null,this._updateInterval=null,this._pipelineManager=new Ui,this.initializeTFLite()}getVBDetails(){return this._vbDetailsNew}getVBStream(){return this._localVBStream}hasLiveVBTrack(){try{return this._localVBStream&&"function"==typeof this._localVBStream.getVideoTracks&&this._localVBStream.getVideoTracks().length>0&&"live"===this._localVBStream.getVideoTracks()[0].readyState}catch(A){return!1}}setPipelineManager(A){this._pipelineManager=A}async initializeTFLite(){try{const A=await Si(Gi);this._vbDetailsNew.tfLite=A.tflite,this._vbDetailsNew.isSIMDSupported=A.isSIMDSupported}catch(A){}}async initializePipeline(A,I){qi.debug("initializePipeline called with videoTrack and backgroundConfig:%O,%O",A,I);let g=null;try{const C=await this._createHiddenVideoElement(A);if(this._vbDetailsNew.hiddenCanvas=this._createHiddenCanvasElement(C),"image"===I.type){const A=await this._createHiddenImageElement(I);if(!A.success)return!1;g=A.hiddenImage}const Q=C.htmlElement;Q instanceof HTMLVideoElement&&Q.paused&&(qi.debug("🎬 Video is paused, starting playback..."),await Q.play());const B=await this._pipelineManager.initialize(C,I,Gi,null,this._vbDetailsNew.tfLite,g,this._vbDetailsNew.hiddenCanvas);qi.debug("Inside getUserMediaSuccess result",B),qi.debug("Pipeline manager active? :%s",this._pipelineManager.isActive()),qi.debug("camera stream live status:%s",A.readyState),B.pipeline.updatePostProcessingConfig(Ri),this._setupPeriodicUpdates(),this._vbDetailsNew.hiddenImage=g,this._vbDetailsNew.sourcePlayback=C;const E=B.canvasRef.captureStream(30);return this._localVBStream=E,{success:!0,vbStream:E}}catch(C){qi.error("Failed to initialize pipeline:%O",C)}}async _createHiddenVideoElement(A){return new Promise(I=>{const g=document.createElement("video");g.autoplay=!0,g.loop=!0,g.controls=!1,g.playsInline=!0,g.muted=!0,g.srcObject=new MediaStream([A]),g.style.cssText="position: fixed; top: 10px; right: 10px; width: 200px; height: 150px; border: 2px solid blue; z-index: 9999; ",document.body.appendChild(g),g.play(),g.onloadeddata=()=>{I({htmlElement:g,width:g.videoWidth,height:g.videoHeight})}})}async _createHiddenVideoElement(A){return new Promise(I=>{const g=document.createElement("video");g.style.display="none",g.autoplay=!0,g.loop=!0,g.controls=!1,g.playsInline=!0,g.muted=!0,g.srcObject=new MediaStream([A]),document.body.appendChild(g);const C=async()=>{try{await g.play()}catch(A){}g.readyState<2||!g.videoWidth||!g.videoHeight?requestAnimationFrame(C):I({htmlElement:g,width:g.videoWidth,height:g.videoHeight})};g.addEventListener("loadedmetadata",C,{once:!0}),C()})}_createHiddenCanvasElement(A){const I=document.createElement("canvas");return I.style.display="none",I.width=A.width,I.height=A.height,document.body.appendChild(I),I}_createHiddenImageElement(A){return new Promise(async I=>{const g=document.createElement("img");if(g.style.display="none",A?.url.includes("http"))try{(await this.testImageCORS(A?.url)).success?(g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})},g.src=A.url):(g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})})}catch(eD){g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})}}else g.crossOrigin="anonymous",document.body.appendChild(g),g.onload=()=>{I({success:!0,hiddenImage:g})},g.src=A.url})}async testImageCORS(A,I=1e4){return new Promise((g,C)=>{const Q=new Image;Q.crossOrigin="anonymous";const B=setTimeout(()=>{Q.src="",C(new Error("CORS_TIMEOUT"))},I);Q.onload=()=>{clearTimeout(B);try{const I=document.createElement("canvas");I.width=Q.width||100,I.height=Q.height||100;const C=I.getContext("2d");C.drawImage(Q,0,0),C.getImageData(0,0,1,1),g({success:!0,url:A,width:Q.naturalWidth,height:Q.naturalHeight,message:"CORS allowed"})}catch(I){C(new Error("CORS_BLOCKED"))}},Q.onerror=A=>{clearTimeout(B),C(new Error("IMAGE_LOAD_FAILED"))},Q.src=A})}_setupPeriodicUpdates(){this._updateInterval&&clearInterval(this._updateInterval),this._updateInterval=setInterval(()=>{if(this._pipelineManager&&this._pipelineManager.isActive()){const A=this._pipelineManager.getState();this._vbDetailsNew.fps=A.fps;const[I,g,C]=A.durations||[0,0,0];this._vbDetailsNew.resizingDuration=I,this._vbDetailsNew.inferenceDuration=g,this._vbDetailsNew.postProcessingDuration=C}},1e3)}cleanup(){try{if(this._localVBStream&&"function"==typeof this._localVBStream.getVideoTracks)try{this._localVBStream.getVideoTracks().forEach(A=>{try{A.stop()}catch(I){}})}catch(A){}try{this._pipelineManager&&"function"==typeof this._pipelineManager.stop&&this._pipelineManager.stop()}catch(A){}if(this._updateInterval){try{clearInterval(this._updateInterval)}catch(A){}this._updateInterval=null}try{if(this._vbDetailsNew?.sourcePlayback?.htmlElement){try{this._vbDetailsNew.sourcePlayback.htmlElement.srcObject=null}catch(A){}try{this._vbDetailsNew.sourcePlayback.htmlElement.remove()}catch(A){}}}catch(A){}try{if(this._vbDetailsNew?.hiddenCanvas)try{this._vbDetailsNew.hiddenCanvas.remove()}catch(A){}}catch(A){}try{if(this._vbDetailsNew?.hiddenImage)try{this._vbDetailsNew.hiddenImage.remove()}catch(A){}}catch(A){}this._localVBStream=null,this._vbDetailsNew&&(this._vbDetailsNew.sourcePlayback=null,this._vbDetailsNew.hiddenCanvas=null,this._vbDetailsNew.hiddenImage=null)}catch(A){}}};class FD extends cg.EventEmitter{static async listDevices(){if(ND)return SD.info("Device list already exists:%O",ND),{success:!0,deviceList:ND};const A=await _E();return A.success?(ND=A.deviceList,{success:!0,deviceList:A.deviceList}):{success:!1,reason:A.reason}}static async changeVB({track:A,details:I}){if(SD.debug("changeVB Received details are:%O",I),SD.debug("changeVB Received track are:%O",A),!I)return SD.debug("VB details not provided. Skipping VB processing."),{success:!1};if(!0===A.active){SD.debug("Track is live, calling initializePipeline",A);const g=A.getVideoTracks()[0],C=await MD.initializePipeline(g,I);return SD.debug("response is :%o",C),C}throw SD.error("Track is not live"),new Error("Track is not live")}static async init({sessionToken:A,roomId:I,peerId:g,roomType:C}={}){if(!A)throw new Error("Session token is required to join the room.");try{let Q;SD.info("session token:%s",A);try{const I=(new TextEncoder).encode("samvyo_tech_321"),{payload:g}=await RD(A,I,{algorithms:["HS256"]});Q=g,SD.info("Decoded token:",Q)}catch(eD){throw SD.error("JWT verification failed:",eD),eD instanceof pi?new Error("Session token has expired"):eD instanceof ui?new Error("Session token not yet active"):new Error("Invalid session token: "+eD.message)}if(!Q||"object"!=typeof Q)throw new Error("Invalid token format");const{data:B,signallingServerUrl:E}=Q;if(!B||!E)throw new Error("Missing required token data");return g||(g=nQ()),I||(I=DQ()),new FD({peerId:g,roomId:I,outputData:{sessionToken:A,innerSessionToken:B,signallingServerUrl:E},roomType:C})}catch(Q){throw SD.error("Failed to initialize:",Q.message),Q}}constructor({peerId:A,roomId:I,outputData:g,roomType:C}){super(),this._closed=!1,this._roomStatus="initialised",this._roomDisplayName=null,this._running=!1,this._cignal=null,this._socket=null,this._sendTransport=null,this._recvTransport=null,this._device=new sg.Device,this._webCamProducer=null,this._micProducer=null,this._shareProducer=null,this._shareAudioProducer=null,this._producers=new Map,this._consumers=new Map,this._peers=new Map,this._data={...g,inputParams:{peerId:A,roomId:I,roomType:C||"conferencing"}},this._micStream=null,this._webCamStream=null,this._webcam={device:null,resolution:"hd"},this._mic={device:null},this._deviceList=ND||null,this._externalVideo=null,this._externalVideoStream=null,this._forceVP8=!1,this._forceH264=!1,this._forceVP9=!1,this._enableWebcamLayers=!0,this._numSimulcastStreams=3,this._enableSharingLayers=!0,this._client=kg.parse(window.navigator.userAgent),this._routerRtpCapabilities=null,this._recordingStartedByMe={},this._cignalConnected=!1,this._reconnectionInitiated=!1,this._restartIceInProgressSendTransport=!1,this._restartIceInProgressRecvTransport=!1,this._activeSpeaker=null,this._speechRecognition=null,this._transcriptStorage=new Map,this._audioContext=null,this._audioAnalyser=null,this._micMonitorStream=null,this._speakingWhileMutedInterval=null,this._speakingThreshold=-50,this._mutedSpeakingDetectionEnabled=!0,this._lastMutedSpeakingNotification=0,this._mutedSpeakingCooldown=3e3,this._audioTroubleShootData={lastDiagnostic:null,deviceTests:{},connectivityStatus:"unknown"},this._audioOutputDevices=[],this._currentSpeakerDevice=null,this._testAudioElements=new Map,this._speakerTestResults=new Map,this._remoteAudioElement=null,this._remoteCaption=null,this._transcriptionRecorder=null,this._transcriptionActive=!1,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,this.initLocal()}get peerId(){return this._peerId}set peerId(A){this._peerId=A}get roomType(){return this._roomType}set roomType(A){this._roomType=A}get closed(){return this._closed}get data(){return this._data}set data(A){throw new Error("Setting the whole data object is not possible!")}get peers(){return this._peers}set peers(A){throw new Error("Setting the whole peers object is not possible!")}get transports(){return{produce:this._sendTransport,consume:this._recvTransport}}set transports(A){throw new Error("Setting of transport is not possible!")}get videoStream(){return this._webCamStream}get audioStream(){return this._micStream}get clientAgent(){return this._client}get activeParameters(){return this._data.inputParams}get deviceList(){return this._deviceList?this._deviceList:{videoDevices:[],audioDevices:[],audioOutputDevices:[]}}set deviceList(A){throw new Error("Setting of deviceList is not possible!")}get currentlyActiveSpeaker(){return this._activeSpeaker}set currentlyActiveSpeaker(A){throw new Error("Setting of currentActivespeaker is not possible!")}get roomDisplayName(){return this._roomDisplayName}set roomDisplayName(A){throw new Error("Setting of roomDisplayName is not possible!")}async initLocal(){const A=sg.detectDevice();SD.debug("The device is:%O",A),await this._initSocket()}async _initSocket(){let A=this;const I=this.data.signallingServerUrl.replace(/^(http|https):\/\//,""),g=`wss://${I}/?sessionToken=${this.data.sessionToken}&roomId=${this.data.inputParams.roomId}&peerId=${this.data.inputParams.peerId}&roomType=${this.data.inputParams.roomType}`;SD.info(`Going to create a new socket! with address: ${I}`),this._socket=new iQ(g,!0),this._listenToSocket(),this._socket.on("notify",({type:A,title:I,message:g})=>{this.emit("notification",{eventType:A,eventText:`${I}: ${g}`,roomId:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId})}),this._socket.on("roomStartedP2p",A=>{SD.info("P2P room successfully started"),this._running=!0}),this._socket.on("userError",I=>{SD.error("User Error happened with message:%O",I),A.emit("notification",{eventType:I.title,eventText:`${I.text}`})}),this._socket.on("validationAlert",A=>{SD.info("Validation alert happened")}),this._socket.on("alreadyActive",({title:A,text:I})=>{this.emit("notification",{eventType:"alreadyActive",eventText:"This peer already has an active connection",roomId:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId})}),this._socket.on("passwordDisabled",()=>{SD.info("password disabled by moderator!"),this.emit("notification",{eventType:"passwordDisabled",eventText:"Password for this room has been disabled by moderator",roomId:this.data.inputParams.roomId})}),this._socket.on("close",({code:A,reason:I})=>{if(SD.info(`socket closed with code ${A}`),4500!==A&&4100!==A){let g=I||"Connection to server closed unexpectedly! Trying to reconnect.";SD.info(`socket close code is${A} with reason ${g}`)}else SD.info("Socket is now closed!"),this.close()}),this._socket.on("connected",async()=>{SD.info("Socket connected"),this.emit("initSuccess")}),this._socket.on("reconnected",async()=>{SD.info("Socket re-connected"),A.pc&&A._sendTransport&&A._recvTransport?roomType===YE.P2P&&A.pc?(SD.info("Socket seems to be reconnected in mid call! RestartIce needed for p2p call."),"failed"!==A.pc.iceConnectionState&&"disconnected"!==A.pc.iceConnectionState||A.restartICE()):(SD.debug("Ice restarts for mediasoup transports for a joined peer"),A._sendTransport&&["failed","disconnected"].includes(A._sendTransport.connectionState)?(SD.debug("Restart ice for sendtransport"),A.restartIce(A._sendTransport.id,"send")):SD.error("Send transport not available!"),A._recvTransport&&["failed","disconnected"].includes(A._recvTransport.connectionState)?(SD.debug("Restart ice for recvtransport"),A.restartIce(A._recvTransport.id,"recv")):SD.error("Recv transport not available!")):(SD.info("Connection getting connected for first time"),this.emit("initSuccess"))}),this._socket.on("defaultJoinStatus",async A=>{SD.info(" Socket defaultjoinstatus:%O",A)})}_sendMessage(A){this._socket.send({usageType:"sdk",...A})}_listenToSocket(){this._socket.on("message",A=>{try{switch("currentlyActiveSpeaker"===A.id||"allStats"===A.id||SD.info("message in Room is:%O",A),A.id){case"chatMessage":this.processChatMessage(A);break;case"customMessage":this.processCustomMessage(A);break;case"existingParticipants":this.onExistingParticipants(A);break;case"newPeerJoin":this.onNewPeer(A);break;case"recordingError":this.handleRecordingErrors(A);break;case"moderatorAuthentication":this.authenticateUser(A);break;case"authenticationRequested":this.authenticationRequested(A);break;case"toggleMyMic":this.toggleMyMic(A);break;case"toggleMyCamera":this.toggleMyCamera(A);break;case"logMeOut":this.logMeOutNew(A);break;case"userAlreadyAuthenticated":this.hideUserAuthenticationDialog(A);break;case"peerLeft":this.peerLeft(A);break;case"recordingStarted":this.setRecordingStatusStarted(A);break;case"recordingStopped":this.setRecordingStatusEnded(A);break;case"startDefaultRecording":this.startRecording(A);break;case"mediaToggled":this.mediaToggled(A);break;case"processingStarted":this.handleProcessingStart(A);break;case"processingCompleted":this.handleProcessingCompletion(A);break;case"processingError":this.handleProcessingError(A);break;case"createTransportResponse":this.handleCreateTransportRequest(A);break;case"connectTransportResponse":this.handleConnectTransportRequest(A);break;case"connectRecvTransportResponse":this.handleConnectRecvTransportRequest(A);break;case"sendTrackResponse":this.handleSendTrackRequest(A);break;case"recvTrackResponse":this.handleRecvTrackRequest(A);break;case"roomClosedByModerator":this.leaveRoomCommon(),this.roomClosed();break;case"currentlyActiveSpeaker":this.setCurrentlyActiveSpeaker(A);break;case"restartIceResponse":this.restartIceResponse(A);break;case"consumerClosed":this.closeConsumer(A);break;case"handRaise":this.handleHandRaise(A);break;case"updateCId":this.updateCId(A);break;case"upgradeParticipant":this.handleUpgradeParticipant(A);break;case"downgradeParticipant":this.handleDowngradeParticipant(A);break;case"switchMicOff":this.handleSwitchMicOff(A);break;case"screenShareLimitReached":this.handleScreenShareLimitReached(A);break;case"upgradeLimitReached":this.handleUpgradeLimitReached(A);break;case"modUpgradeReq":this.handleModUpgradeReq(A);break;case"lockUnlockRoom":this.handleLockUnlockRoom(A);break;case"peersWaiting":this.handlePeersWaiting(A);break;case"remotePeerJoin":this.handleRemotePeerJoin(A);break;case"offer":SD.debug("inside offer"),this.handleOffer(A);break;case"answer":SD.debug("inside answer"),this.handleAnswer(A);break;case"candidate":SD.debug("inside handle candidate"),this.handleCandidate(A.candidate);break;case"p2pRoomClosed":SD.debug("inside p2p room close"),this.leaveRoomNewP2p("leaveAndCloseRoom");break;case"p2pUserLeft":SD.debug("inside p2p user left"),this.userLeftRoom(A);break;case"iceRestart":this.handleIceRestart(A);break;case"iceRestarted":this.handleIceRestartResponse(A);break;case"screenShareP2p":this.handleScreenShareP2p(A);break;case"transcription":this._processTranscriptionMessage(A);break;default:SD.warn("Unrecognized message:%o",A)}}catch(eD){SD.error("listentomessage:%O",eD)}})}joinRoom=async({peerName:A=null,produce:I=!0,produceAudio:g=!0,produceVideo:C=!0,consume:Q=!0,videoResolution:B="hd",forceVp8:E=!1,forceVp9:i=!1,forceH264:D=!1,h264Profile:n="high",forcePCMU:o=!1,forcePCMA:s=!1,forceFPS:w=25,enableWebcamLayers:a=!0,numSimulcastStreams:y=3,autoGainControl:G=!0,echoCancellation:R=!0,noiseSuppression:S=!0,sampleRate:h=44e3,channelCount:N=1,videoBitRates:K=[700,250,75],share:M=!1,shareAudio:F=!1,enableSharingLayers:L=!0,shareBitRates:k=[2500,1250,500],audioDeviceId:J=null,videoDeviceId:U=null,peerType:q="participant",roomType:t=YE.CONFERENCING,authenticationRequired:r=!1,password:c=null,roomDisplayName:H=null,vbdetails:Y,enableTranscription:e=!1}={})=>{SD.info("Going to join room",e),["hd","vga","qvga"].includes(B)||(SD.warn("Invalid video resolution value. setting it to default value of 'hd' "),B="hd"),"boolean"!=typeof I&&(SD.warn("Produe should either be true or false"),I=Boolean(I)),"boolean"!=typeof g&&(SD.warn("ProduceAudio should either be true or false"),g=Boolean(g)),"boolean"!=typeof C&&(SD.warn("ProduceVideo should either be true or false"),C=Boolean(C)),"boolean"!=typeof Q&&(SD.warn("Consume should either be true or false"),Q=Boolean(Q)),"boolean"!=typeof E&&(SD.warn("forceVp8 should either be true or false"),E=Boolean(E)),"boolean"!=typeof i&&(SD.warn("forceVp9 should either be true or false"),i=Boolean(i)),"boolean"!=typeof D&&(SD.warn("forceH264 should either be true or false"),D=Boolean(D)),["high","low"].includes(n.toLowerCase())||(SD.warn("h264Profile should either be 'high' or 'low'"),n="high"),(!Number.isInteger(w)||Number.isInteger(w)&&(w>65||w<5))&&(SD.warn("forceFPS should be a number between 5 to 65, default value is 25 fps."),w=25),"boolean"!=typeof a&&(SD.warn("enableWebcamLayers should either be true or false"),a=Boolean(a)),(!Number.isInteger(y)||Number.isInteger(y)&&(y>3||y<1))&&(SD.warn("numSimulcastStreams should be a number between 1 to 3, default value is 3."),y=3),Array.isArray(K)&&K.length>=1&&K.length<=3&&K.every(A=>Number.isInteger(A)&&A>=75&&A<=800)?SD.debug("videoBitRates values are correct"):(SD.warn("videobitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[700,250,75]'"),K=[700,250,75]),"boolean"!=typeof o&&(SD.warn("forcePCMU should either be true or false"),o=Boolean(o)),"boolean"!=typeof s&&(SD.warn("forcePCMA should either be true or false"),s=Boolean(s)),"boolean"!=typeof G&&(SD.warn("autoGainControl should either be true or false"),G=Boolean(G)),"boolean"!=typeof R&&(SD.warn("echoCancellation should either be true or false"),R=Boolean(R)),"boolean"!=typeof S&&(SD.warn("noiseSuppression should either be true or false"),S=Boolean(S)),(!Number.isInteger(h)||Number.isInteger(h)&&(h>64e3||h<8e3))&&(SD.warn("sampleRate should be a number between 8000 to 64000, default value is 44000 Khz."),h=44e3),(!Number.isInteger(N)||Number.isInteger(N)&&(N>2||N<1))&&(SD.warn("sampleRate should be a number between 1 to 2, default value is 1, which is a mono audio."),N=1),"boolean"!=typeof M&&(SD.warn("share should either be true or false"),M=Boolean(M)),"boolean"!=typeof F&&(SD.warn("shareAudio should either be true or false"),F=Boolean(F)),"boolean"!=typeof L&&(SD.warn("enableSharingLayers should either be true or false"),L=Boolean(L)),Array.isArray(k)&&k.length>=1&&k.length<=3&&k.every(A=>Number.isInteger(A)&&A>=500&&A<=2500)?SD.debug("shareBitRates values are correct"):(SD.warn("sharebitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[2500,1250,500]'"),k=[2500,1250,500]),["moderator","participant","attendee"].includes(q)?SD.debug("peerType is valid:%s",q):(q="participant",SD.debug("peerType is invalid:%s. By default set to: participant",q)),await this.listDevicesInternal(),this._videoResolution=B,this._forceVP8=Boolean(E),this._forceH264=Boolean(D),this._forceVP9=Boolean(i),this._enableWebcamLayers=Boolean(a),this._numSimulcastStreams=y,this._enableSharingLayers=Boolean(L);try{A||(A=ZE()),this.data.inputParams={...this.data.inputParams,peerName:A,produce:I,produceAudio:g,produceVideo:C,consume:Q,videoResolution:B,forceVp8:E,forceVp9:i,forceH264:D,h264Profile:n,forceFPS:w,forcePCMU:o,forcePCMA:s,enableWebcamLayers:a,numSimulcastStreams:y,autoGainControl:G,echoCancellation:R,noiseSuppression:S,sampleRate:h,channelCount:N,videoBitRates:K,share:M,shareAudio:F,enableSharingLayers:L,shareBitRates:k,audioDeviceId:J,videoDeviceId:U,peerType:q,roomType:t,authenticationRequired:r,password:c,roomDisplayName:H,vbdetails:Y,enableTranscription:e},SD.info("input params are:%O",this.data.inputParams);const d={id:"joinRoom",type:"r",peerId:this.data.inputParams.peerId,participantType:"attendee"===q?"viewer":q,roomType:t,roomDisplayName:H||`room-${1e5+Math.round(9e5*Math.random())}`,browser:this._client,name:this.data.inputParams.peerName,room:this.data.inputParams.roomId,authenticationRequired:r,isRoomPassword:!!c,roomPassword:c||null,usageType:"sdk",enableTranscription:e};this._sendMessage(d)}catch(d){return SD.error("Failed to join room:",d.message),{success:!1,reason:d.message}}};authenticateUser=A=>{SD.info("Moderator authentication requested:%O",A),this.emit("moderatorAuthentication",{moderatorName:A.moderatorName,requesterName:A.requesterName,requesterPeerId:A.requesterPeerId,text:A.title})};authenticationRequested=A=>{SD.info("Moderator authentication requested:%O",A),this.emit("authenticationRequested",{requesterName:A.requesterName,requesterPeerId:this.data.inputParams.peerId,text:A.title})};allowRoomJoin=A=>{if(!A)return SD.error("peerId can't be undefined!"),{success:!1,reason:"PeerId can't be undefined"};SD.info("Allow user to join room:%O",A);let I={id:"userAuthenticated",peerId:A,roomName:this.data.inputParams.roomId,moderator:this.data.inputParams.peerId};this._sendMessage(I)};denyRoomJoin=A=>{if(!A)return SD.error("peerId can't be undefined!"),{success:!1,reason:"PeerId can't be undefined"};SD.info("Deny user to join room:%O",A);let I={id:"userDenied",peerId:A,roomName:this.data.inputParams.roomId,moderator:this.data.inputParams.peerId};this._sendMessage(I)};setSpeakingWhileMutedDetection(A=!0){this._mutedSpeakingDetectionEnabled=A,SD.debug("Speaking while muted detection "+(A?"enabled":"disabled"))}setSpeakingThreshold(A=-50){this._speakingThreshold=A,SD.debug(`Speaking threshold set to: ${A}dB`)}async _initializeAudioMonitoring(){if(this._micStream)try{this._audioContext=new AudioContext,this._audioAnalyser=this._audioContext.createAnalyser(),this._audioAnalyser.fftSize=512,this._audioAnalyser.smoothingTimeConstant=.3;const A={audio:{deviceId:this._mic.device?{exact:this._mic.device.deviceId}:void 0,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}};this._micMonitorStream=await navigator.mediaDevices.getUserMedia(A);this._audioContext.createMediaStreamSource(this._micMonitorStream).connect(this._audioAnalyser),SD.debug("Audio monitoring initialized successfully")}catch(A){SD.error("Error initializing audio monitoring:%o",A)}}_getAudioLevel(){if(!this._audioAnalyser)return-1/0;const A=this._audioAnalyser.frequencyBinCount,I=new Uint8Array(A);this._audioAnalyser.getByteFrequencyData(I);let g=0;for(let B=0;B<A;B++)g+=I[B];const C=g/A,Q=20*Math.log10(C/255);return isFinite(Q)?Q:-1/0}_startSpeakingWhileMutedDetection(){this._mutedSpeakingDetectionEnabled&&this._audioAnalyser&&(this._speakingWhileMutedInterval=setInterval(()=>{if(!this._micProducer||!this._micProducer.paused)return;const A=this._getAudioLevel();if(A>this._speakingThreshold){const I=Date.now();I-this._lastMutedSpeakingNotification>this._mutedSpeakingCooldown&&(this._lastMutedSpeakingNotification=I,this.data.inputParams.peerId===this.peerId&&(this.emit("speakingWhileMuted",{peerId:this.data.inputParams.peerId,audioLevel:A,timestamp:I,message:"You appear to be speaking while muted"}),SD.debug(`Speaking while muted detected - Audio level: ${A}dB`)))}},100))}_stopSpeakingWhileMutedDetection(){this._speakingWhileMutedInterval&&(clearInterval(this._speakingWhileMutedInterval),this._speakingWhileMutedInterval=null)}_cleanupAudioMonitoring(){this._stopSpeakingWhileMutedDetection(),this._micMonitorStream&&(this._micMonitorStream.getTracks().forEach(A=>A.stop()),this._micMonitorStream=null),this._audioContext&&"closed"!==this._audioContext.state&&(this._audioContext.close(),this._audioContext=null),this._audioAnalyser=null}async diagnoseAudio(){SD.debug("Starting comprehensive audio diagnostic...");const A={timestamp:Date.now(),browser:this._client,permissions:{},devices:{},connectivity:{},currentSetup:{},recommendations:[]};try{return A.permissions=await this._testAudioPermissions(),A.devices=await this._testAudioDevices(),A.currentSetup=await this._testCurrentMicSetup(),A.connectivity=await this._testWebRTCConnectivity(),A.recommendations=this._generateAudioRecommendations(A),this._audioTroubleShootData.lastDiagnostic=A,this.emit("audioDiagnosticComplete",{peerId:this.data.inputParams.peerId,diagnostic:A}),A}catch(I){return SD.error("Audio diagnostic failed:",I),A.error=I.message,A}}async _testAudioPermissions(){const A={granted:!1,state:"unknown",error:null};try{if(navigator.permissions){const I=await navigator.permissions.query({name:"microphone"});A.state=I.state,A.granted="granted"===I.state}const I=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});A.granted=!0,A.actuallyGranted=!0,I.getTracks().forEach(A=>A.stop())}catch(I){A.error=I.name,A.actuallyGranted=!1,SD.error("Permission test failed:",I)}return A}getSystemHealthStatus(){return{sdk:{roomStatus:this._roomStatus,isConnected:"connected"===this._roomStatus,micActive:!!this._micProducer&&!this._micProducer.closed,micMuted:this._micProducer?.paused,cameraActive:!!this._webcamProducer&&!this._webcamProducer.closed,screenSharing:!!this._shareProducer&&!this._shareProducer.closed},transports:{send:this._sendTransport?{id:this._sendTransport.id,connectionState:this._sendTransport.connectionState,iceState:this._sendTransport.iceState,dtlsState:this._sendTransport.dtlsState}:null,recv:this._recvTransport?{id:this._recvTransport.id,connectionState:this._recvTransport.connectionState,iceState:this._recvTransport.iceState,dtlsState:this._recvTransport.dtlsState}:null},audio:{context:this._audioContext?.state,analyser:!!this._audioAnalyser,currentLevel:this._getAudioLevel(),speaking:this._getAudioLevel()>this._speakingThreshold,monitorStream:!!this._micMonitorStream},streams:{mic:this._micStream?.active,camera:this._webCamStream?.active,micTracks:this._micStream?.getTracks()?.length||0,cameraTracks:this._webCamStream?.getTracks()?.length||0}}}async testNetworkConnectivity(){const A={timestamp:Date.now(),stun:{working:!1,latency:null},turn:{working:!1,latency:null},bandwidth:{upload:null,download:null},packetLoss:null};try{const I=Date.now(),g=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]}),C=(g.createDataChannel("test"),await g.createOffer());await g.setLocalDescription(C),await new Promise(A=>{g.onicecandidate=I=>{I.candidate||A()},setTimeout(A,5e3)}),A.stun.working="failed"!==g.iceConnectionState,A.stun.latency=Date.now()-I,g.close()}catch(I){}return A}async assessAudioQuality(A=5e3){if(!this._micStream)throw new Error("No active microphone stream");const I={duration:A,samples:[],averageLevel:0,peakLevel:-1/0,quietSamples:0,clipSamples:0,quality:"unknown"};try{const g=new AudioContext,C=g.createAnalyser();C.fftSize=1024;g.createMediaStreamSource(this._micStream).connect(C);const Q=C.frequencyBinCount,B=new Uint8Array(Q),E=Date.now(),i=100;return new Promise(D=>{const n=setInterval(()=>{C.getByteFrequencyData(B);let i=0;for(let A=0;A<Q;A++)i+=B[A];const o=i/Q,s=20*Math.log10(o/255);if(isFinite(s)&&(I.samples.push(s),I.peakLevel=Math.max(I.peakLevel,s),s<-70&&I.quietSamples++,s>-3&&I.clipSamples++),Date.now()-E>=A){clearInterval(n),g.close();const A=I.samples.filter(A=>isFinite(A));I.averageLevel=A.reduce((A,I)=>A+I,0)/A.length;const C=I.quietSamples/A.length*100;I.clipSamples/A.length*100>10?I.quality="poor-clipping":C>80?I.quality="poor-quiet":I.averageLevel>-30?I.quality="good":I.averageLevel>-50?I.quality="fair":I.quality="poor-low",D(I)}},i)})}catch(g){throw new Error(`Audio quality assessment failed: ${g.message}`)}}async attemptAutoRemediation(){const A=[],I=this.getSystemHealthStatus();try{"failed"===I.transports.send?.connectionState&&(await this.restartIce(I.transports.send.id,"send"),A.push("Restarted send transport")),"failed"===I.transports.recv?.connectionState&&(await this.restartIce(I.transports.recv.id,"recv"),A.push("Restarted receive transport")),!I.audio.analyser&&this._micStream&&(this._cleanupAudioMonitoring(),await this._initializeAudioMonitoring(),A.push("Restarted audio monitoring")),I.sdk.micActive&&!I.streams.mic&&(await this.disableMic(),await this.enableMic(),A.push("Restarted microphone"));const g=await this.diagnoseAudio();if(g.devices?.working?.length>0){const I=g.currentSetup?.deviceLabel,C=g.devices.working[0];I!==C.label&&(await this.changeAudioInput({deviceId:C.deviceId}),A.push(`Switched to working device: ${C.label}`))}return{success:!0,fixes:A}}catch(g){return{success:!1,error:g.message,fixes:A}}}async getEnhancedDeviceList(){try{const I=await navigator.mediaDevices.enumerateDevices(),g=[];for(const C of I){if("audioinput"!==C.kind)continue;const I={deviceId:C.deviceId,label:C.label,groupId:C.groupId,capabilities:null,testResult:null};try{const A=(await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:C.deviceId}}})).getAudioTracks()[0];I.capabilities=A.getCapabilities(),I.testResult=await this._testSpecificDevice(C.deviceId,1e3),A.stop()}catch(A){I.testResult={working:!1,error:A.message}}g.push(I)}return g}catch(A){throw new Error(`Enhanced device enumeration failed: ${A.message}`)}}async optimizeAudioSettings(){const A=this.getSystemHealthStatus(),I=[];try{const g=await this.assessAudioQuality(3e3);if("poor-clipping"===g.quality?(await this.changeAudioInput({autoGainControl:!1,echoCancellation:!0,noiseSuppression:!0}),I.push("Disabled auto-gain control to prevent clipping")):"poor-quiet"===g.quality&&(await this.changeAudioInput({autoGainControl:!0,echoCancellation:!0,noiseSuppression:!1}),I.push("Enabled auto-gain control for low input levels")),"connected"===A.transports.send?.connectionState){await this._sendTransport.getStats()}return{success:!0,recommendations:I,qualityAssessment:g}}catch(g){return{success:!1,error:g.message,recommendations:I}}}async _testAudioDevices(){const A={available:[],current:null,working:[],failed:[]};try{const g=await navigator.mediaDevices.enumerateDevices();A.available=g.filter(A=>"audioinput"===A.kind).map(A=>({deviceId:A.deviceId,label:A.label,groupId:A.groupId})),A.current=this._mic.device;for(const C of A.available)try{const I=await this._testSpecificDevice(C.deviceId);I.working?A.working.push({...C,audioLevel:I.audioLevel,testDuration:I.duration}):A.failed.push({...C,error:I.error})}catch(I){A.failed.push({...C,error:I.message})}}catch(I){A.error=I.message}return A}async _testSpecificDevice(A,I=2e3){return new Promise(g=>{const C={working:!1,audioLevel:-1/0,duration:I,error:null};let Q=null,B=null,E=null;const i=()=>{Q&&Q.getTracks().forEach(A=>A.stop()),B&&"closed"!==B.state&&B.close()},D=setTimeout(()=>{i(),g(C)},I);navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:A}}}).then(A=>{Q=A,B=new(window.AudioContext||window.webkitAudioContext),E=B.createAnalyser(),E.fftSize=256;B.createMediaStreamSource(Q).connect(E);const n=E.frequencyBinCount,o=new Uint8Array(n),s=setInterval(()=>{E.getByteFrequencyData(o);let A=0;for(let C=0;C<n;C++)A+=o[C];const I=A/n,g=20*Math.log10(I/255);isFinite(g)&&g>C.audioLevel&&(C.audioLevel=g),I>0&&(C.working=!0)},100);setTimeout(()=>{clearInterval(s),clearTimeout(D),i(),g(C)},I-100)}).catch(A=>{clearTimeout(D),C.error=A.message,i(),g(C)})})}async _testCurrentMicSetup(){const A={isActive:!1,isProducing:!1,isMuted:!1,audioLevel:-1/0,deviceLabel:null,streamActive:!1,producerStats:null};try{if(A.isActive=!!this._micProducer,A.isProducing=!(!this._micProducer||this._micProducer.closed),A.isMuted=!(!this._micProducer||!this._micProducer.paused),A.deviceLabel=this._mic.device?.label,A.streamActive=!(!this._micStream||!this._micStream.active),this._micStream){const I=this._micStream.getAudioTracks();I.length>0&&(A.trackEnabled=I[0].enabled,A.trackReadyState=I[0].readyState,A.trackSettings=I[0].getSettings())}if(this._audioAnalyser&&(A.audioLevel=this._getAudioLevel()),this._micProducer&&this._sendTransport)try{const I=await this._sendTransport.getStats();A.producerStats=I}catch(I){A.producerStatsError=I.message}}catch(I){A.error=I.message}return A}async _testWebRTCConnectivity(){const A={sendTransport:null,recvTransport:null,iceConnectionState:null,dtlsState:null,error:null};try{this._sendTransport&&(A.sendTransport={id:this._sendTransport.id,connectionState:this._sendTransport.connectionState,iceState:this._sendTransport.iceState,dtlsState:this._sendTransport.dtlsState}),this._recvTransport&&(A.recvTransport={id:this._recvTransport.id,connectionState:this._recvTransport.connectionState,iceState:this._recvTransport.iceState,dtlsState:this._recvTransport.dtlsState})}catch(I){A.error=I.message}return A}_generateAudioRecommendations(A){const I=[];return A.permissions.granted||I.push({type:"critical",title:"Microphone Permission Required",description:"Please allow microphone access in your browser",action:"Grant microphone permission in browser settings"}),0===A.devices.working.length&&I.push({type:"critical",title:"No Working Audio Devices",description:"No functioning microphone devices detected",action:"Check if microphone is connected and enabled in system settings"}),A.currentSetup.isActive&&!A.currentSetup.streamActive&&I.push({type:"warning",title:"Current Microphone Not Working",description:"The selected microphone device appears to be inactive",action:"Try switching to a different microphone device"}),"failed"===A.connectivity.sendTransport?.connectionState&&I.push({type:"critical",title:"Connection Failed",description:"Unable to establish audio connection to server",action:"Check internet connection and try rejoining the room"}),A.currentSetup.audioLevel<-60&&I.push({type:"info",title:"Low Audio Level",description:"Your microphone level appears to be very low",action:"Check microphone volume in system settings or move closer to microphone"}),I}async quickAudioTest(){const A={working:!1,issues:[],timestamp:Date.now()};try{if(!this._micProducer)return A.issues.push("Microphone not active"),A;if(this._micProducer.closed)return A.issues.push("Microphone producer is closed"),A;if(!this._micStream||!this._micStream.active)return A.issues.push("Microphone stream is not active"),A;const I=this._micStream.getAudioTracks();if(0===I.length)return A.issues.push("No audio tracks found"),A;if("live"!==I[0].readyState)return A.issues.push("Audio track is not live"),A;if("connected"!==this._sendTransport.connectionState)return A.issues.push(`Send transport not connected: ${this._sendTransport.connectionState}`),A;A.working=!0}catch(I){A.issues.push(`Test error: ${I.message}`)}return this.emit("quickAudioTestComplete",{peerId:this.data.inputParams.peerId,result:A}),A}async listAudioOutputDevices(){try{if(this._deviceList&&this._deviceList.audioOutputDevices)return SD.debug("Using cached audio output devices:",this._deviceList.audioOutputDevices),{success:!0,devices:this._deviceList.audioOutputDevices};const A=await navigator.mediaDevices.enumerateDevices();return this._audioOutputDevices=A.filter(A=>"audiooutput"===A.kind),SD.debug("Found audio output devices:",this._audioOutputDevices),{success:!0,devices:this._audioOutputDevices.map(A=>({deviceId:A.deviceId,label:A.label||`Speaker ${A.deviceId.slice(-4)}`,groupId:A.groupId}))}}catch(A){return SD.error("Failed to enumerate audio output devices:",A),{success:!1,error:A.message}}}async testSpeakerDevice(A,I={}){SD.debug("Testing speaker device",A);const{testDuration:g=3e3,testFrequencies:C=[440,1e3,2e3],volume:Q=.3,requireUserConfirmation:B=!0}=I,E=`speaker-test-${A}-${Date.now()}`;try{if(!HTMLAudioElement.prototype.setSinkId)throw new Error("setSinkId is not supported in this browser");const I={deviceId:A,testId:E,timestamp:Date.now(),success:!1,frequencies:[],volume:Q,duration:g,userConfirmed:!1,error:null},i=new Audio;i.volume=Q,i.loop=!1,await i.setSinkId(A),I.setSinkId=!0,this._testAudioElements.set(E,i);for(const A of C){const Q=await this._playTestTone(i,A,g/C.length);I.frequencies.push(Q)}if(B){const g=await this._requestUserConfirmation(A,I);I.userConfirmed=g,I.success=g}else I.success=I.frequencies.every(A=>A.played);return this._speakerTestResults.set(A,I),this.emit("speakerTestComplete",{deviceId:A,testResult:I}),{success:!0,testResult:I}}catch(i){SD.error(`Speaker test failed for device ${A}:`,i);const I={deviceId:A,testId:E,timestamp:Date.now(),success:!1,error:i.message};return this._speakerTestResults.set(A,I),this.emit("speakerTestComplete",{deviceId:A,testResult:I}),{success:!1,error:i.message,testResult:I}}finally{this._cleanupTestAudio(E)}}async _playTestTone(A,I,g){return new Promise((C,Q)=>{try{const Q=new window.AudioContext,B=Q.createOscillator(),E=Q.createGain(),i=Q.createMediaStreamDestination();B.connect(E),E.connect(i),B.frequency.setValueAtTime(I,Q.currentTime),B.type="sine",E.gain.setValueAtTime(0,Q.currentTime),E.gain.linearRampToValueAtTime(.1,Q.currentTime+.1),E.gain.linearRampToValueAtTime(.1,Q.currentTime+g/1e3-.1),E.gain.linearRampToValueAtTime(0,Q.currentTime+g/1e3),A.srcObject=i.stream,B.start(),B.stop(Q.currentTime+g/1e3);const D=A.play();void 0!==D&&D.then(()=>{setTimeout(()=>{B.disconnect(),E.disconnect(),Q.close(),C({frequency:I,duration:g,played:!0,timestamp:Date.now()})},g)}).catch(A=>{Q.close(),C({frequency:I,duration:g,played:!1,error:A.message,timestamp:Date.now()})})}catch(B){Q(B)}})}async _requestUserConfirmation(A,I){return new Promise(g=>{this.emit("speakerTestConfirmationRequired",{deviceId:A,testResult:I,onConfirm:A=>g(A)}),setTimeout(()=>g(!1),1e4)})}async testCurrentSpeakerOutput(){try{const I={timestamp:Date.now(),currentDevice:this._currentSpeakerDevice,remoteAudioPresent:!1,audioElementFound:!1,volumeLevel:0,success:!1},g=document.querySelectorAll("audio"),C=document.querySelectorAll("video");let Q=[];if(g.forEach(A=>{A.srcObject&&A.srcObject.getAudioTracks().length>0&&Q.push(A)}),C.forEach(A=>{A.srcObject&&A.srcObject.getAudioTracks().length>0&&Q.push(A)}),I.audioElementFound=Q.length>0,I.elementsCount=Q.length,Q.length>0){for(const g of Q)try{if(g.srcObject){const A=new AudioContext,C=A.createMediaStreamSource(g.srcObject),Q=A.createAnalyser();C.connect(Q),Q.fftSize=256;const B=Q.frequencyBinCount,E=new Uint8Array(B);Q.getByteFrequencyData(E);const i=E.reduce((A,I)=>A+I,0)/B;I.volumeLevel=Math.max(I.volumeLevel,i),I.remoteAudioPresent=i>0,A.close()}}catch(A){SD.debug("Could not analyze remote audio element:",A)}I.success=I.remoteAudioPresent}return this.emit("currentSpeakerTestComplete",I),{success:!0,testResult:I}}catch(A){return SD.error("Current speaker test failed:",A),{success:!1,error:A.message}}}async diagnoseSpeakers(){SD.debug("Starting comprehensive speaker diagnostic");const A={timestamp:Date.now(),browser:this._client,support:{},devices:{},currentOutput:{},remoteAudio:{},recommendations:[]};try{A.support={setSinkId:!!HTMLAudioElement.prototype.setSinkId,enumerateDevices:!!navigator.mediaDevices?.enumerateDevices,audioContext:!!window.AudioContext};const I=await this.listAudioOutputDevices();A.devices={available:I.devices||[],count:I.devices?.length||0,hasDefault:I.devices?.some(A=>"default"===A.deviceId)||!1};const g=await this.testCurrentSpeakerOutput();return A.currentOutput=g.testResult,A.remoteAudio=this._analyzeRemoteAudioSetup(),A.recommendations=this._generateSpeakerRecommendations(A),this.emit("speakerDiagnosticComplete",{diagnostic:A}),A}catch(I){return SD.error("Speaker diagnostic failed:",I),A.error=I.message,A}}_analyzeRemoteAudioSetup(){const A={consumers:0,activeStreams:0,audioElements:0,videoElements:0,totalTracks:0};try{this._consumers&&this._consumers.forEach(I=>{I&&"audio"===I.kind&&!I.closed&&A.consumers++});const I=document.querySelectorAll("audio"),g=document.querySelectorAll("video");I.forEach(I=>{A.audioElements++,I.srcObject&&I.srcObject.getAudioTracks().length>0&&(A.activeStreams++,A.totalTracks+=I.srcObject.getAudioTracks().length)}),g.forEach(I=>{A.videoElements++,I.srcObject&&I.srcObject.getAudioTracks().length>0&&(A.activeStreams++,A.totalTracks+=I.srcObject.getAudioTracks().length)}),0===A.activeStreams&&0===A.totalTracks&&A.consumers>0&&(A.activeStreams=A.consumers,A.totalTracks=A.consumers)}catch(I){SD.error("Remote audio analysis failed:",I),A.error=I.message}return A}_generateSpeakerRecommendations(A){const I=[];return A.support.setSinkId||I.push({type:"critical",title:"Audio Output Selection Not Supported",description:"Your browser does not support changing audio output devices",actions:["Use Chrome, Edge, or Firefox for audio output selection","Change system default audio device instead","Consider using a different browser"]}),0===A.devices.count&&I.push({type:"critical",title:"No Audio Output Devices Found",description:"No speakers or headphones detected",actions:["Check if speakers/headphones are connected","Verify audio drivers are installed","Try refreshing the page after connecting devices"]}),0===A.remoteAudio.consumers&&0===A.remoteAudio.activeStreams&&I.push({type:"warning",title:"No Remote Audio Detected",description:"Not receiving audio from other participants",actions:["Ask other participants to unmute their microphones","Check if you have muted remote participants","Verify your internet connection"]}),!A.currentOutput.success&&A.currentOutput.audioElementFound&&I.push({type:"warning",title:"Audio Output Issues",description:"Remote audio present but may not be playing correctly",actions:["Check system volume levels","Try switching to a different audio output device","Verify the selected output device is working"]}),0===I.length&&I.push({type:"success",title:"Audio Output System Healthy",description:"Speaker setup appears to be working correctly",actions:["Your audio output is configured properly","Run individual device tests if experiencing issues"]}),I}async progressiveTestAllSpeakers(A={}){SD.debug("Progressive speaker test started");const{testDuration:I=2e3,requireConfirmation:g=!0,volume:C=.2}=A;try{const A=await this.listAudioOutputDevices();if(!A.success)throw new Error("Could not enumerate audio devices");const Q=[];let B=0;this.emit("progressiveSpeakerTestStarted",{totalDevices:A.devices.length,testDuration:I,requireConfirmation:g});for(const E of A.devices){B++,this.emit("progressiveSpeakerTestProgress",{currentIndex:B,totalDevices:A.devices.length,currentDevice:E,progress:B/A.devices.length*100});const i=await this.testSpeakerDevice(E.deviceId,{testDuration:I,volume:C,requireUserConfirmation:g,testFrequencies:[1e3]});Q.push({device:E,...i}),await new Promise(A=>setTimeout(A,500))}return this.emit("progressiveSpeakerTestComplete",{results:Q,workingDevices:Q.filter(A=>A.success),failedDevices:Q.filter(A=>!A.success)}),{success:!0,results:Q,summary:{total:Q.length,working:Q.filter(A=>A.success).length,failed:Q.filter(A=>!A.success).length}}}catch(Q){return SD.error("Progressive speaker test failed:",Q),{success:!1,error:Q.message}}}_cleanupTestAudio(A){if(SD.debug("Cleaning up test audio"),this._testAudioElements.has(A)){const g=this._testAudioElements.get(A);try{g.pause(),g.srcObject=null,g.src=""}catch(I){SD.debug("Error cleaning up test audio:",I)}this._testAudioElements.delete(A)}}getCurrentSpeakerDevice(){return SD.debug("Getting current speaker device"),this._currentSpeakerDevice}async meetingSafeSpeakerTest(A){return SD.debug("Meeting safe speaker test started"),this.testSpeakerDevice(A,{testDuration:1500,testFrequencies:[800],volume:.1,requireUserConfirmation:!0})}hideUserAuthenticationDialog=A=>{SD.debug("authentication already done message:%o",A),this.emit("moderatorAuthStatus",{requesterId:A.requesterId,moderatorActed:A.peerId})};onNewPeer(A){const{peerId:I,displayName:g,participantType:C}=A;this._peers.set(I,{displayName:g,participantType:C,consumers:[]}),this.emit("newPeer",{peerId:I,peerName:g,type:this.data.inputParams.peerId===I?"local":"remote",peerRole:C})}async onExistingParticipants(A){if(SD.debug("Onexisting participant message:%O",A),this._routerRtpCapabilities=A.routerRtpCapabilities,this._roomStatus="connected",this._roomDisplayName=A.roomDisplayName,this._running=!0,this._socket.updateRoomJoinStatus(!0),this.emit("newPeer",{peerId:this.data.inputParams.peerId,peerName:this.data.inputParams.peerName,type:"local",peerRole:this.data.inputParams.peerType,screenSharing:A.screenSharing,userSettings:A.userSettings,participantType:A.participantType,stageModeSettings:A.stageMode}),this.data.inputParams.produce?await this._createSendTransport():SD.debug("Produce is false!"),this.data.inputParams.consume){await this._createRecvTransport();let I=this;A.peers&&A.peers.length>0&&A.peers.forEach(A=>{I.emit("newPeer",{peerId:A.peerId,peerName:A.name,type:"remote",peerRole:A.participantType})})}else SD.debug("Consume is false!")}sendCustomMessage=(A,I="general",g=null,C,Q,B={})=>{const E={id:"customMessage",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,data:A,type:I,recieverPeerId:g,senderType:C,messageType:Q,customData:B};SD.debug("Room sendCustomMessage",E),this._sendMessage(E)};setCaptionPreference(A){try{const I={type:"captions_pref",show:!!A};return SD.debug("Room setCaptionPreference",I),this.sendCustomMessage(JSON.stringify(I),"custom",null,"participant","preference"),{success:!0}}catch(I){return SD.error("Failed to send caption preference",I),{success:!1,reason:I?.message}}}processCustomMessage=A=>{SD.debug("Room processCustomMessage",A),this.emit("customMessage",A)};updateCId=A=>{SD.debug("Received updateCId message",A),A.targetPeerId!==this.data.inputParams.peerId&&A.targetPeerId||this.emit("updateCId",{message:A,cId:A.cId,peerId:this.data.inputParams.peerId,isMyCId:A.targetPeerId===this.data.inputParams.peerId})};setCurrentlyActiveSpeaker(A){const{peerId:I,volume:g}=A.activeSpeaker;this._activeSpeaker=A.activeSpeaker,this.emit("activeSpeaker",{peerId:I,volume:g})}_createSendTransport=async()=>{SD.debug("Room _createSendTransport");try{this._device.loaded||(SD.debug("Room _createSendTransport","Going to load device with routerrtpcapabilities"),await this._device.load({routerRtpCapabilities:this._routerRtpCapabilities}));let A="send";this._sendTransport||this._sendMessage({id:"createTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,direction:A})}catch(eD){SD.error("Room _createSendTransport",eD)}};_createRecvTransport=async()=>{this._device.loaded||(SD.debug("loading device for creating recv transport"),await this._device.load({routerRtpCapabilities:this._routerRtpCapabilities}));this._recvTransport||(SD.debug("receive transport created"),this._sendMessage({id:"createTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,direction:"recv"}))};handleCreateTransportRequest=async A=>{SD.debug("Room handleCreateTransportRequest():%O",A);let I,{transportOptions:g,direction:C}=A;try{if("recv"===C)I=await this._device.createRecvTransport(g),SD.debug("Room",`handleCreateTransportRequest() recv transport created ${I.id}`),this._recvTransport=I,this.handleRecvTransportListeners();else{if("send"!==C)throw new Error(`bad transport 'direction': ${C}`);I=await this._device.createSendTransport(g),SD.debug("Room",`handleCreateTransportRequest() send transport created [id:%s]${I.id}`),this._sendTransport=I,this.handleSendTransportListeners(),this.produceMedia()}}catch(Q){SD.error("Room handleCreateTransportRequest() failed to create transport [error:%o]",Q)}};handleSendTransportListeners=()=>{this._sendTransport.on("connect",this.handleTransportConnectEvent),this._sendTransport.on("produce",this.handleTransportProduceEvent);let A=this;this._sendTransport.on("connectionstatechange",async I=>{if(SD.debug(`ConferenceRoom sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"disconnected"===I)setTimeout(async()=>{if("disconnected"===I)if(SD.debug("Connection state for Send Transport is:%s even after 5 seconds",I),SD.warn(`sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"connected"===A._socket.wsManager.connectionState)A.restartIce(A._sendTransport.id,"send");else{for(;"connected"!==A._socket.wsManager.connectionState;)SD.debug(`socket not yet ready with state- ${A._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._sendTransport.id,"send")}},5e3);else if("failed"===I)if(SD.warn(`sendTransport connectionState ${I} & socketconnection state ${this._socket.wsManager.connectionState}`),"connected"===A._socket.wsManager.connectionState)A.restartIce(A._sendTransport.id,"send");else{for(;"connected"!==A._socket.wsManager.connectionState;)SD.debug(`handleSendTransportListeners() | socket not yet ready with state- ${A._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._sendTransport.id,"send")}SD.debug("ConferenceRoom",`send transport connection state change [state:%s]${I}`)})};handleTransportConnectEvent=({dtlsParameters:A},I,g)=>{try{const g=A=>{SD.debug("connect-transport action"),I(),KD.remove("connectTransport")};KD.push("connectTransport",g);let C={id:"connectTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,transportId:this._sendTransport.id,dtlsParameters:A,direction:"send"};this._sendMessage(C)}catch(C){SD.error("handleTransportConnectEvent() failed [error:%o]",C),g(C)}};handleTransportProduceEvent=({kind:A,rtpParameters:I,appData:g},C,Q)=>{try{const Q=A=>{SD.debug("handleTransportProduceEvent callback [data:%o]",A),C({id:A.producerId}),KD.remove("produce")};KD.push("produce",Q);let B="cam-audio"===g.mediaTag&&void 0!==this.data.inputParams.audioStatus&&!this.data.inputParams.audioStatus;SD.debug(`handleTransportProduceEvent() | pause status->${B}`);let E={id:"sendTrack",transportId:this._sendTransport.id,peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,kind:A,rtpParameters:I,paused:B,appData:g,clientOs:this._client.os.name,browser:this._client.browser};this._sendMessage(E)}catch(B){SD.error("handleTransportProduceEvent() failed [error:%o]",B),Q(B)}};produceMedia=async()=>{this.data.inputParams.produce?(this.data.inputParams.produceAudio?this.enableMic({deviceId:this.data.inputParams.audioDeviceId?this.data.inputParams.audioDeviceId:null}):SD.debug("No need to produce audio!"),this._device.canProduce("video")&&(this.data.inputParams.produceVideo?(SD.debug("going to enable cam with vbdetails",this.data.inputParams.vbdetails),this.enableCam({deviceId:this.data.inputParams.videoDeviceId?this.data.inputParams.videoDeviceId:null,vbdetails:this.data.inputParams.vbdetails})):SD.debug("No need to produce video!"),this.data.inputParams.share&&this.enableShare({shareAudio:this.data.inputParams.shareAudio,enableSharingLayers:this._enableSharingLayers,shareBitRates:this.data.inputParams.shareBitRates}))):SD.warn("produce is false!")};handleRecvTransportListeners=async()=>{this._recvTransport.on("connect",this.handleRecvTransportConnectEvent);let A=this;this._recvTransport.on("connectionstatechange",async I=>{if("disconnected"===I)setTimeout(async()=>{if("disconnected"===I)if(SD.warn("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState),"connected"===this._socket.wsManager.connectionState)A.restartIce(A._recvTransport.id,"recv");else{for(;"connected"!==this._socket.wsManager.connectionState;)SD.debug(`handleRecvTransportListeners() | socket not yet ready with state- ${this._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._recvTransport.id,"recv")}},5e3);else if("failed"===I)if(SD.warn("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState),"connected"===this._socket.wsManager.connectionState)A.restartIce(A._recvTransport.id,"recv");else{for(;"connected"!==this._socket.wsManager.connectionState;)SD.debug(`handleRecvTransportListeners() | socket not yet ready with state- ${this._socket.wsManager.connectionState}`),await Qi(1e3);"connected"===this._roomStatus&&A.restartIce(A._recvTransport.id,"recv")}else SD.debug("Connection state for Recv Transport is:%s even after 5 seconds:%s, socket state",I,this._socket.wsManager.connectionState)});let I={id:"transportsAvailable",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,rtpCapabilities:this._device.rtpCapabilities};this._sendMessage(I)};handleRecvTransportConnectEvent=({dtlsParameters:A},I,g)=>{try{const g=A=>{SD.debug("ConferenceRoom","connect-recv-transport action"),I(),KD.remove("connectRecvTransport")};KD.push("connectRecvTransport",g);let C={id:"connectTransport",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,transportId:this._recvTransport.id,dtlsParameters:A,direction:"recv"};this._sendMessage(C)}catch(C){SD.error("handleTransportConnectEvent() failed [error:%o]",C),g(C)}};handleRecvTrackRequest=async A=>{if(SD.debug("Room handleRecvTrackRequest",A),!this.data.inputParams.consume)return void SD.warn("I do not want to consume");let{senderPeerId:I,mediaTag:g,sender:C,audioStatus:Q,videoStatus:B,senderParticipantType:E,type:i,producerPaused:D,...n}=A;SD.debug("New consumer created",n),n.id=n.consumerId,delete n.consumerId,SD.debug("ConferenceRoom",`senderPeerId is ->${I}`);let o=await this._recvTransport.consume({...n,streamId:`${I}-${"screen-video"===g||"screen-audio"===g?"share":"mic-webcam"}`,appData:{peerId:I,mediaTag:g}});for(;this._recvTransport&&"connected"!==this._recvTransport.connectionState;)SD.debug(`recv transport connstate${this._recvTransport.connectionState}`),await Qi(100);this._consumers.set(o.id,o),o.on("transportclose",()=>{this._consumers.delete(o.id)});const{spatialLayers:s,temporalLayers:w}=sg.parseScalabilityMode(o.rtpParameters.encodings[0].scalabilityMode),a=this._peers.get(this.data.inputParams.peerId);SD.debug(`Consumer created for sender peerId ${I} for kind ${o.kind} for receiver peerId ${this.data.inputParams.peerId}`),SD.info("The old peer data is :%O",a),a?(a["screen-video"===g||"screen-audio"===g?`ss${o.kind}`:o.kind]={consumerId:o.id,type:i,locallyPaused:!1,remotelyPaused:D,rtpParameters:o.rtpParameters,spatialLayers:s,temporalLayers:w,preferredSpatialLayer:s-1,preferredTemporalLayer:w-1,priority:1,codec:o.rtpParameters.codecs[0].mimeType.split("/")[1],track:o.track,share:"screen-video"===g||"screen-audio"===g},SD.info("The new peer data is :%O",a),this._peers.set(this.data.inputParams.peerId,a)):(SD.info("Peer not found!"),this._peers.set(this.data.inputParams.peerId,{["screen-video"===g||"screen-audio"===g?`ss${o.kind}`:o.kind]:{consumerId:o.id,type:i,locallyPaused:!1,remotelyPaused:D,rtpParameters:o.rtpParameters,spatialLayers:s,temporalLayers:w,preferredSpatialLayer:s-1,preferredTemporalLayer:w-1,priority:1,codec:o.rtpParameters.codecs[0].mimeType.split("/")[1],track:o.track,share:"screen-video"===g||"screen-audio"===g}})),await this.resumeConsumer(o),SD.debug("Going to emit mic start / videostart"),"audio"===o.kind?"screen-audio"===g?this.emit("ssAudioStart",{peerId:I,audioTrack:o.track,type:"remote"}):this.emit("micStart",{peerId:I,audioTrack:o.track,type:"remote"}):"video"===o.kind&&("screen-video"===g?this.emit("ssVideoStart",{peerId:I,videoTrack:o.track,type:"remote"}):this.emit("videoStart",{peerId:I,videoTrack:o.track,type:"remote"}))};resumeConsumer=async A=>{if(A){SD.debug("resume consumer",A.appData.peerId,A.appData.mediaTag);try{let I={id:"resumeConsumer",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,consumerId:A.id};this._sendMessage(I),await A.resume()}catch(I){SD.error("resumeConsumer error",I)}}};handleConnectTransportRequest=async A=>{SD.debug("handleTransportConnectRequest()");try{const I=KD.get("connectTransport");if(!I)throw new Error("transport-connect action was not found");await I(A)}catch(I){SD.error("handleTransportConnectRequest() failed [error:%o]",I)}};handleConnectRecvTransportRequest=async A=>{SD.debug("handleTransportConnectRequest()");try{const I=KD.get("connectRecvTransport");if(!I)throw new Error("recv transport-connect action was not found");await I(A)}catch(I){SD.error("handleRecvTransportConnectRequest() failed [error:%o]",I)}};handleSendTrackRequest=async A=>{SD.debug("ConferenceRoom","handleProduceRequest()");try{const I=KD.get("produce");if(!I)throw new Error("produce action was not found");await I(A)}catch(I){SD.error("handleProduceRequest() failed [error:%o]",I)}};mediaToggled=A=>{switch(SD.debug("Media Toggled message:%O",A),A.type){case"video":SD.debug(`mediaToggled() | inside case video${A.videoStatus}`);break;case"audio":SD.debug(`mediaToggled() | inside case audio${A.videoStatus}`),A.audioStatus?this.emit("peerUnMuted",{peerId:A.peerId,type:"remote"}):this.emit("peerMuted",{peerId:A.peerId,type:"remote"})}};closeConsumer=A=>{let{consumerId:I}=A;const g=this._consumers.get(I);if(!g)return void SD.warn("Consumer with id not found!:%s",I);const{peerId:C,mediaTag:Q}=g.appData;SD.debug("Consumer closed for consumerId:%s, type:%s, appData:%o",I,g?.kind,g.appData);let B="screen-audio"===Q||"screen-video"===Q?`ss${g.kind}`:g.kind;g.close(),this._consumers.delete(I);let E=this._peers.get(this.data.inputParams.peerId);SD.debug("Peer data before deletion:%O",E),E[B]&&E[B].consumerId===I&&delete E[B],SD.debug("Peer data after deletion:%O",E),this._peers.set(this.data.inputParams.peerId,E),"audio"===g?.kind?(SD.debug("Going to emit micEnd, consumer closed for audio"),"screen-audio"===Q?this.emit("ssAudioStop",{peerId:C,track:null,type:"remote"}):this.emit("micEnd",{peerId:C,track:null,type:"remote"})):"video"===g?.kind&&(SD.debug("Going to emit videoEnd, consumer closed for video"),"screen-video"===Q?this.emit("ssVideoStop",{peerId:C,track:null,type:"remote"}):this.emit("videoEnd",{peerId:C,track:null,type:"remote"}))};peerLeft=A=>{SD.debug("Peer Left message is:%o",A);let{peerId:I}=A;this._peers.delete(I),this.emit("peerLeft",{peerId:I})};roomClosed=()=>{SD.info("room closed by Moderator"),this._peers=null,this.emit("roomClosed",{roomId:this.data.inputParams.roomId})};close(){this._closed||(this._closed=!0,this._socket=null,this.data.inputParams={},SD.info("Room close()"),this._sendTransport&&this._sendTransport.close(),this._recvTransport&&this._recvTransport.close(),this._roomStatus="closed",this._running=!1)}async leaveRoom(){SD.debug("Leave room is called!!"),"connected"===this._roomStatus?(this._sendMessage({id:"leaveRoomNew",peerId:this.data.inputParams.peerId,roomLeaveType:"client"}),await this.leaveRoomCommon()):SD.error("The room state is:%s",this._roomStatus)}async closeRoom(){"connected"===this._roomStatus?(this._sendMessage({id:"leaveAndCloseRoom",peerId:this.data.inputParams.peerId,roomCloseType:"client"}),await this.leaveRoomCommon()):SD.error("The room state is:%s",this._roomStatus)}leaveRoomCommon=async()=>{try{SD.debug("Starting comprehensive room leave cleanup...");try{this._cleanupAudioMonitoring(),this._stopSpeakingWhileMutedDetection(),this._stopAutoAudioStreaming(),this._transcriptionActive&&this.stopTranscription(),MD&&"function"==typeof MD.cleanup&&MD.cleanup()}catch(A){}const C=new Set;this._webcamProducer?.track&&C.add(this._webcamProducer.track),this._micProducer?.track&&C.add(this._micProducer.track),this._shareProducer?.track&&C.add(this._shareProducer.track),this._shareAudioProducer?.track&&C.add(this._shareAudioProducer.track),this._producers&&this._producers.size>0&&this._producers.forEach(A=>{A?.track&&C.add(A.track)}),this._webCamStream&&this._webCamStream.getTracks().forEach(A=>C.add(A)),this._micStream&&this._micStream.getTracks().forEach(A=>C.add(A));try{const A=MD?.getVBStream?.()||MD?._localVBStream;A&&"function"==typeof A.getTracks&&A.getTracks().forEach(A=>C.add(A))}catch(A){}const Q=[];document.querySelectorAll("video, audio").forEach(A=>{if(A.srcObject&&"function"==typeof A.srcObject.getTracks){A.srcObject.getTracks().forEach(A=>C.add(A)),Q.push({element:A,stream:A.srcObject})}}),SD.debug(`Found ${C.size} total tracks to stop`);let B=0;for(const A of C)try{A&&"live"===A.readyState&&"function"==typeof A.stop&&(A.stop(),B++,SD.debug(`Stopped ${A.kind} track: ${A.label||A.id}`))}catch(I){SD.warn("Error stopping track:",I)}if(SD.debug(`Stopped ${B} tracks`),this._sendTransport){try{this._sendTransport.close()}catch(A){}this._sendTransport=null}if(this._recvTransport){try{this._recvTransport.close()}catch(A){}this._recvTransport=null}this._webcamProducer=null,this._micProducer=null,this._shareProducer=null,this._shareAudioProducer=null,this._webCamStream=null,this._micStream=null,this._producers&&this._producers.clear(),this._consumers&&this._consumers.clear(),this._roomStatus="closed",this._running=!1,this._routerRtpCapabilities=null,await new Promise(A=>setTimeout(A,100));let E=0;document.querySelectorAll("video, audio").forEach(A=>{try{A.srcObject&&(A.srcObject=null,"function"==typeof A.pause&&A.pause(),"function"==typeof A.load&&A.load(),E++,SD.debug(`Force cleared ${A.nodeName} element`))}catch(I){SD.warn("Error clearing element:",I)}}),SD.debug(`Cleared ${E} DOM elements`);try{C.forEach(A=>{A&&"function"==typeof A.removeEventListener&&(A.removeEventListener("ended",()=>{}),A.removeEventListener("mute",()=>{}),A.removeEventListener("unmute",()=>{}))})}catch(A){}if(window.gc&&"function"==typeof window.gc)try{window.gc()}catch(A){}await new Promise(A=>setTimeout(A,200));try{const A=await this.reportActiveMediaUse();SD.debug("Final media usage report:",A);const I=[],g=A.dom.mediaElements.filter(A=>A.hasSrcObject&&A.tracks.length>0);g.forEach(A=>{A.tracks.forEach(g=>{"live"===g.readyState&&I.push({kind:g.kind,label:g.label,id:g.id,element:A.nodeName})})}),(I.length>0||g.length>0)&&(SD.warn("WARNING: Media elements or live tracks still detected after cleanup:",{liveTracks:I,elementsWithTracks:g.length}),await this.emergencyTrackCleanup())}catch(g){SD.error("Failed to generate final media usage report:",g)}}catch(I){SD.error("Error during room leave cleanup:",I),await this.emergencyTrackCleanup()}};emergencyTrackCleanup=async()=>{SD.debug("Performing emergency track cleanup...");try{const A=[];document.querySelectorAll("video, audio").forEach(I=>{if(I.srcObject&&"function"==typeof I.srcObject.getTracks){A.push(...I.srcObject.getTracks()),I.srcObject=null,"function"==typeof I.pause&&I.pause(),"function"==typeof I.load&&I.load();try{I.src=""}catch(g){}}}),A.forEach(A=>{try{"live"===A.readyState&&(A.stop(),SD.debug(`Emergency stopped ${A.kind}: ${A.label||A.id}`))}catch(I){}}),SD.debug(`Emergency cleanup completed - stopped ${A.length} tracks`),await new Promise(A=>setTimeout(A,300))}catch(A){SD.error("Emergency cleanup failed:",A)}};reportActiveMediaUse=async(A=!1)=>{const I={sdk:{micStreamTracks:[],camStreamTracks:[],vbStreamTracks:[],shareTracks:[],producers:[],consumers:[]},dom:{mediaElements:[]},timestamp:Date.now()},g=A=>{try{return{kind:A?.kind,enabled:A?.enabled,readyState:A?.readyState,label:A?.label,id:A?.id,muted:A?.muted}}catch(I){return{error:!0}}};try{this._micStream&&"function"==typeof this._micStream.getTracks&&(I.sdk.micStreamTracks=this._micStream.getTracks().map(g))}catch(Q){}try{this._webCamStream&&"function"==typeof this._webCamStream.getTracks&&(I.sdk.camStreamTracks=this._webCamStream.getTracks().map(g))}catch(Q){}try{const A=MD?.getVBStream?.()||MD?._localVBStream;A&&"function"==typeof A.getTracks&&(I.sdk.vbStreamTracks=A.getTracks().map(g))}catch(Q){}try{this._shareProducer?.track&&I.sdk.shareTracks.push(g(this._shareProducer.track)),this._shareAudioProducer?.track&&I.sdk.shareTracks.push(g(this._shareAudioProducer.track))}catch(Q){}try{this._producers&&this._producers.size>0&&this._producers.forEach((A,C)=>{I.sdk.producers.push({key:C,track:A?.track?g(A.track):null,id:A?.id,paused:A?.paused})})}catch(Q){}try{this._consumers&&this._consumers.size>0&&this._consumers.forEach((A,C)=>{I.sdk.consumers.push({key:C,track:A?.track?g(A.track):null,id:A?.id,paused:A?.paused})})}catch(Q){}try{const A=Array.from(document.querySelectorAll("video, audio"));I.dom.mediaElements=A.map(A=>{let I=[],C=null;try{const Q=A.srcObject;Q&&"function"==typeof Q.getTracks&&(I=Q.getTracks().map(g),C=Q.id)}catch(Q){}return{nodeName:A.nodeName,muted:!!A.muted,paused:!!A.paused,hasSrcObject:!!A.srcObject,streamId:C,tracks:I,src:A.src||null,currentSrc:A.currentSrc||null}})}catch(Q){}const C=[...I.sdk.micStreamTracks,...I.sdk.camStreamTracks,...I.sdk.vbStreamTracks,...I.sdk.shareTracks,...I.sdk.producers.map(A=>A.track).filter(Boolean),...I.sdk.consumers.map(A=>A.track).filter(Boolean),...I.dom.mediaElements.flatMap(A=>A.tracks)].filter(A=>A&&"live"===A.readyState);return I.summary={totalLiveTracks:C.length,elementsWithSrcObject:I.dom.mediaElements.filter(A=>A.hasSrcObject).length,elementsWithTracks:I.dom.mediaElements.filter(A=>A.tracks.length>0).length},I};async listDevicesInternal(){if(navigator.mediaDevices.ondevicechange=async A=>{let I=await XE();SD.info("Media devices changed!:%O",I),I.audioDevices&&I.audioDevices.length>0&&(this._deviceList.audioDevices=I.audioDevices),I.videoDevices&&I.videoDevices.length>0&&(this._deviceList.videoDevices=I.videoDevices),I.audioDevices&&I.audioDevices.length>0&&(this._deviceList.audioOutputDevices=I.audioDevicesOutput),ND=this._deviceList,this.emit("deviceListUpdated")},!this._deviceList){const A=await _E();if(A.success)return this._deviceList=A.deviceList,void(ND=this._deviceList)}}restartIce=async(A,I)=>{if("send"===I&&"connected"===this._sendTransport.connectionState||"recv"===I&&"connected"===this._recvTransport.connectionState)return void SD.debug("no need to restart ICE as transport now connected");SD.debug("websocket is ready and connectionstate is still disconnected, therefore going to restart ICE");let g={id:"restartIce",transportId:A,roomName:this.data.inputParams.roomId,peerId:this.data.inputParams.peerId};this._sendMessage(g)};restartIceResponse=A=>{SD.debug("restart ICE response:%o",A);let{transportId:I,iceParameters:g}=A;this._sendTransport&&this._sendTransport.id===I?this._sendTransport.restartIce({iceParameters:g}):this._recvTransport&&this._recvTransport.id===I&&this._recvTransport.restartIce({iceParameters:g})};startRecording=({recordingType:A=null,outputType:I=null,outputQualities:g=null}={})=>{SD.debug("recording type requested is:%s,outputType:%s, outputQualties:%o",A,I,g);const C=!A||"av"!==A?.toLowerCase()&&"audiovideo"!==A?.toLowerCase()?"mergedA":"mergedAV";if((!I||"hls"!==I.toLowerCase()&&"mp4"!==I.toLowerCase())&&I)return SD.error("Invalid outut type"),{success:!1,reason:`Invalid outputType: ${I}. `};if(I&&"hls"===I.toLowerCase()&&g&&!ri(g))return SD.error("Invalid outut qualities"),{success:!1,reason:`Invalid outputQualities: ${JSON.stringify(g)}. Allowed values are ${Array.from(ti).join(", ")}.`};let Q={id:"startRecording",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,url:window.location.hostname,type:uE,recordingStrategy:C,outputQualities:g,outputType:I?.toLowerCase()};this._sendMessage(Q),this._recordingStartedByMe={...this._recordingStartedByMe,"main-room":{recordingNo:null}}};stopRecording=()=>{SD.debug("going to stop recording for recordingStartedByMe:%o",this._recordingStartedByMe);let A="main-room";if(!this._recordingStartedByMe[A])return{success:!1,error:!0,code:"RRID001",text:"Error while trying to stop recording. Either the recording has not been started yet Or The same user need to stop recording who started it."};{let I={id:"stopRecording",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,recordingNo:this._recordingStartedByMe[A].recordingNo,type:uE};this._sendMessage(I),delete this._recordingStartedByMe[A],this.emit("recordingEnded",{peerId:this.data.inputParams.peerId})}};setRecordingStatusStarted=A=>{SD.debug("Recording/Streaming started by moderator!!:%O",A);let{breakOutRoom:I,recordingStartTime:g,recordingNo:C,type:Q}=A;[uE,pE].includes(Q)&&(this._recordingStartedByMe["main-room"]?(SD.debug("This recording has been started by me."),this._recordingStartedByMe["main-room"].recordingNo=C,this.emit("recordingStarted",{peerId:this.data.inputParams.peerId,startTime:g})):this.emit("recordingStarted",{startTime:g}))};setRecordingStatusEnded=A=>{SD.debug("Recording ended by moderator!!, data:%O",A);let{breakOutRoom:I,type:g}=A;"rtmpStream"===g||this.emit("recordingEnded",{})};startProcessing=async({inputFiles:A=[],outputQualities:I=null,bucket:g=null,cloud:C=null,region:Q=null}={})=>{SD.debug("Processing of Files requested for:%o",A);const B=Math.round(1e7*Math.random()),E=await async function(A){if(ci.info("The input files are:%o, length:%s",A,A.length),A.length>0){ci.info("Files array length is:%s",A.length);for(const{type:I,url:g}of A){if(ci.info("The file detais are type:%s, url:%s",I,g),!Hi.includes(I))return{success:!1,reason:`Type "${I}" is not allowed.`};if(!Yi(g,I))return{success:!1,reason:`Extension mismatch for ${g}; expected .${I}`}}return{success:!0}}return{success:!1,reason:"There are no files for processing!"}}(A);if(E.success){if(I&&!ri(I))return SD.error("Invalid outut qualities"),{success:!1,reason:`Invalid outputQualities: ${JSON.stringify(I)}. Allowed values are ${Array.from(ti).join(", ")}.`};this._processingStartedByMe={...this._processingStartedByMe,[B]:{}};for(const{type:I,url:g}of A)this._processingStartedByMe={...this._processingStartedByMe,[B]:{...this._processingStartedByMe[B],[g]:{type:I,url:g,status:"pending"}}};let E={id:"processVideos",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,inputFiles:A,outputQualities:I,bucket:g,cloud:C,region:Q,requestId:B,type:"process"};return this._sendMessage(E),{success:!0}}return E};checkProcessingStatus=({requestId:A})=>(SD.debug("Going to check processing status for request Id:%s",A),this._processingStartedByMe[A]?{success:!0,details:this._processingStartedByMe[A]}:{success:!0,details:this._processingStartedByMe});handleProcessingStart=A=>{const{processingStartTime:I,processingNo:g,requestId:C}=A;SD.debug("handleProcessingStart()| received message is:%o",A),this.emit("processingStarted",{processingStartTime:I,requestId:C})};handleProcessingCompletion=A=>{const{totalProcessingTime:I,hlsfileKey:g,size:C,originalFile:Q,lastFile:B,requestId:E}=A;if(SD.debug("handleProcessingCompletion()| received message is:%o",A),SD.debug("Before update, Total files to be processed are:%o",this._processingStartedByMe),this._processingStartedByMe[Q]&&(this._processingStartedByMe={...this._processingStartedByMe,[E]:{...this._processingStartedByMe[E],[Q]:{...this._processingStartedByMe[Q],status:"completed",hlsfileKey:g,size:C,totalProcessingTime:I}}}),SD.debug("After update, Total files to be processed are:%o",this._processingStartedByMe),this.emit("processingCompleted",A),B){SD.debug("The last file processing has been completed! Remove all the files that has been completed with the same requesterId");let A={...this._processingStartedByMe};delete A[E],SD.debug("After deleting the current requestId:%o",A),this._processingStartedByMe=A}};handleProcessingError=A=>{const{totalProcessingTime:I,hlsfileKey:g,size:C,originalFile:Q,lastFile:B,requestId:E,error:i}=A;SD.debug("handleProcessingCompletion()| received message is:%o",A),SD.debug("Before update, Total files to be processed are:%o",this._processingStartedByMe),this._processingStartedByMe[Q]&&(this._processingStartedByMe={...this._processingStartedByMe,[E]:{...this._processingStartedByMe[E],[Q]:{...this._processingStartedByMe[Q],status:"error",hlsfileKey:g,size:C,totalProcessingTime:I,error:i}}}),SD.debug("After update, Total files to be processed are:%o",this._processingStartedByMe),this.emit("processingError",A)};async enableMic({deviceId:A=null,autoGainControl:I,noiseSuppression:g,echoCancellation:C,channelCount:Q,sampleRate:B,forcePCMU:E,forcePCMA:i}={}){if(SD.debug("enableMic()"),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID007",text:"Error while trying to start Mic/Audio. Produce flag need to set to true while joining room in order to enable Mic/Audio."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID008",text:`Error while trying to start Mic/Audio as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling Mic? OR if you have already initiated the joinRoom process, then Mic will be enabled automatically once room join process completes."};if(this._micProducer)return SD.debug("Mic is already active!"),{success:!1,warning:!0,code:"RWID002",text:"Error while trying to start Mic/Audio. Mic/Audio is already active!"};if(!this._device.canProduce("audio"))return SD.error("enableMic() | cannot produce audio"),{success:!1,error:!0,code:"REID009",text:"Error while trying to start Mic/Audio. Mic/Audio couldnot be activated due to limitations on this device. If you think this device has a functional Mic and the problem persists even after multiple retries, please contact technical support with the error code."};let D,n;E&&"boolean"==typeof E&&(this.data.inputParams.forcePCMU=E),i&&"boolean"==typeof i&&(this.data.inputParams.forcePCMA=i),I&&"boolean"==typeof I&&(this.data.inputParams.autoGainControl=I),C&&"boolean"==typeof C&&(this.data.inputParams.echoCancellation=C),g&&"boolean"==typeof g&&(this.data.inputParams.noiseSuppression=g),B&&Number.isInteger(B)&&B<64e3&&B>8e3&&(this.data.inputParams.sampleRate=B),Q&&Number.isInteger(Q)&&Q>0&&Q<3&&(this.data.inputParams.channelCount=Q);try{if(this._externalVideo)this._micStream=await this._getExternalVideoStream(),D=this._micStream.getAudioTracks()[0].clone();else{if(A?(n=this._deviceList.audioDevices.find(I=>I.deviceId===A),n||(SD.warn("Selected audio input deviceId:%s not found",A),n=this._deviceList.audioDevices[0])):n=this._deviceList.audioDevices[0],this._mic.device=n,!n)return SD.error("No mic device found! Can't start audio!"),{success:!1,reason:"No mic available for starting audio!"};A&&this.data.inputParams.audioDeviceId!==A&&(this.data.inputParams.audioDeviceId=A),SD.debug("enableMic() | calling getUserMedia()");try{this._micStream=await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:n.deviceId},echoCancellation:this.data.inputParams.echoCancellation,noiseSuppression:this.data.inputParams.noiseSuppression,autoGainControl:this.data.inputParams.autoGainControl,sampleRate:this.data.inputParams.sampleRate,channelCount:this.data.inputParams.channelCount}}),D=this._micStream.getAudioTracks()[0]}catch(eD){throw new Error("Error while acquiring mic. Possible issue with audio constraint values",eD)}}this._micProducer=await this._sendTransport.produce({track:D,codecOptions:this.data.inputParams.forcePCMU||this.data.inputParams.forcePCMA?void 0:{opusStereo:!1,opusDtx:!0,opusFec:!0,opusNack:!0},codec:this.data.inputParams.forcePCMU?this._device.rtpCapabilities.codecs.find(A=>"audio/pcmu"===A.mimeType.toLowerCase()):this.data.inputParams.forcePCMA?this._device.rtpCapabilities.codecs.find(A=>"audio/pcma"===A.mimeType.toLowerCase()):void 0,appData:{mediaTag:"cam-audio"}}),this._producers.set("audio",{id:this._micProducer.id,paused:this._micProducer.paused,track:this._micProducer.track,rtpParameters:this._micProducer.rtpParameters,codec:this._micProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("micStart",{peerId:this.data.inputParams.peerId,audioTrack:this._micProducer.track,type:"local"}),this._micProducer.on("transportclose",()=>{this._micProducer=null}),this._micProducer.on("trackended",()=>{this.disableMic().catch(()=>{})}),await this._initializeAudioMonitoring(),this._startSpeakingWhileMutedDetection()}catch(o){SD.error("enableMic() | failed:%o",o),this.emit("error",{code:"EID002",text:"Error enabling microphone!"}),D&&D.stop()}}async disableMic(){if(SD.debug("disableMic()"),this._cleanupAudioMonitoring(),this._micStream&&this._micStream.getAudioTracks().forEach(A=>A.stop()),this._micProducer){this._micProducer.close(),this._producers.delete("audio");try{let A={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",producerId:this._micProducer.id};this._sendMessage(A),this.emit("micEnd",{peerId:this.data.inputParams.peerId,audioTrack:null,type:"local"})}catch(A){this.emit("error",{code:"EID003",text:"Error disabling microphone!"})}this._micProducer=null}}async muteMic(){SD.debug("muteMic()"),this._micProducer.pause();try{let A={id:"toggleMedia",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",audioStatus:!1,producerId:this._micProducer.id};this._sendMessage(A),this.emit("peerMuted",{peerId:this.data.inputParams.peerId,type:"local"})}catch(A){SD.error("muteMic() | failed: %o",A),this.emit("error",{code:"EID004",text:"Error muting local microphone!"})}}async unmuteMic(){SD.debug("unmuteMic()"),this._micProducer||(SD.debug("Mic is not active!"),await this.enableMic()),this._micProducer.resume();try{let A={id:"toggleMedia",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",audioStatus:!0,producerId:this._micProducer.id};this._sendMessage(A),this.emit("peerUnMuted",{peerId:this.data.inputParams.peerId,type:"local"})}catch(A){SD.error("unmuteMic() | failed: %o",A),this.emit("error",{code:"EID005",text:"Error unmuting local microphone!"})}}handleRoomSettingsGeneral=async({allowScreenShare:A,noOfScreenShare:I,noOfUpgradeRequests:g})=>{const C={type:"roomSetting:generalSettings",allowScreenShare:A,noOfScreenShare:I,noOfUpgradeRequests:g};return SD.debug("Room settings - General: %O",C),this.sendCustomMessage(JSON.stringify(C),"custom",null,"moderator","roomSetting:generalSettings",{}),{success:!0}};handleAuthSettings=async({moderatorApproval:A,passwordRequired:I})=>{const g={type:"roomSetting:authSettings",moderatorApproval:A,passwordRequired:I};return SD.debug("Room settings - Auth: %O",g),this.sendCustomMessage(JSON.stringify(g),"custom",null,"moderator","roomSetting:authSettings",{}),{success:!0}};handleRoomSettingsStage=A=>{const I={type:"roomSetting:stageSettings",stageStatus:A.stageStatus,stagePeers:A.stagePeers,backStageStatus:A.backStageStatus,backStagePeers:A.backStagePeers};return this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:stageSettings",{}),{success:!0}};handlePresenterSettings=async A=>{const I={type:"roomSetting:presenterSettings",presenterSettings:A};return SD.debug("presenter settings: %O",I),this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:presenterSettings",{}),{success:!0}};handleParticipantSettings=async A=>{SD.debug("Going to update participant settings with values:%s",A);const I={type:"roomSetting:participantSettings",participantSettings:A};return this.sendCustomMessage(JSON.stringify(I),"custom",null,"moderator","roomSetting:participantSettings",{}),{success:!0}};startSpeechRecognition(A={}){const I={lang:"es-ES",continuous:!0,interimResults:!0,maxAlternatives:3,autoRestart:!0,restartDelayMs:250,...A},g=window.SpeechRecognition||window.webkitSpeechRecognition,C=window.SpeechGrammarList||window.webkitSpeechGrammarList;if(!g)return this.emit("sttError",{code:"UNSUPPORTED",message:"Web Speech API not supported"}),{success:!1,reason:"unsupported"};try{if(this._speechRecognition){try{this._speechRecognition.onend=null,this._speechRecognition.onresult=null,this._speechRecognition.onerror=null}catch{}try{this._speechRecognition.stop()}catch{}this._speechRecognition=null}const A=new g;if(A.lang=I.lang,A.continuous=!!I.continuous,A.interimResults=!!I.interimResults,A.maxAlternatives=I.maxAlternatives,I.grammars&&Array.isArray(I.grammars)&&C){const g=new C,Q=`#JSGF V1.0; grammar terms; public <term> = ${I.grammars.join(" | ")};`;g.addFromString&&g.addFromString(Q,1),A.grammars&&(A.grammars=g)}return this._sttShouldRun=!0,this._sttAutoRestart=!!I.autoRestart,this._sttRestartDelayMs=Number(I.restartDelayMs)||250,A.onstart=()=>this.emit("sttStart",{timestamp:Date.now(),lang:A.lang}),A.onresult=I=>{const g=I.results[I.results.length-1],C=g&&g[0]?g[0]:null,Q={transcript:C?C.transcript:"",confidence:C?C.confidence:0,isFinal:!!g&&g.isFinal,timestamp:Date.now(),lang:A.lang},B=Q.timestamp,E=this.data.inputParams.peerId||"local";this._transcriptStorage.has(B)||this._transcriptStorage.set(B,new Map);this._transcriptStorage.get(B).set(E,{transcript:Q.transcript,isFinal:Q.isFinal}),this.emit("sttResult",Q)},A.onerror=A=>{this.emit("sttError",{code:A.error||"UNKNOWN",message:A.message||"Speech recognition error"})},A.onend=()=>{if(this.emit("sttEnd",{timestamp:Date.now()}),this._sttShouldRun&&this._sttAutoRestart){const g=this._sttRestartDelayMs;try{setTimeout(()=>{if(this._sttShouldRun&&this._sttAutoRestart)try{A.start()}catch(I){}},g)}catch(I){}}},A.start(),this._speechRecognition=A,{success:!0}}catch(eD){return this.emit("sttError",{code:"INIT_FAILED",message:eD.message}),{success:!1,reason:eD.message}}}stopSpeechRecognition(){try{if(this._sttShouldRun=!1,this._sttAutoRestart=!1,this._speechRecognition){try{this._speechRecognition.onend=null,this._speechRecognition.onresult=null,this._speechRecognition.onerror=null}catch{}this._speechRecognition.stop(),this._speechRecognition=null}return{success:!0}}catch(eD){return this.emit("sttError",{code:"STOP_FAILED",message:eD.message}),{success:!1,reason:eD.message}}}startTranscription(){try{return this._transcriptionActive?(SD.debug("Transcription already active"),{success:!1,reason:"already_active"}):(this._transcriptionActive=!0,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,SD.debug("Transcription started - waiting for audio buffer from client"),this.emit("transcriptionStarted"),{success:!0})}catch(A){return SD.error("Failed to start transcription:",A),this.emit("transcriptionError",{error:A.message}),{success:!1,reason:A.message}}}stopTranscription(){try{return this._transcriptionActive?(this._transcriptionRecorder&&"inactive"!==this._transcriptionRecorder.state&&this._transcriptionRecorder.stop(),this._transcriptionRecorder=null,this._transcriptionActive=!1,this._transcriptionChunks=[],this._currentTranscriptionPeerId=null,this._transcriptionEmittedStart=!1,SD.debug("Transcription stopped completely"),this.emit("transcriptionStopped"),{success:!0}):(SD.debug("Transcription not active"),{success:!1,reason:"not_active"})}catch(A){return SD.error("Failed to stop transcription:",A),this.emit("transcriptionError",{error:A.message}),{success:!1,reason:A.message}}}sendAudioForTranscription(A,I){try{return A?(this.sendCustomMessage({audioBuffer:A,timestamp:Date.now(),activeSpeakerPeerId:I},"general",null,"participant","deepgram:audio"),SD.debug(`Audio buffer sent for transcription from peer: ${I}`),{success:!0}):(SD.debug("No audio buffer provided"),{success:!1,reason:"no_audio_buffer"})}catch(g){return SD.error("Failed to send audio for transcription:",g),{success:!1,reason:g.message}}}isTranscriptionActive(){return this._transcriptionActive||!1}_processTranscriptionMessage=A=>{try{if("transcription"===A.type&&A.data){const I=A.data;this.emit("transcription",{transcript:I.transcript,confidence:I.confidence,isFinal:I.isFinal,timestamp:I.timestamp,speaker:I.speaker}),SD.debug("Transcription received:",I.transcript)}}catch(I){SD.error("Failed to process transcription message:",I)}};async enableCam({deviceId:A=null,videoResolution:I,forceVp8:g,forceVp9:C,forceH264:Q,h264Profile:B,forceFPS:E,enableWebcamLayers:i,numSimulcastStreams:D,videoBitRates:n,vbdetails:o}={}){if(SD.debug("enableWebcam()"),SD.debug("first vbdetails in enablecam",o),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID004",text:"Error while trying to start Camera. Produce flag need to set to true while joining room in order to enable Camera."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID005",text:`Error while trying to start Camera as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling Camera? OR if you have already initiated the joinRoom process, then Camera will be enabled automatically once room join process completes."};if(this._webcamProducer)return SD.debug("Camera is already active!"),{success:!1,warning:!0,code:"RWID003",text:"Error while trying to start Camera. Camera is already active!"};if(!this._device.canProduce("video"))return SD.error("enableWebcam() | cannot produce video"),{success:!1,error:!0,code:"REID006",text:"Error while trying to start Camera. Camera couldnot be activated due to limitations on this device. If you think this device has a functional camera and the problem persists even after multiple retries, please contact technical support with the error code."};let s,w;["hd","vga","qvga"].includes(I)&&(this.data.inputParams.videoResolution=I,this._webcam.resolution=I),g&&"boolean"==typeof g&&(this.data.inputParams.forceVp8=g),C&&"boolean"==typeof C&&(this.data.inputParams.forceVp9=C),Q&&"boolean"==typeof Q&&(this.data.inputParams.forceH264=Q),B&&["high","low"].includes(B.toLowerCase())&&(this.data.inputParams.h264Profile=B),E&&Number.isInteger(E)&&E<65&&E>5&&(this.data.inputParams.forceFPS=25),i&&"boolean"==typeof i&&(this.data.inputParams.enableWebcamLayers=i,this._enableWebcamLayers=i),D&&Number.isInteger(D)&&D<4&&D>0&&(this.data.inputParams.numSimulcastStreams=D,this._numSimulcastStreams=D),Array.isArray(n)&&n.length>=1&&n.length<=3&&n.every(A=>Number.isInteger(A)&&A>=75&&A<=800)?(SD.debug("videoBitRates values are correct"),this.data.inputParams.videoBitRates=n):SD.warn("videobitrates values should be an integer array with maximum 3 elements and minimum 1 element. The values in the array are '[700,250,75]'");try{if(this._externalVideo)w={label:"external video"},this._webCamStream=await this._getExternalVideoStream(),s=this._webCamStream.getVideoTracks()[0].clone();else{A?(w=this._deviceList.videoDevices.find(I=>I.deviceId===A),w||(SD.warn("Selected deviceId:%s not found",A),w=this._deviceList.videoDevices[0])):w=this._deviceList.videoDevices[0],this._webcam.device=w;const{resolution:I}=this._webcam;if(!w)return SD.error("No wencam device found! Can't start video!"),{success:!1,reason:"No Webcam available for starting video!"};A&&this.data.inputParams.videoDeviceId!==A&&(this.data.inputParams.videoDeviceId=A),SD.debug("enableWebcam() | calling getUserMedia()"),this._webCamStream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:w.deviceId},...hD[I],frameRate:{ideal:this.data.inputParams.forceFPS}}}),s=this._webCamStream.getVideoTracks()[0]}let I,g;const C={videoGoogleStartBitrate:1e3};if(SD.debug("Current device codec options are:%O",this._device.rtpCapabilities.codecs),this._forceVP8){if(g=this._device.rtpCapabilities.codecs.find(A=>"video/vp8"===A.mimeType.toLowerCase()),!g)throw new Error("desired VP8 codec+configuration is not supported")}else if(this._forceH264){if("high"===this.data.inputParams.h264Profile?g=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"4d001f"===A.parameters["profile-level-id"]):"low"===this.data.inputParams.h264Profile&&(g=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"42e01f"===A.parameters["profile-level-id"])),!g)throw new Error("desired H264 codec+configuration is not supported");SD.debug("Selected h264 codec is:%O",g)}else if(this._forceVP9&&(g=this._device.rtpCapabilities.codecs.find(A=>"video/vp9"===A.mimeType.toLowerCase()),!g))throw new Error("desired VP9 codec+configuration is not supported");if(this._enableWebcamLayers){const A=this._device.rtpCapabilities.codecs.find(A=>"video"===A.kind);this._forceVP9&&g||"video/vp9"===A.mimeType.toLowerCase()?I=[{maxBitrate:5e6,scalabilityMode:this._webcamScalabilityMode||"L3T3_KEY"}]:(I=[{scaleResolutionDownBy:1,maxBitrate:1e3*this.data.inputParams.videoBitRates[0],scalabilityMode:this._webcamScalabilityMode||"L1T3"}],this._numSimulcastStreams>1&&I.unshift({scaleResolutionDownBy:2,maxBitrate:1e3*this.data.inputParams.videoBitRates[1],scalabilityMode:this._webcamScalabilityMode||"L1T3"}),this._numSimulcastStreams>2&&I.unshift({scaleResolutionDownBy:4,maxBitrate:1e3*this.data.inputParams.videoBitRates[2],scalabilityMode:this._webcamScalabilityMode||"L1T3"}))}if(o)try{const A=MD&&MD._localVBStream;let I=null;if(A&&"function"==typeof A.getVideoTracks&&A.getVideoTracks().length>0&&"live"===A.getVideoTracks()[0].readyState)I=A.getVideoTracks()[0],SD.debug("Using existing Virtual Background track");else{const A=await MD.initializePipeline(s,o);A&&A.vbStream&&"function"==typeof A.vbStream.getVideoTracks&&A.vbStream.getVideoTracks().length>0&&(I=A.vbStream.getVideoTracks()[0],SD.debug("Initialized new Virtual Background pipeline"))}I&&(s=I)}catch(a){SD.debug("VB init failed or skipped in enableCam")}this._webcamProducer=await this._sendTransport.produce({track:s,encodings:I,codecOptions:C,codec:g,appData:{mediaTag:"cam-video"}}),this._producers.set("video",{id:this._webcamProducer.id,deviceLabel:w.label,type:this._getWebcamType(w),paused:this._webcamProducer.paused,track:this._webcamProducer.track,rtpParameters:this._webcamProducer.rtpParameters,codec:this._webcamProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("videoStart",{peerId:this.data.inputParams.peerId,videoTrack:this._webcamProducer.track,type:"local"}),this._webcamProducer.on("transportclose",()=>{this._webcamProducer=null}),this._webcamProducer.on("trackended",()=>{this.disableCam().catch(()=>{})})}catch(y){SD.error("enableWebcam() | failed:%o",y),this.emit("error",{code:"EID011",text:"Enable Webcam failed!"}),s&&s.stop()}}async disableCam(){if(SD.debug("disableWebcam()"),this._webcamProducer){this._webcamProducer.close(),this._producers.delete("video");try{let A={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"video",producerId:this._webcamProducer.id};this._sendMessage(A),this.emit("videoEnd",{peerId:this.data.inputParams.peerId,videoTrack:null})}catch(A){this.emit("error",{code:"EID012",text:"Error while closing server side producer!"})}try{this._webCamStream&&"function"==typeof this._webCamStream.getTracks&&this._webCamStream.getTracks().forEach(A=>{try{A.stop()}catch(I){}})}catch(I){}this._webCamStream=null,this._webcamProducer=null}}async _updateWebcams(){SD.debug("_updateWebcams()"),this._webcams=new Map,SD.debug("_updateWebcams() | calling enumerateDevices()");const A=await navigator.mediaDevices.enumerateDevices();for(const Q of A)"videoinput"===Q.kind&&this._webcams.set(Q.deviceId,Q);const I=Array.from(this._webcams.values()),g=I.length,C=this._webcam.device?this._webcam.device.deviceId:void 0;SD.debug("_updateWebcams() [webcams:%o]",I),0===g?this._webcam.device=null:this._webcams.has(C)||(this._webcam.device=I[0])}async _getExternalVideoStream(){if(this._externalVideoStream)return this._externalVideoStream;if(this._externalVideo.readyState<3&&await new Promise(A=>this._externalVideo.addEventListener("canplay",A)),this._externalVideo.captureStream)this._externalVideoStream=this._externalVideo.captureStream();else{if(!this._externalVideo.mozCaptureStream)throw new Error("video.captureStream() not supported");this._externalVideoStream=this._externalVideo.mozCaptureStream()}return this._externalVideoStream}_getWebcamType(A){return/(back|rear)/i.test(A.label)?(SD.debug("_getWebcamType() | it seems to be a back camera"),"back"):(SD.debug("_getWebcamType() | it seems to be a front camera"),"front")}async changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C}){if(this._webcamProducer){return await this._changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C})}return SD.error("No webcam producer available!"),{success:!1,reason:"You are not sharing your camera yet. Camera Input can be changed to a new camera only when you are sharing an existing camera. "}}async _changeVideoInput({resolution:A,deviceId:I,fps:g,vbdetails:C}){SD.info("_changeVideoInput() | Inside"),A&&["hd","vga","qvga"].includes(A)?this._webcam.resolution=A:SD.warn("Invalid video resolution value "),g&&Number.isInteger(g)&&g<65&&g>5?this.data.inputParams.forceFPS=g:SD.warn("forceFPS should be a number between 5 to 65, default value is 25 fps.");let Q=this._deviceList.videoDevices.find(A=>I&&A.deviceId===I);if(!Q)return SD.error("The selected deviceId not found!"),{success:!1,reason:"Invalid deviceId!"};this._webcam.device=Q;try{this._webCamStream.getVideoTracks().forEach(A=>A.stop()),this._webCamStream=null,SD.debug("changeVideoInput() | calling getUserMedia()"),this._webCamStream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:Q.deviceId},...hD[this._webcam.resolution],frameRate:{ideal:this.data.inputParams.forceFPS}}});let A=this._webCamStream.getVideoTracks()[0];if(SD.debug("The new video track is:%O",A),C)try{const I=await MD.initializePipeline(A,C);I&&I.vbStream&&"function"==typeof I.vbStream.getVideoTracks&&I.vbStream.getVideoTracks()[0]&&(A=I.vbStream.getVideoTracks()[0],SD.debug("Reinitialized VB pipeline for changed camera"))}catch(B){SD.debug("VB init skipped/failed on changeVideoInput")}await this._webcamProducer.replaceTrack({track:A});let I=this._producers.get("video");return I.deviceLabel=Q.label,I.type=this._getWebcamType(Q),I.track=this._webcamProducer.track,SD.debug("Updated producer values are:%O",I),this._producers.set("video",I),this.emit("videoStart",{peerId:this.data.inputParams.peerId,videoTrack:A,type:"local"}),{success:!0}}catch(E){return SD.error("Error while changing input:%O",E),{success:!1,reason:"Couldn't change video input",error:E}}}async changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B}){if(this._micProducer){return await this._changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B})}return{success:!1,reason:"You are not sharing your mic yet. Mic Input can be changed to a new mic only when you are sharing an existing mic. "}}async _changeAudioInput({autoGainControl:A,echoCancellation:I,noiseSuppression:g,sampleRate:C,channelCount:Q,deviceId:B}){A&&"boolean"==typeof A&&(this.data.inputParams.autoGainControl=A),I&&"boolean"==typeof I&&(this.data.inputParams.echoCancellation=Boolean(I)),g&&"boolean"==typeof g&&(this.data.inputParams.noiseSuppression=Boolean(g)),C&&Number.isInteger(C)&&C<64e3&&C>8e3&&(this.data.inputParams.sampleRate=C),Q&&Number.isInteger(Q)&&Q>0&&Q<3&&(this.data.inputParams.channelCount=Q);let E=this._deviceList.audioDevices.find(A=>B&&A.deviceId===B);if(!E)return{success:!1,reason:"Invalid deviceId!"};this._mic.device=E,this._micStream&&this._micStream.getAudioTracks().forEach(A=>A.stop()),this._micStream=null;try{this._micStream=await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:E.deviceId},echoCancellation:this.data.inputParams.echoCancellation,noiseSuppression:this.data.inputParams.noiseSuppression,autoGainControl:this.data.inputParams.autoGainControl,sampleRate:this.data.inputParams.sampleRate,channelCount:this.data.inputParams.channelCount}});const A=this._micStream.getAudioTracks()[0];this._micProducer.replaceTrack({track:A});let I=this._producers.get("audio");return I.deviceLabel=E.label,I.track=this._micProducer.track,SD.debug("Updated producer values are:%O",I),this._producers.set("audio",I),this.emit("micStart",{peerId:this.data.inputParams.peerId,audioTrack:this._micProducer.track,type:"local"}),{success:!0}}catch(eD){return SD.error("Error while changing input:%O",eD),{success:!1,reason:"Couldn't change audio input",err:eD}}}toggleVB=async A=>{if(A&&this._localCamVideo.getVideoTracks()[0]){const A=await this.initializePipeline(this._localCamVideo.getVideoTracks()[0],{type:"blur"});if(SD.debug("response is :%o, localVBTrack is:%O",A,this._localVBStream.getVideoTracks()[0]),A.success&&this._localVBStream.getVideoTracks()[0]){if(this._roomType===bE||this._roomType===xE)if(this._camVideoProducer&&store.getState().conf.joined){await this._camVideoProducer.replaceTrack({track:this._localVBStream.getVideoTracks()[0].clone()});let A={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localVBStream.getVideoTracks()[0]}};this._participants=A,store.dispatch(confActions.addParticipant(A))}else SD.debug("Camvideoproducer not available! virtual background changes in the landing page! ");else if(this._roomType===dE&&this._peerConnection){const A=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});if(SD.debug("found sender:%o",A),A&&this._localVBStream.getVideoTracks()[0]){A.replaceTrack(this._localVBStream.getVideoTracks()[0]);let I={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localVBStream.getVideoTracks()[0]}};this._participants=I,store.dispatch(confActions.addParticipant(I))}else this.showNotification("danger","Error!","Unable to switch off virtual background! Try again OR contact support with code:CM-FE-RC-VB-E04")}}else SD.error("Virtual background procesing can't be enabled")}else if(this._localVBStream?.getVideoTracks()[0].stop(),this._localVBStream=null,this._pipelineManager.stop(),this._vbDetailsNew.sourcePlayback&&(this._vbDetailsNew.sourcePlayback.htmlElement.srcObject=null),this._vbDetailsNew.sourcePlayback?.htmlElement.remove(),this._vbDetailsNew?.hiddenCanvas.remove(),this._vbDetailsNew?.hiddenImage?.remove(),this._vbDetailsNew.sourcePlayback=null,this._vbDetailsNew.hiddenCanvas=null,this._vbDetailsNew.hiddenImage=null,store.dispatch(confActions.setVBItemsStatus(A)),SD.debug("Garbage collection completed. Set the video to original video!"),store.getState().conf.videoStatus)if(this._roomType===bE||this._roomType===xE)if(this._camVideoProducer&&store.getState().conf.joined&&this._localCamVideo.getVideoTracks()[0]&&store.getState().conf.joined&&"live"===this._localCamVideo.getVideoTracks()[0].readyState){await this._camVideoProducer.replaceTrack({track:this._localCamVideo.getVideoTracks()[0].clone()});let A={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localCamVideo.getVideoTracks()[0]}};this._participants=A,store.dispatch(confActions.addParticipant(A))}else SD.debug("Camvideoproducer not available! virtual background changes in the landing page! ");else if(this._roomType===dE&&this._peerConnection){const A=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});if(SD.debug("found sender:%o",A),A&&this._localCamVideo.getVideoTracks()[0]&&"live"===this._localCamVideo.getVideoTracks()[0].readyState){A.replaceTrack(this._localCamVideo.getVideoTracks()[0]);let I={...this._participants,[this._peerId]:{...this._participants[this._peerId],videoRef:this._localCamVideo.getVideoTracks()[0]}};this._participants=I,store.dispatch(confActions.addParticipant(I))}else this.showNotification("danger","Error!","Unable to switch off virtual background! Try again OR contact support with code:CM-FE-RC-VB-E04")}};setVBDetails=async A=>{if(this._vbDetails=A,this._roomType!==bE&&this._roomType!==xE||!store.getState().conf.joined){if(this._roomType===dE&&this._peerConnection){const I=this._peerConnection.getSenders().find(function(A){return"video"===A.track.kind});SD.debug("found sender:%o",I),I?I.replaceTrack(A.stream.getVideoTracks()[0]):this.showNotification("danger","Error!","Unable to set virtual background! Try again OR contact support with code:CM-FE-RC-VB-E02")}}else if(this._camVideoProducer){SD.debug("Going to replace the video track for cam video producer!");try{await this._camVideoProducer.replaceTrack({track:A.stream.getVideoTracks()[0]})}catch(eD){SD.debug("vb set error",eD)}SD.debug("all participants",this._participants),SD.debug("this._localCamVideo",this._localCamVideo)}else SD.warn("Camvideo producer is not available yet!")};async enableShare({shareAudio:A=!1,enableSharingLayers:I=!0,shareBitRates:g=[2500,1250,500]}={}){if(SD.debug("enableShare()"),!this.data.inputParams.produce)return SD.debug("Produce status is set to false!"),{success:!1,error:!0,code:"REID003",text:"Error while trying to start screen share. Produce flag need to set to true while joining room in order to enable screen share."};if("connected"!==this._roomStatus)return SD.debug("Room status is not connected yet!"),{success:!1,error:!0,code:"REID001",text:`Error while trying to start screen share as room not in connected status. Current room status:!${this._roomStatus}`,possibleReasons:"Did you forget to call joinRoom before enabling screen share? OR if you have already initiated the joinRoom process, then try enabling screen share after some seconds."};if(this._shareProducer)return SD.debug("Screen share is already active!"),{success:!1,warning:!0,code:"RWID001",text:"Error while trying to start screen share. Screen share is already active!"};if(!this._device.canProduce("video"))return SD.error("enableShare() | cannot produce video"),{success:!1,error:!0,code:"REID002",text:"Error while trying to start screen share. Screen share couldnot be activated due to limitations on this device. If you think this device is capable of screen share and the problem persists even after multiple retries, please contact technical support with the error code."};let C,Q;this._enableSharingLayers="boolean"!=typeof I?Boolean(I):I,Array.isArray(g)&&g.length>=1&&g.length<=3&&g.every(A=>Number.isInteger(A)&&A>=500&&A<=2500)?this.data.inputParams.shareBitRates=g:this.data.inputParams.shareBitRates=[2500,1250,500];try{SD.debug("enableShare() | calling getDisplayMedia()");const I=await navigator.mediaDevices.getDisplayMedia({audio:!!A,video:{displaySurface:"monitor",logicalSurface:!0,cursor:!0,width:{max:1920},height:{max:1080},frameRate:{max:30}}});if(!I)return SD.error("Unable to capture screen."),void this.emit("error",{code:"EID013",text:"Error while trying to start screen share. Not able to capture screen!"});let g,B;Q=I.getAudioTracks()[0],Q&&(this._shareAudioProducer=await this._sendTransport.produce({track:Q,codecOptions:this.data.inputParams.forcePCMU?void 0:{opusStereo:!1,opusDtx:!0,opusFec:!0,opusNack:!0},codec:this.data.inputParams.forcePCMU?this._device.rtpCapabilities.codecs.find(A=>"audio/pcmu"===A.mimeType.toLowerCase()):void 0,appData:{mediaTag:"screen-audio"}}),this._producers.set("ssAudio",{id:this._shareAudioProducer.id,type:"shareAudio",paused:this._shareAudioProducer.paused,track:this._shareAudioProducer.track,rtpParameters:this._shareAudioProducer.rtpParameters,codec:this._shareAudioProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("ssAudioStart",{peerId:this.data.inputParams.peerId,audioTrack:this._shareAudioProducer.track,type:"local"})),C=I.getVideoTracks()[0];const E={videoGoogleStartBitrate:1e3};if(this._forceVP8){if(B=this._device.rtpCapabilities.codecs.find(A=>"video/vp8"===A.mimeType.toLowerCase()),!B)throw new Error("desired VP8 codec+configuration is not supported")}else if(this._forceH264){if("high"===this.data.inputParams.h264Profile?B=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"4d001f"===A.parameters["profile-level-id"]):"low"===this.data.inputParams.h264Profile&&(B=this._device.rtpCapabilities.codecs.find(A=>"video/h264"===A.mimeType.toLowerCase()&&"42e01f"===A.parameters["profile-level-id"])),!B)throw new Error("desired H264 codec+configuration is not supported");SD.debug("Selected h264 codec is:%O",B)}else if(this._forceVP9&&(B=this._device.rtpCapabilities.codecs.find(A=>"video/vp9"===A.mimeType.toLowerCase()),!B))throw new Error("desired VP9 codec+configuration is not supported");if(this._enableSharingLayers){const A=this._device.rtpCapabilities.codecs.find(A=>"video"===A.kind);this._forceVP9&&B||"video/vp9"===A.mimeType.toLowerCase()?g=[{maxBitrate:1e3*this.data.inputParams.shareBitRates[0],scalabilityMode:this._sharingScalabilityMode||"L3T3",dtx:!0}]:(g=[{scaleResolutionDownBy:1,maxBitrate:1e3*this.data.inputParams.shareBitRates[0],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}],this._numSimulcastStreams>1&&g.unshift({scaleResolutionDownBy:2,maxBitrate:1e3*this.data.inputParams.shareBitRates[1],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}),this._numSimulcastStreams>2&&g.unshift({scaleResolutionDownBy:4,maxBitrate:1e3*this.data.inputParams.shareBitRates[2],scalabilityMode:this._sharingScalabilityMode||"L1T3",dtx:!0}))}this._shareProducer=await this._sendTransport.produce({track:C,encodings:g,codecOptions:E,codec:B,appData:{mediaTag:"screen-video"}}),this._producers.set("ssVideo",{id:this._shareProducer.id,type:"shareVideo",paused:this._shareProducer.paused,track:this._shareProducer.track,rtpParameters:this._shareProducer.rtpParameters,codec:this._shareProducer.rtpParameters.codecs[0].mimeType.split("/")[1]}),this.emit("ssVideoStart",{peerId:this.data.inputParams.peerId,videoTrack:this._shareProducer.track,type:"local"}),this._shareProducer.on("transportclose",()=>{this._shareProducer=null}),this._shareProducer.on("trackended",()=>{this.disableShare().catch(()=>{})})}catch(B){SD.error("enableShare() | failed:%o",B),"NotAllowedError"!==B.name&&this.emit("error",{code:"EID014",text:`Error while trying to start screen share. Error is: ${B}!`}),C&&C.stop()}}async disableShare(){if(SD.debug("disableShare()"),!this._shareProducer)return SD.warn("Screen share doesn't seem to be on!"),void this.emit("error",{code:"EID017",text:"Error while trying to stop screen share. Is the screen share on!"});if(this._shareProducer.close(),this._shareAudioProducer){this._shareAudioProducer.close();try{let I={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"audio",producerId:this._shareAudioProducer.id};this._sendMessage(I),this.emit("ssAudioStop",{peerId:this.data.inputParams.peerId,videoTrack:null,type:"local"});try{this._shareAudioProducer.track&&this._shareAudioProducer.track.stop&&this._shareAudioProducer.track.stop()}catch(A){}}catch(I){this.emit("error",{code:"EID015",text:`Error while trying to stop screen share audio. Error is: ${I}!`})}}try{let I={id:"closeProducerSDK",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,type:"video",producerId:this._shareProducer.id};this._sendMessage(I),this.emit("ssVideoStop",{peerId:this.data.inputParams.peerId,videoTrack:null,type:"local"});try{this._shareProducer.track&&this._shareProducer.track.stop&&this._shareProducer.track.stop()}catch(A){}}catch(I){this.emit("error",{code:"EID016",text:`Error while trying to stop screen share video. Error is: ${I}!`})}this._shareAudioProducer=null,this._shareProducer=null}upgradeParticipant=(A,I=!0,g=!1)=>{SD.debug("JsSdk upgradeParticipant()",`Upgrading ${A}`);const C={id:"upgradeParticipant",peerId:A,roomName:this.data.inputParams.roomId,audioStatus:I,videoStatus:g};this._sendMessage(C)};downgradeParticipant=A=>{SD.debug("JsSdk downgradeParticipant()",`Downgrading ${A}`);const I={id:"downgradeParticipant",peerId:A,roomName:this.data.inputParams.roomId,sendTransportId:null};this._sendMessage(I)};sendUpgradeRequest=(A,I=!0)=>{SD.debug("JsSdk sendUpgradeRequest()",`Sending upgrade request to ${A}, status: ${I}`);const g={id:"modUpgradeReq",peerId:A,status:I,moderator:this.data.inputParams.peerId};this._sendMessage(g),this.emit("upgradeRequestSent",{peerId:A,status:I})};acceptUpgradeRequest=(A=!0,I=!1)=>{SD.debug("JsSdk acceptUpgradeRequest()","Accepting upgrade request");const g={id:"upgradeReqAccepted",audioStatus:A,videoStatus:I};this._sendMessage(g)};rejectUpgradeRequest=A=>{SD.debug("JsSdk rejectUpgradeRequest()","Rejecting upgrade request");const I={id:"modUpgradeReq",peerId:this.data.inputParams.peerId,status:!1};this._sendMessage(I),this.emit("upgradeRequestRejected",{moderatorPeerId:A})};raiseHand=()=>{SD.debug("JsSdk raiseHand()");const A={id:"handRaise",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,status:!0,handRaised:!0};this._sendMessage(A),this.emit("handRaised",{peerId:this.data.inputParams.peerId})};dropHand=(A=null,I=!1)=>{const g=A||this.data.inputParams.peerId;SD.debug("JsSdk dropHand()",`Dropping hand for ${g}`);const C={id:"handRaise",peerId:g,roomName:this.data.inputParams.roomId,status:!1,handRaised:!1,moderator:I};this._sendMessage(C),this.emit("handDropped",{peerId:g,moderator:I})};requestUpgradeToPresenter=async()=>{try{const A={id:"handRaise",peerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId,status:!0,handRaised:!0,upgradeRequest:!0};return this._sendMessage(A),this.emit("upgradeRequestSent",{status:"success",message:"Upgrade request sent"}),{success:!0}}catch(eD){return SD.error("requestUpgradeToPresenter failed",eD),{success:!1,reason:eD?.message||"unknown_error"}}};handleUpgradeParticipant=async A=>{const{peerId:I,audioStatus:g,videoStatus:C}=A;SD.debug("JsSdk handleUpgradeParticipant()",`Upgrade received for ${I}`),this.emit("participantUpgraded",{peerId:I,audioStatus:g,videoStatus:C,participantType:"presenter"}),I===this.data.inputParams.peerId&&(SD.debug("JsSdk handleUpgradeParticipant()","Current user upgraded to presenter"),this.data.inputParams.peerType="presenter",this.data.inputParams.produce=!0,this.data.inputParams.produceAudio=!0,this.data.inputParams.produceVideo=!0,this._sendTransport||await this._createSendTransport(),this.emit("upgraded",{audioStatus:g,videoStatus:C,participantType:"presenter"}))};handleDowngradeParticipant=async A=>{const{peerId:I}=A;if(SD.debug("JsSdk handleDowngradeParticipant()",`Downgrade received for ${I}`),this.emit("participantDowngraded",{peerId:I,participantType:"viewer"}),I===this.data.inputParams.peerId){if(SD.debug("JsSdk handleDowngradeParticipant()","Current user downgraded to viewer"),this.data.inputParams.peerType="viewer",this.data.inputParams.produce=!1,this.data.inputParams.produceAudio=!1,this.data.inputParams.produceVideo=!1,this._sendTransport&&(this._sendTransport.close(),this._sendTransport=null),this._camAudioProducer){try{this._camAudioProducer.track&&this._camAudioProducer.track.stop&&this._camAudioProducer.track.stop()}catch(g){}this._camAudioProducer.close(),this._camAudioProducer=null}if(this._camVideoProducer){try{this._camVideoProducer.track&&this._camVideoProducer.track.stop&&this._camVideoProducer.track.stop()}catch(g){}this._camVideoProducer.close(),this._camVideoProducer=null}if(this._shareProducer){try{this._shareProducer.track&&this._shareProducer.track.stop&&this._shareProducer.track.stop()}catch(g){}this._shareProducer.close(),this._shareProducer=null,this.emit("ssVideoStop",{peerId:this.data.inputParams.peerId,type:"local"})}if(this._shareAudioProducer){try{this._shareAudioProducer.track&&this._shareAudioProducer.track.stop&&this._shareAudioProducer.track.stop()}catch(g){}this._shareAudioProducer.close(),this._shareAudioProducer=null}this._localCamVideo&&(this._localCamVideo.stop(),this._localCamVideo=null),this._localMicAudio&&(this._localMicAudio.stop(),this._localMicAudio=null),this._webCamStream&&(this._webCamStream.getTracks().forEach(A=>A.stop()),this._webCamStream=null),this._micStream&&(this._micStream.getTracks().forEach(A=>A.stop()),this._micStream=null),this.emit("downgraded",{participantType:"viewer"})}};handleModUpgradeReq=A=>{const{peerId:I,status:g,moderator:C}=A;SD.debug("JsSdk handleModUpgradeReq()",`Moderator upgrade request received. Status: ${g}`),"moderator"!==this.data.inputParams.peerType||g?g?this.emit("upgradeRequestReceived",{peerId:this.data.inputParams.peerId,moderator:C,message:"Moderator requested Participant to Presenter upgrade"}):this.emit("upgradeRequestCancelled",{peerId:this.data.inputParams.peerId,moderator:C,message:"Moderator cancelled Participant to Presenter upgrade request"}):this.emit("upgradeRequestRejected",{peerId:I,moderator:C,message:"Participant rejected request for upgrade to Presenter"})};handleUpgradeLimitReached=A=>{SD.debug("JsSdk handleUpgradeLimitReached()",A),this.emit("upgradeLimitReached",{message:A.text||"Maximum number of presenters reached",limit:A.limit})};handleHandRaise=A=>{const{peerId:I,handRaised:g,peerName:C,upgradeRequest:Q}=A;SD.debug("JsSdk handleHandRaise()",`Hand raise status: ${g} for ${I}`),this.emit("handRaise",{peerId:I,handRaised:g,peerName:C,upgradeRequest:!!Q})};handleSwitchMicOff=A=>{SD.debug("JsSdk handleSwitchMicOff()",A),this.emit("micForcedOff",{message:A.text||"Moderator turned off your microphone"}),this._camAudioProducer&&!this._camAudioProducer.paused&&this.muteMic()};handleScreenShareLimitReached=A=>{SD.debug("JsSdk handleScreenShareLimitReached()",A),this.emit("screenShareLimitReached",{message:A.text||"Maximum number of screen shares reached",limit:A.limit})};handleLockUnlockRoom=A=>{const{locked:I}=A;SD.debug("JsSdk handleLockUnlockRoom()","Room "+(I?"locked":"unlocked")),this.emit("roomLockStatusChanged",{locked:I,message:I?"Room has been locked":"Room has been unlocked"})};handlePeersWaiting=A=>{const{peersWaiting:I}=A;SD.debug("JsSdk handlePeersWaiting()",`${I?.length||0} peers waiting`),this.emit("peersWaiting",{peersWaiting:I||[],count:I?.length||0})};logMeOutNew=async()=>{try{SD.debug("Room","inside log me out new"),this.emit("roomClosed",{roomId:this.data.inputParams.roomId,reason:"removed_by_moderator"})}catch(A){}await this.leaveRoom()};logThisUserOutOfMeeting=A=>{if(SD.debug("Room","inside log this user out of meeting"),A===this.data.inputParams.peerId)SD.debug("ConferenceRoom","logging myself Out"),this.leaveRoom();else try{var I={id:"logThisUserOut",peerId:A,moderatorPeerId:this.data.inputParams.peerId,roomName:this.data.inputParams.roomId};this._sendMessage(I)}catch(g){SD.error("Room",g)}}}const LD="cp2p-client";class kD{constructor(A){A?(this._debug=Jg(`${LD}:${A}`),this._info=Jg(`${LD}:INFO:${A}`),this._warn=Jg(`${LD}:WARN:${A}`),this._error=Jg(`${LD}:ERROR:${A}`)):(this._debug=Jg(LD),this._info=Jg(`${LD}:INFO`),this._warn=Jg(`${LD}:WARN`),this._error=Jg(`${LD}:ERROR`)),this._debug.log=function(){}.bind(),this._info.log=function(){}.bind(),this._warn.log=function(){}.bind(),this._error.log=function(){}.bind()}get debug(){return this._debug}get info(){return this._info}get warn(){return this._warn}get error(){return this._error}}const JD={audio:{deviceId:{exact:void 0}},video:!1},UD={video:{deviceId:{exact:void 0},width:{min:320,ideal:640,max:1280},height:{min:240,ideal:480,max:720},frameRate:{min:15,max:30}}},qD={audio:!0,video:{width:{min:320,ideal:1280,max:1280},height:{min:240,ideal:720,max:720},aspectRatio:1.777777778,frameRate:{min:15,max:30}}},tD=new kD("socket");class rD extends cg.EventEmitter{constructor({url:A,roomId:I,peerId:g,peerName:C,role:Q}){super(),tD.debug("constructor():%o ",{url:A,roomId:I,peerId:g,peerName:C,role:Q}),this._closed=!1,this._params={url:A,roomId:I,peerId:g,peerName:C,role:Q},this._socket=null,this._connectionStatus=null,this._createSocket()}get closed(){return this._closed}get connectionStatus(){return this._connectionStatus}close(){if(!this._closed){tD.debug("close()"),this._closed=!0,this.emit("close");try{this._socket.disconnect()}catch(A){tD.error("close() | error closing the Socket:%o",A)}}}async send(A){if(this._closed)throw new Error("transport closed");try{this._socket.send(JSON.stringify(A))}catch(I){throw tD.warn("send() failed:%o",I),I}}async request({type:A,message:I}){return new Promise(g=>{if(this._closed)throw new Error("transport closed");try{this._socket.emit(A,JSON.stringify(I),A=>{g(A)})}catch(C){throw tD.warn("emit() failed:%o",C),C}})}async _createSocket(){let A=this;const I=io(this._params.url,{query:{roomId:this._params.roomId,peerId:this._params.peerId,peerName:this._params.peerName,role:this._params.role}});I.on("connect",()=>{tD.debug("Socket connected!!"),A._connectionStatus=!0,A.emit("connected")}),I.on("disconnect",()=>{tD.debug("Socket disconnected!!"),A._connectionStatus=!1,A.emit("disconnected")}),I.on("reconnect",()=>{tD.debug("Socket reconnected after disconnect!!"),I.emit("reconnected")}),I.on("message",I=>{const g=JSON.parse(I);tD.debug("New mesage received with id:%s",g.type),A.emit("message",g)}),this._socket=I}}
|
|
232
232
|
/*!
|
|
233
233
|
* Platform.js
|
|
234
234
|
* Copyright 2014-2020 Benjamin Tan
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samvyo-js-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.26",
|
|
4
4
|
"description": "This is the client js sdk for cutting-edge Samvyo real-time voice/video cloud.",
|
|
5
5
|
"repository": "git@github.com:sauravkp/VidScale-client-js.git",
|
|
6
6
|
"author": "sauravkp <saurav.codes@gmail.com>",
|