`+ee),Le&&(ee=kt(ee)),b&&vt?M(ee):ee},e.setConfig=function(){letA=arguments.length>0&&arguments[0]!==void0?arguments[0]:{};dr(A),er=!0},e.clearConfig=function(){Ze=null,er=!1,b=x,C=""},e.isValidAttribute=function(A,l,y){Ze||dr({});letE=J(A),L=J(l);returndi(E,L,y)},e.addHook=function(A,l){typeofl=="function"&&tt(R[A],l)},e.removeHook=function(A,l){if(l!==void0){lety=yn(R[A],l);returny===-1?void0:gn(R[A],y,1)[0]}returnSi(R[A])},e.removeHooks=function(A){R[A]=[]},e.removeAllHooks=function(){R=Ii()},e}varDi=Li();varRt=classn{static_keyMetadata=newWeakMap;static_messageSanitizer=null;staticsortObjectKeys(e){if(typeofe!="object"||e===null)returne;if(Array.isArray(e))returne.map(n.sortObjectKeys);lett={};returnObject.keys(e).sort().forEach(r=>{t[r]=n.sortObjectKeys(e[r])}),t}staticassertCryptoKey(e,t=null,r=[]){if(!(einstanceofCryptoKey))thrownewError("Expected CryptoKey");if(t&&e.algorithm?.name!==t)thrownewError(`Expected algorithm ${t}, got ${e.algorithm?.name}`);for(letiofr)if(!e.usages||!e.usages.includes(i))thrownewError(`Missing required key usage: ${i}`)}staticarrayBufferToBase64(e){lett="",r=newUint8Array(e),i=r.byteLength;for(lets=0;s<i;s++)t+=String.fromCharCode(r[s]);returnbtoa(t)}staticbase64ToArrayBuffer(e){try{if(typeofe!="string"||!e)thrownewError("Invalid base64 input: must be a non-empty string");lett=e.trim();if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t))thrownewError("Invalid base64 format");if(t==="")returnnewArrayBuffer(0);letr=atob(t),i=r.length,s=newUint8Array(i);for(leta=0;a<i;a++)s[a]=r.charCodeAt(a);returns.buffer}catch(t){throwconsole.error("Base64 to ArrayBuffer conversion failed:",t.message),newError(`Base64 conversion error: ${t.message}`)}}statichexToUint8Array(e){try{if(!e||typeofe!="string")thrownewError("Invalid hex string input: must be a non-empty string");lett=e.replace(/:/g,"").replace(/\s/g,"");if(!/^[0-9a-fA-F]*$/.test(t))thrownewError("Invalid hex format: contains non-hex characters");if(t.length%2!==0)thrownewError("Invalid hex format: odd length");letr=newUint8Array(t.length/2);for(leti=0;i<t.length;i+=2)r[i/2]=parseInt(t.substr(i,2),16);returnr}catch(t){throwconsole.error("Hex to Uint8Array conversion failed:",t.message),newError(`Hex conversion error: ${t.message}`)}}staticzeroizeBuffer(e){try{if(!e)return;lett=einstanceofUint8Array?e:einstanceofArrayBuffer?newUint8Array(e):null;if(!t||t.length===0)return;crypto.getRandomValues(t),t.fill(0)}catch{}}staticasyncencryptData(e,t){try{letr=typeofe=="string"?e:JSON.stringify(e),i=crypto.getRandomValues(newUint8Array(16)),s=newTextEncoder,a=s.encode(t),o=awaitcrypto.subtle.importKey("raw",a,{name:"PBKDF2"},!1,["deriveKey"]),c=awaitcrypto.subtle.deriveKey({name:"PBKDF2",salt:i,iterations:31e4,hash:"SHA-256"},o,{name:"AES-GCM",length:256},!1,["encrypt"]),d=crypto.getRandomValues(newUint8Array(12)),u=s.encode(r),h=awaitcrypto.subtle.encrypt({name:"AES-GCM",iv:d},c,u),m={version:"1.0",salt:Array.from(i),iv:Array.from(d),data:Array.from(newUint8Array(h)),timestamp:Date.now()},p=JSON.stringify(m);returnn.arrayBufferToBase64(newTextEncoder().encode(p).buffer)}catch(r){throwconsole.error("Encryption failed:",r.message),newError(`Encryption error: ${r.message}`)}}staticasyncdecryptData(e,t){try{letr=n.base64ToArrayBuffer(e),i=newTextDecoder().decode(r),s=JSON.parse(i);if(!s.version||!s.salt||!s.iv||!s.data)thrownewError("Invalid encrypted data format");leta=newUint8Array(s.salt),o=newUint8Array(s.iv),c=newUint8Array(s.data),u=newTextEncoder().encode(t),h=awaitcrypto.subtle.importKey("raw",u,{name:"PBKDF2"},!1,["deriveKey"]),m=awaitcrypto.subtle.deriveKey({name:"PBKDF2",salt:a,iterations:31e4,hash:"SHA-256"},h,{name:"AES-GCM",length:256},!1,["decrypt"]),p=awaitcrypto.subtle.decrypt({name:"AES-GCM",iv:o},m,c),S=newTextDecoder().decode(p);try{returnJSON.parse(S)}catch{returnS}}catch(r){throwconsole.error("Decryption failed:",r.message),newError(`Decryption error: ${r.message}`)}}staticgenerateSecurePassword(){lete="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh
Please wait for real-time cryptographic verification to complete.`,"sec.verificationUnavailable":"Securityverificationnotavailable","chat.placeholder":"Typeanencryptedmessage\u2026","chat.send":"Sendmessage","chat.sendFiles":"Sendfiles","chat.hideFiles":"Hidefiles","chat.recordVoice":"Recordvoicemessage","chat.sendVoice":"Sendvoicemessage","chat.discard":"Discard","chat.codeBlock":"Sendasacodeblock(expandstheinput)","chat.codeHint":"Codesnippet\xB7formattingpreserved\xB7\u2318\u21B5tosend","chat.viewOnce":"Viewonce","chat.viewOnceTitle":"Viewonce-vanishesafterthepeerreadsit","chat.viewOncePrefix":"Viewonce\xB7","chat.viewOnceTap":"Viewonce\xB7taptoreveal","chat.viewedOnce":"Viewedonce","chat.disappearing":"Disappearingmessage-deletesonbothsides","chat.disappearAfter":"Disappearafter","chat.visibleFor":"Visiblefor","chat.timerPrefix":"Timer\xB7","chat.expired":"Thismessagehasexpired","chat.deleteForEveryone":"Deleteforeveryone","chat.sending":"Sending","chat.delivered":"Delivered","chat.notSent":"Notsent","chat.notSentReason":"Notsent-thesecurechannelisnotready.Reconnecttocontinue.","chat.encrypted":"Encrypted","chat.decrypted":"Decrypted","chat.encryptedOnDevice":"Encryptedonyourdevice","chat.uploading":"Uploading","chat.downloading":"Downloading","chat.transferring":"Transferring\u2026","chat.copied":"Copied!","chat.collapse":"Collapse","chat.closeMenu":"Closemenu","chat.newChat":"Newchat","chat.newGroup":"Newgroup","chat.createGroup":"Createagroup","chat.groupChats":"Groupchats","chat.secureChat":"Securechat","chat.nameThis":"Namethischat","chat.rename":"Renamechat(localonly)","chat.renameHint":"Double-clicktorename","chat.localLabel":"Locallabel\xB7storedonlyonthisdevice","chat.setStatus":"Setyourstatus","chat.yourStatusPrefix":"Yourstatus-","chat.meshHint":"Upto8peers\xB7P2Pmesh","chat.offline":"Offline","chat.noNetwork":"Nonetwork\xB7reconnecting","chat.startVoiceCall":"Startencryptedvoicecall","chat.startVideoCall":"Startencryptedvideocall","chat.verifyForCalls":"Verifythesessiontoenablecalls","chat.e2eeNote":"Everymessageisend-to-endencryptedonyourdevicebeforeitleaves.","chat.peersOnly":"Sentend-to-endtoconnectedpeersonly-neverstoredonaserver.","flow.invitationCreated":"Secureinvitationcreated","flow.invitationCreatedBang":"Secureinvitationcreatedandencrypted!","flow.responseCreated":"Secureresponsecreated","flow.responseCreatedBang":"Secureresponsecreated!","flow.sendInvitation":"Sendtheinvitationcodetoyourinterlocutorviaasecurechannel(voicecall,SMS,etc.).","flow.sendResponse":"SendtheresponsecodetotheinitiatorviaasecurechannelorletthemscantheQRcodebelow.","flow.sendEncryptedCode":"Sendtheencryptedcode","flow.sendTheResponse":"Sendtheresponse","flow.pasteOrWrite":"Pasteorwritecode\u2026","flow.processingInvitation":"Processingthesecureinvitation...","flow.processingResponse":"Processingthesecureresponse...","flow.finalizing":"Finalizingthesecureconnection...","flow.channelEstablished":"Securechannelestablished","flow.channelReady":"Securechannelisready","flow.restoring":"Restoringconnection\u2026","flow.invitationCaptured":"Invitationcaptured.","err.needInvitation":"Youneedtoinserttheinvitationcodefromyourinterlocutor.","err.needResponse":"Youneedtoinserttheresponsecodefromyourinterlocutor.","err.responseFormat":"Invalidresponseformat-pleasecheckthecode","err.responseNoKey":"Invalidresponsecode-missingorcorruptedcryptographickey.Pleasecheckthecodeandtryagain.","err.responseNoSignKey":"Invalidresponsecode-missingsignatureverificationkey.Pleasecheckthecodeandtryagain.","err.responseOutdated":"Responsedataisoutdated-pleaseuseafreshinvitation","err.setupError":"Connectionsetuperror","err.notReady":"Connectionnotready","err.securityBreach":"Securitybreachdetected-connectionrejected","err.securityValidation":"Securityvalidationfailed-poss
`}}varFr=newTextEncoder;functionzt(...n){lete=n.reduce((i,s)=>i+s.length,0),t=newUint8Array(e),r=0;for(letiofn)t.set(i,r),r+=i.length;returnt}asyncfunctionKr(n,e){return(awaitn(zt(Fr.encode("sbq2/bind\0"),e))).slice(0,$.BINDING_BYTES)}asyncfunctionVt(n,e){return(awaitn(zt(Fr.encode("sbq2/blob\0"),e))).slice(0,$.COMMITMENT_BYTES)}functionys(n,e,t,r){leti=s=>{leta=newUint8Array(4);returnnewDataView(a.buffer).setUint32(0,s.length),zt(a,s)};returnzt(Fr.encode("sbq2/sas/v1\0"),i(n),i(e),i(t),i(r))}varmt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";functionva(n){lete="";for(lett=0;t<n.length;t+=3){letr=n[t],i=n[t+1],s=n[t+2];if(e+=mt[r>>2],e+=mt[(r&3)<<4|(i??0)>>4],i===void0||(e+=mt[(i&15)<<2|(s??0)>>6],s===void0))break;e+=mt[s&63]}returne}functionTa(n){typeofn!="string"&&F("payload must be a string");lete=n.replace(/\s+/g,"");e.length>Math.ceil($.MAX_PAYLOAD_BYTES*4/3)+4&&F("payload is too long"),/^[A-Za-z0-9_-]*$/.test(e)||F("payload contains characters outside base64url"),e.length%4===1&&F("payload has an impossible length");lett=newUint8Array(Math.floor(e.length*3/4)),r=0,i=0,s=0;for(letaofe)i=i<<6|mt.indexOf(a),s+=6,s>=8&&(s-=8,t[r++]=i>>s&255);returni&(1<<s)-1&&F("payload has non-zero padding bits"),t.subarray(0,r)}varIr="SB2:";functiongs(n){returnIr+va(n)}functionNr(n){typeofn!="string"&&F("payload must be a string");lete=n.trim();returne.startsWith(Ir)||F("not an SB2 descriptor"),Ta(e.slice(Ir.length))}varms=2,Ee=Object.freeze({OFFER:0,ANSWER:1}),We=Object.freeze({MAX_SPKI:256,MIN_SPKI:40,MAX_SIG:160,MIN_SIG:48,MAX_BLOB_BYTES:1024}),Or=classextendsError{constructor(e,t="key_exchange"){super(e),this.name="KeyExchangeError",this.code=t}},le=(n,e)=>{thrownewOr(n,e)};functionSs({role:n,ecdhSpki:e,ecdsaSpki:t}){n!==Ee.OFFER&&n!==Ee.ANSWER&&le("invalid role");for(let[a,o]of[["ecdh",e],["ecdsa",t]])oinstanceofUint8Array||le(`${a} SPKI must be a Uint8Array`),(o.length<We.MIN_SPKI||o.length>We.MAX_SPKI)&&le(`${a} SPKI length out of range`);letr=newUint8Array(4+e.length+2+t.length),i=newDataView(r.buffer),s=0;returnr[s++]=ms,r[s++]=n,i.setUint16(s,e.length),s+=2,r.set(e,s),s+=e.length,i.setUint16(s,t.length),s+=2,r.set(t,s),r}function_s(n){ninstanceofUint8Array||le("key blob must be a Uint8Array"),n.length===0&&le("key blob is empty"),n.length>We.MAX_BLOB_BYTES&&le("key blob exceeds the size limit");lete=newDataView(n.buffer,n.byteOffset,n.byteLength),t=0,r=u=>{t+u>n.length&&le("key blob is truncated")};r(1);leti=n[t++];i!==ms&&le(`unsupported key blob version 0x${i.toString(16)}`,"version"),r(1);lets=n[t++];s!==Ee.OFFER&&s!==Ee.ANSWER&&le("reserved key blob role"),r(2);leta=e.getUint16(t);t+=2,(a<We.MIN_SPKI||a>We.MAX_SPKI)&&le("ECDH SPKI length out of range"),r(a);leto=n.slice(t,t+a);t+=a,r(2);letc=e.getUint16(t);t+=2,(c<We.MIN_SPKI||c>We.MAX_SPKI)&&le("ECDSA SPKI length out of range"),r(c);letd=n.slice(t,t+c);returnt+=c,t!==n.length&&le(`${n.length-t} trailing byte(s) after the key blob`),{version:i,role:s,ecdhSpki:o,ecdsaSpki:d}}functionbs({offerDescriptor:n,answerDescriptor:e,offerBlob:t,answerBlob:r}){for(let[i,s]ofObject.entries({offerDescriptor:n,answerDescriptor:e,offerBlob:t,answerBlob:r}))(!(sinstanceofUint8Array)||s.length===0)&&le(`transcript component ${i} is missing`);returnys(n,e,t,r)}asyncfunctionws(n,e){lett=awaitn.digest("SHA-512",e);returnArray.from(newUint8Array(t))}varEs=newTextEncoder;functionUr(n){lete=Es.encode("sbq2/proof/v1\0"),t=newUint8Array(e.length+n.length);returnt.set(e,0),t.set(n,e.length),t}asyncfunctionvs(n,{ecdhPrivateKey:e,peerEcdhPublicKey:t,transcript:r,digits:i=7}){lets=awaitn.deriveBits({name:"ECDH",public:t},e,256),a=null;try{a=awaitn.importKey("raw",s,"HKDF",!1,["deriveBits"]);leto=newUint8Array(awaitn.digest("SHA-256",r)),c=awaitn.deriveBits({name:"HKDF",hash:"SHA-256",salt:o,info:Es.encode("sbq2-sas-v1")},a,64),d=newDataView(c),u=(d.getUint32(0)^d.getUint32(4))>>>0,h=10**i;returnString(u%h).padStart(i,"0")}finally{try{newUint8Array(s).fill(0)}catch{}}}asyncfuncti
`).map(r=>r.trim()).filter(Boolean).map(r=>({urls:r}));returnRs(t)}functionPs(n){returnArray.isArray(n)?n.some(e=>(Array.isArray(e?.urls)?e.urls:[e?.urls]).some(Ls)):!1}varVe=window.React,Oa=["# One URL per line, e.g.:","stun:stun.example.com:3478","turn:turn.example.com:3478?transport=udp","","# Or paste JSON for servers with credentials:",'[{"urls":"turns:turn.example.com:5349","username":"user","credential":"secret"}]'].join(`
(*! @license DOMPurify 3.4.10 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.10/LICENSE *)