openrtc 0.2.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +49 -0
  2. package/dist/{DelegatingRuntimeAdapter-BxOcVIx_.d.ts → DelegatingRuntimeAdapter-By7pziBs.d.ts} +15 -15
  3. package/dist/IEngineBridge-C7OT2CRv.d.ts +10 -0
  4. package/dist/{IpcRuntimeAdapter-U5AEH0jn.d.ts → IpcRuntimeAdapter-DymXAsNU.d.ts} +2 -2
  5. package/dist/auth/index.js +1 -1
  6. package/dist/auth/internal.js +1 -1
  7. package/dist/chunk-A2ENDDFR.js +2 -0
  8. package/dist/chunk-CK6WQV7J.js +1 -0
  9. package/dist/{chunk-7DN33VUQ.js → chunk-EGEA3GU2.js} +1 -1
  10. package/dist/chunk-KZ3KWQTO.js +1 -0
  11. package/dist/chunk-MA2JFAV7.js +2 -0
  12. package/dist/chunk-OCNLQID3.js +1 -0
  13. package/dist/chunk-VIPNH2BE.js +3 -0
  14. package/dist/device-status-nkXepu97.d.ts +560 -0
  15. package/dist/{framing-lxzHEuSr.d.ts → framing-BUtu0oZK.d.ts} +19 -559
  16. package/dist/index.d.ts +11 -7
  17. package/dist/index.js +2 -2
  18. package/dist/openrtc_bg.wasm +0 -0
  19. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -2
  20. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  21. package/dist/runtime/device-status.d.ts +3 -0
  22. package/dist/runtime/device-status.js +1 -0
  23. package/dist/runtime/index.d.ts +86 -83
  24. package/dist/runtime/index.js +1 -1
  25. package/dist/runtime/tauri.d.ts +4 -3
  26. package/dist/runtime/tauri.js +1 -1
  27. package/dist/transport/index.d.ts +1 -1
  28. package/dist/{types-D0fRvUbN.d.ts → types-CzIpGV9x.d.ts} +87 -5
  29. package/package.json +11 -8
  30. package/dist/chunk-FQETZQPW.js +0 -2
  31. package/dist/chunk-IUHUYHNZ.js +0 -1
  32. package/dist/chunk-UBEE42VU.js +0 -2
  33. package/dist/chunk-UPO23UMZ.js +0 -3
  34. package/dist/chunk-WNJE3MJF.js +0 -1
  35. package/env/index.d.ts +0 -64
  36. package/env/index.mjs +0 -230
@@ -1,3 +0,0 @@
1
- import {a}from'./chunk-IUHUYHNZ.js';import {h,a as a$2,c as c$2,b as b$2,d as d$1}from'./chunk-UBEE42VU.js';import {q,d,u as u$1,s,w as w$1,i,k,c,e,a as a$1,h as h$1,g as g$1,f as f$1}from'./chunk-WNJE3MJF.js';import {t,u,r,q as q$1,g,n,o,p,c as c$1,D,k as k$1,j,l as l$1,b as b$1,B as B$1,e as e$1,f as f$2,a as a$3,i as i$1,h as h$2,v,s as s$1,w as w$2,y,x,z,A}from'./chunk-FQETZQPW.js';import {f,c as c$3,b as b$3}from'./chunk-BLOEZIFJ.js';import {x25519}from'@noble/curves/ed25519.js';import {hkdf}from'@noble/hashes/hkdf.js';import {sha256}from'@noble/hashes/sha2.js';import {getFirestore,collection,onSnapshot}from'firebase/firestore';import*as On from'tweetnacl';var Yn=3e4,Ce=class Ce{constructor(){this.name="webrtc";this.pc=null;this.dc=null;this.state="disconnected";this.pendingCandidates=[];this.connectTimeoutId=null;this.iceDisconnectedGraceTimer=null;this.iceRestartAttempted=false;this.localNodeId="";this.remoteNodeId="";this.candidatesGathered=0;this.sdpOfferSent=false;this.sdpAnswerReceived=false;this._terminalFailure=false;this.activeAttemptId=0;this.negotiationId=null;this.disconnectedGraceExtensions=0;this.offerInFlight=false;this.messageListeners=[];this.stateListeners=[];this.internalSignalSender=null;}get isReady(){return this.state==="connected"}isTerminalFailure(){return this._terminalFailure}getNegotiationId(){return this.negotiationId}getDataChannelReadyState(){return this.dc?.readyState??null}getNativeTransport(){return this.pc}setSignalSender(e){this.internalSignalSender=e;}async init(e$1,t,n){this.closePeerResources();let i=++this.activeAttemptId;this.localNodeId=e$1,this.remoteNodeId=t,this.candidatesGathered=0,this.sdpOfferSent=false,this.sdpAnswerReceived=false,this._terminalFailure=false,this.offerInFlight=false,this.pendingCandidates=[],this.disconnectedGraceExtensions=0,this.negotiationId=typeof n?.negotiationId=="string"&&n.negotiationId.trim().length>0?n.negotiationId.trim():this.createNegotiationId(),this.setState("connecting"),this.startConnectTimeout(i);let o=n.rtcConfig||{},s=typeof n?.forceRole=="string"&&(n.forceRole==="initiator"||n.forceRole==="responder")?n.forceRole:null,a=s?s==="initiator":e$1>t;e(`[WebRTCTransport] init \u2014 role=${a?"initiator":"responder"}`,{local:e$1.slice(0,12),remote:t.slice(0,12),negotiationId:this.negotiationId,forcedRole:s});try{e("[WebRTCTransport] Creating RTCPeerConnection",{iceServers:o.iceServers?.length??0}),this.pc=new RTCPeerConnection(o);}catch(d){console.error("[WebRTCTransport] RTCPeerConnection constructor failed",d),this.setState("failed");return}let c=this.pc.createDataChannel("pluto-dc",{negotiated:true,id:0});this.setupDataChannel(c,i),this.setupPCHandlers(a,i),a&&queueMicrotask(()=>{this.createAndSendOffer(i,"initial-initiator");});}setupDataChannel(e$1,t){this.dc=e$1,e$1.onopen=()=>{this.isCurrentAttempt(t,e$1)&&(e("[WebRTCTransport] DataChannel opened \u2014 upgrade complete"),this.promoteConnectedIfReady("datachannel-open"));},e$1.onmessage=n=>{if(!this.isCurrentAttempt(t,e$1))return;let i=typeof n.data=="string"?new TextEncoder().encode(n.data):new Uint8Array(n.data);this.messageListeners.forEach(o=>o(i));},e$1.onclose=()=>{this.isCurrentAttempt(t,e$1)&&(e("[WebRTCTransport] DataChannel closed"),(this.state==="connected"||this.state==="connecting")&&this.setState("disconnected"));},e$1.onerror=n=>{if(!this.isCurrentAttempt(t,e$1))return;console.warn("[WebRTCTransport] DataChannel error",n);let i=n?.error?.message??"";if((i.includes("User-Initiated Abort")||i.includes("Close called"))&&this.state==="connected"&&e$1.readyState!=="open"){console.warn("[WebRTCTransport] DataChannel aborted post-connect; forcing disconnected state",{readyState:e$1.readyState,connectionState:this.pc?.connectionState,iceConnectionState:this.pc?.iceConnectionState}),this.setState("disconnected");return}this.state==="connecting"&&this.setState("failed");};}setupPCHandlers(e$1,t){let n=this.pc;n&&(n.onicecandidate=i=>{this.isCurrentAttempt(t,void 0,n)&&(i.candidate?(this.candidatesGathered++,e(`[WebRTCTransport] ICE candidate #${this.candidatesGathered}: ${i.candidate.type} ${i.candidate.protocol} ${i.candidate.address??"?"}:${i.candidate.port}`),this.internalSignalSender?this.internalSignalSender({transport:"webrtc",type:"candidate",candidate:i.candidate,negotiationId:this.negotiationId??void 0}).catch(o=>{console.warn("[WebRTCTransport] Failed sending local ICE candidate signal",{error:o,gatheringState:n?.iceGatheringState,iceConnectionState:n?.iceConnectionState});}):console.warn("[WebRTCTransport] ICE candidate dropped \u2014 no signal sender!")):this.candidatesGathered===0?(console.warn("[WebRTCTransport] ICE gathering complete with 0 candidates \u2014 failing immediately.","If both peers are on the same page, WebRTC requires separate tabs or devices.",{local:this.localNodeId.slice(0,12),remote:this.remoteNodeId.slice(0,12)}),this._terminalFailure=true,this.setState("failed")):e(`[WebRTCTransport] ICE gathering complete \u2014 ${this.candidatesGathered} candidate(s)`));},n.onnegotiationneeded=async()=>{e$1&&await this.createAndSendOffer(t,"negotiationneeded");},n.onconnectionstatechange=()=>{if(!this.isCurrentAttempt(t,void 0,n))return;let i=n.connectionState;if(e(`[WebRTCTransport] Connection state: ${i}`),i==="connected")this.promoteConnectedIfReady("pc-connected");else if(i==="failed"){if(this.iceDisconnectedGraceTimer){console.warn("[WebRTCTransport] pc.connectionState=failed during grace window \u2014 deferring to grace timer",{iceState:n.iceConnectionState,iceRestartAttempted:this.iceRestartAttempted});return}console.error("[WebRTCTransport] Connection failed",{iceState:n.iceConnectionState,gatheringState:n.iceGatheringState,signalingState:n.signalingState,candidatesGathered:this.candidatesGathered,sdpOfferSent:this.sdpOfferSent,sdpAnswerReceived:this.sdpAnswerReceived}),this.clearIceDisconnectedGrace("pc-failed"),this.setState("failed");}else i==="closed"?(this.clearIceDisconnectedGrace("pc-closed"),this.setState("disconnected")):i==="disconnected"&&(e("[WebRTCTransport] pc.connectionState=disconnected, deferring to ICE grace period"),this.startIceDisconnectedGrace(t,n,e$1,"pc-disconnected"));},n.oniceconnectionstatechange=()=>{if(!this.isCurrentAttempt(t,void 0,n))return;let i=n.iceConnectionState;if(e(`[WebRTCTransport] ICE connection state: ${i}`,{gatheringState:n.iceGatheringState,signalingState:n.signalingState,candidatesGathered:this.candidatesGathered,hasSdpOffer:this.sdpOfferSent,hasSdpAnswer:this.sdpAnswerReceived,hasRemoteDescription:!!n.remoteDescription,hasLocalDescription:!!n.localDescription}),i==="failed"){if(this.iceDisconnectedGraceTimer){console.warn("[WebRTCTransport] ice failed during grace window \u2014 deferring to grace timer");return}console.error("[WebRTCTransport] ICE failed \u2014 likely NAT traversal issue or no matching candidates",{gatheringState:n.iceGatheringState,signalingState:n.signalingState,candidatesGathered:this.candidatesGathered}),this.clearIceDisconnectedGrace("ice-failed"),this.setState("failed");}else i==="disconnected"?this.startIceDisconnectedGrace(t,n,e$1,"ice-disconnected"):(i==="connected"||i==="completed")&&(this.iceDisconnectedGraceTimer&&e("[WebRTCTransport] ice-recovered \u2014 cancelling grace timer"),this.clearIceDisconnectedGrace("ice-recovered"),this.iceRestartAttempted=false,this.promoteConnectedIfReady("ice-connected"));},n.onicegatheringstatechange=()=>{this.isCurrentAttempt(t,void 0,n)&&e(`[WebRTCTransport] ICE gathering state: ${n.iceGatheringState}`,{iceConnectionState:n.iceConnectionState,signalingState:n.signalingState,hasLocalDesc:!!n.localDescription,hasRemoteDesc:!!n.remoteDescription});});}async createAndSendOffer(e$1,t){let n=this.pc;if(!(!n||!this.isCurrentAttempt(e$1,void 0,n))&&n.signalingState==="stable"&&!(this.sdpOfferSent&&n.localDescription?.type==="offer")&&!this.offerInFlight){e(`[WebRTCTransport] Creating offer (${t})`),this.offerInFlight=true;try{let i=await n.createOffer();if(await n.setLocalDescription(i),!this.isCurrentAttempt(e$1,void 0,n))return;if(this.sdpOfferSent=!0,this.internalSignalSender)try{await this.internalSignalSender({transport:"webrtc",type:"sdp",sdp:i,negotiationId:this.negotiationId??void 0});}catch(o){console.warn("[WebRTCTransport] Offer signaling failed (non-fatal)",{error:o,negotiationId:this.negotiationId,signalingState:n.signalingState,iceConnectionState:n.iceConnectionState});}else console.warn("[WebRTCTransport] No signal sender \u2014 offer not transmitted");}catch(i){console.error("[WebRTCTransport] Offer creation failed",i),this.closePeerResources(),this.setState("failed");}finally{this.isCurrentAttempt(e$1,void 0,n)&&(this.offerInFlight=false);}}}handleSignalingMessage(e$1){if(!this.pc||e$1.transport!=="webrtc")return;let t=this.normalizeNegotiationId(e$1?.negotiationId);if(t&&this.negotiationId&&t!==this.negotiationId){d("[WebRTCTransport] Ignoring stale signaling message for a different negotiation",{signalType:e$1?.type??null,signalNegotiationId:t,activeNegotiationId:this.negotiationId});return}if(e$1.type==="candidate"){let n=e$1.candidate;e("[WebRTCTransport] Received remote ICE candidate",{hasRemoteDesc:!!this.pc.remoteDescription,type:n?.type,protocol:n?.protocol,address:n?.address}),this.pc.remoteDescription?this.pc.addIceCandidate(n).catch(i=>{console.warn("[WebRTCTransport] addIceCandidate failed",i);}):(this.pendingCandidates.push(n),e(`[WebRTCTransport] Buffered remote candidate \u2014 ${this.pendingCandidates.length} pending`));}else if(e$1.type==="sdp"){let n=e$1.sdp,i=n.type==="offer",o=n.type==="answer";if(o&&this.pc.signalingState!=="have-local-offer"){d("[WebRTCTransport] Ignoring SDP answer because no local offer is pending",{signalingState:this.pc.signalingState,iceConnectionState:this.pc.iceConnectionState,signalNegotiationId:t,activeNegotiationId:this.negotiationId,hasLocalDescription:!!this.pc.localDescription,hasRemoteDescription:!!this.pc.remoteDescription});return}e(`[WebRTCTransport] Received SDP ${n.type} \u2014 applying remote description`),o&&(this.sdpAnswerReceived=true),this.pc.setRemoteDescription(n).then(async()=>{if(o&&(e("[WebRTCTransport] Remote SDP answer applied",{signalingState:this.pc?.signalingState,iceConnectionState:this.pc?.iceConnectionState,hasLocalDescription:!!this.pc?.localDescription,hasRemoteDescription:!!this.pc?.remoteDescription}),this.promoteConnectedIfReady("sdp-answer-applied")),this.pendingCandidates.length&&(e(`[WebRTCTransport] Flushing ${this.pendingCandidates.length} buffered candidate(s)`),this.pendingCandidates.forEach(s=>this.pc?.addIceCandidate(s)),this.pendingCandidates=[]),i){e("[WebRTCTransport] Creating answer (responder)");let s=await this.pc.createAnswer();if(await this.pc.setLocalDescription(s),e("[WebRTCTransport] Answer sent"),this.internalSignalSender)try{await this.internalSignalSender({transport:"webrtc",type:"sdp",sdp:s,negotiationId:t??this.negotiationId??void 0});}catch(a){throw console.warn("[WebRTCTransport] Failed sending SDP answer signal",{error:a,signalingState:this.pc?.signalingState,hasLocalDescription:!!this.pc?.localDescription,hasRemoteDescription:!!this.pc?.remoteDescription}),a}else console.warn("[WebRTCTransport] No signal sender \u2014 answer not transmitted");}}).catch(s=>{console.error(`[WebRTCTransport] setRemoteDescription (${n.type}) failed`,s),this.setState("failed");});}}async send(e){if(this.dc&&this.dc.readyState==="open"){let t=new Uint8Array(e);this.dc.send(t);}else throw new Error("WebRTC DataChannel not open")}getBufferedAmount(){return this.dc?.bufferedAmount??0}async waitForDrain(e){!this.dc||this.dc.bufferedAmount<=e||await new Promise(t=>{let n=this.dc;if(!n){t();return}n.bufferedAmountLowThreshold=e,n.onbufferedamountlow=()=>{n.onbufferedamountlow=null,t();};});}close(){this.closePeerResources(),this.setState("disconnected");}onMessage(e){this.messageListeners.push(e);}onStateChange(e){this.stateListeners.push(e);}setState(e){this.state!==e&&(this.state=e,(e==="connected"||e==="failed"||e==="disconnected")&&this.clearConnectTimeout(),this.stateListeners.forEach(t=>t(e)));}startConnectTimeout(e){this.clearConnectTimeout(),this.connectTimeoutId=setTimeout(()=>{this.activeAttemptId===e&&this.state==="connecting"&&(console.warn(`[WebRTCTransport] Timed out after ${Ce.ICE_CONNECT_TIMEOUT_MS}ms`,{iceState:this.pc?.iceConnectionState,gatheringState:this.pc?.iceGatheringState,signalingState:this.pc?.signalingState,candidatesGathered:this.candidatesGathered,sdpOfferSent:this.sdpOfferSent,sdpAnswerReceived:this.sdpAnswerReceived,hasRemoteDescription:!!this.pc?.remoteDescription,hasLocalDescription:!!this.pc?.localDescription}),this.setState("failed"));},Ce.ICE_CONNECT_TIMEOUT_MS);}clearConnectTimeout(){this.connectTimeoutId&&(clearTimeout(this.connectTimeoutId),this.connectTimeoutId=null);}startIceDisconnectedGrace(e$1,t,n,i){if(!this.iceDisconnectedGraceTimer){if(this.iceRestartAttempted)e("[WebRTCTransport] ice-disconnected grace (restart already attempted)",{reason:i});else if(this.iceRestartAttempted=true,n){try{e("[WebRTCTransport] ice-restart-attempted",{reason:i,isInitiator:n}),t.restartIce();}catch(o){console.warn("[WebRTCTransport] restartIce threw",o);}this.sendIceRestartOffer(e$1,t);}else e("[WebRTCTransport] ice-restart deferred to initiator",{reason:i});this.iceDisconnectedGraceTimer=setTimeout(()=>{if(this.iceDisconnectedGraceTimer=null,this.activeAttemptId!==e$1||this.pc!==t)return;let o=t.iceConnectionState,s=t.connectionState,a=this.dc?.readyState??"missing";if(o==="connected"||o==="completed"||s==="connected"||a==="open"){e("[WebRTCTransport] ice-grace expired \u2014 recovered",{ice:o,conn:s,dcReadyState:a});return}if(this.disconnectedGraceExtensions<1){this.disconnectedGraceExtensions+=1,console.warn("[WebRTCTransport] ice-grace expired \u2014 extending once before fail",{ice:o,conn:s,dcReadyState:a,extension:this.disconnectedGraceExtensions}),this.startIceDisconnectedGrace(e$1,t,n,`${i}:extended`);return}console.warn("[WebRTCTransport] ice-grace expired \u2014 marking failed",{ice:o,conn:s}),this.setState("failed");},Ce.ICE_DISCONNECTED_GRACE_MS);}}async sendIceRestartOffer(e$1,t){try{let n=await t.createOffer({iceRestart:!0});if(!this.isCurrentAttempt(e$1,void 0,t)||(await t.setLocalDescription(n),!this.isCurrentAttempt(e$1,void 0,t)))return;this.internalSignalSender?(await this.internalSignalSender({transport:"webrtc",type:"sdp",sdp:n,negotiationId:this.negotiationId??void 0}),e("[WebRTCTransport] ice-restart re-offer sent",{negotiationId:this.negotiationId})):console.warn("[WebRTCTransport] ice-restart re-offer dropped \u2014 no signal sender");}catch(n){console.warn("[WebRTCTransport] ice-restart re-offer failed",n);}}clearIceDisconnectedGrace(e){this.iceDisconnectedGraceTimer&&(clearTimeout(this.iceDisconnectedGraceTimer),this.iceDisconnectedGraceTimer=null);}promoteConnectedIfReady(e$1){let t=this.dc?.readyState??"missing";if(t!=="open"){e("[WebRTCTransport] Deferring connected state until DataChannel is open",{reason:e$1,dcReadyState:t,iceConnectionState:this.pc?.iceConnectionState,connectionState:this.pc?.connectionState});return}this.clearIceDisconnectedGrace(`connected:${e$1}`),this.disconnectedGraceExtensions=0,this.setState("connected");}closePeerResources(){this.activeAttemptId+=1,this.clearConnectTimeout(),this.clearIceDisconnectedGrace("close"),this.iceRestartAttempted=false,this.pendingCandidates=[],this._terminalFailure=false,this.negotiationId=null,this.disconnectedGraceExtensions=0,this.offerInFlight=false,this.dc&&(this.dc.onopen=null,this.dc.onmessage=null,this.dc.onclose=null,this.dc.onerror=null,this.dc.readyState!=="closed"&&this.dc.close(),this.dc=null),this.pc&&(this.pc.onicecandidate=null,this.pc.onnegotiationneeded=null,this.pc.onconnectionstatechange=null,this.pc.oniceconnectionstatechange=null,this.pc.connectionState!=="closed"&&this.pc.close(),this.pc=null);}isCurrentAttempt(e,t,n){return !(this.activeAttemptId!==e||t&&this.dc!==t||n&&this.pc!==n)}createNegotiationId(){return `ts-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}normalizeNegotiationId(e){if(typeof e!="string")return null;let t=e.trim();return t.length>0?t:null}};Ce.ICE_CONNECT_TIMEOUT_MS=Yn,Ce.ICE_DISCONNECTED_GRACE_MS=2e4;var pt=Ce;var ue=class{static createTransport(e){if(this.assertProtocolAvailable(e),e==="webrtc")return new pt;throw new Error(`[TransportFactory] '${e}' is not implemented as an ITransport plugin.`)}static getProtocolCapability(e){return {...this.capabilityMap[e]}}static getProtocolCapabilities(){return {iroh:this.getProtocolCapability("iroh"),"iroh-quic":this.getProtocolCapability("iroh-quic"),"iroh-relay":this.getProtocolCapability("iroh-relay"),"iroh-lan":this.getProtocolCapability("iroh-lan"),ble:this.getProtocolCapability("ble"),webrtc:this.getProtocolCapability("webrtc"),"webrtc-lan":this.getProtocolCapability("webrtc-lan"),moq:this.getProtocolCapability("moq")}}static getPreferredProtocolOrder(e={}){let t=e.runtime??"any",n=e.includePathLabels??true;return Object.values(this.capabilityMap).filter(i=>n||i.implementation!=="path-label").filter(i=>t==="browser"?i.browser:t==="native"?i.native:i.browser||i.native).sort((i,o)=>i.preferredRank-o.preferredRank).map(i=>i.protocol)}static assertProtocolAvailable(e){let t=this.capabilityMap[e];if(!t.available||t.maturity==="unsupported"){let n=t.reason?` ${t.reason}`:"";throw new Error(`[TransportFactory] Protocol '${e}' is unsupported.${n}`)}}};ue.capabilityMap={iroh:{protocol:"iroh",baseProtocol:"iroh",implementation:"native",locality:"mixed",maturity:"stable",preferredRank:80,browser:true,native:true,available:true},"iroh-quic":{protocol:"iroh-quic",baseProtocol:"iroh",implementation:"path-label",locality:"direct-internet",maturity:"stable",preferredRank:30,browser:false,native:true,available:false,reason:"iroh-quic is a path label, not a standalone transport."},"iroh-relay":{protocol:"iroh-relay",baseProtocol:"iroh",implementation:"path-label",locality:"relay",maturity:"stable",preferredRank:70,browser:true,native:true,available:false,reason:"iroh-relay is a path label, not a standalone transport."},"iroh-lan":{protocol:"iroh-lan",baseProtocol:"iroh",implementation:"path-label",locality:"nearby",maturity:"stable",preferredRank:10,browser:false,native:true,available:false,reason:"iroh-lan is a path label, not a standalone transport."},ble:{protocol:"ble",baseProtocol:"iroh",implementation:"path-label",locality:"nearby",maturity:"stable",preferredRank:25,browser:false,native:true,available:false,reason:"ble is a native iroh custom-transport path label, not a browser ITransport plugin."},webrtc:{protocol:"webrtc",baseProtocol:"webrtc",implementation:"plugin",locality:"mixed",maturity:"stable",preferredRank:40,browser:true,native:true,available:true},"webrtc-lan":{protocol:"webrtc-lan",baseProtocol:"webrtc",implementation:"path-label",locality:"nearby",maturity:"stable",preferredRank:20,browser:true,native:true,available:false,reason:"webrtc-lan is a path label, not a standalone transport."},moq:{protocol:"moq",baseProtocol:"moq",implementation:"plugin",locality:"relay",maturity:"experimental",preferredRank:50,browser:true,native:true,available:true,reason:"Client-level session lifecycle with evolving media/data semantics."}};function Ec(r){return ue.getPreferredProtocolOrder(r)}var ut=32,co="openrtc:x25519-hkdf:v1",Xn=new TextEncoder().encode("openrtc:application-crypto:v1");function gt(r,e){if(!(e instanceof Uint8Array)||e.byteLength!==ut)throw new Error(`[OpenRTC] ${r} must be ${ut} bytes`)}function Fs(r,e){let[t,n]=r<=e?[r,e]:[e,r],i=new TextEncoder().encode(t),o=new TextEncoder().encode(n),s=new Uint8Array(Xn.byteLength+1+i.byteLength+1+o.byteLength),a=0;return s.set(Xn,a),a+=Xn.byteLength,s[a]=0,a+=1,s.set(i,a),a+=i.byteLength,s[a]=0,a+=1,s.set(o,a),s}function lo(r=e=>{let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),t}){let e=r(ut);return gt("key agreement secret",e),{publicKey:x25519.getPublicKey(e),secretKey:e}}function po(r,e,t,n){gt("key agreement local secret",r),gt("key agreement remote public key",e);let i=x25519.getSharedSecret(r,e);return hkdf(sha256,i,void 0,Fs(t,n),32)}function uo(r){gt("key agreement public key",r);let e="";for(let n=0;n<r.byteLength;n+=1)e+=String.fromCharCode(r[n]);let t=btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"");return {algorithm:co,publicKey:t}}function go(r){if(!r||r.algorithm!==co)return null;let e=typeof r.publicKey=="string"?r.publicKey.trim():"";if(!e)return null;let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.length%4===0?t:t+"=".repeat(4-t.length%4),i=Uint8Array.from(atob(n),o=>o.charCodeAt(0));return i.byteLength!==ut?null:i}var ht=class{constructor(e,t){this._disposed=false;this.cleanups=[];this.runtime=e,this.scope=t.scope,this.allowAllPeers=t.allowAllPeers??false,this.allowedPeerIds=new Set(t.allowPeers??[]);}get disposed(){return this._disposed}matchesPeer(e){if(this.allowAllPeers||e.scopes?.includes(this.scope))return true;if(this.allowedPeerIds.size>0){let t=[e.peerId,e.deviceId,e.deviceIdHint,e.connectionId];for(let n of t)if(n&&this.allowedPeerIds.has(n))return true}return false}matchesConnectionState(e){if(this.allowAllPeers)return true;let t=e.scopes;if(Array.isArray(t)&&t.includes(this.scope))return true;if(this.allowedPeerIds.size>0){let n=[e.connectionId,e.deviceId,e.deviceIdHint,e.remoteNodeId];for(let i of n)if(i&&this.allowedPeerIds.has(i))return true}return false}matchesStream(e){if(this.allowAllPeers)return true;let t=e.scopes;return !!(Array.isArray(t)&&t.includes(this.scope)||this.allowedPeerIds.size>0&&this.allowedPeerIds.has(e.remoteNodeId))}watchPeerStates(e){this.assertNotDisposed();let t=this.runtime.watchPeerStates(n=>{if(this._disposed)return;let i=this.allowAllPeers?n:n.filter(o=>this.matchesPeer(o));e(i);});return this.cleanups.push(t),t}onConnectionStateChange(e){this.assertNotDisposed();let t=o=>{this._disposed||this.matchesConnectionState(o)&&e(o);},n=this.runtime.onConnectionStateChange(t);return typeof n=="function"?(this.cleanups.push(n),n):n.then(o=>this._disposed?(o(),()=>{}):(this.cleanups.push(o),o))}listConnectedPeers(){this.assertNotDisposed();let e=this.runtime.listConnectedPeers();return this.allowAllPeers?e:e.filter(t=>this.matchesPeer(t))}async getPeerReadiness(e){return this.assertNotDisposed(),this.runtime.getPeerReadiness(e)}connectPeer(e){return this.assertNotDisposed(),this.runtime.connectPeer({...e,scope:e.scope??this.scope})}async disconnectPeer(e){return this.assertNotDisposed(),this.runtime.disconnectPeer(e,this.scope)}onIncomingStream(e){this.assertNotDisposed();let t=this.runtime.onIncomingStream(n=>{this._disposed||this.matchesStream(n)&&e(n);});return this.cleanups.push(t),t}dispose(){if(!this._disposed){this._disposed=true;for(let e of this.cleanups)try{e();}catch{}this.cleanups.length=0,this.releaseScopedPeersOnDispose();}}releaseScopedPeersOnDispose(){let e;try{e=this.runtime.listConnectedPeers();}catch{return}for(let t of e){if(!t.scopes?.includes(this.scope))continue;let n=t.peerId||t.connectionId||t.deviceId||t.deviceIdHint;n&&this.runtime.disconnectPeer(n,this.scope).catch(()=>{});}}assertNotDisposed(){if(this._disposed)throw new Error(`[Session] Session '${this.scope}' has been disposed.`)}};var mt=class{constructor(e,t){this.client=e;this.backend=t;}async connectToDevice(e){let t=this.backend;if(!t||typeof t.connectToDevice!="function")throw new Error("Selected runtime adapter does not support connectToDevice().");return e.deviceId&&(this.clearManualDisconnectProjection(e.deviceId),await t.setAutoConnectExcluded?.(e.deviceId,false).catch(()=>{})),t.connectToDevice(e)}async connectRaw(e){return this.client.connectRaw(e.ticket,e.timeoutMs)}async openBi(e){return this.client.openBi(e)}async openUni(e){return this.client.openUni(e)}async isConnected(e){return this.client.isConnected(e)}async disconnectNode(e){await this.client.disconnectNode(e);}async disconnectDevice(e){let t=this.backend;await t?.setAutoConnectExcluded?.(e,true).catch(()=>{});try{t&&typeof t.disconnectDevice=="function"&&await t.disconnectDevice(e);}finally{await this.client.forceDisconnectPeer(e);}}async setAutoConnectExcluded(e,t){let n=this.backend;n&&typeof n.setAutoConnectExcluded=="function"&&await n.setAutoConnectExcluded(e,t),t||this.clearManualDisconnectProjection(e);}async disconnectPeer(e,t){await this.client.disconnectPeer(e,t);}async forceDisconnectPeer(e){await this.client.forceDisconnectPeer(e);}clearManualDisconnectProjection(e){let t=this.client.clearManualDisconnectProjection;typeof t=="function"&&t.call(this.client,e);}};var mo={classifyScope(r){return r.startsWith("drive-grant:")?{sessionKind:"drive-grant-guest",grantId:r.slice(12),scope:r}:r==="user-device"?{sessionKind:"app-user-device",scope:r}:{scope:r}}},Os=[["sessionKind","session_kind"],["grantId","grant_id"],["scope","scope"],["peerNodeId","peer_node_id"],["connectionId","connection_id"],["transportEpoch","transport_epoch"],["channel","channel"],["tokenFp","token_fp"]];function Ws(r){let e=[];for(let[t,n]of Os){let i=r[t];i==null||i===""||e.push(`${n}=${i}`);}return e.join(" ")}function Us(r,e,t=mo){let n=t.classifyScope(r);return {...{sessionKind:n.sessionKind,grantId:n.grantId,scope:n.scope??r},...e??{}}}function je(r,e){return Us(r,e,mo)}function X(r,e,t,...n){let i=Ws(e),o=Hs(t,n);console.log(i&&o?`${r} ${i} ${o}`:i?`${r} ${i}`:o?`${r} ${o}`:r);}function Hs(r,e){if(!r)return "";if(e.length===0)return r;if(/\{\}/.test(r)){let n=0;return r.replace(/\{\}/g,()=>{let i=n<e.length?e[n]:"";return n+=1,ho(i)})}return [r,...e.map(ho)].join(" ")}function ho(r){if(r==null)return String(r);if(typeof r=="string")return r;if(typeof r=="number"||typeof r=="boolean")return String(r);try{return JSON.stringify(r)}catch{return String(r)}}var ee=class extends Error{constructor(e,t){super(t),this.kind=e,this.name="DriveGrantActorError";}};function Zn(r,e){return {scope:r,peerNodeId:e}}function Jn(r){return `${r.scope}@${r.peerNodeId}`}var Ke=class{constructor(e){this.state="idle";this.inFlight=null;this.key=e.key,this.dial=e.dial,this.close=e.close??(async()=>{});}isReady(){return this.state==="base-ready"||this.state==="protocol-ready"}isClosed(){return this.state==="closed"}getState(){return this.state}getPreferredTransport(){return this.state==="closed"||this.state==="idle"||this.state==="dialing"?"none":"base"}markProtocolReady(){this.state!=="closed"&&(this.state="protocol-ready",X("[drive-grant-actor][state]",this.correlation(),"state=protocol-ready"));}markDegraded(){this.state!=="closed"&&(this.state="degraded",X("[drive-grant-actor][state]",this.correlation(),"state=degraded"));}correlation(e){return je(this.key.scope,{peerNodeId:this.key.peerNodeId,...e??{}})}async ensureReady(){if(this.state==="closed")throw new ee("shutdown","drive-grant actor: already shut down");if(!this.isReady())return this.inFlight?this.inFlight:(this.state="dialing",X("[drive-grant-actor][dial]",this.correlation(),"begin"),this.inFlight=this.dial(this.key).then(()=>{this.state!=="closed"&&(this.state="base-ready",this.inFlight=null,X("[drive-grant-actor][dial]",this.correlation(),"ready_first"));},e=>{this.state!=="closed"&&(this.state="idle"),this.inFlight=null;let t=e instanceof Error?e.message:String(e);throw X("[drive-grant-actor][dial]",this.correlation(),"failed error={}",t),e instanceof ee?e:new ee("dial-failed",`drive-grant actor: dial failed: ${t}`)}),this.inFlight)}async openLogicalChannel(e){if(this.state==="closed")throw new ee("shutdown","drive-grant actor: already shut down");if(!this.isReady())throw new ee("not-ready","drive-grant actor: ensureReady() must resolve before openLogicalChannel");return X("[drive-grant-actor][channel]",this.correlation({channel:e}),"open"),{label:e}}async openLogicalChannelTestStub(e){if(this.state==="closed")throw new ee("shutdown","drive-grant actor: already shut down");if(!this.isReady())throw new ee("not-ready","drive-grant actor: ensureReady() must resolve before openLogicalChannel");return {label:e}}async shutdown(){if(this.state!=="closed"){this.state="closed",this.inFlight=null,X("[drive-grant-actor][shutdown]",this.correlation(),"begin");try{await this.close(this.key);}catch{}X("[drive-grant-actor][shutdown]",this.correlation(),"complete");}}},Ge=class{constructor(e){this.actors=new Map;this.factory=e;}getOrSpawn(e,t){let n=Jn(e),i=this.actors.get(n);if(i&&!i.isClosed())return i;let o=(t??this.factory)(e);return this.actors.set(n,o),o}get(e){return this.actors.get(Jn(e))??null}async shutdownAll(){let e=[...this.actors.values()];this.actors.clear(),await Promise.all(e.map(t=>t.shutdown()));}size(){return this.actors.size}};var js=new TextEncoder,Ks=new TextDecoder;function ei(r){let e=new Uint8Array(4+r.byteLength);return new DataView(e.buffer,e.byteOffset,e.byteLength).setUint32(0,r.byteLength,false),e.set(r,4),e}function Gs(r){let e=new Uint8Array(0);return t=>{for(e=ti(e,t);e.byteLength>=4;){let n=ni(e,0);if(e.byteLength<4+n)break;r(e.slice(4,4+n)),e=e.slice(4+n);}}}function qs(r){return js.encode(JSON.stringify(r))}function Vs(r){return JSON.parse(Ks.decode(r))}function $c(r){return ei(qs(r))}function zc(r,e={}){return Gs(t=>{try{r(Vs(t),t);}catch(n){if(e.onInvalidJson){e.onInvalidJson(n,t);return}throw n}})}function ti(r,e){return t([r,e])}function ni(r,e){return (r[e]<<24|r[e+1]<<16|r[e+2]<<8|r[e+3])>>>0}var Se=class{constructor(e,t){this.appTag=c$1(e),this.backend=t;}get tag(){return this.appTag}async waitForAuth(){return this.backend.waitForAuth()}get currentUser(){return this.backend.currentUser}getRtdbPresence(){let e=this.backend;return typeof e.getRtdbPresence=="function"?e.getRtdbPresence():e.rtdbPresence??null}onAuthChange(e){return this.backend.onAuthChange(e)}async signInAnonymously(){await this.backend.signInAnonymously();}async signInWithPluto(){if(typeof this.backend.signInWithPluto=="function"){await this.backend.signInWithPluto();return}await D().signInWithPluto();}async signOut(){await this.backend.signOut();}async stopAuthScopedActivity(){typeof this.backend.stopAuthScopedActivity=="function"&&await this.backend.stopAuthScopedActivity();}getRuntimeCapabilities(){return this.backend.getRuntimeCapabilities?.()}async getTurnCredentials(){return this.backend.getTurnCredentials()}async updatePresence(e,t,n=true,i=300*1e3,o){await this.backend.updatePresence(e,t,n,i,o);}async setOffline(e){await this.backend.setOffline(e);}async cleanupStaleDevices(){await this.backend.cleanupStaleDevices();}async sendMessage(e,t,n,i){return this.backend.sendMessage(e,t,n,i)}async pollMessages(e){return this.backend.pollMessages(e)}async subscribeSessions(e,t){let i=(await this.backend.subscribeSessions(e)).getReader(),o=false;return (async()=>{try{for(;!o;){let{done:a,value:c}=await i.read();if(a)break;if(c)for(let d of c)"session"in d&&d.session&&await t(d.session);}}catch(a){o||console.error("[Signaling] Session stream error:",a);}})(),()=>{o=true,i.cancel();}}async getLocalDeviceId(){return typeof this.backend.getLocalDeviceId!="function"?null:this.backend.getLocalDeviceId()}async searchDevices(e){return this.backend.searchDevices(e)}async updateDevice(e,t){await this.backend.updateDevice(e,t);}async deleteDevice(e){await this.backend.deleteDevice(e);}onDevicesChange(e,t){return this.backend.onDevicesChange(e,t)}startAutoConnect(e,t){this.backend.startAutoConnect(e,t);}notifyDisconnectRequested(e){typeof this.backend.notifyDisconnectRequested=="function"&&this.backend.notifyDisconnectRequested(e);}startPresenceLoop(e,t,n,i,o){this.backend.startPresenceLoop(e,t,n,i,o);}forceReconnectSnapshot(){this.backend.forceReconnectSnapshot();}async isConnected(e){return this.backend.isConnected(e)}async getConnectionStates(){return typeof this.backend.getConnectionStates=="function"?this.backend.getConnectionStates():[]}onConnectionStateChange(e){return typeof this.backend.onConnectionStateChange=="function"?this.backend.onConnectionStateChange(e):()=>{}}supportsRustPeerLifecycleProjection(){return typeof this.backend.listPeerSessions=="function"||typeof this.backend.getPeerSession=="function"||typeof this.backend.waitForSettledPeer=="function"||typeof this.backend.getConnectionStates=="function"}setWasmClient(e){let t=this.backend;t&&typeof t.setWasmClient=="function"&&t.setWasmClient(e);}};var Ys=6e5,Xs=250,Js=20,ft=class{constructor(e){this.options=e;this.rtdbPresence=null;this.firestore=getFirestore(e.app);}setRtdbPresence(e){this.rtdbPresence=e;}watchMembers(e,t,n){let i=collection(this.firestore,`${this.getNamespaceRoot()}/rooms/${e}/members`);return this.rtdbPresence?this.watchMembersWithRtdb(e,t,i,n):this.watchMembersSnapshot(i,o=>{let s=Date.now(),a=o.docs.map(c=>this.toRoomMember(c)).filter(c=>!!c).filter(c=>c.nodeId!==t).filter(c=>!this.isExpired(c,s)).sort((c,d)=>c.joinedAt!==d.joinedAt?c.joinedAt-d.joinedAt:c.nodeId.localeCompare(d.nodeId));n(a);})}watchMembersWithRtdb(e,t,n,i){let o=this.rtdbPresence,s=this.getAppTag(),a=[],c={},d=()=>{let g=Date.now(),f=a.filter(v=>v.nodeId!==t).filter(v=>!this.isExpired(v,g)).filter(v=>{let y=c[v.nodeId];return !(y&&!y.online)}).sort((v,y)=>v.joinedAt!==y.joinedAt?v.joinedAt-y.joinedAt:v.nodeId.localeCompare(y.nodeId));i(f);},p=this.watchMembersSnapshot(n,g=>{a=g.docs.map(f=>this.toRoomMember(f)).filter(f=>!!f),d();}),u=o.onRoomPresenceChange(s,e,g=>{c=g,d();});return ()=>{p(),u();}}watchMembersSnapshot(e,t){let n=false,i=0,o=null,s=null,a=()=>{n||(s=onSnapshot(e,c=>{i=0,t(c);},c=>{if(s=null,this.isTransientPermissionError(c)&&i<Js){i+=1,o=setTimeout(a,Xs);return}console.warn("[BrowserFirestoreRooms] room watch failed:",c);}));};return a(),()=>{n=true,o&&(clearTimeout(o),o=null),s?.(),s=null;}}isTransientPermissionError(e){if(e?.code==="permission-denied")return true;let n=e instanceof Error?e.message:String(e);return /permission-denied|missing or insufficient permissions/i.test(n)}getNamespaceRoot(){let e=this.options.getRoomBackendTag().trim();if(!e)throw new Error("Room backend tag is required for browser room watches");return e.startsWith("space::")?`spaces/${e.slice(7)}`:`apps/${e}`}getAppTag(){return this.options.getRoomBackendTag().trim()}toRoomMember(e){let t=e.data(),n=typeof t.nodeId=="string"&&t.nodeId.trim().length>0?t.nodeId.trim():e.id,i=typeof t.ticket=="string"?t.ticket:"";return {nodeId:n,userId:typeof t.userId=="string"?t.userId:"",ticket:i,joinedAt:this.toMillis(t.joinedAt)??0,lastSeenAt:this.toMillis(t.lastSeenAt)??0,expiresAt:this.toMillis(t.expiresAt)}}isExpired(e,t){if(typeof e.expiresAt=="number")return e.expiresAt<=t;let n=e.lastSeenAt||e.joinedAt||0;return n>0&&n+Ys<=t}toMillis(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let t=Number(e);if(Number.isFinite(t))return t;let n=Date.parse(e);return Number.isNaN(n)?void 0:n}if(e instanceof Date)return e.getTime();if(e&&typeof e=="object"&&typeof e.toMillis=="function")try{return e.toMillis()}catch{return}}};function fo(r){return {get wasmClient(){return r.wasmClient},get roomCreationMode(){return r.roomCreationMode},get appLimits(){return r.appLimits},ensureAuthenticated:e=>r.ensureAuthenticated(e),getTicket:()=>r.getTicket(),getNodeId:()=>r.getNodeId(),connect:(e,t)=>r.connect(e,t),refreshHostedAppSettings:e=>r.refreshHostedAppSettings(e),usesDirectRoomBackend:()=>r.usesDirectRoomBackend(),getRoomBackendTag:()=>r.getRoomBackendTag()}}var ke=class{constructor(e,t){this.heartbeatStops=new Map;this.browserRooms=null;this.rtdbPresence=null;this.client=e,this.signaling=t;}getBrowserRooms(){return this.browserRooms||(this.browserRooms=new ft({app:D().getApp(),getRoomBackendTag:()=>this.client.getRoomBackendTag()})),this.rtdbPresence&&this.browserRooms&&this.browserRooms.setRtdbPresence(this.rtdbPresence),this.browserRooms}setRtdbPresence(e){this.rtdbPresence=e,this.browserRooms&&this.browserRooms.setRtdbPresence(e);}syncRtdbPresenceFromSignaling(){if(this.rtdbPresence)return;let e=this.signaling.getRtdbPresence();if(e){this.setRtdbPresence(e);return}try{this.setRtdbPresence(new a$1(D().getApp()));}catch{}}usesDirectRoomBackend(){return this.client.usesDirectRoomBackend()}get roomBackendTag(){return this.client.getRoomBackendTag()}resolveRoomUserId(e){return D().getCurrentUser?.()?.uid??this.signaling.currentUser?.id??e??"anonymous"}get appTag(){return this.signaling.tag}async invokeRoomCallable(e,t){let{getFunctions:n,httpsCallable:i}=await import('firebase/functions'),o=n(D().getApp());return (await i(o,e)(t)).data}isAlreadyExistsError(e){if(!e||typeof e!="object")return false;let t="code"in e&&typeof e.code=="string"?e.code:"",n="message"in e&&typeof e.message=="string"?e.message:"";return t.includes("already-exists")||n.toLowerCase().includes("already exists")}normalizeRoomId(e){return e.trim().toUpperCase()}async getMembersInternal(e,t){if(!this.client.wasmClient)throw new Error("WASM Client not loaded");let n=t??await this.client.getNodeId(),i=await this.client.wasmClient.get_members(e,n,this.roomBackendTag);return this.parseMemberDocuments(i)}parseMemberDocuments(e){return JSON.parse(e).map(n=>this.parseRoomMemberDocument(n))}parseRoomMemberDocument(e){let t=e.fields;return {nodeId:t.nodeId?.stringValue||e.name.split("/").pop(),userId:t.userId?.stringValue,ticket:t.ticket?.stringValue,joinedAt:t.joinedAt?.integerValue?parseInt(t.joinedAt.integerValue):void 0,lastSeenAt:t.lastSeenAt?.integerValue?parseInt(t.lastSeenAt.integerValue):void 0,expiresAt:t.expiresAt?.integerValue?parseInt(t.expiresAt.integerValue):void 0}}async createRoom(e){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");this.syncRtdbPresenceFromSignaling();let t=await this.client.getTicket(),n=await this.client.getNodeId(),i=this.resolveRoomUserId(n);if(!this.usesDirectRoomBackend()){if(await this.client.refreshHostedAppSettings(),this.client.roomCreationMode==="server-only")throw new Error("This app uses server-only room creation. Create the room on your backend with your sk_live_... key, then call joinRoom(roomId) on the client.");let d="",p=false,u=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",g=u?1:3;for(let f=0;f<g;f+=1){if(u)d=u;else {let v=new Uint8Array(6);crypto.getRandomValues(v),d=Array.from(v,y=>y.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}try{await this.invokeRoomCallable("createClientRoom",{appTag:this.appTag,roomId:d,nodeId:n,ticket:t}),p=!0;break}catch(v){if(this.isAlreadyExistsError(v)){if(u)throw v;continue}throw v}}if(!p)throw new Error(u?`Failed to create requested room "${u}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(d,n),d}let o="",s=false,a=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",c=a?1:3;for(let d=0;d<c;d++){if(a)o=a;else {let u=new Uint8Array(6);crypto.getRandomValues(u),o=Array.from(u,g=>g.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}await this.client.refreshHostedAppSettings();let p=this.client.appLimits.maxMembersPerRoom>=0?this.client.appLimits.maxMembersPerRoom:50;if(s=await this.client.wasmClient.create_room(o,i,t,n,this.roomBackendTag,p),s){console.log(`Room created: ${o}`);break}else {if(a)throw new Error(`Room "${o}" already exists.`);console.log(`Collision for roomId ${o}, retrying...`);}}if(!s)throw new Error(a?`Failed to create requested room "${a}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(o,n),o}async joinRoom(e,t={}){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");if(this.syncRtdbPresenceFromSignaling(),typeof e!="string"||e.length===0||e.length>64)throw new Error("roomId must be a non-empty string of at most 64 characters");if(e!=="demo"&&!/^[a-zA-Z0-9_-]+$/.test(e))throw new Error("roomId must contain only alphanumeric characters, hyphens, or underscores");let n=await this.client.getTicket(),i=await this.client.getNodeId(),o=this.resolveRoomUserId(i),s=this.normalizeRoomId(e);console.log("[RoomManager] joinRoom request",{roomId:e,normalizedId:s,targetRoomId:s,tag:this.roomBackendTag,userId:o,myNodeId:i,hasTicket:!!n,ticketLength:n?.length||0});try{this.usesDirectRoomBackend()?await this.client.wasmClient.join_room(s,o,n,i,this.roomBackendTag):(await this.client.refreshHostedAppSettings(),await this.invokeRoomCallable("joinClientRoom",{appTag:this.appTag,roomId:s,nodeId:i,ticket:n})),console.log(`Joined room: ${s}`);}catch(c){throw d("[RoomManager] joinRoom failed",c),c}let a=[];if(t.bootstrapPeers!==false){let d$1=(await this.getMembersInternal(s,i)).map(async u=>{let g=false,f=Date.now();if(u.expiresAt)u.expiresAt<f&&(g=true);else {let v=u.lastSeenAt||u.joinedAt||0;f-v>300*1e3&&(g=true);}if(g)return null;if(u.ticket)try{console.log(`Bootstrapping: Connecting to peer ${u.nodeId}...`);let v=await this.client.connect(u.ticket,5e3);return v.send({type:"chat",text:`Use ${o} joined the room.`}).catch(y=>{d("[RoomManager] join notification send skipped",{roomId:s,peerNodeId:u.nodeId,error:y});}),v}catch(v){return console.warn(`Failed to connect to peer ${u.nodeId}:`,v),null}return null});(await Promise.allSettled(d$1)).forEach(u=>{u.status==="fulfilled"&&u.value&&a.push(u.value);});}return await this.registerRtdbRoomMember(s,i),a}async leaveRoom(e){this.usesDirectRoomBackend()||await this.client.ensureAuthenticated("room-op");let t=await this.client.getNodeId();if(!t)return;console.log(`Leaving room ${e}...`),await this.markRtdbRoomMemberOffline(e,t),this.stopHeartbeat(e);let n=this.normalizeRoomId(e);try{this.usesDirectRoomBackend()?await this.client.wasmClient.leave_room(n,t,this.roomBackendTag):await this.invokeRoomCallable("leaveClientRoom",{appTag:this.appTag,roomId:n,nodeId:t}),console.log(`Left room: ${n}`);}catch(i){throw console.warn("Leave room failed:",i),i}}async getRoomMembers(e){await this.client.ensureAuthenticated("room-op");let t=this.normalizeRoomId(e);return this.getMembersInternal(t)}watchRoom(e,t){let n=false,i=null;return (async()=>{try{if(await this.client.ensureAuthenticated("room-op"),n)return;let o=this.normalizeRoomId(e),s=await this.client.getNodeId();if(n)return;i=this.getBrowserRooms().watchMembers(o,s,t),n&&(i(),i=null);}catch(o){n||console.warn("[RoomManager] watchRoom listener failed:",o);}})(),()=>{n=true,i?.(),i=null;}}async registerRtdbRoomMember(e,t){if(this.stopHeartbeat(e),this.rtdbPresence){let n=this.roomBackendTag;try{await this.rtdbPresence.registerRoomMember(n,e,t);}catch(i){throw new Error(`[RoomManager] RTDB room member register failed for ${e}: ${i instanceof Error?i.message:String(i)}`)}this.heartbeatStops.set(e,()=>{this.markRtdbRoomMemberOffline(e,t);});}else throw new Error(`[RoomManager] RTDB presence is required for room liveness (${e}); legacy Firestore heartbeat is disabled`)}async markRtdbRoomMemberOffline(e,t){if(!this.rtdbPresence)return;let n=this.roomBackendTag;try{await this.rtdbPresence.markRoomMemberOffline(n,e,t);}catch(i){console.warn("[RoomManager] RTDB markRoomMemberOffline failed:",i);}}stopHeartbeat(e){if(typeof e=="string"){let t=this.heartbeatStops.get(e);t&&(t(),this.heartbeatStops.delete(e),console.log(`Heartbeat stopped for room ${e}.`));return}for(let[t,n]of this.heartbeatStops.entries())n(),console.log(`Heartbeat stopped for room ${t}.`);this.heartbeatStops.clear();}};function Zs(r,e){let t=r.trim();if(!t)throw new Error("Channel envelope requires a non-empty channel id.");let n=new TextEncoder,i=n.encode(t),o=e?n.encode(JSON.stringify(e)):new Uint8Array(0),s=new Uint8Array(6+i.byteLength+o.byteLength),a=new DataView(s.buffer);return s[0]=127,s[1]=1,a.setUint16(2,i.byteLength,false),a.setUint16(4,o.byteLength,false),s.set(i,6),s.set(o,6+i.byteLength),s}function yo(r,e,t){let n=Zs(e,t),i=r.getWriter(),o=false,s=async()=>{o||(o=true,await i.write(n));};return new WritableStream({write:async a=>{await s(),await i.write(a);},close:async()=>{await s();try{await i.close();}finally{i.releaseLock();}},abort:async a=>{try{await i.abort(a);}finally{i.releaseLock();}}})}var ii=[0,300,600,1e3,1500,2e3,2500,3e3,3500,3500,3500,3500,3500,3500,3500],vo=2e3,yt=0,vt="main",bt=64,bo=4*1024*1024,Co=1,So="openrtc:native-main-message",Io=15e3,wo=16,Po=3e4,Ro=250,_o=250,To=2e3,Ao=600,ko=2e3,No=120,Do=1e3,Mo=6e4,ea="system/peer-default",ta="share/explicit-file",na="share/explicit-control",Eo=[{id:ea,kind:"system",ownership:"shared",peerModel:"device-first",routing:"session-default",readiness:"settled-peer",promotionPolicy:"eligible",signalingPolicy:"hosted",description:"Default trusted device/runtime traffic"},{id:ta,kind:"share",ownership:"shared",peerModel:"anonymous-ticket",routing:"stream-envelope",readiness:"transport-only",promotionPolicy:"never",signalingPolicy:"ticket-only",description:"Explicit file transfer channel for share/ticket traffic"},{id:na,kind:"share",ownership:"shared",peerModel:"anonymous-ticket",routing:"stream-envelope",readiness:"transport-only",promotionPolicy:"never",signalingPolicy:"ticket-only",description:"Explicit control channel for share/ticket traffic"}];function xo(r){return {get registry(){return r.getRegistry()},get wasmClient(){return r.getWasmClient()},get node(){return r.getNode()},get discoveryMode(){return r.getDiscoveryMode()},get localNodeId(){return r.getLocalNodeId()},get deviceId(){return r.getDeviceId()},registerDisposer:e=>r.registerDisposer(e)}}var Lo="openrtc:endpoint-ticket:v1";function se(r){let e=r.lastIndexOf(".");return {irohTicket:e>=0?r.slice(0,e):r,tokenSuffix:e>=0?r.slice(e+1):null}}function Bo(){return Fo(24)}function Ct(r,e,t,n,i){return `${r}.${ia(r,e,t,n,i)}`}function Ie(r,e){let t=oa(e);return !t||!ra(r,t)?null:t}function ia(r,e,t,n,i){return btoa(JSON.stringify({t:e,s:t,m:n,h:Oo(r),...typeof i=="number"?{e:i}:{},a:Lo,n:sa()})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function oa(r){try{let e=r.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4;return JSON.parse(atob(e+"=".repeat(t)))}catch{return null}}function ra(r,e){return !(typeof e.h=="string"&&e.h!==Oo(r)||typeof e.e=="number"&&Number.isFinite(e.e)&&e.e<=Date.now()||typeof e.a=="string"&&e.a!==Lo||typeof e.n=="string"&&!aa(e.n))}function sa(){return Fo(16)}function Fo(r){let e=new Uint8Array(r);return crypto.getRandomValues(e),btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function aa(r){try{let e=r.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4;return atob(e+"=".repeat(t)).length===16}catch{return false}}function te(r,e){return r>>>e|r<<32-e}var ca=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function Oo(r){let e=new TextEncoder().encode(r),t=e.length*8,n=e.length+1;for(;n%64!==56;)n+=1;let i=new Uint8Array(n+8);i.set(e),i[e.length]=128;let o=new DataView(i.buffer);o.setUint32(n,Math.floor(t/4294967296),false),o.setUint32(n+4,t>>>0,false);let s=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],a=new Array(64);for(let c=0;c<i.length;c+=64){for(let I=0;I<16;I+=1)a[I]=o.getUint32(c+I*4,false);for(let I=16;I<64;I+=1){let k=te(a[I-15],7)^te(a[I-15],18)^a[I-15]>>>3,T=te(a[I-2],17)^te(a[I-2],19)^a[I-2]>>>10;a[I]=a[I-16]+k+a[I-7]+T>>>0;}let[d,p,u,g,f,v,y,C]=s;for(let I=0;I<64;I+=1){let k=te(f,6)^te(f,11)^te(f,25),T=f&v^~f&y,_=C+k+T+ca[I]+a[I]>>>0,A=te(d,2)^te(d,13)^te(d,22),E=d&p^d&u^p&u,x=A+E>>>0;C=y,y=v,v=f,f=g+_>>>0,g=u,u=p,p=d,d=_+x>>>0;}s[0]=s[0]+d>>>0,s[1]=s[1]+p>>>0,s[2]=s[2]+u>>>0,s[3]=s[3]+g>>>0,s[4]=s[4]+f>>>0,s[5]=s[5]+v>>>0,s[6]=s[6]+y>>>0,s[7]=s[7]+C>>>0;}return s.map(c=>c.toString(16).padStart(8,"0")).join("")}var St=class{constructor(e,t,n){this.ctx=e;this.options=t;this.deps=n;this.appliedAuthSessionToken=null;this.authSyncUnsubscribe=null;this.authRefreshInterval=null;this.publicAuthChangeUnsubscribes=new Set;this.lastWasmAuthSyncUserId=null;this.lastWasmAuthSyncToken=null;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true;let e=this.authSyncUnsubscribe;if(this.authSyncUnsubscribe=null,e)try{e();}catch(n){console.warn("[Client][WASM-AUTH] auth-change unsubscribe failed",n);}let t=this.authRefreshInterval;this.authRefreshInterval=null,t&&clearInterval(t);for(let n of Array.from(this.publicAuthChangeUnsubscribes))try{n();}catch(i){console.warn("[Client][AUTH] public auth-change unsubscribe failed",i);}this.publicAuthChangeUnsubscribes.clear();}assertActive(){if(this.disposed)throw new Error("[Client][AUTH] Auth coordinator is disposed")}isSpaceWithSpaceKey(){let e=this.options.spaceKey??this.options.space;return (this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof e=="string"&&e.trim().length>0}async ensureAuthenticated(e$1){if(this.assertActive(),this.deps.usesTicketOnlySignalingMode())return;let t=this.options.authMode??"anonymous",n=e$1!=="discovery";if(this.isSpaceWithSpaceKey()){let d=typeof this.options.apiKey=="string"?this.options.apiKey.trim():"",p=this.options.spaceKey??this.options.space,u=typeof p=="string"?p.trim():"",g=d&&u?await b$1(d,u).catch(()=>null):null;if(this.assertActive(),D().getCurrentUser()){let k=await D().getIdToken({forceRefresh:false}).catch(()=>null);this.assertActive();let T=a$2(k);if(g&&c$2(T,g)){await B$1(this.deps.waitForAuth(),5e3),this.assertActive(),n&&e(`[Client][AUTH] Space scoped token already authenticated (${e$1})`);return}n&&e("[Client][AUTH] Existing Firebase user is not scoped to this space; minting scoped token",{reason:e$1,expectedNamespaceId:g?.slice(0,12)??null,actualNamespaceId:b$2(T,"namespaceId")?.slice(0,12)??null});}let v=this.options.spaceTokenProvider;if(!v)throw new Error("[Client][AUTH] space discovery requires spaceTokenProvider (use spaceToken for static sites)");let y=await v(),C=typeof y?.customToken=="string"?y.customToken.trim():"";if(!C)throw new Error("[Client][AUTH] spaceTokenProvider returned no customToken");this.assertActive(),await D().signInWithCustomTokenValue(C),this.assertActive(),await B$1(this.deps.waitForAuth(),5e3),this.assertActive();let I=await D().getIdToken({forceRefresh:true}).catch(()=>null);this.assertActive(),this.setWasmAuthToken(I??C,I?"space-id-token":"space-token"),this.assertActive(),n&&e(`[Client][AUTH] Space scoped token authenticated (${e$1})`);return}let o=typeof this.options.sessionToken=="string"?this.options.sessionToken.trim():"";if(o&&this.appliedAuthSessionToken!==o){this.assertActive(),await D().signInWithCustomTokenValue(o),this.assertActive(),this.appliedAuthSessionToken=o,await B$1(this.deps.waitForAuth(),5e3),this.assertActive(),n&&e(`[Client][AUTH] Session token authenticated (${e$1})`);return}try{await B$1(this.deps.waitForAuth(),5e3);}catch(d){this.assertActive(),n&&console.warn(`[Client][AUTH] waitForAuth timed out (${e$1})`,d);}this.assertActive();let s=this.deps.getCurrentUser(),a=s?.id??s?.uid??null,c=this.options.discoveryMode==="user-scoped"&&typeof a=="string"&&a.startsWith("space_");if(s&&!c){n&&e(`[Client][AUTH] Authenticated (${e$1}) as ${a??"current-user"}`);return}if(c&&n&&e("[Client][AUTH] Ignoring space-scoped user for anonymous user-scoped discovery"),t==="external"||t==="required")throw new Error(`[Client][AUTH] ${t} auth mode requires host-provided auth before ${e$1}`);n&&e(`[Client][AUTH] No user (${e$1}); attempting anonymous sign-in...`),await B$1(this.deps.signInAnonymously(),8e3),this.assertActive();try{await B$1(this.deps.waitForAuth(),5e3);}catch{}if(this.assertActive(),!this.deps.getCurrentUser())throw new Error("[Client][AUTH] Anonymous sign-in did not produce an authenticated user");n&&e(`[Client][AUTH] Anonymous sign-in success (${e$1})`);}setWasmAuthToken(e$1,t){let n=this.ctx.wasmClient;if(!n||typeof n.set_auth_token!="function"){console.warn("[Client][WASM-AUTH] WasmClient.set_auth_token is unavailable");return}let i=e$1?"token":null;this.lastWasmAuthSyncUserId===i&&this.lastWasmAuthSyncToken===e$1||(this.lastWasmAuthSyncUserId=i,this.lastWasmAuthSyncToken=e$1,e(`[Client][WASM-AUTH] Sync token (${t}) hasToken=${!!e$1} tokenLen=${e$1?.length??0}`),n.set_auth_token(e$1));}installAuthTokenSync(){if(this.disposed||this.isSpaceWithSpaceKey()||this.authSyncUnsubscribe)return;let e=this.deps.onAuthChange(()=>{this.disposed||this.syncAuthTokenToWasm("auth-change").catch(t=>{this.disposed||console.warn("[Client][WASM-AUTH] Failed syncing auth token on auth change:",t);});});this.authSyncUnsubscribe=e,this.authRefreshInterval||(this.authRefreshInterval=setInterval(()=>{this.disposed||this.syncAuthTokenToWasm("periodic-refresh",true).catch(t=>{this.disposed||console.warn("[Client][WASM-AUTH] Periodic auth refresh sync failed:",t);});},600*1e3));}async syncAuthTokenToWasm(e$1,t=false){if(this.disposed||this.isSpaceWithSpaceKey())return;let n=this.deps.getCurrentUser(),i=n&&n.getToken?await n.getToken(t):null;if(this.disposed)return;let o=!!i,s=i?.length||0,a=n?.id||null;this.lastWasmAuthSyncUserId===a&&this.lastWasmAuthSyncToken===i||(e(`[Client][WASM-AUTH] Sync token (${e$1}) hasToken=${o} tokenLen=${s} uid=${a||"none"} forceRefresh=${t}`),!this.disposed&&this.setWasmAuthToken(i,e$1));}async refreshRuntimeAuthToken(e="runtime-start"){this.disposed||this.deps.usesTicketOnlySignalingMode()||(await this.ensureAuthenticated("discovery"),!this.disposed&&(this.isSpaceWithSpaceKey()||await this.syncAuthTokenToWasm("auth-change",e==="managed-session")));}get currentUser(){return this.deps.getCurrentUser()}onAuthChange(e){if(this.disposed)return ()=>{};let t=true,n=this.deps.onAuthChange(o=>{!t||this.disposed||e(o);}),i=()=>{if(t){t=false;try{n();}finally{this.publicAuthChangeUnsubscribes.delete(i);}}};return this.publicAuthChangeUnsubscribes.add(i),i}async signInAnonymously(){return this.assertActive(),this.deps.signInAnonymously()}async signInWithPluto(){return this.assertActive(),this.deps.signInWithPluto()}async signOut(){if(!this.disposed&&(this.deps.beforeSignOut(),await this.deps.stopAuthScopedActivity(),!this.disposed))return this.deps.signOut()}};async function da(r$1,e,t){if(!t.localDeviceId)return {success:false,skipped:"missing-local-device-id",attempts:0,error:"Missing local device ID"};let n=t.maxRetries??3,i=t.initialBackoffMs??2e3,o=await e.getConnectionState?.(r$1.deviceId);if(o==="connecting")return {success:true,skipped:"already-connecting",attempts:0};o==="connected"&&e.forceDisconnect&&(await e.forceDisconnect(r$1.deviceId),await e.refreshState?.());let s=async()=>{if(typeof r$1.nodeId=="string"&&r$1.nodeId.trim().length>0||typeof r$1.ticket=="string"&&r$1.ticket.trim().length>0){await e.directConnect(r$1),await e.onConnected?.(r$1);return}let p=await e.signalConnect({localDeviceId:t.localDeviceId,targetDeviceId:r$1.deviceId,targetUserId:t.targetUserId,device:r$1});if(!p.success)throw new Error(p.error||"Signaling failed")},a=0,c;for(;a<=n;)try{return await s(),{success:!0,attempts:a}}catch(d){if(c=d,a===n)break;let p=u(a+1,i,Number.MAX_SAFE_INTEGER);e.onRetry?.(r$1,a+1,p),await r(p),a+=1;}return {success:false,attempts:n+1,error:c instanceof Error?c.message:"Connection failed"}}var It=class{constructor(e,t){this.ctx=e;this.deps=t;this.devicesById=new Map;this.deviceIdsByNodeId=new Map;this.activeScanningStops=new Set;this.activeSubscriptionStops=new Set;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(!this.disposed){this.disposed=true;for(let e of Array.from(this.activeScanningStops))try{e();}catch(t){console.warn("[Client] active device scanning unsubscribe failed",t);}this.activeScanningStops.clear();for(let e of Array.from(this.activeSubscriptionStops))try{e();}catch(t){console.warn("[Client] device directory subscription unsubscribe failed",t);}this.activeSubscriptionStops.clear();}}get byIdMap(){return this.devicesById}set byIdMap(e){this.devicesById=e instanceof Map?e:new Map;}get byNodeIdMap(){return this.deviceIdsByNodeId}set byNodeIdMap(e){this.deviceIdsByNodeId=e instanceof Map?e:new Map;}remember(e){if(!this.disposed&&e?.deviceId){if(this.devicesById.set(e.deviceId,e),typeof e.nodeId=="string"&&e.nodeId.trim()){let t=e.nodeId.trim();this.deviceIdsByNodeId.set(t,e.deviceId);}this.deps.onDeviceRemembered(e);}}getKnownDevice(e,t){let n=typeof e=="string"?e.trim():"";if(n){let o=this.devicesById.get(n);if(o)return o}let i=typeof t=="string"?t.trim():"";if(i){let o=this.deviceIdsByNodeId.get(i);if(o)return this.devicesById.get(o)??null}return null}getKnownDeviceIdForNode(e){let t=typeof e=="string"?e.trim():"";return t?this.deviceIdsByNodeId.get(t)??null:null}getKnownDeviceNodeId(e){let t=typeof e=="string"?e.trim():"";return t&&this.devicesById.get(t)?.nodeId?.trim()||null}rememberKnownDeviceForNode(e,t){if(this.disposed)return;let n=e.trim(),i=t.trim();!n||!i||this.deviceIdsByNodeId.set(n,i);}getKnownDevicePlatform(e,t){let n=this.getKnownDevice(e,t),i=typeof n?.platformType=="string"?n.platformType:typeof n?.platform_type=="string"?n.platform_type:null;return i?String(i).trim().toLowerCase():null}async refreshKnownDeviceCache(){if(this.disposed||!this.deps.requiresManagedTransportTrust())return;let e=await this.searchDevices().catch(()=>[]);this.disposed||e.forEach(t=>this.remember(t));}async searchDevices(){if(this.disposed)return [];if(await this.deps.ensureSignalingReadyForDiscovery("search"),this.disposed)return [];let e=await this.deps.searchDevices();return this.disposed?[]:(e.forEach(t=>{this.remember(t),this.deps.applyDiscoveredDevice(t);}),e)}async updateDevice(e,t){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.updateDevice(e,t));}async deleteDevice(e){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.deleteDevice(e));}async cleanupStaleDevices(){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.cleanupStaleDevices());}onDevicesChange(e){if(this.disposed)return ()=>{};let t=true,n=null,i=()=>{if(!(!t&&!n)){if(t=false,n)try{n();}finally{n=null;}this.activeSubscriptionStops.delete(i);}};return this.activeSubscriptionStops.add(i),(async()=>{await this.deps.ensureSignalingReadyForDiscovery("watch"),!(!t||this.disposed)&&(n=this.deps.onDevicesChange(o=>{!t||this.disposed||(o.forEach(s=>{this.remember(s),this.deps.applyDiscoveredDevice(s);}),e(o));}),(!t||this.disposed)&&i());})().catch(o=>{if(!(!t||this.disposed)){console.warn("[Client] Failed to initialize onDevicesChange listener:",o);try{e([]);}finally{i();}}}),i}async subscribeSessions(e,t){if(this.disposed)return ()=>{};if(await this.deps.ensureSignalingReadyForDiscovery("sessions"),this.disposed)return ()=>{};let n=true,i=await this.deps.subscribeSessions(e,s=>{if(n&&!this.disposed)return t(s)});if(this.disposed)return i(),()=>{};let o=()=>{if(n){n=false;try{i();}finally{this.activeSubscriptionStops.delete(o);}}};return this.activeSubscriptionStops.add(o),o}async startScanningLoop(e){if(this.disposed)return {stop:()=>{}};let t=new Set,n=false,i=null,o=null,s=e.localDeviceId;try{let c=await this.deps.getLocalDeviceId();if(this.disposed)return {stop:()=>{}};c&&(s=c);}catch{}i=this.onDevicesChange(c=>{n||this.disposed||e.onDevices?.(c);});let a=()=>{n=true,i&&(i(),i=null),o&&(o(),o=null),this.activeScanningStops.delete(a);};this.activeScanningStops.add(a);try{(e.onIncomingSession||e.acceptIncomingSession)&&(o=await this.subscribeSessions(s,async c=>{if(n||this.disposed)return;let d=c.sessionId||c.connectionId;if(!(!d||t.has(d))&&c.targetDeviceId===s&&c.initiatorDeviceId!==s&&!(c.state==="connected"||c.state==="closed"||c.state==="failed")){t.add(d);try{if(this.disposed)return;if(e.onIncomingSession){await e.onIncomingSession(c);return}(this.deps.getPeerStatus(c.initiatorDeviceId)==="connected"||e.isConnected?.(c.initiatorDeviceId))&&(this.deps.hasPeerScopes(c.initiatorDeviceId)||(e.hasProtectedConnectionIntent?.(c.initiatorDeviceId)??!1)||await this.deps.forceDisconnectPeer(c.initiatorDeviceId).catch(async()=>{await e.cleanupStaleConnection?.(c.initiatorDeviceId);})),c.initiatorNodeId&&await e.allowIncomingNodeId?.(c.initiatorNodeId);let u=await e.acceptIncomingSession?.(d,c.initiatorDeviceId);if(!u?.success)throw new Error(u?.error||"Failed to accept incoming signaling session");await e.onIncomingSessionAccepted?.(c);}catch(p){throw t.delete(d),p}}}));}catch(c){throw a(),c}return {stop:a}}async connectDeviceWithRetry(e,t,n){return da(e,t,n)}};var wt=class{constructor(e,t,n){this.ctx=e;this.options=t;this.deps=n;this.managedPresenceGrant=null;this.disposed=false;this.activePresenceDescriptor=null;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true,this.managedPresenceGrant=null;let e=this.activePresenceDescriptor;this.activePresenceDescriptor=null,!(!e||!this.ctx.localNodeId)&&this.markOfflineDuringDispose(this.ctx.localNodeId);}markOfflineDuringDispose(e){let t=n=>{console.warn("[Client][PRESENCE] failed to mark offline during dispose",n);};try{Promise.resolve(this.deps.setOffline(e)).catch(t);}catch(n){t(n);}}assertActive(){if(this.disposed)throw new Error("[Client][PRESENCE] Presence controller is disposed")}resolvePresenceUserId(){let e=(this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0;return this.deps.getCurrentUser()?.id??(e?this.ctx.localNodeId:null)}startSignalingPresenceLoop(e){if(this.disposed)return;let t=this.activePresenceDescriptor,n=(t?.metadata??"")===(e.metadata??"");t&&t.userId===e.userId&&t.nodeId===e.nodeId&&t.deviceName===e.deviceName&&t.ticket===e.ticket&&n||(this.deps.startPresenceLoop(e.userId,e.nodeId,e.deviceName,e.ticket,e.metadata),this.activePresenceDescriptor=e);}notifySignalingBackendChanged(){this.activePresenceDescriptor=null;}setManagedPresenceTicket(e){if(this.disposed)return;let t=e?.trim()||"";if(!t){this.managedPresenceGrant=null;return}let{irohTicket:n,tokenSuffix:i}=this.deps.splitCompoundTicket(t),o=i?this.deps.decodeCompoundTicketPayload(n,i):null;if(!o?.t||!o?.s)throw new Error("Managed presence ticket must be a compound ticket with an embedded token payload");this.managedPresenceGrant={scope:o.s,token:o.t,maxConnections:typeof o.m=="number"?o.m:0,compoundTicket:t,irohTicket:n};let s=this.ctx.wasmClient;s&&typeof s.register_session_token=="function"&&s.register_session_token(o.t,o.s,typeof o.m=="number"?o.m:0);}clearManagedPresenceTicket(){this.managedPresenceGrant=null;}async resolvePresenceTicket(e){this.assertActive();let t=e?.trim();if(t)return t;if(this.managedPresenceGrant)return this.refreshManagedPresenceTicketIfNeeded();let n=this.options.ticket?.trim();return n||this.deps.getTicket()}async refreshManagedPresenceTicketIfNeeded(){let e=this.managedPresenceGrant;if(!e)return this.deps.getTicket();let t=e.irohTicket;try{t=await this.deps.getTicket();}catch{return e.compoundTicket}if(t===e.irohTicket)return e.compoundTicket;let n=this.ctx.wasmClient;if(n&&typeof n.endpoint_ticket_with_token=="function"){let i=n.endpoint_ticket_with_token.bind(n),o=await d$1(()=>i(e.scope,e.maxConnections),{isActive:()=>!this.disposed}),{irohTicket:s,tokenSuffix:a}=this.deps.splitCompoundTicket(o),c=a?this.deps.decodeCompoundTicketPayload(s,a):null;return e.irohTicket=s,e.compoundTicket=o,c?.t&&c?.s&&(e.token=c.t,e.scope=c.s,e.maxConnections=typeof c.m=="number"?c.m:0),d("[Client][PRESENCE] reminted managed compound ticket through Rust",{grantScope:e.scope}),e.compoundTicket}if(e.scope==="user-device")throw new Error("Managed user-device presence refresh requires Rust/WASM endpoint_ticket_with_token support.");return e.irohTicket=t,e.compoundTicket=this.deps.buildCompoundTicketWithPayload(t,e.token,e.scope,e.maxConnections),d("[Client][PRESENCE] rebuilt managed compound ticket after endpoint change",{grantScope:e.scope}),e.compoundTicket}async startPresenceLoop(e){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.ctx.localNodeId;if(!t)throw new Error("startPresenceLoop requires an initialized node");let n=this.resolvePresenceUserId();if(!n)throw new Error("startPresenceLoop requires an authenticated user");let i=await this.resolvePresenceTicket(e?.ticket);if(this.assertActive(),!i||!i.trim())throw new Error("startPresenceLoop requires a valid endpoint ticket");this.startSignalingPresenceLoop({userId:n,nodeId:t,deviceName:e?.deviceName||this.options.deviceName||"Unknown Device",ticket:i,metadata:e?.metadata}),this.deps.syncRoomRtdbPresence();}async startPresenceLoopForListen(){if(this.disposed)return;let e=this.ctx.localNodeId,t=this.resolvePresenceUserId();if(!t||!e)return;let n=await this.resolvePresenceTicket();this.disposed||this.startSignalingPresenceLoop({userId:t,nodeId:e,deviceName:this.options.deviceName||"Unknown Device",ticket:n,metadata:""});}async setOffline(){this.disposed||(this.activePresenceDescriptor=null,this.ctx.localNodeId&&await this.deps.setOffline(this.ctx.localNodeId));}async updatePresence(e=true,t=3e5,n,i){if(this.disposed||!this.ctx.wasmClient)return;let o=(this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0;if(o&&(await this.deps.ensureAuthenticated("discovery"),this.disposed)||!this.deps.getCurrentUser()?.id&&!o)return;let a=this.ctx.localNodeId;if(!a)return;let c=await this.resolvePresenceTicket(i);if(this.disposed)return;if(!c||!c.trim())throw new Error("updatePresence requires a valid endpoint ticket");let d=n,p=await this.deps.getLocalDeviceId()||this.ctx.deviceId;if(!this.disposed){if(!p)throw new Error("updatePresence requires a stable local device ID");try{let u=n?JSON.parse(n):{};u.deviceId||(u.deviceId=p,d=JSON.stringify(u));}catch{d=JSON.stringify({deviceId:p,rawMetadata:n});}await this.deps.updatePresence(a,c,e,t,d);}}};var Pt=class{constructor(e,t){this.ctx=e;this.deps=t;this.hostedAppSettingsLoaded=false;this.backendConnectionStateUnsubscribe=null;this.signalingBackend=null;this.subscriptionGeneration=0;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}async refreshHostedAppSettings(e=false){if(!(this.disposed||this.deps.usesTicketOnlySignalingMode())&&!(this.hostedAppSettingsLoaded&&!e))try{let{getFunctions:t,httpsCallable:n}=await import('firebase/functions');if(this.disposed)return;let i=t(D().getApp()),s=await n(i,"validateApiKey")({apiKey:this.deps.getApiKey()});if(this.disposed)return;let a=s.data;a.warning&&console.warn("[pluto-rtc]",a.warning),this.deps.setAppLimits(a.limits),a.discoveryMode&&this.deps.setDiscoveryMode(a.discoveryMode),this.deps.setRoomCreationMode(a.roomCreationMode??((this.deps.getOptions().discoveryMode??"space")==="space"?"client-open":"client-auth")),this.hostedAppSettingsLoaded=!0;}catch(t){if(this.disposed)return;console.warn("[pluto-rtc] Could not fetch hosted app settings, using local defaults.",t);}}setSignalingBackend(e){if(this.disposed)return;this.disposeBackendConnectionSubscription();let t=this.subscriptionGeneration,n=this.deps.getCurrentSignaling();this.deps.stopRoomLiveness(),this.stopAuthScopedActivityBestEffort(n);let i=this.deps.createSignaling(e);this.signalingBackend=e,this.deps.installBackend(i,e),this.deps.onSignalingBackendChanged(),this.syncRoomRtdbPresenceFromBackend();let o=e.setCoreClient;typeof o=="function"&&o.call(e,this.deps.getCoreClientHost());try{e.checkForSSOToken();}catch(a){console.warn("[Client] backend SSO token check failed:",a);}c("[Client] subscribing to backend connection state changes",{backendType:e?.constructor?.name??"unknown",hasGetConnectionStates:typeof e.getConnectionStates=="function",hasOnConnectionStateChange:typeof e.onConnectionStateChange=="function"});let s;try{s=i.onConnectionStateChange(a=>{this.disposed||t!==this.subscriptionGeneration||(this.deps.applyBackendConnectionStateSideEffects(a),this.schedulePeerReconciliationBestEffort("backend-state"));});}catch(a){if(this.disposed||t!==this.subscriptionGeneration)return;console.warn("[Client] Failed to subscribe to backend connection state changes:",a);return}if(typeof s=="function"){let a=s;if(this.disposed||t!==this.subscriptionGeneration){this.callBackendConnectionStateUnsubscribe(a);return}this.backendConnectionStateUnsubscribe=a,c("[Client] backend connection state subscription established synchronously");}else s&&typeof s.then=="function"&&s.then(a=>{if(this.disposed||t!==this.subscriptionGeneration){this.callBackendConnectionStateUnsubscribe(a);return}this.backendConnectionStateUnsubscribe=a,c("[Client] backend connection state subscription established asynchronously");}).catch(a=>{this.disposed||t!==this.subscriptionGeneration||console.warn("[Client] Failed to subscribe to backend connection state changes:",a);});}syncRoomRtdbPresenceFromBackend(){if(this.disposed)return;let e=this.signalingBackend?.rtdbPresence;e&&this.deps.setRoomRtdbPresence(e);}async getLocalDeviceId(){return this.disposed?null:this.deps.getCurrentSignaling().getLocalDeviceId()}async getTurnCredentials(){return this.disposed?null:this.deps.getCurrentSignaling().getTurnCredentials()}setWasmClient(e){this.disposed||this.deps.getCurrentSignaling().setWasmClient(e);}getCurrentUser(){return this.disposed?null:this.deps.getCurrentSignaling().currentUser}async waitForAuth(){this.disposed||await this.deps.getCurrentSignaling().waitForAuth();}onAuthChange(e){return this.disposed?()=>{}:this.deps.getCurrentSignaling().onAuthChange(e)}async signInAnonymously(){if(!this.disposed)return this.deps.getCurrentSignaling().signInAnonymously()}async signInWithPluto(){if(!this.disposed)return this.deps.getCurrentSignaling().signInWithPluto()}async signOut(){if(!this.disposed)return this.deps.getCurrentSignaling().signOut()}getRuntimeCapabilities(){if(!this.disposed)return this.deps.getCurrentSignaling().getRuntimeCapabilities?.()}startAutoConnect(e,t){this.disposed||this.deps.getCurrentSignaling().startAutoConnect(e,t);}async isConnected(e){return this.disposed?false:this.deps.getCurrentSignaling().isConnected(e)}notifyDisconnectRequested(e){this.disposed||this.deps.getCurrentSignaling().notifyDisconnectRequested(e);}forceReconnectSnapshot(){this.disposed||this.deps.getCurrentSignaling().forceReconnectSnapshot();}startPresenceLoop(e,t,n,i,o){this.disposed||this.deps.getCurrentSignaling().startPresenceLoop(e,t,n,i,o);}async setOffline(e){this.disposed||await this.deps.getCurrentSignaling().setOffline(e);}async updatePresence(e,t,n,i,o){this.disposed||await this.deps.getCurrentSignaling().updatePresence(e,t,n,i,o);}async searchDevices(){return this.disposed?[]:this.deps.getCurrentSignaling().searchDevices()}async updateDevice(e,t){this.disposed||await this.deps.getCurrentSignaling().updateDevice(e,t);}async deleteDevice(e){this.disposed||await this.deps.getCurrentSignaling().deleteDevice(e);}async cleanupStaleDevices(){this.disposed||await this.deps.getCurrentSignaling().cleanupStaleDevices();}onDevicesChange(e){return this.disposed?()=>{}:this.deps.getCurrentSignaling().onDevicesChange(e)}async subscribeSessions(e,t){return this.disposed?()=>{}:this.deps.getCurrentSignaling().subscribeSessions(e,t)}async stopAuthScopedActivity(){this.disposed||(this.deps.stopRoomLiveness(),await this.stopAuthScopedActivityFor(this.deps.getCurrentSignaling()));}dispose(){if(this.disposed)return;this.disposed=true,this.disposeBackendConnectionSubscription(),this.deps.stopRoomLiveness();let e=this.deps.getCurrentSignaling();this.stopAuthScopedActivityBestEffort(e);}async stopAuthScopedActivityFor(e){if(e&&typeof e.stopAuthScopedActivity=="function")try{await e.stopAuthScopedActivity();}catch(t){if(this.disposed)return;console.warn("[Client] signaling auth-scoped teardown failed",t);}}stopAuthScopedActivityBestEffort(e){try{this.stopAuthScopedActivityFor(e);}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}disposeBackendConnectionSubscription(){this.subscriptionGeneration+=1,this.callBackendConnectionStateUnsubscribe(this.backendConnectionStateUnsubscribe),this.backendConnectionStateUnsubscribe=null;}callBackendConnectionStateUnsubscribe(e){if(e)try{e();}catch(t){console.warn("[Client] backend connection-state unsubscribe failed",t);}}};function Wo(r){return new oi({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getApiKey:()=>r.options.apiKey,getCurrentSignaling:()=>r.signaling,createSignaling:e=>new Se(o(r.options),e),stopRoomLiveness:()=>r.rooms.stopHeartbeat(),installBackend:e=>{r.setSignaling(e),r.setRooms(new ke(r.roomClientHost,e));},setRoomRtdbPresence:e=>{r.rooms.setRtdbPresence(e);},setAppLimits:e=>{r.setAppLimits(e);},setDiscoveryMode:e=>{r.options.discoveryMode=e;},setRoomCreationMode:e=>{r.setRoomCreationMode(e);},getCoreClientHost:()=>({connect:(e,t,n,i,o)=>r.connectionDialer.connect(e,t,n,i,o),waitForApplicationCryptoForPeer:(e,t)=>r.waitForApplicationCryptoForPeer(e,t),hasApplicationRouteForPeer:(e,t)=>r.hasApplicationRouteForPeer(e,t)}),applyBackendConnectionStateSideEffects:e=>r.peerProjection.applyBackendConnectionStateSideEffects(e),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),beforeSignOut:()=>r.prepareStreamListenForSignOutIfExists(),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getTicket:()=>r.runtimeIdentity.getTicket(),ensureSignalingReadyForDiscovery:e=>r.runtimeReadiness.ensureSignalingReadyForDiscovery(e),requiresManagedTransportTrust:()=>r.runtimeStatus.requiresManagedTransportTrust(r.discoveryMode),onDeviceRemembered:e=>{r.applicationCrypto.reindexDevice(e);},applyDiscoveredDevice:e=>{r.peerServices.applyDiscoveredDevice(e);},getPeerStatus:e=>r.peerServices.getPeerStatus(e),hasPeerScopes:e=>r.peerServices.hasPeerScopes(e),forceDisconnectPeer:e=>r.peerServices.forceDisconnectPeer(e)})}var oi=class{constructor(e){this.host=e;}get auth(){return this._auth||(this._auth=new St(this.host.getContext(),this.host.getOptions(),{usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode(),getCurrentUser:()=>this.backend.getCurrentUser(),waitForAuth:()=>this.backend.waitForAuth(),onAuthChange:e=>this.backend.onAuthChange(e),signInAnonymously:()=>this.backend.signInAnonymously(),signInWithPluto:()=>this.backend.signInWithPluto(),signOut:()=>this.backend.signOut(),beforeSignOut:()=>this.host.beforeSignOut(),stopAuthScopedActivity:()=>this.backend.stopAuthScopedActivity()})),this._auth}get backend(){return this._backend||(this._backend=new Pt(this.host.getContext(),{getOptions:()=>this.host.getOptions(),getApiKey:()=>this.host.getApiKey(),usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode(),getCurrentSignaling:()=>this.host.getCurrentSignaling(),createSignaling:e=>this.host.createSignaling(e),stopRoomLiveness:()=>this.host.stopRoomLiveness(),installBackend:(e,t)=>this.host.installBackend(e,t),setRoomRtdbPresence:e=>this.host.setRoomRtdbPresence(e),setAppLimits:e=>this.host.setAppLimits(e),setDiscoveryMode:e=>this.host.setDiscoveryMode(e),setRoomCreationMode:e=>this.host.setRoomCreationMode(e),getCoreClientHost:()=>this.host.getCoreClientHost(),applyBackendConnectionStateSideEffects:e=>this.host.applyBackendConnectionStateSideEffects(e),schedulePeerReconciliation:e=>this.host.schedulePeerReconciliation(e),onSignalingBackendChanged:()=>{this._presence?.notifySignalingBackendChanged();}})),this._backend}get presence(){return this._presence||(this._presence=new wt(this.host.getContext(),this.host.getOptions(),{ensureWasmRuntimeForP2P:()=>this.host.ensureWasmRuntimeForP2P(),ensureAuthenticated:e=>this.auth.ensureAuthenticated(e),getTicket:()=>this.host.getTicket(),getLocalDeviceId:()=>this.backend.getLocalDeviceId(),getCurrentUser:()=>this.backend.getCurrentUser(),startPresenceLoop:(e,t,n,i,o)=>this.backend.startPresenceLoop(e,t,n,i,o),setOffline:e=>this.backend.setOffline(e),updatePresence:(e,t,n,i,o)=>this.backend.updatePresence(e,t,n,i,o),syncRoomRtdbPresence:()=>this.backend.syncRoomRtdbPresenceFromBackend(),splitCompoundTicket:e=>se(e),decodeCompoundTicketPayload:(e,t)=>Ie(e,t),buildCompoundTicketWithPayload:(e,t,n,i)=>Ct(e,t,n,i)})),this._presence}get devices(){return this._devices||(this._devices=new It(this.host.getContext(),{ensureSignalingReadyForDiscovery:e=>this.host.ensureSignalingReadyForDiscovery(e),searchDevices:()=>this.backend.searchDevices(),updateDevice:(e,t)=>this.backend.updateDevice(e,t),deleteDevice:e=>this.backend.deleteDevice(e),cleanupStaleDevices:()=>this.backend.cleanupStaleDevices(),onDevicesChange:e=>this.backend.onDevicesChange(e),subscribeSessions:(e,t)=>this.backend.subscribeSessions(e,t),requiresManagedTransportTrust:()=>this.host.requiresManagedTransportTrust(),onDeviceRemembered:e=>this.host.onDeviceRemembered(e),applyDiscoveredDevice:e=>this.host.applyDiscoveredDevice(e),getPeerStatus:e=>this.host.getPeerStatus(e),hasPeerScopes:e=>this.host.hasPeerScopes(e),forceDisconnectPeer:e=>this.host.forceDisconnectPeer(e),getLocalDeviceId:()=>this.backend.getLocalDeviceId()})),this._devices}clearManagedPresenceTicketIfExists(){this._presence?.clearManagedPresenceTicket();}};var Rt=class{constructor(e){this.localTerminalConnectionIds=new Set;this.connections=e??new Map;}get(e){return this.connections.get(e)}has(e){return this.connections.has(e)}set(e,t){this.connections.set(e,t);}delete(e){return this.connections.delete(e)}values(){return this.connections.values()}forEach(e){this.connections.forEach(e);}[Symbol.iterator](){return this.connections[Symbol.iterator]()}get size(){return this.connections.size}all(){return Array.from(this.connections.values())}applicationReady(e={}){return this.all().filter(t=>typeof t.isReadyForApplicationPayload=="function"?t.isReadyForApplicationPayload(e):!t.isClosed)}get backingMap(){return this.connections}set backingMap(e){this.connections=e instanceof Map?e:new Map;}getForPeer(e,t){for(let n of this.connections.values())if(e&&n.id===e||t&&n.remoteNodeId===t)return n;return null}markLocalTerminalClose(e){this.localTerminalConnectionIds.add(e);}clearLocalTerminalClose(e){this.localTerminalConnectionIds.delete(e);}hasLocalTerminalClose(e){return !!e&&this.localTerminalConnectionIds.has(e)&&!this.connections.has(e)}};function qe(){return BigInt(Date.now())}function _t(r,e){let t=new ArrayBuffer(17),n=new DataView(t);return n.setUint8(0,3),n.setBigUint64(1,r,false),n.setBigInt64(9,e,false),new Uint8Array(t)}function Uo(r,e){let t=new ArrayBuffer(25),n=new DataView(t);return n.setUint8(0,4),n.setBigUint64(1,r.seq,false),n.setBigInt64(9,r.senderUnixMs,false),n.setBigInt64(17,e,false),new Uint8Array(t)}function Ho(r){if(r.byteLength<17||r[0]!==3)return null;let e=new DataView(r.buffer,r.byteOffset,r.byteLength);return {seq:e.getBigUint64(1,false),senderUnixMs:e.getBigInt64(9,false)}}function jo(r){if(r.byteLength<25||r[0]!==4)return null;let e=new DataView(r.buffer,r.byteOffset,r.byteLength);return {seq:e.getBigUint64(1,false),senderUnixMs:e.getBigInt64(9,false),recvUnixMs:e.getBigInt64(17,false)}}function ri(r,e){let t=import.meta.env??{};if(!(String(t.VITE_E2E??"").toLowerCase()==="true"))return e;let i=r==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS:r==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS:r==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS:void 0,o=Number(i);return Number.isFinite(o)&&o>0?o:e}var Ve={tickIntervalMs:ri("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS",5e3),suspectAfterMs:ri("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS",1e4),staleAfterMs:ri("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS",3e4)},Tt=class{constructor(e,t,n=Ve){this.seq=0n;this.pendingPings=new Map;this.lastPongAtMs=null;this.firstPingSentAtMs=null;this.currentHealth="unknown";this.tickTimer=null;this.stopped=false;this.probeWaiters=new Map;this.probeLatencyWaiters=new Map;this.probeTimers=new Map;this.probeLatencyTimers=new Map;this.sendFn=e,this.onHealthChange=t,this.config=n;}start(){this.tickTimer!==null||this.stopped||(this.tickTimer=setInterval(()=>{this.tick();},this.config.tickIntervalMs),this.tick());}stop(){this.stopped=true,this.tickTimer!==null&&(clearInterval(this.tickTimer),this.tickTimer=null);for(let e of this.probeWaiters.values())e(false);this.probeWaiters.clear();for(let e of this.probeTimers.values())clearTimeout(e);this.probeTimers.clear();for(let e of this.probeLatencyWaiters.values())e(null);this.probeLatencyWaiters.clear();for(let e of this.probeLatencyTimers.values())clearTimeout(e);this.probeLatencyTimers.clear(),this.pendingPings.clear();}handleIncoming(e){if(!e||e.byteLength===0)return false;let t=e[0];if(t===3){let n=Ho(e);if(n){d("[TransportHeartbeat] ping received from peer, sending pong",{seq:n.seq.toString()});let i=Uo(n,qe());this.sendFn(i).catch(o=>console.warn("[TransportHeartbeat] pong send failed",o));}else console.warn("[TransportHeartbeat] ping decode failed",{byteLength:e.byteLength});return true}if(t===4){let n=jo(e);if(n){let i=this.pendingPings.get(n.seq),o=i!==void 0;d("[TransportHeartbeat] pong received",{seq:n.seq.toString(),wasPending:o,pendingCount:this.pendingPings.size}),o&&(this.pendingPings.delete(n.seq),this.lastPongAtMs=Date.now(),this.evaluateHealth());let s=this.probeWaiters.get(n.seq);s&&(this.probeWaiters.delete(n.seq),s(true));let a=this.probeLatencyWaiters.get(n.seq);a&&(this.probeLatencyWaiters.delete(n.seq),a(o&&i!==void 0?Math.max(0,Date.now()-i):null));}else console.warn("[TransportHeartbeat] pong decode failed",{byteLength:e.byteLength});return true}return false}async tick(){if(this.stopped)return;let e=Date.now(),t=e-this.config.staleAfterMs;for(let[o,s]of this.pendingPings)s<=t&&this.pendingPings.delete(o);this.seq++;let n=this.seq,i=_t(n,qe());try{await this.sendFn(i),this.firstPingSentAtMs===null&&(this.firstPingSentAtMs=e),this.pendingPings.set(n,e),d("[TransportHeartbeat] ping sent",{seq:n.toString(),pendingCount:this.pendingPings.size,lastPongAtMs:this.lastPongAtMs,silenceSinceLastPongMs:this.lastPongAtMs?e-this.lastPongAtMs:null});}catch(o){console.warn("[TransportHeartbeat] ping send failed",{seq:n.toString(),error:o});}this.evaluateHealth();}evaluateHealth(){let e=this.computeHealth();if(e!==this.currentHealth){d("[TransportHeartbeat] health transition",{from:this.currentHealth,to:e,lastPongAtMs:this.lastPongAtMs,firstPingSentAtMs:this.firstPingSentAtMs,silenceMs:this.lastPongAtMs?Date.now()-this.lastPongAtMs:this.firstPingSentAtMs?Date.now()-this.firstPingSentAtMs:null,pendingCount:this.pendingPings.size}),this.currentHealth=e;try{this.onHealthChange(e);}catch{}}}computeHealth(){let e=Date.now();if(this.firstPingSentAtMs===null)return "unknown";if(this.lastPongAtMs!==null){let n=e-this.lastPongAtMs;return n>=this.config.staleAfterMs?"stale":n>=this.config.suspectAfterMs?"suspect":"healthy"}let t=e-this.firstPingSentAtMs;return t>=this.config.staleAfterMs?"stale":t>=this.config.suspectAfterMs?"suspect":"unknown"}get health(){return this.currentHealth}async probe(e){if(this.stopped)return false;this.seq++;let t=this.seq,n=_t(t,qe()),i=Date.now();return this.pendingPings.set(t,i),this.firstPingSentAtMs===null&&(this.firstPingSentAtMs=i),await new Promise(o=>{let s=setTimeout(()=>{this.probeTimers.delete(t),this.probeWaiters.delete(t)&&(this.pendingPings.delete(t),o(false));},e);this.probeTimers.set(t,s),this.probeWaiters.set(t,a=>{let c=this.probeTimers.get(t);c&&(clearTimeout(c),this.probeTimers.delete(t)),o(a);}),this.sendFn(n).catch(()=>{let a=this.probeTimers.get(t);a&&(clearTimeout(a),this.probeTimers.delete(t)),this.pendingPings.delete(t),this.probeWaiters.delete(t)&&o(false);});})}async probeLatency(e){if(this.stopped)return null;this.seq++;let t=this.seq,n=_t(t,qe()),i=Date.now();return this.pendingPings.set(t,i),this.firstPingSentAtMs===null&&(this.firstPingSentAtMs=i),await new Promise(o=>{let s=setTimeout(()=>{this.probeLatencyTimers.delete(t),this.probeLatencyWaiters.delete(t)&&(this.pendingPings.delete(t),o(null));},e);this.probeLatencyTimers.set(t,s),this.probeLatencyWaiters.set(t,a=>{let c=this.probeLatencyTimers.get(t);c&&(clearTimeout(c),this.probeLatencyTimers.delete(t)),o(a);}),this.sendFn(n).catch(()=>{let a=this.probeLatencyTimers.get(t);a&&(clearTimeout(a),this.probeLatencyTimers.delete(t)),this.pendingPings.delete(t),this.probeLatencyWaiters.delete(t)&&o(null);});})}};var L=class L{constructor(e,t,n,i,o,s={}){this.listeners=[];this.pendingMessages=[];this.pendingEncryptedApplicationPayloads=[];this.webrtcBinaryHandlers=[];this.closeListeners=[];this.upgradeStateListeners=[];this.writer=null;this.reader=null;this._isClosed=false;this.receiveBuffer=new Uint8Array(0);this.writeMutex=Promise.resolve();this.applicationCryptoWaiters=[];this.nativeSignalSender=null;this.webrtcTransport=null;this.webRtcApplicationRouteReadyTransport=null;this.webRtcApplicationRouteReadyNegotiationId=null;this.upgradeState="none";this.upgradeRequested=false;this.negotiationSwitchCount=0;this.upgradeAttemptActive=false;this.upgradeRetryCount=0;this.upgradeReDriveCount=0;this.upgradeReDriveTimer=null;this.upgradeRetryTimer=null;this.upgradeAttemptTimeoutTimer=null;this.lastReportedTransportStatus=null;this.applicationRouteMissingNotified=false;this.upgradeTerminalFailure=false;this.pendingSignals=[];this.activeNegotiationId=null;this.webrtcHeartbeat=null;this.webRtcHeartbeatProbeInFlight=false;this.webRtcApplicationRouteProbeInFlight=false;this.webRtcHeartbeatConsecutiveProbeFailures=0;this.irohHealthListeners=[];this.webrtcHealthListeners=[];this.lastWebRtcHeartbeatOkAt=null;this.lastWebRtcDataChannelOpenAt=null;this.lastForegroundAt=null;this.webRtcDisconnectedGraceTimer=null;this.preferredWebRtcRole=null;this.lastWebRtcLocalCandidateType=null;this.lastWebRtcRemoteCandidateType=null;this._peerMoQReady=false;this._remoteSupportsWebRTC=false;this.mediaListeners=[];this.trackListeners=[];this.warnedSrtpApplicationCryptoBoundary=false;this.id=e,this.localNodeId=t,this.remoteNodeId=n,this.deviceId=n,this.writer=i,this.reader=o,this.options=s,this.readLoop(),this.options.rtcConfig?.lanMode&&this.options.rtcConfig&&queueMicrotask(()=>this.requestWebRTCUpgrade("lan-mode"));}get isClosed(){return this._isClosed}setApplicationCrypto(e){this.options={...this.options,applicationCrypto:e},e&&(this.applicationRouteMissingNotified=false,this.resolveApplicationCryptoWaiters(),this.flushPendingEncryptedApplicationPayloads(),!this.isCurrentWebRtcTransportApplicationRouteReady()&&this.webrtcTransport&&this.upgradeState==="upgraded"&&(this.lastWebRtcHeartbeatOkAt!==null?this.markWebRtcApplicationRouteReady(this.webrtcTransport):this.startWebRtcApplicationRouteProbe(this.webrtcTransport,"application-crypto-ready")));}requireApplicationCrypto(){this.options={...this.options,requireApplicationCrypto:true};}isApplicationCryptoRequired(){return this.options.requireApplicationCrypto===true}isReadyForApplicationPayload(e={}){if(this.isClosed||!this.hasRequiredApplicationCrypto())return false;let t=e.preferredTransports??[],n=this.getTransportStatus().activeTransport;return t.length===0?this.isTransportAvailableForApplicationPayload(n):t.includes(n)?this.isTransportAvailableForApplicationPayload(n):e.allowFallbackAfterPreferredTransportFailure===true&&this.upgradeState==="failed"&&this.isTransportAvailableForApplicationPayload(n)}getApplicationPayloadTransports(e={}){if(!this.isReadyForApplicationPayload(e))return [];let t=this.getTransportStatus(),n=[t.activeTransport];return e.includeFallbackTransports===true&&t.parallelTransport&&t.parallelTransport!==t.activeTransport&&this.isTransportAvailableForApplicationPayload(t.parallelTransport)&&n.push(t.parallelTransport),n}isTransportAvailableForApplicationPayload(e){return this._isClosed||!this.hasRequiredApplicationCrypto()?false:e==="webrtc"||e==="webrtc-lan"?this.isWebRtcApplicationRouteReady():e==="moq"?this.isMoQApplicationRouteReady():e==="iroh"||e==="iroh-relay"||e==="iroh-quic"||e==="iroh-lan"||e==="ble"?!!this.writer:false}resolveApplicationCryptoWaiters(){let e=this.applicationCryptoWaiters.splice(0);for(let t of e)t.timer&&clearTimeout(t.timer),t.resolve();}rejectApplicationCryptoWaiters(e){let t=this.applicationCryptoWaiters.splice(0);for(let n of t)n.timer&&clearTimeout(n.timer),n.reject(e);}async waitForRequiredApplicationCrypto(){if(!this.options.requireApplicationCrypto||this.options.applicationCrypto)return;if(this.isClosed)throw new Error("[Connection] Application crypto is required but the connection is closed.");let e=this.options.applicationCryptoWaitMs??L.DEFAULT_APPLICATION_CRYPTO_WAIT_MS;if(e<=0)throw new Error("[Connection] Application crypto is required before sending app payloads.");await new Promise((t,n)=>{let i={resolve:t,reject:n,timer:null};i.timer=setTimeout(()=>{this.applicationCryptoWaiters=this.applicationCryptoWaiters.filter(o=>o!==i),n(new Error("[Connection] Application crypto negotiation timed out before sending app payloads."));},e),this.applicationCryptoWaiters.push(i);});}requestWebRTCUpgrade(e="peer-capable"){if(!this.options.rtcConfig){this.traceLifecycle("webrtc-request-skipped",{reason:e,skipReason:"missing-rtc-config"});return}let t=this.getDeterministicWebRtcRole();this.upgradeState==="upgrading"&&this.preferredWebRtcRole==="responder"||(this.preferredWebRtcRole=t),this.traceLifecycle("webrtc-requested",{reason:e,requestedRole:t}),this.beginWebRtcRecovery(e,{forceRenegotiate:false,replaceExisting:false,resetRetryBudget:true,skipIfAlreadyUpgrading:true});}isWebRtcRouteHeartbeatLive(){if(!this.isWebRtcDataChannelOpen())return false;let e=this.lastWebRtcHeartbeatOkAt===null?null:Date.now()-this.lastWebRtcHeartbeatOkAt;if(e!==null&&e<=L.WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS)return true;let t=this.lastWebRtcDataChannelOpenAt===null?null:Date.now()-this.lastWebRtcDataChannelOpenAt;return t!==null&&t<=L.WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS}requestTransportRecovery(e,t={}){!this.options.rtcConfig||this._isClosed||this.beginWebRtcRecovery(e,{forceRenegotiate:!!t.forceRenegotiate,replaceExisting:!!t.replaceExisting,resetRetryBudget:false,skipIfAlreadyUpgrading:false});}handleAppForeground(){if(this.lastForegroundAt=Date.now(),this._isClosed||!this.options.rtcConfig||!this.upgradeRequested||!this.hasRecoverableBasePath())return;let e=this.webrtcTransport,t=e?.getNativeTransport?.(),n=e?.getDataChannelReadyState?.()??null,i=typeof t?.connectionState=="string"?t.connectionState:null,o=typeof t?.iceConnectionState=="string"?t.iceConnectionState:null;if(this.upgradeState!=="upgraded"||n!=="open"||i==="failed"||i==="disconnected"||o==="failed"||o==="disconnected"){this.requestTransportRecovery("app-foreground",{forceRenegotiate:true,replaceExisting:!!e||this.upgradeState==="failed"||this.upgradeState==="upgraded"});return}let a=this.webrtcHeartbeat,c=this.lastWebRtcHeartbeatOkAt===null?null:Date.now()-this.lastWebRtcHeartbeatOkAt;!(c!==null&&c>=Ve.suspectAfterMs)||!a||a.probe(L.FOREGROUND_PROBE_TIMEOUT_MS).then(p=>{p||this._isClosed||this.webrtcTransport===e&&this.requestTransportRecovery("app-foreground-probe-failed",{forceRenegotiate:true,replaceExisting:true});});}beginWebRtcRecovery(e,t){if(!this.options.rtcConfig||this._isClosed)return;let n=t.forceRenegotiate,i=t.replaceExisting,o=t.resetRetryBudget;if(t.skipIfAlreadyUpgrading&&(this.upgradeState==="upgrading"||this.upgradeState==="upgraded")){let s=this.isWebRtcApplicationRouteReady();if(!(this.upgradeState==="upgraded"&&!s&&!this.isWebRtcRouteHeartbeatLive()&&this.getDeterministicWebRtcRole()==="initiator")){d("[Connection] WebRTC recovery request ignored: attempt already active",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,currentState:this.upgradeState,routeAlreadyProven:s});return}d("[Connection] WebRTC recovery replacing a stale upgraded route (heartbeat not live)",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e}),this.stopWebRtcHeartbeat(),this.pendingSignals=[],this.teardownWebRTCTransport(`recovery-replace-stale:${e}`),this.setUpgradeState("none");}d("[Connection] beginWebRtcRecovery called",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,replaceExisting:i,forceRenegotiate:n,resetRetryBudget:o,currentState:this.upgradeState,caller:new Error().stack?.split(`
2
- `).slice(1,4).join(" | ")}),this.upgradeRequested=true,this.upgradeAttemptActive=false,this.upgradeTerminalFailure=false,this.clearUpgradeRetryTimer(),this.clearUpgradeReDriveTimer(),this.clearUpgradeAttemptTimeoutTimer(),o&&(this.upgradeRetryCount=0,this.upgradeReDriveCount=0),i&&(this.stopWebRtcHeartbeat(),this.pendingSignals=[],this.teardownWebRTCTransport(`recovery-replace-existing:${e}`)),this.attemptUpgrade({forceRenegotiate:n,replaceExisting:i});}getUpgradeState(){return this.upgradeState}updateRTCConfig(e){this.options.rtcConfig=e;}onUpgradeStateChange(e){this.upgradeStateListeners.push(e);}async getTransportDiagnostics(){let{activeTransport:e,parallelTransport:t}=this.getTransportStatus(),n={activeTransport:e,parallelTransport:t,usesRelay:null,relaySource:null,webrtc:null},i=this.webrtcTransport?.getNativeTransport?.();if(!i||typeof i.getStats!="function")return n;try{let o=await i.getStats(),s=null;o.forEach(C=>{if(s||C?.type!=="transport")return;let I=C?.selectedCandidatePairId;!I||typeof o.get!="function"||(s=o.get(I)??null);}),s||o.forEach(C=>{if(!s&&C?.type==="candidate-pair"){if(C?.selected===!0){s=C;return}C?.nominated===!0&&C?.state==="succeeded"&&(s=C);}});let a=s?.localCandidateId&&typeof o.get=="function"?o.get(s.localCandidateId):null,c=s?.remoteCandidateId&&typeof o.get=="function"?o.get(s.remoteCandidateId):null,d=typeof a?.candidateType=="string"?a.candidateType:null,p=typeof c?.candidateType=="string"?c.candidateType:null,u=typeof a?.protocol=="string"?a.protocol:null,g=typeof c?.protocol=="string"?c.protocol:null,f=!!(d||p),v=f?d==="relay"||p==="relay":null,y=f?`${d??"unknown"}<->${p??"unknown"}`:null;return this.lastWebRtcLocalCandidateType=d,this.lastWebRtcRemoteCandidateType=p,{...n,usesRelay:v,relaySource:v==null?null:v?"webrtc-candidate-relay":"webrtc-candidate-direct",webrtc:{iceConnectionState:typeof i.iceConnectionState=="string"?i.iceConnectionState:null,iceGatheringState:typeof i.iceGatheringState=="string"?i.iceGatheringState:null,localCandidateType:d,remoteCandidateType:p,localProtocol:u,remoteProtocol:g,candidateTypeSummary:y}}}catch{return {...n,relaySource:"webrtc-stats-unavailable"}}}get transportType(){return this.isWebRtcApplicationRouteReady()?this.lastWebRtcLocalCandidateType==="host"||this.lastWebRtcRemoteCandidateType==="host"?"webrtc-lan":"webrtc":this.isMoQApplicationRouteReady()?"moq":"iroh-relay"}get peerMoQReady(){return this._peerMoQReady}set peerMoQReady(e){this._peerMoQReady!==e&&(this._peerMoQReady=e,this.reportTransportStatusIfChanged());}get remoteSupportsWebRTC(){return this._remoteSupportsWebRTC}set remoteSupportsWebRTC(e){this._remoteSupportsWebRTC=e;}async send(e,t={}){return this.sendTyped(0,e,{requireApplicationCrypto:true,useApplicationPayloadRoute:true,routeOptions:t})}async sendMedia(e,t){let n=e==="video"?1:2;return this.sendTyped(n,t,{requireApplicationCrypto:true})}async sendOnTransport(e,t){return this.sendTypedOnTransport(e,0,t,{requireApplicationCrypto:true})}async sendControl(e){return this.sendTyped(0,e,{requireApplicationCrypto:false,protectApplicationPayload:false})}async sendRawIrohFrame(e){if(this.isClosed||!this.writer)throw new Error("[Connection] Requested transport unavailable: iroh");let t=this.writeMutex,n;this.writeMutex=new Promise(i=>{n=i;});try{if(await t,!this.writer)throw new Error("[Connection] Requested transport unavailable: iroh");await this.writer.write(e);}catch(i){throw this.preserveWebRtcConnectionAfterBaseTransportLoss(`Iroh Send Error: ${i}`)||(console.error("[Connection] Iroh Send error:",i),this.close(`Send Error: ${i}`)),i}finally{n();}}getAvailableTransports(){let e=[],{activeTransport:t,parallelTransport:n}=this.getTransportStatus();this.webrtcTransport&&this.upgradeState==="upgraded"&&e.push(this.transportType==="webrtc-lan"?"webrtc-lan":"webrtc");this.options.transportContext;if(this.isMoQApplicationRouteReady()&&e.push("moq"),this.writer){let o=t==="iroh-lan"||t==="iroh-quic"||t==="iroh-relay"||t==="ble"?t:n;e.push(o??"iroh-relay");}return e}onWebRTCBinaryMessage(e){this.webrtcBinaryHandlers.push(e);}dispatchWebRtcBinaryHandlers(e){for(let t of this.webrtcBinaryHandlers)if(t(e))return true;return false}getWebRTCTransport(){return this.upgradeState!=="upgraded"?null:this.webrtcTransport}async sendOnWebRTC(e){if(!this.webrtcTransport||this.upgradeState!=="upgraded")throw new Error("[Connection] WebRTC transport unavailable");await this.webrtcTransport.send(e);}encodePayload(e){return typeof e=="string"?new TextEncoder().encode(e):e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new TextEncoder().encode(JSON.stringify(e))}protectApplicationPayload(e,t){return this.options.applicationCrypto?.protectPayload(e,t)??t}openApplicationPayload(e,t){let n=this.options.applicationCrypto;return n?n.openPayload(e,t):f$1(t)?(this.queueEncryptedApplicationPayload(e,t),null):t}openUntypedApplicationPayload(e){if(!f$1(e))return e;let t=this.options.applicationCrypto;return t?t.openPayload(0,e)??t.openPayload(3,e):(this.queueEncryptedApplicationPayload("untyped",e),null)}queueEncryptedApplicationPayload(e,t){this._isClosed||(this.pendingEncryptedApplicationPayloads.push({typeId:e,payload:new Uint8Array(t)}),this.pendingEncryptedApplicationPayloads.length>L.MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS&&this.pendingEncryptedApplicationPayloads.splice(0,this.pendingEncryptedApplicationPayloads.length-L.MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS));}flushPendingEncryptedApplicationPayloads(){let e=this.options.applicationCrypto;if(!e||this.pendingEncryptedApplicationPayloads.length===0)return;let t=this.pendingEncryptedApplicationPayloads.splice(0),n=[];for(let i of t){let o=i.typeId==="untyped"?e.openPayload(0,i.payload)??e.openPayload(3,i.payload):e.openPayload(i.typeId,i.payload);if(o){i.typeId===1?this.emitMedia("video",o):i.typeId===2?this.emitMedia("audio",o):this.processDataPayload(o);continue}f$1(i.payload)&&n.push(i);}n.length>L.MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS&&n.splice(0,n.length-L.MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS),this.pendingEncryptedApplicationPayloads=n;}buildFrame(e,t){let n=5+t.length,i=new Uint8Array(n);return new DataView(i.buffer).setUint32(0,1+t.length,false),i[4]=e,i.set(t,5),i}async sendOverIroh(e,t,n){if(this.options.transportContext?.disableIrohFallback&&e!==0)return console.warn(`[Connection] Iroh disabled for ${n}; dropping packet.`),false;if(this.isClosed||!this.writer)return false;let o=this.writeMutex,s;this.writeMutex=new Promise(a=>{s=a;});try{return await o,this.writer?(await this.writer.write(t),!0):!1}catch(a){if(this.preserveWebRtcConnectionAfterBaseTransportLoss(`Iroh Send Error: ${a}`))return false;throw console.error("[Connection] Iroh Send error:",a),this.close(`Send Error: ${a}`),a}finally{s();}}async sendUsingTransport(e,t,n,i,o){let s=this.options.transportContext;return e==="webrtc-lan"?this.transportType!=="webrtc-lan"||!this.webrtcTransport||this.upgradeState!=="upgraded"||t!==0?false:(await this.webrtcTransport.send(i),true):e==="webrtc"?!this.webrtcTransport||this.upgradeState!=="upgraded"||t!==0?false:(await this.webrtcTransport.send(i),true):e==="moq"?s&&s.isMoQReady()&&this.peerMoQReady&&this.isMoQDataRouteReady(s)?(await s.sendMoQ(o,{alreadyProtected:true}),true):false:e==="iroh-lan"||e==="ble"?this.transportType!==e?false:this.sendOverIroh(t,o,"explicit transport send"):e==="iroh"||e==="iroh-relay"||e==="iroh-quic"?this.sendOverIroh(t,o,"explicit transport send"):false}async sendTypedOnTransport(e,t,n,i={}){i.requireApplicationCrypto&&await this.waitForRequiredApplicationCrypto();let o=this.encodePayload(n),s=i.protectApplicationPayload===false?o:this.protectApplicationPayload(t,o),a=this.buildFrame(t,s);if(!await this.sendUsingTransport(e,t,n,s,a))throw new Error(`[Connection] Requested transport unavailable: ${e}`)}async sendTyped(e,t,n={}){this.options.transportContext;n.requireApplicationCrypto&&await this.waitForRequiredApplicationCrypto();let o=this.encodePayload(t),s=n.protectApplicationPayload===false?o:this.protectApplicationPayload(e,o),a=this.buildFrame(e,s),c=n.useApplicationPayloadRoute&&e===0?this.getApplicationPayloadTransports(n.routeOptions??{}):this.getSendTransportPriorities(n);if(c.length===0)throw new Error("[Connection] Application payload route is not ready.");let d=null;for(let u of c)try{if(await this.sendUsingTransport(u,e,t,s,a))return}catch(g){d=g,console.warn(`[Connection] ${u} Send Failed:`,g);}let p=c.join(", ");throw d instanceof Error?new Error(`[Connection] Failed to send app payload on route(s): ${p}. Last error: ${d.message}`):new Error(`[Connection] Failed to send app payload on route(s): ${p}.`)}getSendTransportPriorities(e){let t=["webrtc","moq","iroh"],n=this.options.transportContext?.priorities??t,i=n.length>0?n:t;return e.requireApplicationCrypto===false||e.protectApplicationPayload===false?["iroh",...i.filter(s=>s!=="iroh"&&s!=="iroh-relay"&&s!=="iroh-quic"&&s!=="iroh-lan")]:i}async disconnect(){this.close("Explicit Disconnect");}onMessage(e){if(this.listeners.push(e),this.pendingMessages.length!==0)for(let t of this.pendingMessages)e(t);}onMedia(e){this.mediaListeners.push(e);}onDisconnect(e){this.closeListeners.push(e);}close(e){if(this._isClosed)return;if(this._isClosed=true,this.upgradeRequested=false,this.upgradeAttemptActive=false,this.activeNegotiationId=null,this.pendingSignals=[],this.clearUpgradeRetryTimer(),this.clearUpgradeReDriveTimer(),this.clearUpgradeAttemptTimeoutTimer(),this.clearWebRtcDisconnectedGraceTimer(),this.teardownWebRTCTransport(`connection-close:${e??"unspecified"}`),this.setUpgradeState("none"),this.rejectApplicationCryptoWaiters(new Error("[Connection] Application crypto negotiation stopped because the connection closed.")),this.pendingEncryptedApplicationPayloads=[],this.writer?.close().catch(()=>{}),(this.options.transportContext?.readerCloseStrategy??"cancel")==="release-lock")try{this.reader?.releaseLock();}catch{}else this.reader?.cancel().catch(()=>{});this.writer=null,this.reader=null,this.closeListeners.forEach(n=>n());}preserveWebRtcConnectionAfterBaseTransportLoss(e){let t=this.getControlFrameMode()==="native-main"&&!!this.nativeSignalSender,n=!!this.webrtcTransport&&(this.upgradeState==="upgraded"||this.upgradeState==="upgrading"&&!!this.nativeSignalSender);if(!t&&!n)return false;d("[Connection] Base transport closed while a control/WebRTC route remains usable; preserving connection",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,transportStatus:this.getTransportStatus(),upgradeState:this.upgradeState}),this.clearUpgradeRetryTimer();try{this.reader?.releaseLock();}catch{}try{this.writer?.releaseLock();}catch{}return this.reader=null,this.writer=null,this.reportTransportStatusIfChanged(),true}async readLoop(){if(this.reader)try{for(;!this.isClosed;){let{done:e,value:t}=await this.reader.read();if(e){if(this.preserveWebRtcConnectionAfterBaseTransportLoss("Read Done (Remote Closed)"))break;this.close("Read Done (Remote Closed)");break}t&&this.handleData(t);}}catch(e){let t=`Read Error: ${e}`;if(this.preserveWebRtcConnectionAfterBaseTransportLoss(t))return;console.error("[Connection] Read loop error:",e),this.close(t);}}injectData(e){this.handleData(e);}handleData(e){let t=new Uint8Array(this.receiveBuffer.length+e.length);for(t.set(this.receiveBuffer),t.set(e,this.receiveBuffer.length),this.receiveBuffer=t;!(this.receiveBuffer.length<4);){let i=new DataView(this.receiveBuffer.buffer,this.receiveBuffer.byteOffset,this.receiveBuffer.byteLength).getUint32(0,false);if(this.receiveBuffer.length<4+i)break;let o=this.receiveBuffer.slice(4,4+i);if(o.length>0){let s=o[0],a=o.slice(1);if(L.isUntypedDataFrame(o)){let c=this.openUntypedApplicationPayload(o);c&&this.processDataPayload(c);}else if(s===3)this.sendIrohHeartbeatPong(a);else if(s===4)this.irohHealthListeners.forEach(c=>c("healthy"));else if(s===1){let c=this.openApplicationPayload(s,a);c&&this.emitMedia("video",c);}else if(s===2){let c=this.openApplicationPayload(s,a);c&&this.emitMedia("audio",c);}else {if(s===0&&this.tryHandlePlaintextNativeSignal(a)){this.receiveBuffer=this.receiveBuffer.slice(4+i);continue}let c=this.openApplicationPayload(s,a);c&&this.processDataPayload(c);}}this.receiveBuffer=this.receiveBuffer.slice(4+i);}}tryHandlePlaintextNativeSignal(e){let t;try{t=JSON.parse(L.textDecoder.decode(e));}catch{return false}return !t||typeof t!="object"||t.type!=="#pluto-signal"?false:(this.handleInternalSignal(t),true)}static isUntypedDataFrame(e){let t=e[0];return t===123||t===91||f$1(e)?true:e.length>=4&&e[0]===68&&e[1]===86&&e[2]===67&&e[3]===72}processDataPayload(e){if(f$1(e)){let t=this.openUntypedApplicationPayload(e);t&&t!==e&&this.processDataPayload(t);return}try{let t=L.textDecoder.decode(e);if(!this.isLikelyTextPayload(e,t)){this.emitMessage(e);return}let n=JSON.parse(t);if(n&&typeof n=="object"&&n.type==="#pluto-signal"){this.handleInternalSignal(n);return}typeof n=="object"&&n!==null?this.emitMessage(n):this.emitMessage(t);}catch{try{let t=L.textDecoder.decode(e);if(this.isLikelyTextPayload(e,t)){this.emitMessage(t);return}}catch{}this.emitMessage(e);}}isLikelyTextPayload(e,t){try{for(let i=0;i<t.length;i+=1){let o=t.charCodeAt(i);if(o<32&&o!==9&&o!==10&&o!==13)return !1}let n=L.textEncoder.encode(t);if(n.byteLength!==e.byteLength)return !1;for(let i=0;i<n.byteLength;i+=1)if(n[i]!==e[i])return !1;return !0}catch{return false}}emitMedia(e,t){this.mediaListeners.forEach(n=>n(e,t));}emitMessage(e){this.pendingMessages.push(e),this.pendingMessages.length>L.MAX_PENDING_MESSAGES&&this.pendingMessages.splice(0,this.pendingMessages.length-L.MAX_PENDING_MESSAGES),this.listeners.length!==0&&this.listeners.forEach(t=>t(e));}receiveMessage(e){this.emitMessage(e);}receiveDataPayload(e){this.processDataPayload(e);}warnSrtpApplicationCryptoBoundary(e){!this.options.applicationCrypto||this.warnedSrtpApplicationCryptoBoundary||(this.warnedSrtpApplicationCryptoBoundary=true,console.warn(`[Connection] ${e} uses WebRTC DTLS-SRTP media encryption, not the ORTCE1 applicationCrypto envelope. Use sendMedia() for ORTCE1-protected app-encoded media chunks.`));}addTrack(e){let t=this.webrtcTransport?.getNativeTransport?.();return t&&typeof t.addTrack=="function"?(this.warnSrtpApplicationCryptoBoundary("addTrack"),t.addTrack(e)):null}addTransceiver(e,t){let n=this.webrtcTransport?.getNativeTransport?.();return n&&typeof n.addTransceiver=="function"?(this.warnSrtpApplicationCryptoBoundary("addTransceiver"),n.addTransceiver(e,t)):null}onTrack(e){this.trackListeners.push(e);}hasRecoverableBasePath(){return !!this.nativeSignalSender||!!this.writer}isWebRtcDataChannelOpen(){return this.upgradeState==="upgraded"&&!!this.webrtcTransport&&this.webrtcTransport.getDataChannelReadyState?.()==="open"}clearWebRtcDisconnectedGraceTimer(){this.webRtcDisconnectedGraceTimer&&(clearTimeout(this.webRtcDisconnectedGraceTimer),this.webRtcDisconnectedGraceTimer=null);}transportStillLikelyAlive(e){let t=e.getDataChannelReadyState?.()??null,n=e.getNativeTransport?.()??null,i=typeof n?.connectionState=="string"?n.connectionState:null,o=typeof n?.iceConnectionState=="string"?n.iceConnectionState:null;return t==="closed"||t==="closing"?false:t==="open"?true:i==="connected"||i==="connecting"||o==="connected"||o==="completed"||o==="checking"}handleUnhealthyWebRtcTransportStateWithGrace(e,t){let n=e.getDataChannelReadyState?.()??null;if(n==="closed"||n==="closing"){d("[Connection] WebRTC unhealthy with closed DataChannel; failing upgraded transport immediately",{connectionId:this.id,remoteNodeId:this.remoteNodeId,state:t,dcReadyState:n}),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure(`transport-state-${t}-dc-closed`);return}this.webRtcDisconnectedGraceTimer||(d("[Connection] WebRTC transport reported unhealthy; applying grace window before fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId,state:t}),this.webRtcDisconnectedGraceTimer=setTimeout(()=>{if(this.webRtcDisconnectedGraceTimer=null,!(this._isClosed||this.webrtcTransport!==e)){if(this.transportStillLikelyAlive(e)){d("[Connection] WebRTC unhealthy grace expired but transport appears alive; suppressing fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId,state:t});return}this.stopWebRtcHeartbeat(),this.handleUpgradeFailure(`transport-state-${t}-grace-expired`);}},L.WEBRTC_DISCONNECTED_GRACE_MS));}async attemptUpgrade(e$1){if(this._isClosed||!this.upgradeRequested||!this.options.rtcConfig)return;let t=typeof e$1=="object"&&e$1!==null?e$1:{preferredNegotiationId:e$1??null},n=t.preferredNegotiationId,i=!!t.forceRenegotiate;if(!!!t.replaceExisting&&(this.upgradeAttemptActive||this.upgradeState==="upgraded"))return;this.upgradeAttemptActive=true,this.teardownWebRTCTransport("upgrade-attempt-replacement"),this.applicationRouteMissingNotified=false;let s=this.normalizeNegotiationId(n)??this.createNegotiationId();this.activeNegotiationId=s,this.setUpgradeState("upgrading"),this.startUpgradeAttemptTimeout(s),(i||this.upgradeRetryCount>0)&&this.sendInternalSignal({transport:"webrtc",type:"renegotiate",negotiationId:s}).catch(()=>{});try{this.webrtcTransport=ue.createTransport("webrtc");}catch(p){this.upgradeAttemptActive=false,d("[Connection] WebRTC upgrade unavailable",p),this.handleUpgradeFailure("transport-create-error");return}let a=this.webrtcTransport;typeof a.setSignalSender=="function"&&a.setSignalSender(p=>this.sendInternalSignal(p)),a.onMessage(p=>{if(p instanceof Uint8Array&&p.byteLength>0&&(this.webrtcHeartbeat?.handleIncoming(p)||this.dispatchWebRtcBinaryHandlers(p)))return;let u=this.openApplicationPayload(0,p);u&&this.processDataPayload(u);}),a.onStateChange(p=>{if(!(this._isClosed||this.webrtcTransport!==a)){if(e(`[Connection] WebRTC transport state changed: ${p}`),p==="connected"){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.clearUpgradeRetryTimer(),this.lastWebRtcDataChannelOpenAt=Date.now(),this.setUpgradeState("upgraded"),this.startWebRtcHeartbeat(a),this.startWebRtcApplicationRouteProbe(a,"transport-connected");return}if(p==="failed"||p==="disconnected"){if(this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,this.upgradeState==="upgraded"&&(p==="disconnected"||this.isWebRtcApplicationRouteReadyForTransport(a))){this.handleUnhealthyWebRtcTransportStateWithGrace(a,p);return}this.clearWebRtcDisconnectedGraceTimer(),a.isTerminalFailure?.()&&(this.upgradeTerminalFailure=true),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure(`transport-state-${p}`);}}});try{await a.init(this.localNodeId,this.deviceId,{rtcConfig:this.options.rtcConfig,negotiationId:s,forceRole:this.preferredWebRtcRole??void 0});}catch(p){this.upgradeAttemptActive=false,this.clearUpgradeAttemptTimeoutTimer(),d("[Connection] WebRTC init failed",p),this.handleUpgradeFailure("init-error");return}if(this.webrtcTransport!==a){this.upgradeAttemptActive=false;return}let c=a.getNegotiationId?.();if(c&&(this.activeNegotiationId=this.normalizeNegotiationId(c)??s),this.pendingSignals.length>0){let p=this.pendingSignals.splice(0);for(let u of p)a.handleSignalingMessage?.(u);}let d$1=a.getNativeTransport?.();d$1&&d$1.ontrack!==void 0&&(d$1.ontrack=p=>{e(`[Connection] Peer track received: ${p.track.kind}`),this.trackListeners.forEach(u=>u(p));});}setUpgradeState(e){this.upgradeState!==e&&(this.upgradeState=e,this.reportTransportStatusIfChanged(),this.upgradeStateListeners.forEach(t=>{try{t(e);}catch(n){d("[Connection] Upgrade state listener failed",n);}}));}handleUpgradeFailure(e){if(this._isClosed||!this.upgradeRequested)return;this.clearUpgradeAttemptTimeoutTimer();let t=this.upgradeTerminalFailure,n=!t&&this.shouldRetryUpgrade();this.upgradeAttemptActive=false,this.setUpgradeState("failed");let i={connectionId:this.id,remoteNodeId:this.remoteNodeId,retryCount:this.upgradeRetryCount,maxRetries:L.MAX_UPGRADE_RETRIES,terminal:t,willRetry:n};if(n?d(`[Connection] WebRTC upgrade retry scheduled after failure: ${e}`,i):console.warn(`[Connection] WebRTC upgrade failed: ${e}`,i),t&&console.warn("[Connection] WebRTC upgrade is terminal \u2014 not retrying. Both peers may be on the same page (same-context loopback)."),d(`[Connection] WebRTC upgrade fallback: ${e}`),n){this.scheduleUpgradeRetry();return}this.clearUpgradeRetryTimer(),this.teardownWebRTCTransport(`upgrade-failed:${e}`),!t&&this.upgradeRequested&&!this._isClosed&&this.upgradeRetryCount>=L.MAX_UPGRADE_RETRIES&&this.upgradeReDriveCount<L.MAX_UPGRADE_REDRIVES&&this.hasRecoverableBasePath()&&this.scheduleUpgradeReDrive();}scheduleUpgradeReDrive(){this.clearUpgradeReDriveTimer(),this.upgradeReDriveCount+=1;let e$1=this.upgradeReDriveCount;this.upgradeReDriveTimer=setTimeout(()=>{this.upgradeReDriveTimer=null,!(this._isClosed||!this.upgradeRequested||this.upgradeAttemptActive)&&(this.isWebRtcApplicationRouteReady()||!this.hasRecoverableBasePath()||(this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,e(`[Connection] Re-driving WebRTC upgrade (round ${e$1}/${L.MAX_UPGRADE_REDRIVES}) after the retry budget was exhausted on a healthy base route`),this.attemptUpgrade()));},L.UPGRADE_REDRIVE_DELAY_MS);}clearUpgradeReDriveTimer(){this.upgradeReDriveTimer&&(clearTimeout(this.upgradeReDriveTimer),this.upgradeReDriveTimer=null);}shouldRetryUpgrade(){return !(this._isClosed||!this.upgradeRequested||this.upgradeTerminalFailure||!this.options.rtcConfig||!this.hasRecoverableBasePath()||this.upgradeRetryCount>=L.MAX_UPGRADE_RETRIES)}scheduleUpgradeRetry(){this.clearUpgradeRetryTimer(),this.upgradeRetryCount+=1;let e$1=this.upgradeRetryCount;this.upgradeRetryTimer=setTimeout(()=>{this.upgradeRetryTimer=null,!(this._isClosed||!this.upgradeRequested||this.upgradeAttemptActive)&&(e(`[Connection] Retrying WebRTC upgrade ${e$1}/${L.MAX_UPGRADE_RETRIES}`),this.attemptUpgrade());},L.UPGRADE_RETRY_DELAY_MS);}clearUpgradeRetryTimer(){this.upgradeRetryTimer&&(clearTimeout(this.upgradeRetryTimer),this.upgradeRetryTimer=null);}startUpgradeAttemptTimeout(e){this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptTimeoutTimer=setTimeout(()=>{this.upgradeAttemptTimeoutTimer=null,!(this._isClosed||!this.upgradeRequested)&&this.upgradeState==="upgrading"&&this.activeNegotiationId===e&&(this.upgradeAttemptActive=false,d("[Connection] WebRTC upgrade attempt timed out",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:e}),this.handleUpgradeFailure("upgrade-attempt-timeout"));},L.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS);}clearUpgradeAttemptTimeoutTimer(){this.upgradeAttemptTimeoutTimer&&(clearTimeout(this.upgradeAttemptTimeoutTimer),this.upgradeAttemptTimeoutTimer=null);}teardownWebRTCTransport(e){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer();let t=this.webrtcTransport;if(!t)return;let n=t.getNativeTransport?.();this.traceLifecycle("webrtc-transport-teardown",{reason:e,negotiationId:this.activeNegotiationId,dataChannelReadyState:t.getDataChannelReadyState?.()??null,peerConnectionState:n?.connectionState??null,iceConnectionState:n?.iceConnectionState??null}),this.webrtcTransport=null,this.clearWebRtcApplicationRouteReady(),this.applicationRouteMissingNotified=false,this.stopWebRtcHeartbeat();try{t.close();}catch(i){d("[Connection] WebRTC transport close failed",i);}this.reportTransportStatusIfChanged();}startWebRtcHeartbeat(e$1){this.stopWebRtcHeartbeat();let t=Date.now();d("[Connection] WebRTC heartbeat starting",{connectionId:this.id,startedAt:t,config:Ve});let n=new Tt(async i=>{d("[Connection] WebRTC heartbeat send",{connectionId:this.id,byteLength:i.byteLength,typeId:i[0]}),await e$1.send(i);},i=>{let o=Date.now()-t;if(d("[Connection] WebRTC heartbeat health callback",{connectionId:this.id,health:i,elapsedSinceStartMs:o}),i==="healthy"&&(this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0,this.isWebRtcApplicationRouteReadyForTransport(e$1)||(this.hasRequiredApplicationCrypto()?this.webrtcTransport===e$1?this.markWebRtcApplicationRouteReady(e$1):this.traceLifecycle("webrtc-route-proof-ignored",{reason:"stale-transport",negotiationId:e$1.getNegotiationId?.()??null,activeNegotiationId:this.activeNegotiationId}):this.notifyWebRtcApplicationRouteMissing("webrtc-heartbeat-before-crypto"))),this.webrtcHealthListeners.forEach(s=>s(i)),i==="stale"){if(this.webRtcHeartbeatProbeInFlight)return;this.webRtcHeartbeatProbeInFlight=true,e("[Connection] WebRTC heartbeat stale \u2014 probing transport before fallback"),n.probe(4e3).then(s=>{if(this._isClosed||this.webrtcTransport!==e$1)return;if(s){this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0,e("[Connection] WebRTC heartbeat probe succeeded \u2014 keeping upgraded transport");return}if(this.webRtcHeartbeatConsecutiveProbeFailures+=1,this.transportStillLikelyAlive(e$1)){this.lastWebRtcHeartbeatOkAt=Date.now(),e("[Connection] WebRTC heartbeat probe failed but transport appears alive \u2014 suppressing fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId,consecutiveFailures:this.webRtcHeartbeatConsecutiveProbeFailures});return}if(this.webRtcHeartbeatConsecutiveProbeFailures<2){e("[Connection] WebRTC heartbeat probe failed \u2014 awaiting one more failure before fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId,consecutiveFailures:this.webRtcHeartbeatConsecutiveProbeFailures});return}if(!this.hasRecoverableBasePath()){this.lastWebRtcHeartbeatOkAt=Date.now(),e("[Connection] WebRTC heartbeat probe failed but no base recovery path exists \u2014 keeping transport",{connectionId:this.id,remoteNodeId:this.remoteNodeId});return}e("[Connection] WebRTC heartbeat probe failed consecutively \u2014 triggering upgrade fallback"),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("heartbeat-stale-probe-failed");}).finally(()=>{this.webRtcHeartbeatProbeInFlight=false;});}},Ve);this.webrtcHeartbeat=n,n.start();}stopWebRtcHeartbeat(){this.webRtcHeartbeatProbeInFlight=false,this.webRtcApplicationRouteProbeInFlight=false,this.webRtcHeartbeatConsecutiveProbeFailures=0,this.webrtcHeartbeat&&(this.webrtcHeartbeat.stop(),this.webrtcHeartbeat=null);}notifyWebRtcApplicationRouteMissing(e){this.applicationRouteMissingNotified||(this.applicationRouteMissingNotified=true,this.traceLifecycle("webrtc-route-proved-application-crypto-missing",{negotiationId:this.activeNegotiationId,reason:e}),this.options.onApplicationRouteMissing?.({connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,negotiationId:this.activeNegotiationId}));}startWebRtcApplicationRouteProbe(e,t){if(this.webRtcApplicationRouteProbeInFlight||this._isClosed||this.webrtcTransport!==e||this.upgradeState!=="upgraded"||this.isWebRtcApplicationRouteReadyForTransport(e))return;let n=this.webrtcHeartbeat;if(!n)return;this.webRtcApplicationRouteProbeInFlight=true;let i=e.getNegotiationId?.()??this.activeNegotiationId;this.traceLifecycle("webrtc-application-route-probe-start",{reason:t,negotiationId:i}),(async()=>{let o=[0,250,750,1500,3e3];for(let s of o){if(this._isClosed||this.webrtcTransport!==e||this.upgradeState!=="upgraded"||this.isWebRtcApplicationRouteReadyForTransport(e)||s>0&&(await r(s),this._isClosed||this.webrtcTransport!==e||this.upgradeState!=="upgraded"||this.isWebRtcApplicationRouteReadyForTransport(e)))return;let a=await n.probe(1500);if(this._isClosed||this.webrtcTransport!==e||this.upgradeState!=="upgraded")return;if(a){this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0,this.hasRequiredApplicationCrypto()?this.markWebRtcApplicationRouteReady(e):this.notifyWebRtcApplicationRouteMissing("webrtc-heartbeat-before-crypto");return}}this.traceLifecycle("webrtc-application-route-probe-deferred",{reason:t,negotiationId:i});})().finally(()=>{this.webrtcTransport===e&&(this.webRtcApplicationRouteProbeInFlight=false);});}async sendIrohHeartbeatPong(e){if(e.byteLength<16||!this.writer)return;let t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=t.getBigUint64(0,false),i=t.getBigInt64(8,false),o=BigInt(Date.now()),s=new ArrayBuffer(29),a=new DataView(s);a.setUint32(0,25,false),a.setUint8(4,4),a.setBigUint64(5,n,false),a.setBigInt64(13,i,false),a.setBigInt64(21,o,false);let c=this.writeMutex,d;this.writeMutex=new Promise(p=>{d=p;});try{await c,this.writer&&await this.writer.write(new Uint8Array(s));}catch{}finally{d();}}onWebRtcHeartbeatHealth(e){this.webrtcHealthListeners.push(e);}onIrohHeartbeatHealth(e){this.irohHealthListeners.push(e);}reportTransportStatusIfChanged(){if(this._isClosed)return;let{activeTransport:e,parallelTransport:t}=this.getTransportStatus(),n=`${e}:${t??""}`;this.lastReportedTransportStatus!==n&&(this.lastReportedTransportStatus=n,this.options.onTransportStatusChange?.({activeTransport:e,parallelTransport:t}));}getTransportStatus(){let e=this.transportType;return {activeTransport:e,parallelTransport:this.resolveParallelTransport(e)}}resolveParallelTransport(e){if(this._isClosed)return null;let t=c$3(e);return !t&&this.writer||!t&&f(e)&&this.hasRecoverableBasePath()?"iroh-relay":t&&this.isWebRtcDataChannelOpen()?"webrtc":null}setNativeSignalSender(e){this.nativeSignalSender=e;}traceLifecycle(e,t={}){let n={event:e,connectionId:this.id,localNodeId:this.localNodeId,remoteNodeId:this.remoteNodeId,upgradeState:this.upgradeState,upgradeRequested:this.upgradeRequested,upgradeAttemptActive:this.upgradeAttemptActive,upgradeRetryCount:this.upgradeRetryCount,activeNegotiationId:this.activeNegotiationId,preferredWebRtcRole:this.preferredWebRtcRole,hasWriter:!!this.writer,hasNativeSignalSender:!!this.nativeSignalSender,isClosed:this._isClosed,...t};d("[OpenRTC][lifecycle]",n);try{d(`[OpenRTC][lifecycle-json] ${JSON.stringify(n)}`);}catch{}}getControlFrameMode(){return this.options.controlFrameMode??"typed"}async sendNativeControlEnvelope(e){return this.getControlFrameMode()!=="native-main"||!this.nativeSignalSender?false:(await this.nativeSignalSender(e),true)}promoteToNativeMainControlRoute(e){this.options={...this.options,controlFrameMode:"native-main"},this.nativeSignalSender=e,this.traceLifecycle("native-main-control-route-promoted");}hasRequiredApplicationCrypto(){return this.options.requireApplicationCrypto!==true||!!this.options.applicationCrypto}clearWebRtcApplicationRouteReady(){this.webRtcApplicationRouteReadyTransport=null,this.webRtcApplicationRouteReadyNegotiationId=null;}isCurrentWebRtcTransportApplicationRouteReady(){return !!this.webrtcTransport&&this.isWebRtcApplicationRouteReadyForTransport(this.webrtcTransport)}isWebRtcApplicationRouteReadyForTransport(e){return this.webRtcApplicationRouteReadyTransport===e&&this.webRtcApplicationRouteReadyNegotiationId===(e.getNegotiationId?.()??this.activeNegotiationId)}markWebRtcApplicationRouteReady(e){if(this.isWebRtcApplicationRouteReadyForTransport(e)||!this.hasRequiredApplicationCrypto()){this.hasRequiredApplicationCrypto()||this.traceLifecycle("webrtc-route-promotion-skipped",{reason:"missing-application-crypto",negotiationId:e.getNegotiationId?.()??this.activeNegotiationId});return}if(this.webrtcTransport!==e){this.traceLifecycle("webrtc-route-promotion-skipped",{reason:"stale-transport",negotiationId:e.getNegotiationId?.()??null,activeNegotiationId:this.activeNegotiationId});return}this.webRtcApplicationRouteReadyTransport=e,this.webRtcApplicationRouteReadyNegotiationId=e.getNegotiationId?.()??this.activeNegotiationId,this.negotiationSwitchCount=0,this.upgradeReDriveCount=0,this.clearUpgradeReDriveTimer(),this.traceLifecycle("webrtc-application-route-ready",{negotiationId:this.webRtcApplicationRouteReadyNegotiationId}),this.reportTransportStatusIfChanged();}isWebRtcApplicationRouteReady(){return this.isCurrentWebRtcTransportApplicationRouteReady()&&this.upgradeState==="upgraded"&&!!this.webrtcTransport&&this.hasRequiredApplicationCrypto()}isMoQApplicationRouteReady(){let e=this.options.transportContext;return !this._isClosed&&!!e&&e.isMoQReady()&&this.peerMoQReady&&this.isMoQDataRouteReady(e)&&this.hasRequiredApplicationCrypto()}isMoQDataRouteReady(e){return typeof e.isMoQDataReady=="function"?e.isMoQDataReady():true}async sendInternalSignal(e$1){let t=e$1&&(e$1.transport==="webrtc"||!e$1.transport)?{...e$1,transport:"webrtc",negotiationId:this.normalizeNegotiationId(e$1.negotiationId)??this.activeNegotiationId??void 0}:e$1,n={type:"#pluto-signal",content:t};if(this.getControlFrameMode()==="native-main"){if(this.nativeSignalSender)try{await this.nativeSignalSender(n),e("[Connection] Sent internal signal via native sender",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});return}catch(i){console.warn("[Connection] Native signal sender failed, falling back to own native-main stream",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null,error:i});}if(this.writer&&typeof this.sendRawIrohFrame=="function")try{let i=new TextEncoder().encode(JSON.stringify(n)),o=new Uint8Array(1+i.byteLength);o[0]=0,o.set(i,1);let s=new ArrayBuffer(4+o.byteLength),a=new DataView(s),c=new Uint8Array(s);a.setUint32(0,o.byteLength,!1),c.set(o,4),await this.sendRawIrohFrame(c),e("[Connection] Sent internal signal over own native-main stream",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});return}catch(i){console.warn("[Connection] Own native-main stream signal send failed; falling back to typed iroh",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null,error:i});}}try{if((t?.type==="sdp"||t?.type==="candidate"||t?.type==="renegotiate")&&d("[Connection][WebRTC][signal][send]",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:t?.negotiationId??null,signalType:t?.type??null,sdpType:t?.sdp?.type??null,hasSdp:!!t?.sdp?.sdp,hasCandidate:!!t?.candidate}),this.writer&&typeof this.sendRawIrohFrame=="function"){let i=new TextEncoder().encode(JSON.stringify(n)),o=new Uint8Array(1+i.byteLength);o[0]=0,o.set(i,1);let s=new ArrayBuffer(4+o.byteLength),a=new DataView(s),c=new Uint8Array(s);a.setUint32(0,o.byteLength,!1),c.set(o,4),await this.sendRawIrohFrame(c),e("[Connection] Sent internal signal over native-main iroh frame",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});return}await this.sendTypedOnTransport("iroh",0,n,{requireApplicationCrypto:!1}),e("[Connection] Sent internal signal over iroh (typed-frame fallback)",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});}catch(i){throw console.warn("[Connection] Failed to send internal signal over iroh",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null,error:i}),i}}receiveInternalSignal(e){this._isClosed||!e||typeof e!="object"||this.handleInternalSignal({type:"#pluto-signal",content:e});}handleInternalSignal(e){if(!(e.content&&(e.content.transport==="webrtc"||!e.content.transport)))return;let n=e.content,i=typeof n?.type=="string"?n.type:null,o=n?.sdp&&typeof n.sdp=="object"&&typeof n.sdp.type=="string"?n.sdp.type:null,s=i==="sdp"&&o==="offer",a=this.normalizeNegotiationId(n?.negotiationId);if((i==="sdp"||i==="candidate"||i==="renegotiate")&&d("[Connection][WebRTC][signal][recv]",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:a??null,signalType:i,sdpType:o,hasSdp:!!n?.sdp?.sdp,hasCandidate:!!n?.candidate,upgradeState:this.upgradeState}),i==="renegotiate"){let C=this.lastWebRtcHeartbeatOkAt===null?null:Date.now()-this.lastWebRtcHeartbeatOkAt,I=this.lastWebRtcDataChannelOpenAt===null?null:Date.now()-this.lastWebRtcDataChannelOpenAt,k=C!==null&&C<=L.WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS||this.isWebRtcDataChannelOpen()&&I!==null&&I<=L.WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS;if(this.isWebRtcDataChannelOpen()||this.upgradeState==="upgraded"){let A=!!a&&a!==this.activeNegotiationId&&a.startsWith("conn-")&&!a.startsWith(`conn-${this.id}-`)&&this.getDeterministicWebRtcRole()==="responder";if(k&&!A){d("[Connection] Ignoring WebRTC renegotiate request; route is provably live",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId,heartbeatSilenceMs:C,dataChannelOpenForMs:I});return}d("[Connection] Honoring WebRTC renegotiate by tearing down the current route",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId,priorState:this.upgradeState,heartbeatSilenceMs:C,dataChannelOpenForMs:I,reason:A?"fresh-remote-generation":"stale-route"}),this.clearUpgradeRetryTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,this.pendingSignals=[],this.stopWebRtcHeartbeat(),this.teardownWebRTCTransport(A?"inbound-renegotiate-fresh-generation":"inbound-renegotiate-stale-route"),this.setUpgradeState("none");}else if(this.upgradeState==="upgrading"&&this.webrtcTransport)if(!!a&&a!==this.activeNegotiationId&&a.startsWith("native-"))d("[Connection] Honoring fresh native WebRTC renegotiate during in-flight upgrade",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId}),this.clearUpgradeRetryTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,this.pendingSignals=[],this.stopWebRtcHeartbeat(),this.teardownWebRTCTransport("inbound-native-renegotiate-while-upgrading"),this.setUpgradeState("none"),this.preferredWebRtcRole=this.getDeterministicWebRtcRole();else {d("[Connection] Ignoring WebRTC renegotiate request while an upgrade is already in flight",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId});return}}let c=!!a&&!!this.activeNegotiationId&&a!==this.activeNegotiationId,d$1=i==="sdp"&&s||i==="renegotiate"&&this.upgradeState!=="upgrading"&&this.upgradeState!=="upgraded";if(c&&!d$1){d("[Connection] Ignoring stale WebRTC signal from a previous negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:i,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId});return}let p=!!this.activeNegotiationId?.startsWith("native-"),u=!!a?.startsWith("native-"),g=s&&!!a?.startsWith(`conn-${this.id}-`);if(c&&d$1&&this.upgradeState==="upgrading"&&this.preferredWebRtcRole==="responder"&&p&&g){d("[Connection] Ignoring reflected WebRTC offer during active native negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId});return}let f=s&&!!a?.startsWith(`conn-${this.id}-`);if(c&&d$1&&f&&!p&&this.getDeterministicWebRtcRole()==="initiator"&&(this.upgradeState==="upgrading"||this.upgradeAttemptActive)){d("[Connection] Ignoring competing inbound WebRTC offer as glare-impolite initiator",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId});return}let v=f&&!u;if(c&&d$1&&v&&this.negotiationSwitchCount>=L.MAX_NEGOTIATION_SWITCHES){console.warn("[Connection] Ignoring competing inbound WebRTC offer: negotiation switch budget exhausted",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:a,activeNegotiationId:this.activeNegotiationId,switchBudget:L.MAX_NEGOTIATION_SWITCHES});return}c&&d$1&&(v&&(this.negotiationSwitchCount+=1),d("[Connection] Switching to a fresh inbound WebRTC negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,priorNegotiationId:this.activeNegotiationId,nextNegotiationId:a,priorState:this.upgradeState,signalType:i,switchCount:this.negotiationSwitchCount,budgetedNegotiationSwitch:v}),this.clearUpgradeRetryTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,this.pendingSignals=[],this.stopWebRtcHeartbeat(),this.teardownWebRTCTransport("inbound-negotiation-switch")),a&&(!this.activeNegotiationId||c)&&(this.activeNegotiationId=a);let y=!this.webrtcTransport||this.upgradeState==="failed"||c&&this.upgradeState!=="upgrading";if(d$1&&y&&this.options.rtcConfig&&!this._isClosed){d("[Connection] Auto-requesting WebRTC upgrade from incoming signal",{connectionId:this.id,remoteNodeId:this.remoteNodeId,currentState:this.upgradeState,signalType:i,sdpType:o,signalNegotiationId:a,preferredRole:s?"responder":this.preferredWebRtcRole}),s?this.preferredWebRtcRole="responder":i==="renegotiate"&&a?.startsWith("native-")&&(this.preferredWebRtcRole=this.getDeterministicWebRtcRole()),this.upgradeRequested=true,this.upgradeTerminalFailure=false,this.pendingSignals=[n],this.attemptUpgrade(a);return}n.transport||(n.transport="webrtc"),this.webrtcTransport?.handleSignalingMessage?this.webrtcTransport.handleSignalingMessage(n):(!a||!this.activeNegotiationId||a===this.activeNegotiationId)&&this.pendingSignals.push(n);}createNegotiationId(){return `conn-${this.id}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}getDeterministicWebRtcRole(){return this.localNodeId>this.remoteNodeId?"initiator":"responder"}normalizeNegotiationId(e){if(typeof e!="string")return null;let t=e.trim();return t.length>0?t:null}};L.textDecoder=new TextDecoder("utf-8",{fatal:true}),L.textEncoder=new TextEncoder,L.UPGRADE_RETRY_DELAY_MS=1e3,L.MAX_UPGRADE_RETRIES=5,L.MAX_UPGRADE_REDRIVES=1,L.UPGRADE_REDRIVE_DELAY_MS=5e3,L.WEBRTC_DISCONNECTED_GRACE_MS=4e3,L.MAX_PENDING_MESSAGES=256,L.DEFAULT_APPLICATION_CRYPTO_WAIT_MS=1e4,L.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS=Yn+3e3,L.MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS=256,L.WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS=12e3,L.MAX_NEGOTIATION_SWITCHES=6,L.FOREGROUND_PROBE_TIMEOUT_MS=2e3;var ge=L;async function he(r,e,t){await y(r,e)&&d("[Client][CONNECT] Closed unused bi stream after adopting existing connection",{remoteNodeId:t??null,reason:e});}function Go(r){let e=false,t=new Set,n=new Set,i=new Set,o=async()=>{try{await r.disconnectNodeTransport(r.remoteNodeId);}catch{}};return {id:r.connectionId,localNodeId:r.localNodeId,remoteNodeId:r.remoteNodeId,deviceId:r.remoteNodeId,get isClosed(){return e},get transportType(){return "iroh"},getTransportStatus(){return {activeTransport:"iroh-relay",parallelTransport:null}},peerMoQReady:false,async send(){throw new Error("Transport-only ticket-only channels do not expose a main message stream.")},async sendMedia(){throw new Error("Transport-only ticket-only channels do not expose a media stream.")},async disconnect(){if(!e){e=true,await o();for(let s of [...i])s();}},onMessage(s){typeof s=="function"&&t.add(s);},onMedia(s){typeof s=="function"&&n.add(s);},onDisconnect(s){typeof s=="function"&&i.add(s);}}}var At=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async connect(e$1,t=2e4,n,i,o){if(this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive(),!e$1||!e$1.trim())throw new Error("connect requires a non-empty endpoint ticket");let s=e$1.trim(),{irohTicket:a,tokenSuffix:c}=se(s),d$1=this.deps.getWasmClient(),p;try{p=await d$1.endpoint_id_from_ticket(a);}catch(D){throw new Error(`connect requires a valid endpoint ticket: ${D?.message||D}`)}this.assertActive();let u=null;if(c){let D=Ie(a,c);typeof D?.t=="string"&&(u=D.t,this.deps.rememberPendingTokenForNode(p,D.t,c));}let g=this.deps.getDeterministicConnectionId(p),f=this.deps.getRegisteredChannel(i??null),v=this.deps.isTransportOnlyChannel(i);d("[Client][CONNECT] resolved ticket target",{nodeId:p,connectionId:g,channelId:i??null,registeredChannel:f?{id:f.id,readiness:f.readiness,promotionPolicy:f.promotionPolicy,signalingPolicy:f.signalingPolicy}:null,transportOnlyChannel:v,hasCompoundTicketToken:!!u});let y=this.ctx.registry.get(g);if(y&&!u){let D=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,o?.approvedScope??null,u,y);return D&&this.deps.initializeConnectionTrust(y,D),await this.deps.refreshApplicationRouteHandshake(y,"connect-existing"),this.assertActive(),y}let C=c?Ie(a,c):null,I=o?.approvedScope??null;!I&&typeof C?.s=="string"&&C.s.trim()&&(I=C.s.trim());let k=async D=>{e(`Initiating managed transport dial to ${p} (${D})...`);let O=await this.deps.ensureWasmManagedTransport(s,n??null,{skipIfConnected:o?.admissionAlreadyPresented===true,admissionAlreadyPresented:o?.admissionAlreadyPresented===true,timeoutMs:t});if(this.assertActive(),O.approvedScope)I=O.approvedScope,this.deps.setSessionTokenApprovedScope(g,O.approvedScope);else if(u&&!I){await this.schedulePeerReconciliationBestEffort("managed-dial-scope-lookup"),this.assertActive();let Q=this.deps.getSessionTokenApprovedScope(g);if(typeof Q=="string"&&Q.trim())I=Q.trim();else {let Te=this.deps.getPeerState(n??p)?.scopes?.[0];typeof Te=="string"&&Te.trim()&&(I=Te.trim());}}};try{await k("initial");}catch(D){if(this.deps.isLocalIrohRuntimeNotInitializedError(D)){let O=await this.deps.recoverLocalIrohRuntime("connect-managed-dial");if(this.assertActive(),!O)throw new Error(`Failed to initiate managed transport dial to ${p}: ${D?.message||D}`);try{await k("after-local-runtime-recovery");}catch(Q){throw new Error(`Failed to initiate managed transport dial to ${p} after local Iroh runtime recovery: ${Q?.message||Q}`)}}else throw D}if(this.assertActive(),u){let D=I??o?.approvedScope??null,O=this.ctx.registry.get(g);if(O&&!O.isClosed){let Q=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,D,u,O);return this.deps.assignConnectionChannel(O,i),this.deps.initializeConnectionTrust(O,Q),Q&&this.deps.bindConnectionDeviceIdInRust(O,Q),this.deps.approveSessionTokenNode(p),this.deps.approveSessionTokenConnection(O.id),this.deps.applySessionTokenTrustApproval(O,D,"dialer-compound-ticket-existing-connection"),this.deps.announceConnectionWhenStable(O),d("[Client][AUTH] adopted token-approved existing connection",{nodeId:p,connectionId:O.id,localNodeId:O.localNodeId,remoteNodeId:O.remoteNodeId,approvalScope:I||null}),await this.deps.refreshApplicationRouteHandshake(O,"dialer-compound-ticket-existing-connection"),this.assertActive(),O}}if(v){let D=Go({connectionId:g,localNodeId:this.ctx.localNodeId,remoteNodeId:p,disconnectNodeTransport:Q=>this.deps.disconnectNodeTransport(Q)}),O=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,I??o?.approvedScope??null,u,D);return this.deps.assignConnectionChannel(D,i),this.deps.initializeConnectionTrust(D,O),this.deps.registerConnection(D),this.deps.announceConnectionWhenStable(D),d("[Client][AUTH] using transport-only channel connection",{nodeId:p,connectionId:D.id,channelId:i??null,signalingMode:this.deps.getOptions().signalingMode??"hosted",hasCompoundTicketToken:!!u}),D}let T=await this.openMainBiStream(p,t,!!u);this.disposed&&(await he(T,"dial-coordinator-disposed-after-open",p),this.assertActive());let _=this.ctx.registry.get(g);if(_&&!_.isClosed){let D=I??o?.approvedScope??null,O=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,D,u,_);return await he(T,"late-dial-adopted-existing-connection",p),this.deps.assignConnectionChannel(_,i),this.deps.initializeConnectionTrust(_,O),O&&this.deps.bindConnectionDeviceIdInRust(_,O),u&&(this.deps.approveSessionTokenNode(p),this.deps.approveSessionTokenConnection(_.id),this.deps.applySessionTokenTrustApproval(_,D,"dialer-compound-ticket-late-existing-connection")),this.deps.announceConnectionWhenStable(_),d("[Client][CONNECT] adopted existing connection after async dial completed",{nodeId:p,connectionId:_.id,channelId:i??null,approvalScope:I||null,upgradeState:typeof _.getUpgradeState=="function"?_.getUpgradeState():null}),await this.deps.refreshApplicationRouteHandshake(_,"late-dial-adopted-existing-connection"),this.assertActive(),_}let A=this.deps.shouldUseNativeMainFramingForPeer(p,this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,I??o?.approvedScope??null,u,null),!!u);A&&(await B$1(this.deps.writeNativeMainLabelHeaderOnBiStream(T,p),4e3,"writeNativeMainLabelHeaderOnBiStream"),this.disposed&&(await he(T,"dial-coordinator-disposed-after-native-label",p),this.assertActive()));let E=this.createConnection({connId:g,nodeId:p,biStream:T,useNativeMainFraming:A});this.deps.assignConnectionChannel(E,i);let x=I??o?.approvedScope??null,j=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,x,u,E);if(this.deps.initializeConnectionTrust(E,j),this.disposed&&(await this.disconnectConnectionBestEffort(E),this.assertActive()),this.deps.registerConnection(E),j&&this.deps.bindConnectionDeviceIdInRust(E,j),u){await this.schedulePeerReconciliationBestEffort("compound-ticket-connect"),this.assertActive();let D=this.deps.getPeerState(E.id)??this.deps.getPeerState(p),O=this.deps.consumePendingSessionTokenTrustApproval(E.id);O.approved?this.deps.applySessionTokenTrustApproval(E,O.scope??x,"dialer-compound-ticket-pending"):D?.admissionState==="admitted"&&this.deps.applySessionTokenTrustApproval(E,x,"dialer-compound-ticket-rust-admitted"),d("[Client][AUTH] token-approved connection registered locally",{nodeId:p,connectionId:E.id,localNodeId:E.localNodeId,remoteNodeId:E.remoteNodeId,rustAdmissionState:D?.admissionState??null,pendingApproval:O.approved});}return this.deps.announceConnectionWhenStable(E),d("[Client][HANDSHAKE] sending hello (dial path)",{connectionId:E.id,remoteNodeId:E.remoteNodeId}),this.sendDialHelloInBackground(E),E}async connectPeer(e){this.assertActive();let t=e.scope??"persistent";if(!e.ticket)throw new Error("connectPeer requires a ticket.");d("[Client][connectPeer] starting",{scope:t,channelId:e.channelId??null,hasDeviceId:!!e.deviceId,ticketLength:e.ticket.length});let n=se(e.ticket).tokenSuffix!==null;if(e.respectManualDisconnect&&this.hasManualDisconnectProjection(e.deviceId))throw new Error(`connectPeer suppressed by manual disconnect for device ${e.deviceId}`);e.deviceId&&!n&&!e.respectManualDisconnect&&this.deps.clearManualDisconnectProjection(e.deviceId);let i=await this.connect(e.ticket,2e4,e.deviceId,e.channelId);this.assertActive();let o=this.deps.getSessionTokenApprovedScope(i.id),s=[...o?[o]:[],...this.deps.getPeerScopes(i.id)].filter((g,f,v)=>v.indexOf(g)===f),a=s.length>0?s:[t],d$1=s.length===0||a.some(g=>this.deps.sessionTokenScopeAllowsDeviceBinding(g))?e.deviceId:void 0,p=this.deps.resolvePromotionEligibility({connectionId:i.id,nodeId:i.remoteNodeId,deviceId:d$1??void 0}),u=d$1||i.remoteNodeId||i.deviceId||i.id;d$1&&n&&this.deps.clearManualDisconnectProjection(d$1),this.deps.hasRustPeerLifecycleProjection()?this.schedulePeerReconciliationInBackground("connect-peer"):this.deps.dispatchLiveConnectionProjection(i,{trustProjection:null,promotionEligible:p,peerId:u,deviceId:d$1,ticket:e.ticket,scopes:a,applicationRouteReady:this.deps.hasApplicationRouteForConnection(i),webRtcApplicationRouteReady:this.deps.isWebRtcApplicationRouteReadyForConnection(i)});for(let g of a)this.deps.addPeerScope(u,g);return i}hasManualDisconnectProjection(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;let n=this.deps.getWasmClient();if(n&&typeof n.is_auto_connect_excluded=="function"&&n.is_auto_connect_excluded(t)===true)return true;let i=this.deps.getPeerState(t);if(!i)return false;if(i.manualDisconnect===true)return true;let o=i,s=[i.error,o.lastDisconnectReason].filter(a=>typeof a=="string"&&a.length>0).join(" ");return /manual disconnect/i.test(s)}async openMainBiStream(e,t,n){this.assertActive();let i=null,o=0,s=500,a=Math.ceil(t/s),c=this.deps.getWasmClient();for(;o<a;){this.assertActive();try{let d=c.open_peer_bi,p=n&&typeof d=="function"?d.call(c,e,2500):c.open_bi(e);i=await B$1(p,2500,n?"wasmClient.open_peer_bi":"wasmClient.open_bi"),this.disposed&&(await he(i,"dial-coordinator-disposed-during-open",e),this.assertActive());break}catch(d){if(this.disposed)throw d;o++,await r(s);}}if(!i)throw new Error(`Failed to establish connection to ${e} after ${t} ms`);return i}assertActive(){if(this.disposed)throw new Error("Connection dial cancelled because the client was disposed.")}createConnection(e){let{connId:t,nodeId:n,biStream:i,useNativeMainFraming:o}=e,s=new ge(t,this.deps.getLocalNodeId(),n,i.send.getWriter(),i.recv.getReader(),{rtcConfig:this.deps.getRTCConfig(),transportContext:this.deps.createTransportContext(n),applicationCrypto:this.deps.getOptions()?.applicationCrypto,requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:o?"native-main":"typed",onTransportStatusChange:a=>{this.deps.handleConnectionTransportStatus(t,a.activeTransport,a.parallelTransport);},onApplicationRouteMissing:a=>{this.deps.handleConnectionApplicationRouteMissing(t,a);}});if(o&&this.deps.getWasmClient()){let a=this.deps.getWasmClient();s.setNativeSignalSender(async c=>{await this.deps.sendNativeSignalEnvelope(s,n,c,a);}),d("[Client][NATIVE-MAIN] Attached native signal sender to dial-path connection",{connectionId:s.id,remoteNodeId:n});}return s}sendDialHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send outgoing handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).then(()=>{this.disposed||this.deps.requestProtectedWebRTCUpgradeIfInitiator(e,"protected-hello:dial");}).catch(t);}catch(n){t(n);}}schedulePeerReconciliationBestEffort(e){try{return Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>[])}catch{return Promise.resolve([])}}schedulePeerReconciliationInBackground(e){if(!this.disposed)try{this.schedulePeerReconciliationBestEffort(e);}catch{}}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};var kt=class{constructor(e){this.deps=e;this.connectionListeners=[];this.disconnectionListeners=[];this.announcedConnections=new Set;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.connectionListeners=[],this.disconnectionListeners=[],this.announcedConnections.clear());}findLiveConnectionForRemoteNode(e,t){let n=this.deps.registry.get(t);if(n&&!n.isClosed)return n;for(let i of this.deps.registry.values())if(i.remoteNodeId===e&&!i.isClosed)return i;return null}cleanupReplacedConnection(e){this.disposed||(this.deps.registry.delete(e),this.forgetAnnouncedConnection(e),this.deps.cleanupConnectionState(e));}healOrphanTsConnection(e){if(this.disposed)return;let t=this.deps.registry.get(e);!t||t.isClosed||(d("[Client][PEER-RECONCILE] closing orphan TS connection",{connectionId:e}),this.disconnectBestEffort(t));}registerConnection(e){if(this.disposed)return;let t=this.deps.registry;t.clearLocalTerminalClose(e.id);let n=t.get(e.id);if(t.set(e.id,e),n&&n!==e&&!n.isClosed&&this.disconnectBestEffort(n),typeof e.setApplicationCrypto=="function"){let s=this.deps.resolveApplicationCryptoForPeer(e.remoteNodeId,e);s&&e.setApplicationCrypto(s);}this.flushPendingNativeMainHandshakesBestEffort(e.remoteNodeId,"connection-registered"),this.flushPendingNativeMainSignalsBestEffort(e.remoteNodeId,"connection-registered");let i=this.deps.getConnectionTrustState(e.id),o=i?.verifiedDeviceId??i?.expectedDeviceId??this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId)??null;o?this.deps.bindConnectionDeviceIdInRust(e,o):this.lookupConnectionDeviceBindingInBackground(e),i?.verified&&o&&this.deps.retireSupersededConnections(e,o,"registered-trusted-replacement"),typeof e.onUpgradeStateChange=="function"&&e.onUpgradeStateChange(()=>{this.disposed||!t.has(e.id)||e.isClosed||this.deps.hasRustPeerLifecycleProjection()||this.deps.applyConnectionTrustProjection(e);}),this.deps.hasRustPeerLifecycleProjection()?this.schedulePeerReconciliationBestEffort("register-connection"):this.deps.applyConnectionTrustProjection(e),typeof e.reportTransportStatusIfChanged=="function"&&e.reportTransportStatusIfChanged(),typeof e.onWebRTCBinaryMessage=="function"&&e.onWebRTCBinaryMessage(s=>this.disposed?false:this.deps.maybeHandleWebRTCExplicitFileEnvelope(e,s)),e.onMessage(s=>{if(!this.disposed)try{Promise.resolve(this.deps.handleMessage(e,s)).catch(a=>{this.disposed||console.warn("[Client] connection message handler failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});});}catch(a){this.disposed||console.warn("[Client] connection message handler failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});}}),e.onDisconnect(()=>{if(this.disposed||(e.peerMoQReady=false,t.get(e.id)!==e))return;t.markLocalTerminalClose(e.id);let s=this.deps.getExistingPeerProjectionForDisconnect(e);t.delete(e.id),this.deps.cleanupConnectionState(e.id),this.deps.dispatchLiveConnectionProjection(e,{trustProjection:null,promotionEligible:this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),existingProjection:s,terminalTransportClose:true,applicationRouteReady:false,webRtcApplicationRouteReady:false}),this.deps.hasRustPeerLifecycleProjection()&&this.schedulePeerReconciliationBestEffort("connection-disconnect"),this.announcedConnections.delete(e.id)&&this.emitDisconnection(e);});}announceConnectionWhenStable(e){(async()=>{if(this.disposed)return;let t=await this.waitForStableConnection(e);if(!this.disposed){if(!t){if(!e.isClosed){let i=this.deps.getConnectionTrustState(e.id);console.warn(`[Client] Suppressing unstable connection ${e.id}`,{deviceId:e.deviceId,upgradeState:e.getUpgradeState?.()??null,transportStatus:typeof e.getTransportStatus=="function"?e.getTransportStatus():null,trustRequired:i?.required??null,trustVerified:i?.verified??null,trustFailed:i?.failed??null,trustFailureReason:i?.failureReason??null});}let n=this.deps.getConnectionTrustState(e.id);if(n?.required&&!e.isClosed){if(this.disposed)return;await this.deps.enforceConnectionTrustFailure(e,n.failureReason??"trusted-device-proof-timeout").catch(()=>{});}return}this.announcedConnections.has(e.id)||(this.announcedConnections.add(e.id),this.emitConnection(e));}})();}async waitForStableConnection(e){if(this.disposed)return false;let t=this.deps.initializeConnectionTrust(e),n=false,i=false,o=this.deps.hasApplicationRouteForConnection(e),s=this.deps.allowsTransportOnlyStability(e),a=null,c=this.deps.getWasmClient(),d=c&&typeof c.wait_for_settled_peer=="function"?c.wait_for_settled_peer:null;if(d)try{let g=await d.call(c,e.deviceId,this.deps.stableTimeoutMs),f=e.getUpgradeState;if(a=typeof f=="function"?f.call(e):null,o=this.deps.hasApplicationRouteForConnection(e),g?.settledReady&&(!t.required||t.verified)&&(o||s))return !0;if(t.required&&t.failed)return console.warn("[Client][STABILITY] trust failed during settled-peer gate",{connectionId:e.id,deviceId:e.deviceId,settledReady:g?.settledReady??null,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,upgradeState:a}),!1;if(!t.verified&&!this.deps.usesTicketOnlySignalingMode())return console.warn("[Client][STABILITY] settled-peer gate rejected connection before poll loop",{connectionId:e.id,deviceId:e.deviceId,settledReady:g?.settledReady??null,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,upgradeState:a}),!1}catch{}let p=Date.now(),u=null;for(;Date.now()-p<this.deps.stableTimeoutMs;){if(this.disposed||e.isClosed||t.required&&t.failed)return false;let g=await this.deps.isCoreConnectionHealthy(e.deviceId);if(this.disposed)return false;let f=e.getUpgradeState;a=typeof f=="function"?f.call(e):null;let v=a==="upgraded";if(n=g,i=v,o=this.deps.hasApplicationRouteForConnection(e),g||v){if(u===null&&(u=Date.now()),Date.now()-u>=this.deps.stableWindowMs&&(!t.required||t.verified)&&(o||s))return true}else u=null;await r(this.deps.stablePollMs);}return console.warn("[Client][STABILITY] connection did not become stable before timeout",{connectionId:e.id,deviceId:e.deviceId,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,lastCoreHealthy:n,lastUpgradedTransportHealthy:i,lastApplicationRouteReady:o,lastUpgradeState:a,transportStatus:typeof e.getTransportStatus=="function"?e.getTransportStatus():null}),false}onConnection(e){return this.disposed?()=>{}:(this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);})}onDisconnection(e){return this.disposed?()=>{}:(this.disconnectionListeners.push(e),()=>{this.disconnectionListeners=this.disconnectionListeners.filter(t=>t!==e);})}isConnectionAnnounced(e){return this.announcedConnections.has(e)}forgetAnnouncedConnection(e){this.announcedConnections.delete(e);}emitConnection(e){for(let t of [...this.connectionListeners])try{t(e);}catch(n){console.warn("[Client] connection listener failed",n);}}emitDisconnection(e){for(let t of [...this.disconnectionListeners])try{t(e);}catch(n){console.warn("[Client] disconnection listener failed",n);}}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}flushPendingNativeMainHandshakesBestEffort(e,t){if(!this.disposed)try{Promise.resolve(this.deps.flushPendingNativeMainHandshakesForNode(e,t)).catch(()=>{});}catch{}}flushPendingNativeMainSignalsBestEffort(e,t){if(!this.disposed)try{Promise.resolve(this.deps.flushPendingNativeMainSignalsForNode(e,t)).catch(()=>{});}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}lookupConnectionDeviceBindingInBackground(e){try{Promise.resolve(this.deps.searchDevices()).then(()=>{if(this.disposed)return;let t=this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId);t&&this.deps.bindConnectionDeviceIdInRust(e,t);}).catch(()=>{});}catch{}}};var Nt=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async handleMessage(e,t){this.disposed||t&&typeof t=="object"&&t.type==="handshake"&&(!await this.handleHandshake(e,t)||this.disposed)||this.deps.dispatchMessage(e,t);}async handleHandshake(e$1,t){if(this.disposed)return false;let n=t.action??"hello",i=!!this.deps.resolveApplicationCryptoForPeer(e$1.remoteNodeId,e$1),o=await this.deps.handleApplicationKeyAgreement(e$1,t).catch(C=>this.disposed?{remotePublicChanged:false,cryptoReady:false}:(console.warn("[Client][KEY-AGREEMENT] Handshake key agreement failed; closing connection",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,error:C}),this.disconnectBestEffort(e$1),{remotePublicChanged:false,cryptoReady:false}));if(this.disposed)return false;let s=!i&&!!this.deps.resolveApplicationCryptoForPeer(e$1.remoteNodeId,e$1),a=t.capabilities&&typeof t.capabilities=="object"?t.capabilities:void 0,c=!!a&&Object.prototype.hasOwnProperty.call(a,"webrtc"),d$1=!!a&&Object.prototype.hasOwnProperty.call(a,"moq"),p=typeof t.moq=="boolean",u=c&&a.webrtc===true,g=d$1?a.moq===true:!!t.moq,f=this.deps.isWebRTCTransportEnabled(),v=this.deps.requiresManagedTransportTrust(),y=C=>{if(this.disposed||e$1.isClosed||!u||!f)return;let I=this.deps.getLocalNodeId();this.deps.usesTicketOnlySignalingMode()&&I&&e$1.remoteNodeId&&I.localeCompare(e$1.remoteNodeId)<0||(d("[Client][HANDSHAKE] requesting WebRTC upgrade from handshake",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:n,reason:C}),e$1.requestWebRTCUpgrade(C));};if(n==="hello"){let C=await this.deps.validateIncomingSessionTokenWithRetry(t.sessionToken??"",e$1.id,{remoteNodeId:e$1.remoteNodeId,source:"handshake-hello",tokenPayload:typeof t.sessionTokenPayload=="string"?t.sessionTokenPayload:void 0});if(this.disposed)return false;if(!C.ok)return console.warn("[Client][SESSION-TOKEN] Rejecting connection \u2014 invalid session token",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,reason:C.reason,hasToken:!!t.sessionToken}),this.disconnectBestEffort(e$1),false;t.sessionToken&&this.deps.applySessionTokenTrustApproval(e$1,C.scope??null,"handshake-hello");}return d("[Client][HANDSHAKE] received",{action:n,connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,channelId:t.channelId??this.deps.getConnectionChannelId(e$1.id)??null,remoteSupportsWebRTC:u,remoteSupportsMoQ:g,localWebRTCEnabled:f,hasSessionToken:!!t.sessionToken,hasTransportTrust:!!t.transportTrust}),(n==="response"||n==="ack"||n==="capability-update")&&this.deps.clearPendingTokenForNode(e$1.remoteNodeId),n==="capability-update"&&(s||o.remotePublicChanged)&&t.capabilities?.applicationKeyAgreement===true&&this.sendHandshakeInBackground(e$1,"capability-update","[Client][KEY-AGREEMENT] Failed to reciprocate capability key agreement"),c&&(e$1.remoteSupportsWebRTC=u),!v&&f&&u&&(n==="hello"||n==="capability-update"||n==="response"&&!t.transportTrust)&&y(`handshake:${n}`),(d$1||p)&&(g&&this.deps.getMoQState()==="ready"?(e(`[Client] Peer ${e$1.deviceId.substring(0,6)} supports MoQ. Upgrading...`),this.deps.enableMoQForConnection(e$1)):g||(e$1.peerMoQReady=false,this.deps.forgetMoQPeerSubscription(e$1.id))),this.deps.assignConnectionChannel(e$1,t.channelId??null),t.transportTrust||v?this.handleTransportTrustHandshakeInBackground(e$1,t,n,v,y):(t.action==="hello"||!t.action)&&t.sessionToken&&this.sendHandshakeWithRecoveryInBackground(e$1,"response",null,"session-token-response","[Client][SESSION-TOKEN] Failed to send response handshake"),true}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}sendHandshakeInBackground(e,t,n){let i=o=>{this.disposed||console.warn(n,{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:o});};try{Promise.resolve(this.deps.sendTransportHandshake(e,t)).catch(i);}catch(o){i(o);}}sendHandshakeWithRecoveryInBackground(e,t,n,i,o){let s=a=>{this.disposed||console.warn(o,{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});};try{Promise.resolve(this.deps.sendTransportHandshakeWithRecovery(e,t,n,i)).catch(s);}catch(a){s(a);}}handleTransportTrustHandshakeInBackground(e,t,n,i,o){let s=a=>{this.disposed||console.warn("[Client][TRUST] Handshake processing failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});};try{Promise.resolve(this.handleTransportTrustHandshake(e,t,n,i,o)).catch(s);}catch(a){s(a);}}async handleTransportTrustHandshake(e,t,n,i,o){try{if(this.disposed)return;let s=n,a=t.transportTrust??null,c=this.deps.initializeConnectionTrust(e);if(a?.deviceId&&!c.expectedDeviceId&&this.deps.getKnownDevice(a.deviceId,e.remoteNodeId)&&(c.expectedDeviceId=a.deviceId),s==="hello"){let d$1=typeof a?.challenge=="string"?a.challenge:null;if(!d$1&&c.required)if(this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)){c.required=!1,c.verified=!0,c.failed=!1,c.failureReason=void 0,c.issuedChallenge=null,this.deps.applyConnectionTrustProjection(e);let p=typeof a?.deviceId=="string"&&a.deviceId.trim()?a.deviceId.trim():c.expectedDeviceId??this.deps.getKnownDeviceIdForNode(e.remoteNodeId)??null;p&&this.deps.bindConnectionDeviceIdInRust(e,p),d("[Client][TRUST] Skipping challenge enforcement for session-token-approved connection",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:s});}else c.failureReason="missing-transport-trust-challenge",this.deps.applyConnectionTrustProjection(e),d("[Client][TRUST] Deferring missing hello challenge enforcement pending response/ack or session-token approval",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:s});if(await this.deps.sendTransportHandshakeWithRecovery(e,"response",d$1,`trust-${s}-response`),this.disposed)return}else if(s==="response"||s==="ack"){let d=await this.deps.verifyRemoteTransportTrust(e,a);if(this.disposed)return;if(!d.verified){if(this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)){this.deps.applySessionTokenTrustApproval(e,null,"handshake-proof-bypass-after-session-token");return}c.required&&await this.deps.enforceConnectionTrustFailure(e,d.reason??"remote-transport-proof-invalid");return}if(this.deps.markConnectionTrustVerified(e,d.deviceId),s==="response"&&o(`handshake:${s}:trust-verified`),s==="response"&&typeof a?.challenge=="string"&&(await this.deps.sendTransportHandshakeWithRecovery(e,"ack",a.challenge,"trust-response-ack"),this.disposed))return}else s==="capability-update"&&(this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)||this.deps.getConnectionTrustState(e.id)?.verified)&&o("capability-update:trust-reused");}catch(s){console.warn("[Client][TRUST] Handshake processing failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:s});}}};var Dt=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async handleUnhandledIncomingStreamEvent(e){if(await this.closeIfDisposed(e,"incoming-acceptor-disposed"))return;let{type:t,stream:n,remoteNodeId:i,traceId:o}=e,s=e.protocolHint;if(t==="bi"&&s==="native-main"&&(s=this.deps.normalizeAuthoritativeIncomingProtocolHint("native-main",i,o)??"native-main",e={...e,protocolHint:s}),!e.invalid){if(t==="uni"){if(!this.deps.shouldSkipIncomingStreamProbe()&&await this.deps.tryHandleNativeMainUniStream(n,i,o))return;await this.deps.cancelUnhandledIncomingUniStream(n,i);return}if(t==="bi"&&s==="native-main"){d("[Client][INCOMING] Handling native desktop main stream",{remoteNodeId:i,traceId:o||null}),this.handleNativeMainStreamInBackground(n,i,o,"[Client][NATIVE-MAIN] Background handler crashed");return}if(this.deps.shouldTreatIncomingStreamAsTransportOnly(e)){this.deps.logIncomingDiagnostic("bi:drop-unhandled-ticket-flow",{remoteNodeId:i||"unknown",traceId:o||null,protocolHint:s,channelId:e.channel?.channelId??null});return}t==="bi"&&s!=="explicit"&&await this.acceptIncomingBiStream(e);}}async acceptIncomingBiStream(e){if(await this.closeIfDisposed(e,"incoming-acceptor-disposed-before-accept"))return;let{stream:t,remoteNodeId:n,traceId:i}=e,o=e.protocolHint,s=this.deps.getDeterministicConnectionId(n),a=this.deps.getKnownDevice(null,n),c=typeof a?.platformType=="string"?String(a.platformType).toLowerCase():typeof a?.platform_type=="string"?String(a.platform_type).toLowerCase():null;if(!this.deps.usesTicketOnlySignalingMode()&&(c==="desktop"||c==="mobile")){d("[Client][INCOMING] Routing unhinted native peer stream through native-main handler",{connectionId:s,remoteNodeId:n,traceId:i||null,protocolHint:o,knownRemotePlatform:c}),this.handleNativeMainStreamInBackground(t,n,i,"[Client][NATIVE-MAIN] Unhinted native peer stream handler crashed");return}let d$1=this.deps.getConnection(s);if(d$1&&!d$1.isClosed){let y=d$1.getUpgradeState(),C=await this.deps.isCoreConnectionHealthy(n).catch(()=>false);if(await this.closeIfDisposed(e,"incoming-acceptor-disposed-after-core-health"))return;let I=typeof d$1.getControlFrameMode=="function"&&d$1.getControlFrameMode()==="native-main";if(C){if(!I){d("[Client][INCOMING] Closing auxiliary bi stream while typed connection is upgrading/upgraded",{connectionId:s,remoteNodeId:n,traceId:i||null,existingUpgradeState:y,protocolHint:o}),await he(t,"typed-connection-auxiliary-stream",n);return}d("[Client][INCOMING] Routing auxiliary bi stream to native-main handler while connection is upgrading/upgraded",{connectionId:s,remoteNodeId:n,traceId:i||null,existingUpgradeState:y,protocolHint:o}),this.handleNativeMainStreamInBackground(t,n,i,"[Client][NATIVE-MAIN] Auxiliary stream handler crashed");return}if((y==="upgrading"||y==="upgraded")&&d("[Client][INCOMING] Replacing upgraded connection due to stale core transport",{connectionId:s,remoteNodeId:n,traceId:i||null,existingUpgradeState:y,coreTransportConnected:C}),d("[Client][INCOMING] Replacing existing connection main stream",{connectionId:s,remoteNodeId:n,traceId:i||null}),await this.disconnectConnection(d$1),await this.closeIfDisposed(e,"incoming-acceptor-disposed-after-existing-disconnect"))return;this.deps.cleanupReplacedConnection(s);}let p=t;if(!v(p)){console.error("[Client][INCOMING] Unable to construct connection from invalid bi stream",{remoteNodeId:n});return}let u,g;try{u=p.send.getWriter(),g=p.recv.getReader();}catch(y){console.error("[Client][INCOMING] Failed to acquire incoming stream reader/writer",{remoteNodeId:n,error:y});return}let f=new ge(s,this.deps.getLocalNodeId(),n,u,g,{rtcConfig:this.deps.getRTCConfig(),transportContext:this.deps.createTransportContext(n),applicationCrypto:this.deps.getOptions()?.applicationCrypto,requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:"typed",onTransportStatusChange:y=>{this.deps.handleConnectionTransportStatus(s,y.activeTransport,y.parallelTransport);},onApplicationRouteMissing:y=>{this.deps.handleConnectionApplicationRouteMissing(s,y);}}),v$1=this.deps.getKnownDeviceIdForNode(n);if(this.deps.initializeConnectionTrust(f,v$1),this.disposed){await this.disconnectConnection(f);return}this.deps.registerConnection(f),v$1?this.deps.bindConnectionDeviceIdInRust(f,v$1):this.lookupAcceptedDeviceBindingInBackground(f,n),this.deps.announceConnectionWhenStable(f),d("[Client][HANDSHAKE] sending hello (incoming connection path)",{connectionId:f.id,remoteNodeId:f.remoteNodeId}),this.sendIncomingHelloInBackground(f);}handleNativeMainStreamInBackground(e,t,n,i){let o=s=>{this.disposed||console.error(i,{remoteNodeId:t,traceId:n||null,error:s});};try{Promise.resolve(this.deps.handleNativeMainStream(e,t)).catch(o);}catch(s){o(s);}}lookupAcceptedDeviceBindingInBackground(e,t){let n=i=>{this.disposed||console.warn("[Client][BIND] Accept-side searchDevices fallback failed",{connectionId:e.id,remoteNodeId:t,error:i});};try{Promise.resolve(this.deps.searchDevices()).then(()=>{if(this.disposed)return;let i=this.deps.getKnownDeviceIdForNode(t);i?this.deps.bindConnectionDeviceIdInRust(e,i):console.warn("[Client][BIND] Accept-side directory lookup found no deviceId for remote node",{connectionId:e.id,remoteNodeId:t});}).catch(n);}catch(i){n(i);}}sendIncomingHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send incoming handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).then(()=>{this.disposed||this.deps.requestProtectedWebRTCUpgradeIfInitiator(e,"protected-hello:incoming");}).catch(t);}catch(n){t(n);}}async disconnectConnection(e){try{await Promise.resolve(e.disconnect());}catch{}}async closeIfDisposed(e,t){return this.disposed?(e.type==="bi"?await he(e.stream,t,e.remoteNodeId):e.type==="uni"&&await this.deps.cancelUnhandledIncomingUniStream(e.stream,e.remoteNodeId),true):false}};function qo(r){return r==="desktop"||r==="mobile"||r==="native"}function Vo(r,e,t=false){return true}function $o(r){return !r}function Mt(r,e,t){return r}var ai={ready:false,phase:"frame-start",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};function zo(r,e){let t=new TextEncoder().encode(JSON.stringify(r)),n=new TextEncoder().encode(e.label),i=new Uint8Array(5+n.byteLength+4+t.byteLength),o=new DataView(i.buffer),s=0;return i[s]=e.protocolByte,s+=1,o.setUint32(s,n.byteLength,false),s+=4,i.set(n,s),s+=n.byteLength,o.setUint32(s,t.byteLength,false),s+=4,i.set(t,s),i}async function Qo(r,e,t,n=8e3){if(typeof window>"u"||typeof window.dispatchEvent!="function")return null;let i=[],o=a=>{i.push(Promise.resolve(a));};if(window.dispatchEvent(new CustomEvent(r,{detail:{remoteNodeId:e,message:t,respondWith:o}})),i.length===0)return null;let s;try{let a=await Promise.race([Promise.allSettled(i),new Promise(c=>{s=setTimeout(()=>c([]),n);})]);for(let c of a)if(c.status==="fulfilled"&&c.value!==void 0&&c.value!==null)return c.value}finally{s&&clearTimeout(s);}return null}function Yo(r,e){if(r.byteLength===0)return ai;if(r[0]===e.protocolByte){if(r.byteLength<5)return ai;let i=new DataView(r.buffer,r.byteOffset,r.byteLength),o=i.getUint32(1,false);if(o>0&&o<=e.maxLabelBytes&&r.byteLength>=5+o&&new TextDecoder().decode(r.slice(5,5+o))===e.label){let a=5+o+4;if(r.byteLength<a)return {ready:false,phase:"frame-body",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};let c=i.getUint32(5+o,false);if(c>e.maxFrameBytes)throw new Error(`native-main frame too large: ${c}`);return r.byteLength<a+c?{ready:false,phase:"frame-body",expectedFrameLength:c,consumedBytes:0,payloadBytes:new Uint8Array}:{ready:true,phase:"frame-body",expectedFrameLength:c,consumedBytes:a+c,payloadBytes:r.slice(a,a+c)}}}if(r.byteLength<4)return ai;let n=new DataView(r.buffer,r.byteOffset,r.byteLength).getUint32(0,false);if(n>e.maxFrameBytes)throw new Error(`legacy native-main frame too large: ${n}`);return r.byteLength<4+n?{ready:false,phase:"frame-body",expectedFrameLength:n,consumedBytes:0,payloadBytes:new Uint8Array}:{ready:true,phase:"frame-body",expectedFrameLength:n,consumedBytes:4+n,payloadBytes:r.slice(4,4+n)}}function Xo(r){let{host:e,transports:t,trustServices:n}=r;return new At(e.getContext(),{ensureWasmRuntimeForP2P:()=>e.ensureWasmRuntimeForP2P(),getOptions:()=>e.getOptions(),getWasmClient:()=>e.getWasmClient(),getLocalNodeId:()=>e.getLocalNodeId(),getDeterministicConnectionId:i=>t.peerIdentity.getDeterministicConnectionId(i),getRegisteredChannel:i=>e.getRegisteredChannel(i),isTransportOnlyChannel:i=>n.channelPolicy.isTransportOnlyChannel(i),rememberPendingTokenForNode:(i,o,s)=>e.rememberPendingTokenForNode(i,o,s),resolveExpectedDeviceIdForSessionTokenScope:(i,o,s,a)=>n.trust.resolveExpectedDeviceIdForSessionTokenScope(i,o,s,a),initializeConnectionTrust:(i,o)=>n.trust.initialize(i,o),refreshApplicationRouteHandshake:(i,o)=>t.upgrade.refreshApplicationRouteHandshake(i,o),ensureWasmManagedTransport:(i,o,s)=>e.ensureWasmManagedTransport(i,o,s),isLocalIrohRuntimeNotInitializedError:i=>e.isLocalIrohRuntimeNotInitializedError(i),recoverLocalIrohRuntime:i=>e.recoverLocalIrohRuntime(i),getSessionTokenApprovedScope:i=>e.getSessionTokenApprovedScope(i),setSessionTokenApprovedScope:(i,o)=>e.setSessionTokenApprovedScope(i,o),getPeerState:i=>e.getPeerState(i),assignConnectionChannel:(i,o)=>n.channelPolicy.assign(i,o),bindConnectionDeviceIdInRust:(i,o)=>n.deviceBinder.bindConnectionDeviceIdInRust(i,o),approveSessionTokenNode:i=>e.approveSessionTokenNode(i),approveSessionTokenConnection:i=>e.approveSessionTokenConnection(i),applySessionTokenTrustApproval:(i,o,s)=>e.applySessionTokenTrustApproval(i,o,s),announceConnectionWhenStable:i=>r.getLifecycle().announceConnectionWhenStable(i),disconnectNodeTransport:i=>t.health.disconnectNodeTransport(i),shouldUseNativeMainFramingForPeer:(i,o,s)=>Vo(i,o,s),writeNativeMainLabelHeaderOnBiStream:(i,o)=>e.writeNativeMainLabelHeaderOnBiStream(i,o),getRTCConfig:()=>t.getRTCConfig(),createTransportContext:i=>t.contexts.create(i),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(i,o,s)=>t.health.handleConnectionTransportStatus(i,o,s),handleConnectionApplicationRouteMissing:(i,o)=>t.upgrade.handleApplicationRouteMissing(i,o),sendNativeSignalEnvelope:(i,o,s,a)=>e.sendNativeSignalEnvelope(i,o,s,a),registerConnection:i=>r.getLifecycle().registerConnection(i),schedulePeerReconciliation:i=>e.schedulePeerReconciliation(i),consumePendingSessionTokenTrustApproval:i=>e.consumePendingSessionTokenTrustApproval(i),sendTransportHandshake:(i,o)=>t.handshake.sendTransportHandshake(i,o),requestProtectedWebRTCUpgradeIfInitiator:(i,o)=>t.handshake.requestProtectedWebRTCUpgradeIfInitiator(i,o),clearManualDisconnectProjection:i=>e.clearManualDisconnectProjection(i),getPeerScopes:i=>e.getPeerScopes(i),sessionTokenScopeAllowsDeviceBinding:i=>n.trust.sessionTokenScopeAllowsDeviceBinding(i),resolvePromotionEligibility:i=>n.channelPolicy.resolvePromotionEligibility(i),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),dispatchLiveConnectionProjection:(i,o)=>e.dispatchLiveConnectionProjection(i,o),hasApplicationRouteForConnection:i=>t.upgrade.hasApplicationRouteForConnection(i),isWebRtcApplicationRouteReadyForConnection:i=>t.upgrade.isWebRtcApplicationRouteReadyForConnection(i),addPeerScope:(i,o)=>e.addPeerScope(i,o)})}function Jo(r){let{host:e,transports:t,trustServices:n}=r;return new Nt({registerDisposer:i=>e.registerDisposer(i),resolveApplicationCryptoForPeer:(i,o)=>e.resolveApplicationCryptoForPeer(i,o),handleApplicationKeyAgreement:(i,o)=>e.handleApplicationKeyAgreement(i,o),isWebRTCTransportEnabled:()=>k$1(e.getOptions()),requiresManagedTransportTrust:()=>e.requiresManagedTransportTrust(e.getDiscoveryMode()),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),getLocalNodeId:()=>e.getLocalNodeId(),validateIncomingSessionTokenWithRetry:(i,o,s)=>e.validateIncomingSessionTokenWithRetry(i,o,s),applySessionTokenTrustApproval:(i,o,s)=>e.applySessionTokenTrustApproval(i,o,s),getConnectionChannelId:i=>n.channelPolicy.getConnectionChannelId(i),clearPendingTokenForNode:i=>e.clearPendingTokenForNode(i),sendTransportHandshake:(i,o)=>t.handshake.sendTransportHandshake(i,o),getMoQState:()=>e.getMoQState(),enableMoQForConnection:i=>e.enableMoQForConnection(i),forgetMoQPeerSubscription:i=>e.forgetMoQPeerSubscription(i),assignConnectionChannel:(i,o)=>n.channelPolicy.assign(i,o),initializeConnectionTrust:i=>n.trust.initialize(i),getKnownDevice:(i,o)=>e.getKnownDevice(i,o),isSessionTokenApproved:(i,o)=>e.isSessionTokenApproved(i,o),applyConnectionTrustProjection:i=>e.applyConnectionTrustProjection(i),getKnownDeviceIdForNode:i=>e.getKnownDeviceIdForNode(i),bindConnectionDeviceIdInRust:(i,o)=>n.deviceBinder.bindConnectionDeviceIdInRust(i,o),sendTransportHandshakeWithRecovery:(i,o,s,a)=>t.handshake.sendTransportHandshakeWithRecovery(i,o,s,a),verifyRemoteTransportTrust:(i,o)=>n.trust.verifyRemoteTransportTrust(i,o),enforceConnectionTrustFailure:(i,o)=>n.trust.enforceFailure(i,o),markConnectionTrustVerified:(i,o)=>n.trust.markVerified(i,o),getConnectionTrustState:i=>n.trust.getStateByConnectionId(i),dispatchMessage:(i,o)=>e.dispatchIncomingMessage(i,o)})}function Zo(r){let{host:e,registry:t,transports:n,trustServices:i}=r;return new Dt({registerDisposer:o=>e.registerDisposer(o),normalizeAuthoritativeIncomingProtocolHint:(o,s,a)=>Mt(o),shouldSkipIncomingStreamProbe:()=>e.shouldSkipIncomingStreamProbe(),tryHandleNativeMainUniStream:(o,s,a)=>e.tryHandleNativeMainUniStream(o,s,a),cancelUnhandledIncomingUniStream:(o,s)=>e.cancelUnhandledIncomingUniStream(o,s,(a,c)=>e.logIncomingDiagnostic(a,c)),handleNativeMainStream:(o,s)=>e.handleNativeMainStream(o,s),shouldTreatIncomingStreamAsTransportOnly:o=>e.shouldTreatIncomingStreamAsTransportOnly(o),logIncomingDiagnostic:(o,s)=>e.logIncomingDiagnostic(o,s),getDeterministicConnectionId:o=>n.peerIdentity.getDeterministicConnectionId(o),getKnownDevice:(o,s)=>e.getKnownDevice(o,s),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),getConnection:o=>t.get(o),isCoreConnectionHealthy:o=>n.health.isCoreConnectionHealthy(o),cleanupReplacedConnection:o=>r.getLifecycle().cleanupReplacedConnection(o),getLocalNodeId:()=>e.getLocalNodeId(),getRTCConfig:()=>n.getRTCConfig(),createTransportContext:o=>n.contexts.create(o),getOptions:()=>e.getOptions(),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(o,s,a)=>n.health.handleConnectionTransportStatus(o,s,a),handleConnectionApplicationRouteMissing:(o,s)=>n.upgrade.handleApplicationRouteMissing(o,s),getKnownDeviceIdForNode:o=>e.getKnownDeviceIdForNode(o),initializeConnectionTrust:(o,s)=>i.trust.initialize(o,s),registerConnection:o=>r.getLifecycle().registerConnection(o),bindConnectionDeviceIdInRust:(o,s)=>i.deviceBinder.bindConnectionDeviceIdInRust(o,s),searchDevices:()=>e.searchDevices(),announceConnectionWhenStable:o=>r.getLifecycle().announceConnectionWhenStable(o),sendTransportHandshake:(o,s)=>n.handshake.sendTransportHandshake(o,s),requestProtectedWebRTCUpgradeIfInitiator:(o,s)=>n.handshake.requestProtectedWebRTCUpgradeIfInitiator(o,s)})}function er(r){let{host:e,registry:t,transports:n,trustServices:i}=r;return new kt({registerDisposer:o=>e.registerDisposer(o),registry:t,resolveApplicationCryptoForPeer:(o,s)=>e.resolveApplicationCryptoForPeer(o,s),flushPendingNativeMainHandshakesForNode:(o,s)=>e.flushPendingNativeMainHandshakesForNode(o,s),flushPendingNativeMainSignalsForNode:(o,s)=>e.flushPendingNativeMainSignalsForNode(o,s),getConnectionTrustState:o=>i.trust.getStateByConnectionId(o),getKnownDeviceIdByNodeId:o=>e.getKnownDeviceIdForNode(o),bindConnectionDeviceIdInRust:(o,s)=>i.deviceBinder.bindConnectionDeviceIdInRust(o,s),searchDevices:()=>e.searchDevices(),retireSupersededConnections:(o,s,a)=>i.deviceBinder.retireSupersededConnections(o,s,a),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:o=>e.applyConnectionTrustProjection(o),schedulePeerReconciliation:o=>e.schedulePeerReconciliation(o),maybeHandleWebRTCExplicitFileEnvelope:(o,s)=>e.maybeHandleWebRTCExplicitFileEnvelope(o,s),handleMessage:(o,s)=>r.getMessageHandler().handleMessage(o,s),getExistingPeerProjectionForDisconnect:o=>e.getPeerState(o.id)||e.getPeerProjectionList().find(s=>s.connectionIds.includes(o.id)||s.nodeId===o.deviceId),cleanupConnectionState:o=>{i.trust.clearForConnection(o),i.channelPolicy.forget(o),e.clearSessionTokenConnectionApproval(o),e.forgetMoQPeerSubscription(o);},dispatchLiveConnectionProjection:(o,s)=>e.dispatchLiveConnectionProjection(o,s),resolvePromotionEligibility:o=>i.channelPolicy.resolvePromotionEligibility(o),enforceConnectionTrustFailure:(o,s)=>i.trust.enforceFailure(o,s),initializeConnectionTrust:o=>i.trust.initialize(o),getWasmClient:()=>e.getWasmClient(),isCoreConnectionHealthy:o=>n.health.isCoreConnectionHealthy(o),hasApplicationRouteForConnection:o=>n.upgrade.hasApplicationRouteForConnection(o),allowsTransportOnlyStability:o=>i.channelPolicy.allowsTransportOnlyStability(o),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),stableWindowMs:Ao,stableTimeoutMs:ko,stablePollMs:No})}function tr(r){return new ci({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,getLocalNodeId:()=>r.localNodeId,getDiscoveryMode:()=>r.discoveryMode,registerDisposer:e=>r.lifecycleScope.register(e),getTransportServices:()=>r.transportServices,getTrustServices:()=>r.trustServices,ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),ensureWasmManagedTransport:(e,t,n)=>r.managedTransportDialer.ensureWasmManagedTransport(e,t,n),isLocalIrohRuntimeNotInitializedError:e=>r.managedTransportDialer.isLocalIrohRuntimeNotInitializedError(e),recoverLocalIrohRuntime:e=>r.runtimeBootstrap.recoverLocalIrohRuntime(e),requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),getRegisteredChannel:e=>r.incomingStreamRouter.getRegisteredChannel(e),maybeHandleWebRTCExplicitFileEnvelope:(e,t)=>r.incomingStreamRouter.maybeHandleWebRTCExplicitFileEnvelope(e,t),dispatchIncomingMessage:(e,t)=>r.incomingStreamRouter.dispatchMessage(e,t),shouldSkipIncomingStreamProbe:()=>r.incomingDiagnostics.shouldSkipIncomingStreamProbe(),cancelUnhandledIncomingUniStream:(e,t,n)=>r.incomingDiagnostics.cancelUnhandledIncomingUniStream(e,t,n),logIncomingDiagnostic:(e,t)=>r.incomingDiagnostics.logIncomingDiagnostic(e,t),shouldTreatIncomingStreamAsTransportOnly:e=>r.applicationIncomingStreams.shouldTreatIncomingStreamAsTransportOnly(e),tryHandleNativeMainUniStream:(e,t,n)=>r.nativeMain.tryHandleNativeMainUniStream(e,t??"",n),handleNativeMainStream:(e,t)=>r.nativeMain.handleNativeMainStream(e,t??""),flushPendingNativeMainHandshakesForNode:(e,t)=>r.nativeMain.flushPendingHandshakesForNode(e,t),flushPendingNativeMainSignalsForNode:(e,t)=>r.nativeMain.flushPendingSignalsForNode(e,t),writeNativeMainLabelHeaderOnBiStream:(e,t)=>r.nativeMain.writeLabelHeaderOnBiStream(e,t),sendNativeSignalEnvelope:(e,t,n,i)=>r.nativeMain.sendSignalEnvelope(e,t,n,i),resolveApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.resolveForPeer(e,t),handleApplicationKeyAgreement:(e,t)=>r.applicationCrypto.handleKeyAgreement(e,t),shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),rememberPendingTokenForNode:(e,t,n)=>r.sessionTokens.rememberPendingTokenForNode(e,t,n),getSessionTokenApprovedScope:e=>r.sessionTokens.getApprovedScope(e),setSessionTokenApprovedScope:(e,t)=>r.sessionTokens.setApprovedScope(e,t),approveSessionTokenNode:e=>r.sessionTokens.approveNode(e),approveSessionTokenConnection:e=>r.sessionTokens.approveConnection(e),applySessionTokenTrustApproval:(e,t,n)=>r.sessionTokens.applyTrustApproval(e,t,n),consumePendingSessionTokenTrustApproval:e=>r.sessionTokens.consumePendingTrustApproval(e),validateIncomingSessionTokenWithRetry:(e,t,n)=>r.sessionTokens.validateIncomingSessionTokenWithRetry(e,t,n),clearPendingTokenForNode:e=>r.sessionTokens.clearPendingTokenForNode(e),isSessionTokenApproved:(e,t)=>r.sessionTokens.isApproved(e,t),clearSessionTokenConnectionApproval:e=>r.sessionTokens.clearConnectionApproval(e),getPeerState:e=>r.peerServices.getPeerState(e),getPeerScopes:e=>r.peerServices.getPeerScopes(e),addPeerScope:(e,t)=>r.peerServices.addPeerScope(e,t),clearManualDisconnectProjection:e=>r.peerServices.clearManualDisconnectProjection(e),getPeerProjectionList:()=>r.peerServices.listPeerStates(),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),dispatchLiveConnectionProjection:(e,t)=>r.peerProjection.dispatchLiveConnectionProjection(e,t),getKnownDevice:(e,t)=>r.deviceDirectory.getKnownDevice(e,t),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),searchDevices:()=>r.deviceDirectory.searchDevices(),getMoQState:()=>r.moqServices.state,enableMoQForConnection:e=>r.moqServices.enableForConnection(e),forgetMoQPeerSubscription:e=>r.moqServices.forgetPeerSubscription(e)})}var ci=class{constructor(e){this.host=e;this.registry=new Rt;}get transports(){return this.host.getTransportServices()}get trustServices(){return this.host.getTrustServices()}get factoryHost(){return {host:this.host,registry:this.registry,transports:this.transports,trustServices:this.trustServices,getLifecycle:()=>this.lifecycle,getMessageHandler:()=>this.messageHandler}}get dialer(){return this._dialer??(this._dialer=Xo(this.factoryHost))}get messageHandler(){return this._messageHandler??(this._messageHandler=Jo(this.factoryHost))}get incomingAcceptor(){return this._incomingAcceptor??(this._incomingAcceptor=Zo(this.factoryHost))}get lifecycle(){return this._lifecycle??(this._lifecycle=er(this.factoryHost))}};var Et=class{constructor(){this.wasmClient=null;this.node=null;this.localNodeId="";this.deviceId=null;}};var xt=class{constructor(e=(t,n)=>{console.warn(t,n);}){this.logError=e;this.disposers=[];this.destroyed=false;}get isDestroyed(){return this.destroyed}register(e){if(this.destroyed){try{e();}catch(t){this.logError("[Client] late disposer failed",t);}return}this.disposers.push(e);}destroy(){if(!this.destroyed){this.destroyed=true;for(let e of this.disposers.splice(0).reverse())try{e();}catch(t){this.logError("[Client] disposer failed during destroy",t);}}}};var pa=(1n<<62n)-1n;BigInt(Number.MAX_SAFE_INTEGER);function ua(r){if(typeof r=="number"){if(!Number.isSafeInteger(r)||r<0)throw new Error(`Invalid varint value: ${r}`);return BigInt(r)}if(r<0n||r>pa)throw new Error(`Invalid varint value: ${r.toString()}`);return r}var ne=class{constructor(){this.offset=0;this.checkpoints=[];this.buffer=new Uint8Array(0);}append(e){let t=new Uint8Array(this.buffer.length+e.length);t.set(this.buffer),t.set(e,this.buffer.length),this.buffer=t;}peekVarInt(){if(this.buffer.length-this.offset<1)return null;let e=this.buffer[this.offset],t=e>>6,n=e&63;return t===0?{val:n,len:1}:t===1?this.buffer.length-this.offset<2?null:{val:new DataView(this.buffer.buffer,this.buffer.byteOffset,this.buffer.byteLength).getUint16(this.offset)&16383,len:2}:t===2?this.buffer.length-this.offset<4?null:{val:new DataView(this.buffer.buffer,this.buffer.byteOffset,this.buffer.byteLength).getUint32(this.offset)&1073741823,len:4}:this.buffer.length-this.offset<8?null:{val:new DataView(this.buffer.buffer,this.buffer.byteOffset,this.buffer.byteLength).getBigUint64(this.offset)&BigInt("0x3fffffffffffffff"),len:8}}advance(e){this.offset+=e,this.offset>1024&&this.offset>this.buffer.length/2&&(this.buffer=this.buffer.slice(this.offset),this.offset=0);}has(e){return this.buffer.length-this.offset>=e}readBytes(e){if(!this.has(e))throw new Error("EOF");let t=this.buffer.slice(this.offset,this.offset+e);return this.advance(e),t}readVarInt(){let e=this.peekVarInt();if(!e)throw new Error("EOF");return this.advance(e.len),e.val}readUint8(){if(!this.has(1))throw new Error("EOF");let e=this.buffer[this.offset];return this.advance(1),e}checkpoint(){this.checkpoints.push(this.offset);}commit(){this.checkpoints.pop();}rewind(){let e=this.checkpoints.pop();if(e!==void 0)this.offset=e;else throw new Error("No checkpoint to rewind to")}readString(){let e=this.peekVarInt();if(!e)throw new Error("EOF");let t=Number(e.val),n=e.len+t;if(!this.has(n))throw new Error("EOF");this.advance(e.len);let i=this.readBytes(t);return new TextDecoder().decode(i)}},ie=class{constructor(){this.chunks=[];this.length=0;}writeUint8(e){let t=new Uint8Array(1);t[0]=e,this.chunks.push(t),this.length+=1;}writeVarInt(e){let t=ua(e);if(t<64n)this.writeUint8(Number(t));else if(t<16384n){let n=new Uint8Array(2);new DataView(n.buffer).setUint16(0,Number(t)|16384),this.chunks.push(n),this.length+=2;}else if(t<1073741824n){let n=new Uint8Array(4);new DataView(n.buffer).setUint32(0,Number(t)|2147483648),this.chunks.push(n),this.length+=4;}else {let n=new Uint8Array(8);new DataView(n.buffer).setBigUint64(0,t|0xc000000000000000n),this.chunks.push(n),this.length+=8;}}writeString(e){let t=new TextEncoder().encode(e);this.writeVarInt(t.length),this.chunks.push(t),this.length+=t.length;}writeBytes(e){this.chunks.push(e),this.length+=e.byteLength;}toUint8Array(){let e=new Uint8Array(this.length),t=0;for(let n of this.chunks)e.set(n,t),t+=n.length;return e}},Lt=class{constructor(){this.mutex=Promise.resolve();}lock(){let e=()=>{},t=new Promise(i=>{e=i;}),n=this.mutex.then(()=>e);return this.mutex=this.mutex.then(()=>t),n}async dispatch(e){let t=await this.lock();try{return await Promise.resolve(e())}finally{t();}}};var Bt=0,ga=1,nr=64*1024;function di(r,e){let t=new TextEncoder().encode(e);r.writeVarInt(1),r.writeVarInt(t.length),r.writeBytes(t);}function li(r){let e=Number(r.readVarInt()),t=[];for(let n=0;n<e;n++){let i=Number(r.readVarInt()),o=r.readBytes(i);t.push(new TextDecoder().decode(o));}return t.join("/")}var $e=class{static serialize(e){let t=new ie;switch(e.type){case 64:{let o=e;t.writeVarInt(o.supportedVersions.length);for(let c of o.supportedVersions)t.writeVarInt(c);let s=new ie,a=0;o.role!==void 0&&(a++,s.writeVarInt(Bt),s.writeVarInt(1),s.writeVarInt(o.role)),t.writeVarInt(a),t.writeBytes(s.toUint8Array());break}case 65:{let o=e;t.writeVarInt(o.selectedVersion);let s=new ie,a=0;o.role!==void 0&&(a++,s.writeVarInt(Bt),s.writeVarInt(1),s.writeVarInt(o.role)),t.writeVarInt(a),t.writeBytes(s.toUint8Array());break}case 3:{let o=e;t.writeVarInt(o.subscribeId),t.writeVarInt(o.trackAlias),di(t,o.trackNamespace);let s=new TextEncoder().encode(o.trackName);t.writeVarInt(s.length),t.writeBytes(s),t.writeUint8(o.subscriberPriority??128),t.writeUint8(o.groupOrder??1),o.startGroup!==void 0&&o.startObject!==void 0&&o.endGroup!==void 0&&o.endObject!==void 0?(t.writeVarInt(4),t.writeVarInt(o.startGroup),t.writeVarInt(o.startObject),t.writeVarInt(o.endGroup),t.writeVarInt(o.endObject)):o.startGroup!==void 0&&o.startObject!==void 0?(t.writeVarInt(3),t.writeVarInt(o.startGroup),t.writeVarInt(o.startObject)):t.writeVarInt(1),t.writeVarInt(0);break}case 4:{let o=e;t.writeVarInt(o.subscribeId),t.writeVarInt(o.expires),t.writeUint8(1),t.writeUint8(0),t.writeVarInt(0);break}case 6:{di(t,e.trackNamespace),t.writeVarInt(0);break}case 7:{di(t,e.trackNamespace);break}}let n=t.toUint8Array();if(n.byteLength>nr)throw new Error(`MoQ control message length exceeds limit: ${n.byteLength}`);let i=new ie;return i.writeVarInt(e.type),i.writeVarInt(n.length),i.writeBytes(n),i.toUint8Array()}static deserialize(e$1){if(!e$1.peekVarInt())return null;let n=false;try{e$1.checkpoint();let i=Number(e$1.readVarInt()),o=Number(e$1.readVarInt());if(e(`[MoQ] Deserializing msg type=0x${i.toString(16)}, length=${o}`),!Number.isSafeInteger(o)||o<0||o>nr)throw new Error(`MoQ control message length exceeds limit: ${o}`);if(!e$1.has(o))return e$1.rewind(),null;let s=e$1.readBytes(o);n=!0;let a=new ne;a.append(s);let c;switch(i){case 65:{let d=Number(a.readVarInt()),p=Number(a.readVarInt()),u=0;for(let g=0;g<p;g++){let f=Number(a.readVarInt()),v=Number(a.readVarInt()),y=a.readBytes(v);if(f===Bt){let C=new ne;C.append(y),u=Number(C.readVarInt());}}c={type:i,selectedVersion:d,role:u};break}case 3:{let d=Number(a.readVarInt()),p=Number(a.readVarInt()),u=li(a),g=Number(a.readVarInt()),f=a.readBytes(g),v=new TextDecoder().decode(f);a.readUint8(),a.readUint8();let y=Number(a.readVarInt()),C,I,k,T;y===3?(C=Number(a.readVarInt()),I=Number(a.readVarInt())):y===4&&(C=Number(a.readVarInt()),I=Number(a.readVarInt()),k=Number(a.readVarInt()),T=Number(a.readVarInt()));let _=Number(a.readVarInt());for(let A=0;A<_;A++){let E=Number(a.readVarInt()),x=Number(a.readVarInt());a.readBytes(x);}c={type:i,subscribeId:d,trackAlias:p,trackNamespace:u,trackName:v,startGroup:C,startObject:I};break}case 4:{let d=Number(a.readVarInt()),p=Number(a.readVarInt());a.readUint8(),a.readUint8()===1&&(a.readVarInt(),a.readVarInt());let g=Number(a.readVarInt());for(let f=0;f<g;f++){let v=Number(a.readVarInt()),y=Number(a.readVarInt());a.readBytes(y);}c={type:i,subscribeId:d,expires:p};break}case 7:{let d=li(a);c={type:i,trackNamespace:d};break}case 8:{let d=li(a),p=Number(a.readVarInt()),u=Number(a.readVarInt()),g=a.readBytes(u),f=new TextDecoder().decode(g);console.warn(`[MoQ] ANNOUNCE_ERROR: ns=${d} code=${p} reason=${f}`),c={type:i,trackNamespace:d,code:p,reason:f};break}case 21:{let d=Number(a.readVarInt());e(`[MoQ] MAX_SUBSCRIBE_ID: ${d}`),c={type:i,subscribeId:d};break}case 5:{let d=Number(a.readVarInt()),p=Number(a.readVarInt()),u=Number(a.readVarInt()),g=a.readBytes(u),f=new TextDecoder().decode(g),v=Number(a.readVarInt());(p===404?e:console.warn)(`[MoQ] SUBSCRIBE_ERROR: id=${d} code=${p} reason=${f} alias=${v}`),c={type:i,subscribeId:d,code:p,reason:f};break}case 16:{let d=Number(a.readVarInt());a.readBytes(d),console.warn("[MoQ] GOAWAY received"),c={type:i};break}case 64:{let d=Number(a.readVarInt()),p=[];for(let v=0;v<d;v++)p.push(Number(a.readVarInt()));let u=Number(a.readVarInt()),g=0,f;for(let v=0;v<u;v++){let y=Number(a.readVarInt()),C=Number(a.readVarInt()),I=a.readBytes(C);if(y===Bt){let k=new ne;k.append(I),g=Number(k.readVarInt());}else y===ga&&(f=new TextDecoder().decode(I));}c={type:i,supportedVersions:p,role:g,path:f};break}case 10:{let d=Number(a.readVarInt());e(`[MoQ] UNSUBSCRIBE for id=${d}`),c={type:i,subscribeId:d};break}case 11:{let d=Number(a.readVarInt()),p=Number(a.readVarInt()),u=Number(a.readVarInt()),g=a.readBytes(u),f=new TextDecoder().decode(g),v,y;a.readUint8()===1&&(v=Number(a.readVarInt()),y=Number(a.readVarInt())),e(`[MoQ] SUBSCRIBE_DONE for id=${d} code=${p} reason=${f}`),c={type:i,subscribeId:d,code:p,reason:f,finalGroup:v,finalObject:y};break}default:{console.warn(`[MoQ] Unknown MsgType: 0x${i.toString(16)}, skipping ${o} bytes`),c={type:i};break}}return e$1.commit(),c}catch(i){if(i.message==="EOF"&&!n)return e$1.rewind(),null;throw i}}};var Ft=class{constructor(e,t={}){this.tracks=new Map;this.activePublishers=new Map;this.pendingAnnounces=new Map;this.session=e,this.maxPendingAnnounces=t.maxPendingAnnounces??64,this.announceTimeoutMs=t.announceTimeoutMs??5e3,this.maxSubscribedTracks=t.maxSubscribedTracks??256,this.maxActivePublishers=t.maxActivePublishers??256,this.maxTrackIdChars=t.maxTrackIdChars??512;}async announce(e$1){if(!e$1.trim())throw new Error("MoQ announce namespace must be non-empty");if(this.pendingAnnounces.has(e$1))throw new Error(`MoQ announce already pending for namespace: ${e$1}`);if(!this.pendingAnnounces.has(e$1)&&this.pendingAnnounces.size>=this.maxPendingAnnounces)throw new Error(`MoQ pending announce limit exceeded (${this.maxPendingAnnounces})`);e(`[MoQ] Announcing namespace: ${e$1}`);let t={type:6,trackNamespace:e$1,params:{}};return new Promise(async(n,i)=>{let o=setTimeout(()=>{this.pendingAnnounces.has(e$1)&&(this.pendingAnnounces.delete(e$1),i(new Error("Announce timed out")));},this.announceTimeoutMs);this.pendingAnnounces.set(e$1,{resolve:n,reject:i,timeout:o});try{await this.session.sendControlMessage(t);}catch(s){clearTimeout(o),this.pendingAnnounces.delete(e$1),i(s);}})}onAnnounceResult(e,t){let n=this.pendingAnnounces.get(e);n&&(this.pendingAnnounces.delete(e),clearTimeout(n.timeout),t?n.reject(new Error(`Announce failed: code=${t.code} reason=${t.reason}`)):n.resolve());}onSubscribe(e$1){let t=this.resolveTrackId(e$1.trackNamespace,e$1.trackName);if(!t){console.warn("[MoQ] Dropping SUBSCRIBE with invalid track namespace/name");return}if(!this.tracks.has(t)&&this.tracks.size>=this.maxSubscribedTracks){console.warn(`[MoQ] Dropping SUBSCRIBE for ${t}; subscribed track limit reached`);return}e(`[MoQ] Publisher received SUBSCRIBE for ${t} -> subId=${e$1.subscribeId} alias=${e$1.trackAlias}`),this.tracks.set(t,{subscribeId:e$1.subscribeId,trackAlias:e$1.trackAlias});}onUnsubscribe(e$1){for(let[t,n]of this.tracks.entries())if(n.subscribeId===e$1){e(`[MoQ] Publisher received UNSUBSCRIBE for ${t} (subId=${e$1})`),this.tracks.delete(t);break}}hasTrackSubscriber(e,t){let n=this.resolveTrackId(e,t);return !!n&&this.tracks.has(n)}async createTrack(e$1,t){let n=this.resolveTrackId(e$1,t);if(!n)throw new Error("MoQ track namespace and name must be non-empty and within length limits");if(this.activePublishers.has(n))return this.activePublishers.get(n);if(this.activePublishers.size>=this.maxActivePublishers)throw new Error(`MoQ active publisher limit exceeded (${this.maxActivePublishers})`);let i=null,o=0,s=0,a=new Lt,c=()=>{if(i){let g=i;i=null,g.close().catch(()=>{});}},d=()=>{e(`[MoQ] Stopping publisher for ${n}`),c(),this.activePublishers.delete(n);},p=async()=>{c(),o++,s=0;let g=this.tracks.get(n);if(g===void 0)return;let{subscribeId:f,trackAlias:v}=g,C=(await this.session.transport.createUnidirectionalStream()).getWriter();o<=2&&e(`[MoQ] Opening Group ${o} for ${n} (subId=${f} alias=${v})`);let I=new ie;I.writeVarInt(4),I.writeVarInt(f),I.writeVarInt(v),I.writeVarInt(o),I.writeVarInt(0),I.writeUint8(0),await C.write(I.toUint8Array()),i=C;},u={close:d,push:async(g,f)=>{await a.dispatch(async()=>{if(!this.tracks.has(n))return;if(f.isKey)await p();else if(!i)return;if(!i)return;let v=new ie;if(v.writeVarInt(s++),v.writeVarInt(g.length),v.writeBytes(g),i)try{if(await i.write(v.toUint8Array()),f.closeAfterPush){let y=i;i=null,await y.close();}}catch(y){(y.message||"").includes("STOP_SENDING")||y.name==="WebTransportError"?(console.warn(`[MoQ] Group stream closed by remote (STOP_SENDING) for ${n}.`),i=null):console.error(`[MoQ] Writer error for ${n}:`,y);}});}};return this.activePublishers.set(n,u),u}resolveTrackId(e,t){if(typeof e!="string"||typeof t!="string")return null;let n=e.trim(),i=t.trim();if(!n||!i)return null;let o=`${n}/${i}`;return o.length>this.maxTrackIdChars?null:o}};var Ot=class{constructor(e,t,n={}){this.aliasMap=new Map;this.nextAlias=0;this.nextSubscribeId=1;this.pendingSubscriptions=new Map;this.deliveryState=new Map;this.activeSubscriptions=new Map;this.session=e,this.onObject=t,this.maxPendingSubscriptions=n.maxPendingSubscriptions??128,this.maxSubscribeRetries=n.maxSubscribeRetries??1,this.subscribeRetryDelayMs=n.subscribeRetryDelayMs??2e3,this.maxBufferedGroupsPerTrack=n.maxBufferedGroupsPerTrack??32,this.maxBufferedFramesPerGroup=n.maxBufferedFramesPerGroup??256,this.maxBufferedBytesPerTrack=n.maxBufferedBytesPerTrack??16*1024*1024,this.maxObjectPayloadBytes=n.maxObjectPayloadBytes??4*1024*1024;}async subscribe(e$1,t){if(!e$1.trim()||!t.trim())throw new Error("MoQ subscribe namespace and name must be non-empty");if(this.pendingSubscriptions.size>=this.maxPendingSubscriptions)throw new Error(`MoQ pending subscription limit exceeded (${this.maxPendingSubscriptions})`);let n=this.nextAlias++,i=this.nextSubscribeId++;this.aliasMap.set(n,{namespace:e$1,name:t}),e(`[MoQ] Subscribing to ${e$1}/${t} with Alias ${n} ID ${i}`);let o={type:3,subscribeId:i,trackAlias:n,trackNamespace:e$1,trackName:t};this.pendingSubscriptions.set(i,{namespace:e$1,name:t,trackAlias:n,retries:0}),this.activeSubscriptions.set(i,n);try{await this.session.sendControlMessage(o);}catch(s){throw this.pendingSubscriptions.delete(i),this.activeSubscriptions.delete(i),this.aliasMap.delete(n),s}}onSubscribeOk(e){this.pendingSubscriptions.delete(e);}async onSubscribeError(e$1,t){let n=this.pendingSubscriptions.get(e$1);if(this.pendingSubscriptions.delete(e$1),this.activeSubscriptions.delete(e$1),!!n){if(t===404&&n.retries<this.maxSubscribeRetries){if(e(`[MoQ] Will retry subscription to ${n.namespace}/${n.name} in ${this.subscribeRetryDelayMs}ms...`),await new Promise(a=>setTimeout(a,this.subscribeRetryDelayMs)),this.pendingSubscriptions.size>=this.maxPendingSubscriptions){this.aliasMap.delete(n.trackAlias),this.deliveryState.delete(n.trackAlias),console.warn(`[MoQ] Dropping retry for ${n.namespace}/${n.name}; pending subscription queue is full`);return}let i=this.nextSubscribeId++,o={...n,retries:n.retries+1},s={type:3,subscribeId:i,trackAlias:n.trackAlias,trackNamespace:n.namespace,trackName:n.name};e(`[MoQ] Retrying subscription to ${n.namespace}/${n.name} with ID ${i}`),this.pendingSubscriptions.set(i,o),this.activeSubscriptions.set(i,n.trackAlias);try{await this.session.sendControlMessage(s);}catch(a){throw this.pendingSubscriptions.delete(i),this.activeSubscriptions.delete(i),this.aliasMap.delete(n.trackAlias),this.deliveryState.delete(n.trackAlias),a}return}this.aliasMap.delete(n.trackAlias),this.deliveryState.delete(n.trackAlias);}}onSubscribeDone(e,t,n){let i=this.activeSubscriptions.get(e);i!==void 0?(console.warn(`[MoQ] Subscription ${e} (alias ${i}) ended: ${t} ${n}`),this.activeSubscriptions.delete(e),this.aliasMap.delete(i),this.deliveryState.delete(i)):console.warn(`[MoQ] Subscription ${e} ended (unknown alias): ${t} ${n}`);}wakeDelivery(e){let t=this.deliveryState.get(e);if(t?.notifyResolve){let n=t.notifyResolve;t.notifyResolve=null,n();}}async runDeliveryLoop(e){let t=this.deliveryState.get(e);if(!t)return;let n=this.aliasMap.get(e),i=n?n.namespace:"unknown",o=n?n.name:"unknown";for(;;){let s=t.groups.get(t.nextDeliverGroupId);if(s){for(;s.frames.length>0;){let a=s.frames.shift();s.bufferedBytes-=a.payload.byteLength,t.bufferedBytes-=a.payload.byteLength,this.onObject(i,o,a.payload,{groupId:a.groupId,objectId:a.objectId});}if(s.done){t.bufferedBytes-=s.bufferedBytes,t.groups.delete(t.nextDeliverGroupId),t.nextDeliverGroupId++;continue}}else {let a=null;for(let c of t.groups.keys())c>t.nextDeliverGroupId&&(a===null||c<a)&&(a=c);if(a!==null&&a>t.nextDeliverGroupId+1){console.warn(`[MoQ] Skipping missing group ${t.nextDeliverGroupId}, jumping to ${a}`),t.nextDeliverGroupId=a;continue}}await new Promise(a=>{t.notifyResolve=a;});}}async handleIncomingUniStream(e){let t=e.getReader(),n=new ne,i=-1,o=-1,s=null;try{for(;;){let{done:c,value:d}=await t.read();if(c)return;d&&n.append(d);try{n.checkpoint();let p=Number(n.readVarInt()),u=Number(n.readVarInt());if(i=Number(n.readVarInt()),o=Number(n.readVarInt()),n.readVarInt(),n.readUint8(),n.commit(),p!==4)throw new Error(`Unexpected MoQ unidirectional stream type: ${p}`);break}catch(p){if(p.message==="EOF"){n.rewind();continue}throw p}}let a=this.deliveryState.get(i);if(a||(a={groups:new Map,nextDeliverGroupId:o,notifyResolve:null,loopRunning:!1,bufferedBytes:0},this.deliveryState.set(i,a)),o<a.nextDeliverGroupId){t.cancel().catch(()=>{});return}if(!a.groups.has(o)&&a.groups.size>=this.maxBufferedGroupsPerTrack){t.cancel().catch(()=>{}),console.warn(`[MoQ] Dropping group ${o} for alias ${i}; buffered group limit reached`);return}for(s={frames:[],done:!1,bufferedBytes:0},a.groups.set(o,s),a.loopRunning||(a.loopRunning=!0,this.runDeliveryLoop(i));;){if(!n.has(1)){let{done:c,value:d}=await t.read();if(c)break;d&&n.append(d);}try{n.checkpoint();let c=Number(n.readVarInt()),d=Number(n.readVarInt());if(!Number.isFinite(d)||d<0||d>this.maxObjectPayloadBytes)throw new Error(`MoQ object payload length exceeds limit: ${d}`);if(s.frames.length>=this.maxBufferedFramesPerGroup)throw new Error(`MoQ group buffered frame limit exceeded: ${this.maxBufferedFramesPerGroup}`);if(a.bufferedBytes+d>this.maxBufferedBytesPerTrack)throw new Error(`MoQ track buffered byte limit exceeded: ${this.maxBufferedBytesPerTrack}`);let p=n.readBytes(d);n.commit(),s.frames.push({payload:p,groupId:o,objectId:c}),s.bufferedBytes+=p.byteLength,a.bufferedBytes+=p.byteLength,this.wakeDelivery(i);}catch(c){if(c.message==="EOF"){n.rewind();let{done:d,value:p}=await t.read();if(d)break;p&&n.append(p);continue}throw c}}}catch(a){console.error("Subscriber Stream Error",a);}finally{s&&(s.done=true,this.wakeDelivery(i));}}};var Wt=class{constructor(e$1,t,n=3){this.controlStreamWriter=null;this.controlStreamReader=null;this.uniStreamReader=null;this.closeListeners=[];this.closed=false;this.closeEmitted=false;this.resourcesClosed=false;this.setupComplete=false;this.setupResolve=null;this.maxSubscribeId=0;this.streamBuffer=new ne;this.transport=e$1,this.role=n,this.setupPromise=new Promise(i=>{this.setupResolve=i;}),this.publisher=new Ft(this),this.subscriber=new Ot(this,t||((i,o,s,a)=>e(`[MoQ] Object: ${i}/${o}`,a)));}async waitForSetup(){return this.setupPromise}async init(){await this.transport.ready;let e=await this.transport.createBidirectionalStream();this.controlStreamWriter=e.writable.getWriter(),this.controlStreamReader=e.readable.getReader();let t={type:64,supportedVersions:[4278190087],role:this.role};await this.sendControlMessage(t),this.readLoop(),this.readUniStreams();}onClose(e){return this.closeListeners.push(e),()=>{this.closeListeners=this.closeListeners.filter(t=>t!==e);}}close(){this.closed||(this.closed=true,this.cleanupResources(),this.emitClose("local-close"));}cleanupResources(){if(!this.resourcesClosed){this.resourcesClosed=true;try{this.controlStreamWriter?.close().catch(()=>{});}catch{}try{this.controlStreamReader?.cancel().catch(()=>{});}catch{}try{this.uniStreamReader?.cancel().catch(()=>{});}catch{}try{this.transport.close();}catch{}}}emitClose(e){this.closed||(this.closed=true),this.cleanupResources(),!this.closeEmitted&&(this.closeEmitted=true,this.closeListeners.forEach(t=>{try{t(e);}catch{}}));}async readUniStreams(){let e=this.transport.incomingUnidirectionalStreams.getReader();this.uniStreamReader=e;try{for(;;){let{done:t,value:n}=await e.read();if(t)break;n&&this.subscriber&&this.subscriber.handleIncomingUniStream(n);}}catch(t){this.closed||console.error("UniStream Loop Error",t);}finally{this.uniStreamReader===e&&(this.uniStreamReader=null);}}async sendControlMessage(e){if(this.closed)throw new Error("MoQ session closed");let t=$e.serialize(e);if(!this.controlStreamWriter)throw new Error("Control stream not open");await this.controlStreamWriter.write(t);}async readLoop(){if(!this.controlStreamReader)return;let e$1="control-stream-closed";try{for(;;){let{done:t,value:n}=await this.controlStreamReader.read();if(t){console.warn("[MoQ] Control Stream Closed by Remote");break}n&&(e(`[MoQ] Control Stream RX: ${n.byteLength} bytes`),this.streamBuffer.append(n),this.processBuffer());}}catch(t){e$1=t,this.closed||console.error("Control stream error",t);}finally{this.emitClose(e$1);}e("[MoQ] Read Loop Exited");}processBuffer(){for(;;){let e;try{e=$e.deserialize(this.streamBuffer);}catch(t){throw console.error("[MoQ] Deserialization Error:",t),t}if(!e)break;this.handleControlMessage(e);}}handleControlMessage(e$1){switch(e$1.type){case 65:e(`[MoQ] Handshake Complete. Server selected version: 0x${e$1.selectedVersion.toString(16)}`),this.setupComplete=true,this.setupResolve&&(this.setupResolve(),this.setupResolve=null);break;case 21:this.maxSubscribeId=e$1.subscribeId,e(`[MoQ] Max Subscribe ID updated: ${this.maxSubscribeId}`);break;case 3:this.publisher.onSubscribe(e$1);let t={type:4,subscribeId:e$1.subscribeId,expires:0};this.sendControlMessage(t).catch(console.error);break;case 4:e(`[MoQ] SUBSCRIBE_OK for id=${e$1.subscribeId}`),this.subscriber.onSubscribeOk(e$1.subscribeId);break;case 5:e$1.code===404?e(`[MoQ] SUBSCRIBE_ERROR for id=${e$1.subscribeId} code=${e$1.code}`):console.error(`[MoQ] SUBSCRIBE_ERROR for id=${e$1.subscribeId} code=${e$1.code}`),this.subscriber.onSubscribeError(e$1.subscribeId,e$1.code).catch(console.error);break;case 7:e(`[MoQ] ANNOUNCE_OK for ns=${e$1.trackNamespace}`),this.publisher.onAnnounceResult(e$1.trackNamespace);break;case 8:console.error(`[MoQ] ANNOUNCE_ERROR for ns=${e$1.trackNamespace} code=${e$1.code}`),this.publisher.onAnnounceResult(e$1.trackNamespace,{code:e$1.code,reason:e$1.reasonPhrase||"Unknown"});break;case 10:this.publisher.onUnsubscribe(e$1.subscribeId);break;case 11:this.subscriber.onSubscribeDone(e$1.subscribeId,e$1.code,e$1.reason);break;case 16:console.warn("[MoQ] GOAWAY received");break;default:e(`[MoQ] Received Control Message type=0x${e$1.type.toString(16)}`);}}};var ha=5e3,ma=125,fa=8,Ut=class{constructor(e,t){this.ctx=e;this.deps=t;this.session=null;this.state="none";this.readyListeners=[];this.failedListeners=[];this.objectListeners=[];this.reconnectTimer=null;this.reconnectAttempts=0;this.peerSubscriptions=new Set;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}get bundle(){return this.state!=="ready"||!this.session?null:{session:this.session,publisher:this.session.publisher,subscriber:this.session.subscriber}}onReady(e){return this.disposed?()=>{}:(this.readyListeners.push(e),()=>{this.readyListeners=this.readyListeners.filter(t=>t!==e);})}onFailed(e){return this.disposed?()=>{}:(this.failedListeners.push(e),()=>{this.failedListeners=this.failedListeners.filter(t=>t!==e);})}onObject(e){return this.disposed?()=>{}:(this.objectListeners.push(e),()=>{this.objectListeners=this.objectListeners.filter(t=>t!==e);})}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);}closeSession(e){let t=this.session;if(this.session=null,this.peerSubscriptions.clear(),!!t)try{t.close();}catch(n){d("[Client] MoQ session close failed",{reason:e,error:n});}}dispose(){this.disposed=true,this.clearReconnectTimer(),this.closeSession("client-dispose"),this.state="none",this.readyListeners=[],this.failedListeners=[],this.objectListeners=[];}handleSessionClosed(e,t){this.disposed||this.session===e&&(this.session=null,this.state="failed",this.peerSubscriptions.clear(),this.ctx.registry.forEach(n=>{n.peerMoQReady=false;}),this.emitFailed(),d("[Client] MoQ session closed; scheduling reconnect",{reason:t}),this.scheduleReconnect(t));}scheduleReconnect(e$1){if(this.disposed||!this.deps.getMoQConfig()||this.reconnectTimer)return;let t=Math.min(this.deps.initialReconnectDelayMs*Math.max(1,2**this.reconnectAttempts),this.deps.maxReconnectDelayMs);this.reconnectAttempts+=1;let n=(this.reconnectAttempts*17%21-10)/100,i=Math.max(this.deps.initialReconnectDelayMs,Math.trunc(t+t*n));this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,!(this.disposed||!this.deps.getMoQConfig()||this.state==="ready"||this.state==="connecting")&&(e(`[Client] Reconnecting MoQ relay after ${i}ms`,e$1),this.init());},i);}enableForConnection(e){this.state!=="ready"||!this.bundle||(e.peerMoQReady=true,this.subscribePeer(e));}subscribePeer(e){this.subscribePeerNode(e.remoteNodeId,e.id,()=>e.isClosed);}forgetPeerSubscription(e){this.peerSubscriptions.delete(e);}subscribePeerNode(e,t=e,n){if(this.disposed)return;let i=this.bundle,o=e?.trim(),s=t?.trim()||o;!i||!this.ctx.localNodeId||!o||!s||n?.()||this.peerSubscriptions.has(s)||(this.peerSubscriptions.add(s),this.subscribePeerNodeInBackground(i,o,s));}resubscribePeers(){this.peerSubscriptions.clear(),this.ctx.registry.forEach(e=>{!e.isClosed&&e.peerMoQReady&&this.subscribePeer(e);});}async init(){if(this.disposed||!this.deps.getMoQConfig()||this.state==="ready"||this.state==="connecting")return;this.clearReconnectTimer(),this.closeSession("init"),this.state="connecting";let e$1=this.deps.getMoQConfig(),n=(e$1&&typeof e$1=="object"?{...this.deps.getDefaultMoQConfig(),...e$1}:{...this.deps.getDefaultMoQConfig()}).relayUrl,i=null;try{let o=new WebTransport(n);if(await o.ready,this.disposed){try{o.close?.();}catch{}return}if(i=new Wt(o,(s,a,c,d)=>{this.handleObject(s,a,c,d);}),this.session=i,i.onClose(s=>this.handleSessionClosed(i,s)),await i.init(),this.disposed){i.close();return}if(await i.waitForSetup(),this.disposed||this.session!==i){i.close();return}if(await i.publisher.announce(this.ctx.localNodeId),this.disposed||this.session!==i){i.close();return}if(await this.createDataTracks(),this.disposed||this.session!==i){i.close();return}this.state="ready",this.reconnectAttempts=0,this.peerSubscriptions.clear(),e(`[Client] MoQ Session Ready: Pub/Sub via ${n}`),this.emitReady(),this.resubscribePeers(),this.broadcastReadyCapabilityInBackground();}catch(o){if(this.disposed){i&&this.session===i&&(this.session=null),i?.close();return}console.warn("[Client] MoQ init failed:",o),this.session===i&&(this.session=null),this.state="failed",this.emitFailed(),this.scheduleReconnect(o);}}async createDataTracks(){if(!this.disposed&&!(!this.session||!this.ctx.localNodeId))try{await this.session.publisher.createTrack(this.ctx.localNodeId,"data/broadcast"),e("[Client] MoQ Data Track created: data / broadcast");}catch(e){console.warn("Failed to create MoQ broadcast track",e);}}isDataReady(e){let t=this.bundle;if(!t||!this.ctx.localNodeId)return false;let n=e?`data / ${e} `:"data / broadcast";return t.publisher.hasTrackSubscriber(this.ctx.localNodeId,n)}async sendData(e,t,n={}){if(this.disposed)throw new Error("MoQ not ready");if(this.state!=="ready"||!this.bundle)throw new Error("MoQ not ready");let i=e?`data / ${e} `:"data / broadcast";if(!await this.waitForStableDataReady(e))throw this.disposed||this.state!=="ready"||!this.bundle?new Error("MoQ not ready"):new Error(`MoQ data track is not subscribed: ${i}`);let o=await this.bundle.publisher.createTrack(this.ctx.localNodeId,i);if(!o)return;if(this.disposed)throw new Error("MoQ not ready");let s=Date.now(),a=n.alreadyProtected?t:this.deps.protectDirectPayload(t,e??void 0),c=e?this.deps.getConnectionById(this.deps.getDeterministicConnectionId(e)):void 0;if(await o.push(a,{isKey:true,timestamp:s,closeAfterPush:true}),!this.disposed&&c&&!c.isClosed){let d=typeof c.getTransportStatus=="function"?c.getTransportStatus():null;this.deps.handleConnectionTransportStatus(c.id,"moq",d?.activeTransport??null);}}async waitForStableDataReady(e){let t=Date.now(),n=0;for(;!this.disposed&&this.state==="ready"&&this.bundle;){if(this.isDataReady(e)){if(n+=1,n>=fa)return true}else n=0;if(Date.now()-t>=ha)return false;await r(ma);}return false}extractTrackPeerId(e){let t=e.replace(/\s+/g,"");if(!t.startsWith("data/"))return;let n=t.slice(5);if(!(!n||n==="broadcast"))return n}handleObject(e,t,n,i){if(this.disposed)return;this.deps.getConnectionById(this.deps.getDeterministicConnectionId(e));let s=this.deps.openDirectPayload(n,e);if(!s.payload||(this.emitObject(e,t,s.payload,i),s.encrypted))return;if(t.replace(/\s+/g,"").startsWith("data/")&&this.ctx.localNodeId){let c=this.deps.getDeterministicConnectionId(e),d=this.deps.getConnectionById(c);d&&d.injectData(n);}}emitReady(){for(let e of [...this.readyListeners])try{e();}catch(t){console.warn("[Client] MoQ ready listener failed",t);}}subscribePeerNodeInBackground(e,t,n){let i=()=>{this.peerSubscriptions.delete(n);};try{Promise.allSettled([e.subscriber.subscribe(t,"data/broadcast"),e.subscriber.subscribe(t,`data / ${this.ctx.localNodeId} `)]).then(o=>{this.disposed||o.some(s=>s.status==="rejected")&&i();});}catch{i();}}broadcastReadyCapabilityInBackground(){try{Promise.resolve(this.deps.broadcastTransportCapabilityUpdate("moq-ready")).catch(e=>{this.disposed||d("[Client] Late MoQ capability update failed",e);});}catch(e){if(this.disposed)return;d("[Client] Late MoQ capability update failed",e);}}emitFailed(){for(let e of [...this.failedListeners])try{e();}catch(t){console.warn("[Client] MoQ failed listener failed",t);}}emitObject(e,t,n,i){for(let o of [...this.objectListeners])try{o(e,t,n,i);}catch(s){console.warn("[Client] MoQ object listener failed",s);}}};function ir(r){return new pi({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getDeterministicConnectionId:e=>r.peerIdentity.getDeterministicConnectionId(e),getConnectionById:e=>r.registry.get(e),protectDirectPayload:(e,t,n)=>r.applicationCrypto.protectDirectMoQPayload(e,t,n),openDirectPayload:(e,t,n)=>r.applicationCrypto.openDirectMoQPayload(e,t,n),handleConnectionTransportStatus:(e,t,n)=>r.transportHealth.handleConnectionTransportStatus(e,t,n),broadcastTransportCapabilityUpdate:e=>r.transportHandshake.broadcastTransportCapabilityUpdate(e)})}var pi=class{constructor(e){this.host=e;}get controller(){return this._controller||(this._controller=new Ut(this.host.getContext(),{getMoQConfig:()=>this.host.getOptions()?.transports?.moq,getDefaultMoQConfig:()=>({...j}),getDeterministicConnectionId:e=>this.host.getDeterministicConnectionId(e),getConnectionById:e=>this.host.getConnectionById(e),protectDirectPayload:(e,t,n)=>this.host.protectDirectPayload(e,t,n),openDirectPayload:(e,t,n)=>this.host.openDirectPayload(e,t,n),handleConnectionTransportStatus:(e,t,n)=>this.host.handleConnectionTransportStatus(e,t,n),broadcastTransportCapabilityUpdate:e=>this.host.broadcastTransportCapabilityUpdate(e),initialReconnectDelayMs:Do,maxReconnectDelayMs:Mo})),this._controller}get state(){return this._controller?.state??"none"}get bundle(){return this._controller?.bundle??null}init(){return this.controller.init()}onReady(e){return this.controller.onReady(e)}onFailed(e){return this.controller.onFailed(e)}onObject(e){return this.controller.onObject(e)}isReady(){return this._controller?.state==="ready"}isDataReady(e){return this._controller?.isDataReady(e)??false}enableForConnection(e){this.controller.enableForConnection(e);}subscribePeerNode(e,t){this.controller.subscribePeerNode(e,t);}forgetPeerSubscription(e){this._controller?.forgetPeerSubscription(e);}sendData(e,t,n){return this.controller.sendData(e,t,n)}};function ae(){if(typeof navigator>"u")return false;let r=navigator.userAgent||"",e=navigator.userAgentData?.platform||navigator.platform||"";return /iPhone|iPad|iPod|Android|Mobile|CriOS|FxiOS/i.test(`${r} ${e}`)}function Ht(){return typeof window>"u"?false:new URLSearchParams(window.location.search).has("ticket")}function or(r){return r?r.routing==="stream-envelope"&&r.readiness==="transport-only":false}function ze(r){let e=r.signalingMode??"hosted",t=ae(),n=Ht(),i=e==="ticket-only",o=t&&n;return {flow:i?"ticket-only":"default",signalingMode:e,mobileBrowser:t,ticketQueryPresent:n,diagnosticsMode:o,skipIncomingBiProbe:o,skipIncomingChannelEnvelopeInspection:o,readerCloseStrategy:o?"release-lock":"cancel"}}var Kt=class Kt{constructor(e){this.deps=e;this.disposed=false;}dispose(){this.disposed=true;}async acceptNativeMessage(e,t,n){if(this.disposed||!t)return false;let i=this.deps.getDeterministicConnectionId(t),o=this.deps.getConnection(i);if(o){try{Promise.resolve(this.deps.handleMessage(o,n)).catch(s=>{this.disposed||console.warn("[Client][NATIVE-MAIN] Existing connection message handling failed",{remoteNodeId:t,connectionId:o.id,error:s});});}catch(s){this.disposed||console.warn("[Client][NATIVE-MAIN] Existing connection message handling failed",{remoteNodeId:t,connectionId:o.id,error:s});}return false}if(n&&typeof n=="object"&&n.type==="handshake"&&(n.action==="hello"||!n.action)){let s=await this.deps.validateIncomingSessionToken(n.sessionToken??"",e??void 0,{remoteNodeId:t,source:"accept-native-message",tokenPayload:typeof n.sessionTokenPayload=="string"?n.sessionTokenPayload:void 0});if(this.disposed)return false;if(!s.ok)return console.warn("[Client][SESSION-TOKEN] Rejecting native connection \u2014 invalid session token",{remoteNodeId:t,reason:s.reason,hasToken:!!n.sessionToken}),true}return false}async resolveLocalHandshakePayload(){let e=await this.deps.getLocalDeviceId().catch(()=>null)||this.deps.getFallbackLocalDeviceId();if(!e)throw new Error("Local device id unavailable for native handshake response");let t=this.deps.isNativeRuntime(),n=t?this.deps.isLikelyMobileBrowser()?"mobile":"desktop":"web",i=t?{canHost:true,canSync:true,readOnly:false}:{canHost:false,canSync:true,readOnly:false},o=n==="mobile"?"Mobile Device":n==="desktop"?"Desktop Device":"Browser Device";return {deviceId:e,deviceName:this.deps.getConfiguredDeviceName()||o,platformType:n,capabilities:i,protocolVersion:this.deps.getNativeMainProtocolVersion(),timestamp:Date.now()}}async handleHandshakeRequest(e,t,n){if(this.disposed)return;let i=await this.resolveLocalHandshakePayload();this.disposed||(await this.deps.writeNativeMainMessage(e,{channel:"handshake",action:"response",requestId:n.requestId,payload:{accepted:true,...i},timestamp:Date.now()}),!this.disposed&&(this.schedulePeerReconciliationBestEffort("native-main-handshake"),d("[Client][NATIVE-MAIN] Responded to desktop handshake",{remoteNodeId:t,requestId:n.requestId??null,localDeviceId:i.deviceId})));}async handleSessionTokenRequest(e,t,n){if(this.disposed)return;let i=this.deps.getSessionTokenRejectionCooldown(t),o=this.deps.getNativeMainConnectionId(t);if(i!==void 0&&Date.now()-i<Kt.TOKEN_REJECTION_COOLDOWN_MS){await this.deps.writeNativeMainMessage(e,{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:"session-token-rejection-cooldown",connectionId:o},timestamp:Date.now()}),console.warn("[Client][AUTH] session-token presentation during rejection cooldown \u2014 wrote rejection for dialer",{remoteNodeId:t,connectionId:o});return}let s=n.payload&&typeof n.payload.token=="string"?n.payload.token.trim():"",a=n.payload&&typeof n.payload.tokenPayload=="string"?n.payload.tokenPayload.trim():void 0,c=await this.deps.validateIncomingSessionToken(s,o,{remoteNodeId:t,source:"native-main-session-token",tokenPayload:a||void 0});if(!this.disposed&&(await this.deps.writeNativeMainMessage(e,c.ok?{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:true,scope:c.scope??null,connectionId:o},timestamp:Date.now()}:{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:c.reason??"session-token-rejected",connectionId:o},timestamp:Date.now()}),!this.disposed)){if(c.ok){let d$1=this.deps.getConnection(o);d$1&&!d$1.isClosed?(this.deps.applySessionTokenTrustApproval(d$1,c.scope??null,"native-main-session-token"),d$1.requestTransportRecovery("managed-token-approved",{forceRenegotiate:true,replaceExisting:true})):(this.deps.rememberPendingSessionTokenTrustApproval(o,c.scope??null),this.deps.markSessionTokenApprovedNode(t),this.deps.markSessionTokenApprovedConnection(o)),this.deps.clearSessionTokenRejectionCooldown(t),this.deps.clearTrustFailureCooldown(t),d("[Client][AUTH] host approved managed session token",{remoteNodeId:t,connectionId:o,scope:c.scope??null}),this.schedulePeerReconciliationBestEffort("session-token-approval"),(!d$1||d$1.isClosed)&&this.kickstartApprovedControlConnection(t,o);return}console.warn("[Client][AUTH] host rejected managed session token",{remoteNodeId:t,connectionId:o,reason:c.reason??"session-token-rejected",hasToken:s.length>0}),this.deps.setSessionTokenRejectionCooldown(t,Date.now()),this.deps.disconnectRemoteNode(t);}}kickstartApprovedControlConnection(e,t){let n=i=>{this.disposed||console.warn("[Client][AUTH] post-approval kickstart error",{remoteNodeId:e,connectionId:t,error:i});};try{Promise.resolve(this.deps.ensureIncomingConnectionForRemoteNode(e)).then(i=>{this.disposed||(i?d("[Client][AUTH] post-approval kickstart opened control connection",{remoteNodeId:e,connectionId:i.id}):console.warn("[Client][AUTH] post-approval kickstart failed to open control connection",{remoteNodeId:e,connectionId:t}));}).catch(n);}catch(i){n(i);}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};Kt.TOKEN_REJECTION_COOLDOWN_MS=5e3;var jt=Kt;var Gt=class{constructor(e){this.deps=e;this.pendingConnections=new Map;this.disposed=false;}dispose(){this.disposed=true,this.pendingConnections.clear();}async ensureIncomingConnectionForRemoteNode(e){if(this.disposed)return null;let t=this.deps.getDeterministicConnectionId(e),n=this.deps.getConnection(t);if(n&&!n.isClosed)return this.attachNativeSignalSenderIfEligible(n,e),n;let i=this.pendingConnections.get(t);if(i)return i;let o=this.deps.getTrustFailureCooldown(e),s=this.deps.getTrustFailureCooldownMs();if(o!==void 0&&Date.now()-o<s&&!this.deps.isSessionTokenApprovedNode(e))return d("[Client][TRUST] Skipping connection rebuild for node in trust-failure cooldown",{remoteNodeId:e,cooldownRemainingMs:s-(Date.now()-o)}),null;let a=this.createIncomingConnection(t,e);this.pendingConnections.set(t,a);try{return await a}finally{this.pendingConnections.delete(t);}}attachNativeSignalSenderIfEligible(e,t){let n=typeof e.getControlFrameMode=="function"?e.getControlFrameMode():"typed";d("[Client][NATIVE-MAIN] Reusing existing control connection",{connectionId:e.id,remoteNodeId:t,upgradeState:typeof e.getUpgradeState=="function"?e.getUpgradeState():null,controlFrameMode:n});let i=this.deps.getKnownDevicePlatform(this.deps.getKnownDeviceIdForNode(t),t);if(!this.deps.isNativeMainPeerPlatform(i))return;let o=this.deps.getWasmClient();if(!o||typeof o.open_bi!="function")return;let s=async a=>{await this.deps.sendNativeSignalEnvelope(e,t,a,o);};n!=="native-main"&&typeof e.promoteToNativeMainControlRoute=="function"?(e.promoteToNativeMainControlRoute(s),d("[Client][NATIVE-MAIN] Promoted bootstrap connection to native control route",{connectionId:e.id,remoteNodeId:t})):n==="native-main"&&e.setNativeSignalSender(s);}async createIncomingConnection(e,t){if(this.disposed)return null;let n=this.deps.getWasmClient();if(!n||typeof n.open_bi!="function")return null;let i=this.deps.getKnownDeviceIdForNode(t);if(!this.deps.getKnownDevicePlatform(i,t))return d("[Client][NATIVE-MAIN] Deferring native-main connection creation until peer platform is known",{remoteNodeId:t,connectionId:e,knownDeviceId:i}),null;let s;try{s=await this.deps.openNativeSignalBiStream(n,t);}catch(c){return console.warn("[Client][NATIVE-MAIN] Failed to open control stream for native signal routing",{remoteNodeId:t,connectionId:e,error:c}),null}if(this.disposed)return await y(s,"native-main-connection-disposed-after-open"),null;try{await this.deps.writeNativeMainLabelHeaderOnBiStream(s,t);}catch(c){return console.warn("[Client][NATIVE-MAIN] Failed to write label header on control stream",{remoteNodeId:t,connectionId:e,error:c}),null}if(this.disposed)return await y(s,"native-main-connection-disposed-after-label"),null;let a=new ge(e,this.deps.getLocalNodeId(),t,s.send.getWriter(),s.recv.getReader(),{rtcConfig:this.deps.getRTCConfig(),transportContext:this.deps.createTransportContext(t),applicationCrypto:this.deps.getApplicationCrypto(),requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:"native-main",onTransportStatusChange:c=>{this.deps.handleConnectionTransportStatus(e,c.activeTransport,c.parallelTransport);},onApplicationRouteMissing:c=>{this.deps.handleConnectionApplicationRouteMissing(e,c);}});return a.setNativeSignalSender(async c=>{await this.deps.sendNativeSignalEnvelope(a,t,c,n);}),this.deps.initializeConnectionTrust(a,i),this.deps.markConnectionTrustVerified(a,i),this.deps.registerConnection(a),this.deps.announceConnectionWhenStable(a),d("[Client][HANDSHAKE] sending hello (native signal routing path)",{connectionId:a.id,remoteNodeId:a.remoteNodeId}),this.sendNativeRoutingHelloInBackground(a),d("[Client][NATIVE-MAIN] Created control connection for native signal routing",{connectionId:a.id,remoteNodeId:t,channelId:this.deps.getConnectionChannelId(a.id)??null,rtcEnabled:this.deps.isWebRTCTransportEnabled()}),a}sendNativeRoutingHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send outgoing handshake for native signal routing",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).then(()=>{this.disposed||this.deps.requestProtectedWebRTCUpgradeIfInitiator(e,"protected-hello:native-signal-routing");}).catch(t);}catch(n){t(n);}}};var qt=class{constructor(e,t,n=[0,250,1e3,2500]){this.maxPerNode=e;this.ttlMs=t;this.retryDelaysMs=n;this.pendingByNodeId=new Map;this.retryTimers=new Set;this.disposed=false;}queue(e,t,n,i,o){if(this.disposed)return;let s=this.pendingByNodeId.get(e)??[];s.push({message:t,source:n,traceId:i??null,receivedAtMs:Date.now()}),s.length>this.maxPerNode&&s.splice(0,s.length-this.maxPerNode),this.pendingByNodeId.set(e,s),d("[Client][NATIVE-MAIN] Queued TS handshake until control connection is registered",{remoteNodeId:e,action:t.action??"hello",source:n,traceId:i||null,pendingCount:s.length});for(let a of this.retryDelaysMs){let c=setTimeout(()=>{this.retryTimers.delete(c),!this.disposed&&o(e,`queued-handshake-retry:${a}`);},a);this.retryTimers.add(c);}}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.retryTimers)clearTimeout(e);this.retryTimers.clear(),this.pendingByNodeId.clear();}}async flush(e,t,n){if(this.disposed)return false;let i=this.pendingByNodeId.get(e);if(!i||i.length===0)return false;let o=n.findManualDisconnectProjectionForNativeNode(e);if(o)return this.pendingByNodeId.delete(e),d("[Client][NATIVE-MAIN] Dropped queued TS handshakes for manually disconnected peer",{remoteNodeId:e,peerId:o.peerId,droppedCount:i.length,trigger:t}),false;let s=n.findLiveConnectionForRemoteNode(e);if(s||(s=await n.ensureIncomingConnectionForRemoteNode(e).catch(()=>null)),this.disposed)return false;if(!s){let a=Date.now(),c=i.filter(d=>a-d.receivedAtMs<=this.ttlMs);return c.length===0?(this.pendingByNodeId.delete(e),console.warn("[Client][NATIVE-MAIN] Dropping queued TS handshakes after control connection did not appear",{remoteNodeId:e,trigger:t,droppedCount:i.length})):c.length!==i.length&&this.pendingByNodeId.set(e,c),false}this.pendingByNodeId.delete(e),d("[Client][NATIVE-MAIN] Replaying queued TS handshakes to Connection",{remoteNodeId:e,connectionId:s.id,trigger:t,count:i.length});for(let a of i){if(this.disposed)return false;await n.handleMessage(s,a.message);}return true}};var ya="main";function Qe(){let r=new TextEncoder().encode(ya),e=new ArrayBuffer(5+r.byteLength),t=new Uint8Array(e);return t[0]=0,new DataView(e).setUint32(1,r.byteLength,false),t.set(r,5),t}function we(r){let e=JSON.stringify(r),t=new TextEncoder().encode(e),n=new Uint8Array(1+t.byteLength);return n[0]=0,n.set(t,1),n}function ce(r){let e=new ArrayBuffer(4+r.byteLength);new DataView(e).setUint32(0,r.byteLength,false);let n=new Uint8Array(e);return n.set(r,4),n}var Vt=class{constructor(e,t){this.config=e;this.deps=t;}protocolConfig(){return {protocolByte:this.config.protocolByte,label:this.config.label,maxLabelBytes:this.config.maxLabelBytes,maxFrameBytes:this.config.maxFrameBytes}}encodeFrame(e){return zo(e,this.protocolConfig())}async dispatchMessage(e,t){return Qo(this.config.eventName,e,t)}async writeAck(e,t,n=null){let i=this.deps.getReceiverDeviceId();await this.writeMessage(e,{channel:"native-main",action:"ack",requestId:t.requestId,payload:{received:true,channel:t.channel,action:t.action,...i?{receiverDeviceId:i}:{},...n!==null?{handlerResponse:n}:{}},timestamp:Date.now(),from:"web"});}async writeMessage(e,t){await e.write(this.encodeFrame(t));}async writeLabeledMessage(e,t){await e.write(Qe()),await e.write(ce(new TextEncoder().encode(JSON.stringify(t))));}async writeLabelHeaderOnBiStream(e,t){let n=e.send.getWriter();try{await n.write(Qe());}catch(i){throw console.warn("[Client][NATIVE-MAIN] Label header write failed",{remoteNodeId:t,error:i}),i}finally{try{n.releaseLock();}catch{}}}};var $t=class{constructor(e){this.deps=e;this.disposed=false;this.activeReaders=new Set;}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.activeReaders)this.cancelReaderBestEffort(e);this.activeReaders.clear();}}async handleNativeMainStream(e,t$1){if(this.disposed||!v(e))return;let n,i,o=false;try{n=e.recv.getReader(),i=e.send.getWriter();}catch(p){console.warn("[Client][NATIVE-MAIN] Unable to acquire stream handles",{remoteNodeId:t$1,error:p});return}this.activeReaders.add(n);let s=new Uint8Array(0),a="stream-active",c=0,d$1=()=>{o||(this.deps.registerInboundNativeMainWriter(t$1,i),o=true);};try{for(;!this.disposed;){let p=this.tryExtractNativeMainPayload(s);for(;!p.ready&&!this.disposed;){let{done:g,value:f}=await n.read();if(this.disposed)return;if(g){a=p.phase==="frame-start"?c>0?"remote-closed-after-frame":"remote-closed-before-frame-length":"remote-closed-mid-frame",(c===0||p.phase!=="frame-start")&&this.schedulePeerReconciliationBestEffort("native-main-stream-close"),p.phase==="frame-start"?d("[Client][NATIVE-MAIN] Remote closed native main stream",{remoteNodeId:t$1,handledFrameCount:c}):console.warn("[Client][NATIVE-MAIN] Native main stream ended mid-frame",{remoteNodeId:t$1,messageLen:p.expectedFrameLength,bufferedBytes:s.byteLength});return}f&&f.byteLength>0&&(s=t([s,new Uint8Array(f)]));try{p=this.tryExtractNativeMainPayload(s);}catch(v){a="invalid-native-main-frame",console.warn("[Client][NATIVE-MAIN] Invalid native main frame",{remoteNodeId:t$1,error:v});return}}if(p.expectedFrameLength===0){s=s.slice(p.consumedBytes);continue}let u=p.payloadBytes;s=s.slice(p.consumedBytes),c+=1,await this.handleNativeMainPayloadBytes(u,t$1,i,void 0,"bi",d$1);}}catch(p){if(this.disposed)return;a="handler-error",this.schedulePeerReconciliationBestEffort("native-main-handler-error"),console.error("[Client][NATIVE-MAIN] Native main stream handler failed",{remoteNodeId:t$1,error:p});}finally{o&&this.deps.clearInboundNativeMainWriter(t$1,i,a),this.activeReaders.delete(n);try{i.releaseLock();}catch{}try{n.releaseLock();}catch{}}}tryExtractNativeMainPayload(e){return Yo(e,this.deps.getProtocolConfig())}async tryHandleNativeMainUniStream(e,t$1,n){if(this.disposed||!e||typeof e.getReader!="function")return false;let i;try{i=e.getReader();}catch{return false}this.activeReaders.add(i);let o=new Uint8Array(0),s=false;try{for(;!this.disposed;){let a=this.tryExtractNativeMainPayload(o);for(;!a.ready&&!this.disposed;){let{done:c,value:d}=await i.read();if(this.disposed||c)return s;d&&d.byteLength>0&&(o=t([o,new Uint8Array(d)])),a=this.tryExtractNativeMainPayload(o);}s=!0,o=o.slice(a.consumedBytes),await this.handleNativeMainPayloadBytes(a.payloadBytes,t$1,null,n,"uni");}return s}catch(a){return this.disposed?s:s?(console.warn("[Client][NATIVE-MAIN] Read-only native main uni handler failed",{remoteNodeId:t$1,traceId:n||null,error:a}),true):false}finally{this.activeReaders.delete(i);try{i.releaseLock();}catch{}}}async handleNativeMainPayloadBytes(e,t,n,i,o,s){if(this.disposed)return;let a=e.byteLength>1&&e[0]===0?e.slice(1):e,c;try{c=JSON.parse(new TextDecoder().decode(a));}catch(g){let f=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;f?f.receiveDataPayload(a):console.warn("[Client][NATIVE-MAIN] Dropping binary app payload: no control connection",{remoteNodeId:t,traceId:i||null,source:o,error:g});return}let d$1=this.deps.findManualDisconnectProjectionForNativeNode(t);if(this.isHandshakeMessage(c)){if(s?.(),d$1){d("[Client][NATIVE-MAIN] Dropping TS handshake for manually disconnected peer",{remoteNodeId:t,peerId:d$1.peerId,action:c.action??"hello",source:o});return}let g=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!g){this.deps.queuePendingNativeMainHandshake(t,c,o,i||null);return}d("[Client][NATIVE-MAIN] Routed TS handshake to Connection",{remoteNodeId:t,connectionId:g.id,action:c.action??"hello",source:o}),await this.deps.handleMessage(g,c);return}if(this.isNativeSignalEnvelope(c)){if(s?.(),d("[Client][NATIVE-MAIN] Received #pluto-signal envelope",{remoteNodeId:t,signalType:c.content?.type??null,transport:c.content?.transport??null,source:o}),d$1){d("[Client][NATIVE-MAIN] Dropping native WebRTC signal for manually disconnected peer",{remoteNodeId:t,peerId:d$1.peerId,signalType:c.content?.type??null,source:o});return}let g=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!g){this.deps.queuePendingNativeMainSignal(t,c.content,o,i||null);return}g.receiveInternalSignal(c.content),d("[Client][NATIVE-MAIN] Routed #pluto-signal to Connection",{remoteNodeId:t,connectionId:g.id,signalType:c.content?.type??null,source:o});return}let p=c;if(d("[Client][NATIVE-MAIN] Received native main message",{remoteNodeId:t,channel:p.channel,action:p.action,requestId:p.requestId??null,source:o}),p.channel==="handshake"&&p.action==="request"){n&&await this.deps.handleNativeHandshakeRequest(n,t,p);return}if(p.channel==="session-token"&&p.action==="request"){n&&await this.deps.handleNativeSessionTokenRequest(n,t,p);return}if(!p.channel&&!p.action&&!p.requestId){s?.();let g=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!g){console.warn("[Client][NATIVE-MAIN] Dropping app payload: no control connection",{remoteNodeId:t,traceId:i||null,source:o});return}g.receiveMessage(c);return}let u=await this.deps.dispatchNativeMainMessage(t,p);this.disposed||n&&await this.writeReceiveAckBestEffort(n,p,u,t,o);}isNativeSignalEnvelope(e){if(!e||typeof e!="object")return false;let t=e;return t.type==="#pluto-signal"&&typeof t.content=="object"&&t.content!==null}isHandshakeMessage(e){return !e||typeof e!="object"?false:e.type==="handshake"}cancelReaderBestEffort(e){try{Promise.resolve(e.cancel("native-main-payload-router-disposed")).catch(()=>{});}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}async writeReceiveAckBestEffort(e,t,n,i,o){if(!this.disposed)try{await this.deps.writeNativeMainReceiveAck(e,t,n);}catch(s){if(this.disposed)return;console.warn("[Client][NATIVE-MAIN] Failed to ack native main message",{remoteNodeId:i,channel:t.channel,action:t.action,source:o,error:s});}}};var zt=class{constructor(e,t,n=[0,250,1e3,2500]){this.maxPerNode=e;this.ttlMs=t;this.retryDelaysMs=n;this.pendingByNodeId=new Map;this.retryTimers=new Set;this.disposed=false;}queue(e,t,n,i,o){if(this.disposed)return;let s=this.pendingByNodeId.get(e)??[];s.push({content:t,source:n,traceId:i??null,receivedAtMs:Date.now()}),s.length>this.maxPerNode&&s.splice(0,s.length-this.maxPerNode),this.pendingByNodeId.set(e,s),d("[Client][NATIVE-MAIN] Queued native WebRTC signal until control connection is registered",{remoteNodeId:e,signalType:t?.type??null,source:n,traceId:i||null,pendingCount:s.length});for(let a of this.retryDelaysMs){let c=setTimeout(()=>{this.retryTimers.delete(c),!this.disposed&&o(e,`queued-signal-retry:${a}`);},a);this.retryTimers.add(c);}}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.retryTimers)clearTimeout(e);this.retryTimers.clear(),this.pendingByNodeId.clear();}}async flush(e,t,n){if(this.disposed)return false;let i=this.pendingByNodeId.get(e);if(!i||i.length===0)return false;let o=n.findManualDisconnectProjectionForNativeNode(e);if(o)return this.pendingByNodeId.delete(e),d("[Client][NATIVE-MAIN] Dropped queued native WebRTC signals for manually disconnected peer",{remoteNodeId:e,peerId:o.peerId,droppedCount:i.length,trigger:t}),false;let s=n.findLiveConnectionForRemoteNode(e);if(s||(s=await n.ensureIncomingConnectionForRemoteNode(e).catch(()=>null)),this.disposed)return false;if(!s){let a=Date.now(),c=i.filter(d=>a-d.receivedAtMs<=this.ttlMs);return c.length===0?(this.pendingByNodeId.delete(e),console.warn("[Client][NATIVE-MAIN] Dropping queued native WebRTC signals after control connection did not appear",{remoteNodeId:e,trigger:t,droppedCount:i.length})):c.length!==i.length&&this.pendingByNodeId.set(e,c),false}this.pendingByNodeId.delete(e),d("[Client][NATIVE-MAIN] Replaying queued native WebRTC signals to Connection",{remoteNodeId:e,connectionId:s.id,trigger:t,count:i.length});for(let a of i){if(this.disposed)return false;s.receiveInternalSignal(a.content);}return true}};var Qt=class{constructor(e){this.deps=e;this.disposed=false;}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Native main signal sender is disposed")}async openNativeSignalBiStream(e,t){this.assertActive();let n=e.open_native_main_control_bi;if(typeof n=="function"){let i=await n.call(e,t);return this.assertActive(),i}throw new Error("[Client][NATIVE-MAIN] open_native_main_control_bi is unavailable on this WASM build; native-main signaling cannot open a control stream under mandatory application crypto. Rebuild the openrtc WASM (pnpm --filter openrtc build:wasm).")}async sendViaDedicatedStream(e,t,n,i){this.assertActive();let o=await this.openNativeSignalBiStream(e,t);this.assertActive();let s=o.send.getWriter();try{if(await s.write(Qe()),this.disposed)return;await s.write(ce(we(i)));}catch(a){throw console.warn("[Client][NATIVE-MAIN] Dedicated-stream signal send failed",{remoteNodeId:t,signalType:i?.content?.type??null,error:a}),a}finally{try{s.releaseLock();}catch{}}}async sendEnvelope(e,t,n,i){if(this.disposed)return;let o=n?.content?.transport??null,s=n?.content?.type??null,a=o==="webrtc"&&(s==="sdp"||s==="candidate"||s==="renegotiate"),c=n?.type==="handshake",d$1=a&&e.getUpgradeState()==="upgrading"||c,p=this.deps.isSessionTokenApprovedNode(t)&&this.deps.isSessionTokenApprovedConnection(e.id),u=p||d$1,g=this.deps.isSessionTokenApprovedNode(t),f=this.deps.isSessionTokenApprovedConnection(e.id),y=a&&s==="renegotiate"&&u?{sent:false,reason:"dedicated-renegotiate-preferred",writerId:null,writerAgeMs:null,error:null}:await this.deps.sendViaInboundControlStream(t,n,{ignoreCooldown:d$1});if(!this.disposed){if(y.sent){if(d("[Client][NATIVE-MAIN] Sent native signal over inbound control stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:y.writerId,writerAgeMs:y.writerAgeMs}),d("[Client][NATIVE-MAIN] Signal route=inbound-control",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,writerId:y.writerId,writerAgeMs:y.writerAgeMs}),d("[SIGNAL-STREAM][TS] reply-on-persistent-writer",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:y.writerId,writerAgeMs:y.writerAgeMs}),d$1&&u&&s!=="renegotiate")try{if(await this.sendViaDedicatedStream(i,t,e,n),this.disposed)return;d("[Client][NATIVE-MAIN] Signal route=dedicated-open_bi-mirror",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null});}catch(I){console.warn("[Client][NATIVE-MAIN] Recovery dedicated-stream mirror send failed",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,error:I});}return}if(d("[Client][NATIVE-MAIN] Signal route=inbound-control-unavailable",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,reason:y.reason,writerId:y.writerId,writerAgeMs:y.writerAgeMs,inboundError:y.error,hasApprovedNode:g,hasApprovedConnectionId:f,hasApprovedDedicatedStream:p,preferDedicatedSignalPath:d$1,canUseDedicatedStream:u}),u)try{if(await this.sendViaDedicatedStream(i,t,e,n),this.disposed)return;d("[Client][NATIVE-MAIN] Sent native signal over dedicated stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),d("[Client][NATIVE-MAIN] Signal route=dedicated-open_bi",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:y.reason});return}catch(C){console.warn("[Client][NATIVE-MAIN] Dedicated-stream signal send failed; falling back to control stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,error:C});}try{if(this.disposed||(await e.sendRawIrohFrame(ce(we(n))),this.disposed))return;d("[Client][NATIVE-MAIN] Sent native signal over control stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),d("[Client][NATIVE-MAIN] Signal route=cached-control-writer",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:y.reason});return}catch(C){if(console.warn("[Client][NATIVE-MAIN] Control-stream signal send failed",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,error:C}),!u)throw C}this.disposed||(await this.sendViaDedicatedStream(i,t,e,n),!this.disposed&&(d("[Client][NATIVE-MAIN] Sent native signal over dedicated stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),d("[Client][NATIVE-MAIN] Signal route=dedicated-open_bi-fallback",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:y.reason})));}}};var Yt=class{constructor(){this.writers=new Map;this.writeMutexes=new Map;this.writerMeta=new Map;this.bypassUntilMs=new Map;this.writerSeq=0;this.disposed=false;}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.writers.values())try{e.releaseLock();}catch{}this.writers.clear(),this.writeMutexes.clear(),this.writerMeta.clear(),this.bypassUntilMs.clear();}}registerInboundWriter(e,t){if(this.disposed){try{t.releaseLock();}catch{}return}let n=this.writers instanceof Map?this.writers:null,i=this.writerMeta instanceof Map?this.writerMeta:null;if(!n||!e||!t)return;let o=n.get(e);this.writerSeq+=1;let s=this.writerSeq;n.set(e,t),i?.set(e,{id:s,registeredAtMs:Date.now()}),this.bypassUntilMs instanceof Map&&this.bypassUntilMs.delete(e),d("[Client][NATIVE-MAIN] Inbound control writer registered",{remoteNodeId:e,writerId:s,replacedExistingWriter:!!o&&o!==t}),d("[SIGNAL-STREAM][TS] writer-registered",{remoteNodeId:e,writerId:s,replacedExistingWriter:!!o&&o!==t});}clearInboundWriter(e,t,n,i="stream-finalize"){if(this.disposed)return;let o=this.writers instanceof Map?this.writers:null,s=this.writeMutexes instanceof Map?this.writeMutexes:null,a=this.writerMeta instanceof Map?this.writerMeta:null;if(!o||!s)return;let c=o.get(e),d$1=a?.get(e);c===t?(o.delete(e),a?.delete(e),this.bypassUntilMs.set(e,Date.now()+n),d("[Client][NATIVE-MAIN] Inbound control writer cleared",{remoteNodeId:e,writerId:d$1?.id??null,ageMs:d$1?Date.now()-d$1.registeredAtMs:null,reason:i}),d("[SIGNAL-STREAM][TS] writer-cleared",{remoteNodeId:e,writerId:d$1?.id??null,ageMs:d$1?Date.now()-d$1.registeredAtMs:null,reason:i})):d("[Client][NATIVE-MAIN] Inbound control writer clear skipped (mismatch)",{remoteNodeId:e,activeWriterId:d$1?.id??null,reason:i}),s.delete(e);}async sendViaInboundControlStream(e,t,n,i={}){if(this.disposed)return {sent:false,reason:"writer-registry-disposed",writerId:null,writerAgeMs:null,error:null};let o=this.writers instanceof Map?this.writers:null,s=this.writeMutexes instanceof Map?this.writeMutexes:null,a=this.writerMeta instanceof Map?this.writerMeta:null;if(!o||!s)return {sent:false,reason:"writer-or-mutex-map-unavailable",writerId:null,writerAgeMs:null,error:null};let c=a?.get(e),d=this.bypassUntilMs instanceof Map?this.bypassUntilMs:null,p=d?.get(e)??0;if(!i.ignoreCooldown&&p>Date.now())return {sent:false,reason:"inbound-writer-cooldown",writerId:c?.id??null,writerAgeMs:c?Date.now()-c.registeredAtMs:null,error:null};let u=o.get(e),g=c?.id??null,f=c?Date.now()-c.registeredAtMs:null;if(!u)return d?.set(e,Date.now()+n),{sent:false,reason:"no-inbound-writer",writerId:g,writerAgeMs:f,error:null};let v=ce(we(t)),y=s.get(e)??Promise.resolve(),C,I=new Promise(k=>{C=k;});s.set(e,I);try{return await y.catch(()=>{}),await u.write(v),{sent:!0,reason:"sent",writerId:g,writerAgeMs:f,error:null}}catch(k){return d?.set(e,Date.now()+n),console.warn("[Client][NATIVE-MAIN] Inbound control-stream signal send failed",{remoteNodeId:e,signalType:t?.content?.type??null,writerId:g,writerAgeMs:f,error:k}),{sent:false,reason:"inbound-writer-write-failed",writerId:g,writerAgeMs:f,error:k?.message??String(k)}}finally{C(),s.get(e)===I&&s.delete(e);}}};var Xt=class{constructor(e,t,n){this.deps=e;this.protocolConfig=t;this.timingConfig=n;this.writers=new Yt;this.disposed=false;this.messageIO=new Vt({eventName:t.eventName,protocolByte:t.protocolByte,label:t.label,maxLabelBytes:t.maxLabelBytes,maxFrameBytes:t.maxFrameBytes},{getReceiverDeviceId:()=>e.getReceiverDeviceId()}),this.handshakeQueue=new qt(n.pendingHandshakeMaxPerNode,n.pendingHandshakeTtlMs),this.signalQueue=new zt(n.pendingHandshakeMaxPerNode,n.pendingHandshakeTtlMs),this.deps.registerDisposer(()=>this.dispose());}get writerRegistry(){return this.writers}get connectionController(){return this.getConnections()}get handshakeQueueController(){return this.handshakeQueue}get messageIOController(){return this.messageIO}get payloadRouterController(){return this.getPayloadRouter()}dispose(){this.disposed=true,this.handshakeQueue.dispose(),this.signalQueue.dispose(),this.admission?.dispose(),this.connections?.dispose(),this.payloadRouter?.dispose(),this.writers.dispose(),this.signalSender?.dispose();}async acceptNativeMessage(e,t,n){return this.disposed?false:this.getAdmission().acceptNativeMessage(e,t,n)}tryHandleNativeMainUniStream(e,t,n){return this.disposed?Promise.resolve(false):this.getPayloadRouter().tryHandleNativeMainUniStream(e,t,n)}handleNativeMainStream(e,t){return this.disposed?Promise.resolve():this.getPayloadRouter().handleNativeMainStream(e,t)}writeLabelHeaderOnBiStream(e,t){return this.disposed?Promise.resolve():this.messageIO.writeLabelHeaderOnBiStream(e,t)}openSignalBiStream(e,t){return this.disposed?Promise.reject(new Error("Native main controller is disposed")):this.getSignalSender().openNativeSignalBiStream(e,t)}sendSignalEnvelope(e,t,n,i){return this.disposed?Promise.resolve():this.getSignalSender().sendEnvelope(e,t,n,i)}ensureIncomingConnectionForRemoteNode(e){return this.disposed?Promise.resolve(null):this.getConnections().ensureIncomingConnectionForRemoteNode(e)}flushPendingHandshakesForNode(e,t){return this.disposed?Promise.resolve(false):this.handshakeQueue.flush(e,t,{findManualDisconnectProjectionForNativeNode:n=>this.deps.findManualDisconnectProjectionForNativeNode(n),findLiveConnectionForRemoteNode:n=>this.deps.findLiveConnectionForRemoteNode(n),ensureIncomingConnectionForRemoteNode:n=>this.deps.ensureIncomingConnectionForRemoteNode(n),handleMessage:(n,i)=>Promise.resolve(this.deps.handleMessage(n,i))})}flushPendingSignalsForNode(e,t){return this.disposed?Promise.resolve(false):this.signalQueue.flush(e,t,{findManualDisconnectProjectionForNativeNode:n=>this.deps.findManualDisconnectProjectionForNativeNode(n),findLiveConnectionForRemoteNode:n=>this.deps.findLiveConnectionForRemoteNode(n),ensureIncomingConnectionForRemoteNode:n=>this.deps.ensureIncomingConnectionForRemoteNode(n)})}getSignalSender(){return this.signalSender||(this.signalSender=new Qt({isSessionTokenApprovedNode:e=>this.deps.isSessionTokenApprovedNode(e),isSessionTokenApprovedConnection:e=>this.deps.isSessionTokenApprovedConnection(e),sendViaInboundControlStream:(e,t,n)=>this.writers.sendViaInboundControlStream(e,t,this.timingConfig.inboundWriterRetryCooldownMs,n)}),this.disposed&&this.signalSender.dispose()),this.signalSender}getConnections(){return this.connections||(this.connections=new Gt({getDeterministicConnectionId:e=>this.deps.getDeterministicConnectionId(e),getConnection:e=>this.deps.getConnection(e),getWasmClient:()=>this.deps.getWasmClient(),getLocalNodeId:()=>this.deps.getLocalNodeId(),getKnownDeviceIdForNode:e=>this.deps.getKnownDeviceIdForNode(e),getKnownDevicePlatform:(e,t)=>this.deps.getKnownDevicePlatform(e,t),isNativeMainPeerPlatform:e=>this.deps.isNativeMainPeerPlatform(e),getTrustFailureCooldown:e=>this.deps.getTrustFailureCooldown(e),getTrustFailureCooldownMs:()=>this.timingConfig.trustFailureCooldownMs,isSessionTokenApprovedNode:e=>this.deps.isSessionTokenApprovedNode(e),openNativeSignalBiStream:(e,t)=>this.openSignalBiStream(e,t),writeNativeMainLabelHeaderOnBiStream:(e,t)=>this.writeLabelHeaderOnBiStream(e,t),sendNativeSignalEnvelope:(e,t,n,i)=>this.sendSignalEnvelope(e,t,n,i),getRTCConfig:()=>this.deps.getRTCConfig(),createTransportContext:e=>this.deps.createTransportContext(e),getApplicationCrypto:()=>this.deps.getApplicationCrypto(),shouldNegotiateApplicationKeyAgreement:()=>this.deps.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(e,t,n)=>this.deps.handleConnectionTransportStatus(e,t,n??null),handleConnectionApplicationRouteMissing:(e,t)=>this.deps.handleConnectionApplicationRouteMissing(e,t),initializeConnectionTrust:(e,t)=>{this.deps.initializeConnectionTrust(e,t);},markConnectionTrustVerified:(e,t)=>{this.deps.markConnectionTrustVerified(e,t);},registerConnection:e=>this.deps.registerConnection(e),announceConnectionWhenStable:e=>this.deps.announceConnectionWhenStable(e),sendTransportHandshake:(e,t)=>this.deps.sendTransportHandshake(e,t),requestProtectedWebRTCUpgradeIfInitiator:(e,t)=>this.deps.requestProtectedWebRTCUpgradeIfInitiator(e,t),getConnectionChannelId:e=>this.deps.getConnectionChannelId(e),isWebRTCTransportEnabled:()=>this.deps.isWebRTCTransportEnabled()}),this.disposed&&this.connections.dispose()),this.connections}getAdmission(){return this.admission||(this.admission=new jt({getDeterministicConnectionId:e=>this.deps.getDeterministicConnectionId(e),getNativeMainConnectionId:e=>this.deps.getNativeMainConnectionId(e),getConnection:e=>this.deps.getConnection(e),handleMessage:(e,t)=>this.deps.handleMessage(e,t),getLocalDeviceId:()=>this.deps.getLocalDeviceId(),getFallbackLocalDeviceId:()=>this.deps.getFallbackLocalDeviceId(),getConfiguredDeviceName:()=>this.deps.getConfiguredDeviceName(),getNativeMainProtocolVersion:()=>this.protocolConfig.protocolVersion,isNativeRuntime:()=>this.deps.isNativeRuntime(),isLikelyMobileBrowser:()=>this.deps.isLikelyMobileBrowser(),writeNativeMainMessage:(e,t)=>this.messageIO.writeLabeledMessage(e,t),validateIncomingSessionToken:(e,t,n)=>this.deps.validateIncomingSessionToken(e,t,n),applySessionTokenTrustApproval:(e,t,n)=>this.deps.applySessionTokenTrustApproval(e,t,n),rememberPendingSessionTokenTrustApproval:(e,t)=>this.deps.rememberPendingSessionTokenTrustApproval(e,t),markSessionTokenApprovedNode:e=>this.deps.markSessionTokenApprovedNode(e),markSessionTokenApprovedConnection:e=>this.deps.markSessionTokenApprovedConnection(e),clearSessionTokenRejectionCooldown:e=>this.deps.clearSessionTokenRejectionCooldown(e),getSessionTokenRejectionCooldown:e=>this.deps.getSessionTokenRejectionCooldown(e),setSessionTokenRejectionCooldown:(e,t)=>this.deps.setSessionTokenRejectionCooldown(e,t),clearTrustFailureCooldown:e=>{this.deps.clearTrustFailureCooldown(e);},schedulePeerReconciliation:e=>this.deps.schedulePeerReconciliation(e),ensureIncomingConnectionForRemoteNode:e=>this.deps.ensureIncomingConnectionForRemoteNode(e),disconnectRemoteNode:e=>this.deps.disconnectRemoteNode(e)}),this.disposed&&this.admission.dispose()),this.admission}getPayloadRouter(){return this.payloadRouter||(this.payloadRouter=new $t({getProtocolConfig:()=>this.messageIO.protocolConfig(),registerInboundNativeMainWriter:(e,t)=>this.writers.registerInboundWriter(e,t),clearInboundNativeMainWriter:(e,t,n)=>this.writers.clearInboundWriter(e,t,this.timingConfig.inboundWriterRetryCooldownMs,n),schedulePeerReconciliation:e=>this.deps.schedulePeerReconciliation(e),ensureIncomingConnectionForRemoteNode:e=>this.deps.ensureIncomingConnectionForRemoteNode(e),queuePendingNativeMainHandshake:(e,t,n,i)=>this.handshakeQueue.queue(e,t,n,i,(o,s)=>{this.flushPendingHandshakesForNode(o,s);}),queuePendingNativeMainSignal:(e,t,n,i)=>this.signalQueue.queue(e,t,n,i,(o,s)=>{this.flushPendingSignalsForNode(o,s);}),findManualDisconnectProjectionForNativeNode:e=>this.deps.findManualDisconnectProjectionForNativeNode(e),handleMessage:(e,t)=>this.deps.handleMessage(e,t),handleNativeHandshakeRequest:(e,t,n)=>this.getAdmission().handleHandshakeRequest(e,t,n),handleNativeSessionTokenRequest:(e,t,n)=>this.getAdmission().handleSessionTokenRequest(e,t,n),dispatchNativeMainMessage:(e,t)=>this.messageIO.dispatchMessage(e,t),writeNativeMainReceiveAck:(e,t,n)=>this.messageIO.writeAck(e,t,n)}),this.disposed&&this.payloadRouter.dispose()),this.payloadRouter}};function rr(r){let{host:e}=r;return new Xt({registerDisposer:t=>e.registerDisposer(t),getDeterministicConnectionId:t=>e.getDeterministicConnectionId(t),getNativeMainConnectionId:t=>e.getNativeMainConnectionId(t),getConnection:t=>e.getConnection(t),getWasmClient:()=>e.getWasmClient(),getLocalNodeId:()=>e.getLocalNodeId(),getReceiverDeviceId:()=>e.getDeviceId()??e.getOptions().localDeviceId??null,getKnownDeviceIdForNode:t=>e.getKnownDeviceIdForNode(t),getKnownDevicePlatform:(t,n)=>e.getKnownDevicePlatform(t,n),isNativeMainPeerPlatform:t=>qo(t),getTrustFailureCooldown:t=>e.getTrustFailureCooldown(t),isSessionTokenApprovedNode:t=>e.isSessionTokenApprovedNode(t),isSessionTokenApprovedConnection:t=>e.isSessionTokenApprovedConnection(t),getRTCConfig:()=>l$1(e.getOptions(),t=>d(t)),createTransportContext:t=>e.createTransportContext(t),getApplicationCrypto:()=>e.getApplicationCrypto(),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(t,n,i)=>e.handleConnectionTransportStatus(t,n,i??null),handleConnectionApplicationRouteMissing:(t,n)=>e.handleConnectionApplicationRouteMissing(t,n),initializeConnectionTrust:(t,n)=>{e.initializeConnectionTrust(t,n);},markConnectionTrustVerified:(t,n)=>{e.markConnectionTrustVerified(t,n);},registerConnection:t=>e.registerConnection(t),announceConnectionWhenStable:t=>e.announceConnectionWhenStable(t),sendTransportHandshake:(t,n)=>e.sendTransportHandshake(t,n),requestProtectedWebRTCUpgradeIfInitiator:(t,n)=>e.requestProtectedWebRTCUpgradeIfInitiator(t,n),getConnectionChannelId:t=>e.getConnectionChannelId(t),isWebRTCTransportEnabled:()=>k$1(e.getOptions()),getLocalDeviceId:()=>e.getLocalDeviceId(),getFallbackLocalDeviceId:()=>e.getDeviceId()||e.getOptions().localDeviceId||null,getConfiguredDeviceName:()=>e.getOptions().deviceName,isNativeRuntime:()=>typeof window<"u"&&typeof window.__TAURI__<"u",isLikelyMobileBrowser:()=>ae(),validateIncomingSessionToken:(t,n,i)=>e.validateIncomingSessionToken(t,n,i),applySessionTokenTrustApproval:(t,n,i)=>e.applySessionTokenTrustApproval(t,n,i),rememberPendingSessionTokenTrustApproval:(t,n)=>e.rememberPendingSessionTokenTrustApproval(t,n),markSessionTokenApprovedNode:t=>e.markSessionTokenApprovedNode(t),markSessionTokenApprovedConnection:t=>e.markSessionTokenApprovedConnection(t),clearSessionTokenRejectionCooldown:t=>e.clearSessionTokenRejectionCooldown(t),getSessionTokenRejectionCooldown:t=>e.getSessionTokenRejectionCooldown(t),setSessionTokenRejectionCooldown:(t,n)=>e.setSessionTokenRejectionCooldown(t,n),clearTrustFailureCooldown:t=>{e.clearTrustFailureCooldown(t);},schedulePeerReconciliation:t=>e.schedulePeerReconciliation(t),ensureIncomingConnectionForRemoteNode:t=>r.getController().ensureIncomingConnectionForRemoteNode(t),disconnectRemoteNode:t=>e.disconnectRemoteNode(t),findManualDisconnectProjectionForNativeNode:t=>e.findManualDisconnectProjectionForNativeNode(t),findLiveConnectionForRemoteNode:t=>e.findLiveConnectionForRemoteNode(t),handleMessage:(t,n)=>e.handleMessage(t,n)},{eventName:So,protocolByte:yt,label:vt,maxLabelBytes:bt,maxFrameBytes:bo,protocolVersion:Co},{trustFailureCooldownMs:Po,inboundWriterRetryCooldownMs:Ro,pendingHandshakeTtlMs:Io,pendingHandshakeMaxPerNode:wo})}function sr(r){return new ui({registerDisposer:e=>r.lifecycleScope.register(e),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,getLocalNodeId:()=>r.localNodeId,getDeviceId:()=>r.deviceId,getDeterministicConnectionId:e=>r.peerIdentity.getDeterministicConnectionId(e),getNativeMainConnectionId:e=>r.peerIdentity.getNativeMainConnectionId(e),getConnection:e=>r.registry.get(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),getKnownDevicePlatform:(e,t)=>r.deviceDirectory.getKnownDevicePlatform(e,t),getTrustFailureCooldown:e=>r.connectionTrust.getFailureCooldown(e),isSessionTokenApprovedNode:e=>r.sessionTokens.isApprovedNode(e),isSessionTokenApprovedConnection:e=>r.sessionTokens.isApprovedConnection(e),createTransportContext:e=>r.transportContexts.create(e),getApplicationCrypto:()=>r.options?.applicationCrypto,shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),handleConnectionTransportStatus:(e,t,n)=>r.transportHealth.handleConnectionTransportStatus(e,t,n),handleConnectionApplicationRouteMissing:(e,t)=>r.transportUpgrade.handleApplicationRouteMissing(e,t),initializeConnectionTrust:(e,t)=>{r.connectionTrust.initialize(e,t);},markConnectionTrustVerified:(e,t)=>{r.connectionTrust.markVerified(e,t);},registerConnection:e=>r.connectionLifecycle.registerConnection(e),announceConnectionWhenStable:e=>r.connectionLifecycle.announceConnectionWhenStable(e),sendTransportHandshake:(e,t)=>r.transportHandshake.sendTransportHandshake(e,t),requestProtectedWebRTCUpgradeIfInitiator:(e,t)=>r.transportHandshake.requestProtectedWebRTCUpgradeIfInitiator(e,t),getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),validateIncomingSessionToken:(e,t,n)=>r.sessionTokens.validateIncomingSessionTokenWithRetry(e,t,n),applySessionTokenTrustApproval:(e,t,n)=>r.sessionTokens.applyTrustApproval(e,t,n),rememberPendingSessionTokenTrustApproval:(e,t)=>r.sessionTokens.rememberPendingTrustApproval(e,t),markSessionTokenApprovedNode:e=>r.sessionTokens.approveNode(e),markSessionTokenApprovedConnection:e=>r.sessionTokens.approveConnection(e),clearSessionTokenRejectionCooldown:e=>r.sessionTokens.clearRejectionCooldown(e),getSessionTokenRejectionCooldown:e=>r.sessionTokens.getRejectionCooldown(e),setSessionTokenRejectionCooldown:(e,t)=>r.sessionTokens.setRejectionCooldown(e,t),clearTrustFailureCooldown:e=>{r.connectionTrust.clearFailureCooldown(e);},schedulePeerReconciliation:e=>r.peerProjection.schedule(e),disconnectRemoteNode:e=>r.runtimeConnections.disconnectNodeBestEffort(e),findManualDisconnectProjectionForNativeNode:e=>r.peerIdentity.findManualDisconnectProjectionForNativeNode(e),findLiveConnectionForRemoteNode:e=>{let t=r.peerIdentity.getDeterministicConnectionId(e);return r.connectionLifecycle.findLiveConnectionForRemoteNode(e,t)},handleMessage:(e,t)=>r.connectionMessageHandler.handleMessage(e,t)})}var ui=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getController:()=>this.controller}}get controller(){return this._controller??(this._controller=rr(this.factoryHost))}writeLabelHeaderOnBiStream(e,t){return this.controller.writeLabelHeaderOnBiStream(e,t)}flushPendingHandshakesForNode(e,t){return this.controller.flushPendingHandshakesForNode(e,t)}flushPendingSignalsForNode(e,t){return this.controller.flushPendingSignalsForNode(e,t)}};var Jt=class{constructor(e,t){this.peerLifecycle=e;this.deps=t;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}watchPeerStates(e){return this.peerLifecycle.watch(e)}getPeerState(e){return this.peerLifecycle.get(e)}listConnectedPeers(){return this.peerLifecycle.listConnected()}isPeerPromotionEligible(e){return this.deps.resolvePromotionEligibility(e)}addPeerScope(e,t="persistent"){let n=this.deps.getWasmClient();return n&&typeof n.add_peer_scope=="function"?(n.add_peer_scope(e,t).then(()=>{this.disposed||this.deps.scheduleRefreshPeerSnapshot();}).catch(()=>{}),this.peerLifecycle.get(e)):this.peerLifecycle.addScope(e,t)}releasePeerScope(e,t){let n=this.deps.getWasmClient();return n&&typeof n.release_peer_scope=="function"?(n.release_peer_scope(e,t??null).then(()=>{this.disposed||this.deps.scheduleRefreshPeerSnapshot();}).catch(()=>{}),this.peerLifecycle.get(e)):this.peerLifecycle.releaseScope(e,t)}getPeerScopes(e){return this.peerLifecycle.get(e)?.scopes??[]}isSamePeer(e,t){let n=this.peerLifecycle.get(e),i=this.peerLifecycle.get(t);return n&&i?n.peerId===i.peerId:false}clearManualDisconnectProjection(e){let t=this.peerLifecycle.get(e);this.peerLifecycle.dispatch({type:"ManualDisconnectCleared",peerId:t?.peerId??e,deviceId:t?.deviceId??e,deviceIdHint:t?.deviceIdHint,nodeId:t?.nodeId,connectionId:t?.connectionId});}async disconnectPeer(e,t="persistent"){let n=this.peerLifecycle.releaseScope(e,t);n&&n.scopes.length>0||await this.forceDisconnectPeer(e);}async forceDisconnectPeer(e){let t=this.peerLifecycle.releaseScope(e),n=this.getPeerCandidates(t?.peerId||e);if(await Promise.allSettled(Array.from(n).map(async i=>{let o=Array.from(this.deps.getConnections()).filter(a=>{let c=a.id.trim().toLowerCase(),d=a.deviceId.trim().toLowerCase();return i===d||i===c||c.includes(i)});await Promise.allSettled(o.map(a=>a.disconnect()));let s=t?.nodeId||(o[0]?.deviceId??null);s&&i===s.trim().toLowerCase()&&await this.deps.disconnectNode(s).catch(()=>{});})),this.deps.hasRustPeerLifecycleProjection()){if(this.disposed)return;await this.deps.schedulePeerReconciliation("disconnect-node").catch(()=>{});}this.disposed||this.peerLifecycle.dispatch({type:"ManualDisconnect",peerId:t?.peerId??e,deviceId:t?.deviceId,deviceIdHint:t?.deviceIdHint,nodeId:t?.nodeId,connectionId:t?.connectionId});}async getPeerHealth(e){let t=this.peerLifecycle.get(e);return t?t.health:"unknown"}getPeerCandidates(e){let t=this.peerLifecycle.get(e),n=new Set;return [e,t?.peerId,t?.deviceId,t?.nodeId,t?.connectionId,...t?.connectionIds??[]].forEach(o=>{if(!o)return;let s=o.trim().toLowerCase();s&&n.add(s);}),n}};function Pe(r){if(!r)return null;let e=r.trim();return e?e.toLowerCase():null}function gi(r){return r.deviceId||r.deviceIdHint||r.peerId||null}function Zt(r){return [...r].sort()}function Ne(r,e){return r?r.peerId===e.peerId&&(r.deviceId??null)===(e.deviceId??null)&&(r.deviceIdHint??null)===(e.deviceIdHint??null)&&(r.nodeId??null)===(e.nodeId??null)&&(r.connectionId??null)===(e.connectionId??null)&&(r.ticket??null)===(e.ticket??null)&&!!r.online==!!e.online&&(r.deviceName??null)===(e.deviceName??null)&&(r.platformType??null)===(e.platformType??null)&&r.status===e.status&&r.health===e.health&&(r.lifecycleStage??null)===(e.lifecycleStage??null)&&(r.generation??null)===(e.generation??null)&&(r.baseTransportState??null)===(e.baseTransportState??null)&&(r.admissionState??null)===(e.admissionState??null)&&(r.transportState??null)===(e.transportState??null)&&(r.protocolState??null)===(e.protocolState??null)&&(r.webrtcState??null)===(e.webrtcState??null)&&!!r.routable==!!e.routable&&(r.activeTransportStableId??null)===(e.activeTransportStableId??null)&&(r.transportGeneration??null)===(e.transportGeneration??null)&&(r.activeTransport??null)===(e.activeTransport??null)&&(r.fallbackTransport??null)===(e.fallbackTransport??null)&&(r.parallelTransport??null)===(e.parallelTransport??null)&&!!r.manualDisconnect==!!e.manualDisconnect&&(r.lastAuthoritativeEventAt??null)===(e.lastAuthoritativeEventAt??null)&&(r.lastTransientEventAt??null)===(e.lastTransientEventAt??null)&&(r.promotionEligible??true)===(e.promotionEligible??true)&&(r.error??null)===(e.error??null)&&JSON.stringify(Zt(r.connectionIds))===JSON.stringify(Zt(e.connectionIds))&&JSON.stringify(Zt(r.scopes))===JSON.stringify(Zt(e.scopes)):false}function De(r){return r==="closed"||r==="disconnected"||r==="failed"}function va(r){let{status:e,health:t,lifecycleStage:n,generation:i,baseTransportState:o,admissionState:s,transportState:a,protocolState:c,webrtcState:d,routable:p,activeTransportStableId:u,transportGeneration:g,activeTransport:f,fallbackTransport:v,parallelTransport:y,connectionId:C,error:I,...k}=r;return k}function dr(r){if(De(r.status))return "closed";let e=(r.transportState??"").trim().toLowerCase();return e==="connected"||r.connectionId||r.activeTransport?"connected":e==="connecting"||r.status==="connecting"?"connecting":e==="failed"||e==="degraded"?"degraded":"unknown"}function Ye(r){return De(r.status)||r.webrtcState!=="ready"||!r.connectionId||r.activeTransportStableId===null||r.activeTransportStableId===void 0||r.health!=="healthy"||r.transportState!=="connected"?false:[r.activeTransport,r.parallelTransport].filter(t=>typeof t=="string").some(f)}function ar(r){return f(r)}function hi(r){return De(r.status)?"closed":Ye(r)?"ready":r.webrtcState?r.webrtcState:[r.activeTransport,r.parallelTransport].filter(t=>typeof t=="string").some(f)?r.transportState==="connected"?"transport-open":"connecting":"unknown"}function ba(r){if(r.manualDisconnect||De(r.status))return "closed";let e=hi(r);if(e==="ready")return "webrtc-ready";if(e==="connecting"||e==="transport-open"||e==="route-probing")return "upgrading";if(r.routable===true||r.protocolState==="routable")return "protocol-ready";if(r.admissionState==="admitted")return "admitted";let t=r.baseTransportState??dr(r);return t==="connected"?"base-connected":t==="degraded"||r.health==="suspect"||r.health==="stale"?"degraded":r.status==="connecting"?"dialing":"discovered"}function Ca(r){return De(r.status)?r.status:r.routable===true||r.protocolState==="routable"||Ye(r)?"connected":r.status}function cr(r){return {peerId:r.peerId,deviceId:r.deviceId??null,deviceIdHint:r.deviceIdHint??null,nodeId:r.nodeId??null,connectionId:r.connectionId??null,status:r.status,health:r.health,lifecycleStage:r.lifecycleStage??null,generation:r.generation??null,baseTransportState:r.baseTransportState??null,admissionState:r.admissionState??null,transportState:r.transportState??null,protocolState:r.protocolState??null,webrtcState:r.webrtcState??null,routable:r.routable??null,activeTransportStableId:r.activeTransportStableId??null,transportGeneration:r.transportGeneration??null,activeTransport:r.activeTransport??null,parallelTransport:r.parallelTransport??null,manualDisconnect:r.manualDisconnect??false,scopes:r.scopes,error:r.error??null}}function Sa(r,e,t){let n={event:r,before:e?cr(e):null,after:cr(t)};d("[OpenRTC][projection]",n);}var en=class{constructor(){this.peers=new Map;this.aliases=new Map;this.watchers=new Set;this.disposed=false;}resolveCanonicalPeerId(e){let t=[e.deviceId,e.deviceIdHint,e.nodeId,e.peerId,e.connectionId];for(let n of t){let i=Pe(n);if(!i)continue;let o=this.aliases.get(i);if(o)return o}return gi(e)}setAlias(e,t){let n=Pe(e);n&&this.aliases.set(n,t);}snapshot(e){let t=Ye(e),n=e.baseTransportState??dr(e),i=hi(e),o=e.routable||t,s=o?"routable":e.protocolState;return {peerId:e.peerId,deviceId:e.deviceId,deviceIdHint:e.deviceIdHint,nodeId:e.nodeId,connectionId:e.connectionId,connectionIds:Array.from(e.connectionIds.values()),ticket:e.ticket,online:e.online,deviceName:e.deviceName,platformType:e.platformType,status:Ca(e),health:e.health,lifecycleStage:e.lifecycleStage??ba(e),generation:e.generation??e.transportGeneration,baseTransportState:n,admissionState:e.admissionState,transportState:e.transportState,protocolState:s,webrtcState:i,routable:o,activeTransportStableId:e.activeTransportStableId,transportGeneration:e.transportGeneration,activeTransport:e.activeTransport,fallbackTransport:e.fallbackTransport,parallelTransport:e.parallelTransport,manualDisconnect:e.manualDisconnect,lastAuthoritativeEventAt:e.lastAuthoritativeEventAt,lastTransientEventAt:e.lastTransientEventAt,promotionEligible:e.promotionEligible,scopes:Array.from(e.scopes.values()),lastSeenAt:e.lastSeenAt,error:t?void 0:e.error}}emit(){if(this.disposed)return;let e=this.list();this.watchers.forEach(t=>t(e));}rekeyPeer(e,t){let n=this.peers.get(e);if(!n)throw new Error(`Cannot rekey missing peer ${e}`);if(e===t)return n;this.peers.delete(e),n.peerId=t,this.peers.set(t,n);for(let[i,o]of this.aliases.entries())o===e&&this.aliases.set(i,t);return n}upsert(e){let t=e,n=this.resolveCanonicalPeerId(t)??gi(t);if(!n)throw new Error("Peer projection upsert requires a device-keyed identifier.");let i=gi(t)??n,o=this.peers.get(n),s=!!o;o||(o={peerId:n,connectionIds:new Set,status:t.status??"disconnected",health:t.health??"unknown",scopes:new Set},this.peers.set(n,o));let a=s?this.snapshot(o):void 0;if(i!==o.peerId){let _=t.deviceId||o.deviceId||t.deviceIdHint||o.deviceIdHint||t.nodeId||o.nodeId||o.peerId;_&&_!==o.peerId&&(o=this.rekeyPeer(o.peerId,_));}s&&typeof t.transportGeneration=="number"&&typeof o.transportGeneration=="number"&&t.transportGeneration<o.transportGeneration&&t.manualDisconnect!==true&&(t=va(t)),t.deviceId&&(o.deviceId=t.deviceId),t.deviceIdHint!==void 0&&(o.deviceIdHint=t.deviceIdHint),t.nodeId&&(o.nodeId=t.nodeId);let c={generation:o.generation,lifecycleStage:o.lifecycleStage,protocolState:o.protocolState,webrtcState:o.webrtcState,routable:o.routable,activeTransportStableId:o.activeTransportStableId,transportGeneration:o.transportGeneration,activeTransport:o.activeTransport,fallbackTransport:o.fallbackTransport,parallelTransport:o.parallelTransport},d=Ye(o)||hi(o)==="ready",p=t.connectionId===void 0||o.connectionId===void 0||t.connectionId===o.connectionId,u=t.activeTransport!==void 0||t.parallelTransport!==void 0||t.activeTransportStableId!==void 0||t.transportGeneration!==void 0||t.transportState!==void 0,g=ar(t.activeTransport)||ar(t.parallelTransport)||t.webrtcState==="ready"||t.webrtcState==="connecting",f=t.webrtcState==="closed"||t.webrtcState==="failed"||t.lifecycleStage==="closed"||t.status==="closed"||t.status==="disconnected"||t.status==="failed"||t.manualDisconnect===true,v=d&&p&&u&&!g&&!f;t.connectionId&&(o.connectionId=t.connectionId,o.connectionIds.add(t.connectionId)),t.ticket!==void 0&&(o.ticket=t.ticket),t.online!==void 0&&(o.online=t.online),t.deviceName!==void 0&&(o.deviceName=t.deviceName),t.platformType!==void 0&&(o.platformType=t.platformType);let y=s&&(o.manualDisconnect===true||De(o.status)&&typeof o.error=="string"&&o.error.toLowerCase().includes("manual disconnect")),C=t.status==="connected"||t.status==="connecting"||t.routable===true||t.protocolState==="routable"||t.transportState==="connected"||t.activeTransport!==void 0||t.parallelTransport!==void 0;if(y&&C){let _=this.snapshot(o);return Ne(a,_)||this.emit(),_}C&&(o.lifecycleStage==="closed"&&t.lifecycleStage===void 0&&(o.lifecycleStage=void 0),o.baseTransportState==="closed"&&t.baseTransportState===void 0&&(o.baseTransportState=void 0),o.webrtcState==="closed"&&t.webrtcState===void 0&&(o.webrtcState=void 0),o.transportState==="closed"&&t.transportState===void 0&&(o.transportState=void 0),o.protocolState==="closed"&&t.protocolState===void 0&&(o.protocolState=void 0)),t.status&&(o.status=t.status),t.health&&(o.health=t.health),t.lifecycleStage!==void 0&&(o.lifecycleStage=t.lifecycleStage),t.generation!==void 0&&(o.generation=t.generation),t.baseTransportState!==void 0&&(o.baseTransportState=t.baseTransportState),t.admissionState!==void 0&&(o.admissionState=t.admissionState),t.transportState!==void 0&&(o.transportState=t.transportState),t.protocolState!==void 0&&(o.protocolState=t.protocolState),t.webrtcState!==void 0&&(o.webrtcState=t.webrtcState),t.routable!==void 0&&(o.routable=t.routable),t.activeTransportStableId!==void 0&&(o.activeTransportStableId=t.activeTransportStableId),t.transportGeneration!==void 0&&(o.transportGeneration=t.transportGeneration),t.activeTransport!==void 0&&(o.activeTransport=t.activeTransport),t.fallbackTransport!==void 0&&(o.fallbackTransport=t.fallbackTransport),t.parallelTransport!==void 0&&(o.parallelTransport=t.parallelTransport),t.manualDisconnect!==void 0&&(o.manualDisconnect=t.manualDisconnect),t.lastAuthoritativeEventAt!==void 0&&(o.lastAuthoritativeEventAt=t.lastAuthoritativeEventAt),t.lastTransientEventAt!==void 0&&(o.lastTransientEventAt=t.lastTransientEventAt),t.promotionEligible!==void 0&&(o.promotionEligible=t.promotionEligible);let I=t.transportState!==void 0||t.activeTransportStableId!==void 0||t.activeTransport!==void 0||t.parallelTransport!==void 0,k=t.routable===true||t.protocolState==="routable";if(I&&!k&&!Ye(o)&&(o.routable=false,o.protocolState==="routable"&&(o.protocolState=o.transportState==="connected"?"transport-only":o.transportState)),v&&(o.generation=c.generation,o.lifecycleStage=c.lifecycleStage,o.protocolState=c.protocolState,o.webrtcState=c.webrtcState,o.routable=c.routable,o.activeTransportStableId=c.activeTransportStableId,o.transportGeneration=c.transportGeneration,o.activeTransport=c.activeTransport,o.fallbackTransport=c.fallbackTransport,o.parallelTransport=c.parallelTransport),t.clearError?(o.error=void 0,t.manualDisconnect!==true&&(o.manualDisconnect=false)):t.error!==void 0&&(o.error=t.error,t.error.toLowerCase().includes("manual disconnect")&&(o.manualDisconnect=true)),t.lastSeenAt!==void 0&&(o.lastSeenAt=t.lastSeenAt),t.scopes)for(let _ of t.scopes)o.scopes.add(_);(o.status==="closed"||o.status==="failed"||o.status==="disconnected")&&(o.routable=false,o.activeTransportStableId=null,o.activeTransport=void 0,o.fallbackTransport=null,o.parallelTransport=null,o.webrtcState="closed",o.baseTransportState="closed",o.lifecycleStage="closed",(!o.transportState||o.transportState==="connected")&&(o.transportState="closed"),(!o.protocolState||o.protocolState==="routable")&&(o.protocolState="closed")),this.setAlias(o.peerId,o.peerId),this.setAlias(o.deviceId,o.peerId),this.setAlias(o.deviceIdHint,o.peerId),this.setAlias(o.nodeId,o.peerId),this.setAlias(o.connectionId,o.peerId);for(let _ of o.connectionIds)this.setAlias(_,o.peerId);let T=this.snapshot(o);return Ne(a,T)||(Sa(s?"upsert":"create",a??null,T),this.emit()),T}dispatch(e){let t={peerId:e.peerId,deviceId:e.deviceId,deviceIdHint:e.deviceIdHint,nodeId:e.nodeId,connectionId:e.connectionId};switch(e.type){case "ConnectionStateProjected":{let{type:n,...i}=e;return this.upsert(i)}case "ManualDisconnectCleared":return this.upsert({...t,status:"disconnected",health:"unknown",manualDisconnect:false,clearError:true,lastSeenAt:Date.now()});case "RosterDeviceDiscovered":return this.upsert({...t,deviceName:e.deviceName,platformType:e.platformType,ticket:e.ticket,online:e.online??true,scopes:e.scopes,lastSeenAt:e.lastSeenAt??Date.now()});case "PresenceOnline":return this.upsert({...t,online:true,lastSeenAt:e.lastSeenAt??Date.now()});case "PresenceOffline":return this.upsert({...t,online:false});case "DialStarted":return this.get(this.targetLookupId(t))?.status==="connected"?this.get(this.targetLookupId(t)):this.upsert({...t,status:"connecting"});case "BaseTransportConnected":return this.upsert({...t,status:this.get(this.targetLookupId(t))?.status==="connected"?void 0:"connecting",transportState:"connected",baseTransportState:"connected",transportGeneration:e.transportGeneration});case "AdmissionAccepted":return this.upsert({...t,admissionState:"admitted"});case "AdmissionRejected":return this.upsert({...t,admissionState:"rejected",error:e.reason});case "WebRtcNegotiationStarted":return this.upsert({...t,webrtcState:"connecting",generation:e.generation,transportGeneration:e.generation});case "WebRtcFailed":return this.upsert({...t,webrtcState:"failed",transportGeneration:e.transportGeneration});case "ControlPathClosed":return this.upsert({...t,status:"disconnected"});case "HealthObserved":return this.updateHealth(this.targetLookupId(t),e.health);case "ManualDisconnect":return this.upsert({...t,status:"closed",health:"stale",manualDisconnect:true,error:"manual disconnect"});case "ExplicitUnshare":return this.upsert({...t,status:"closed",manualDisconnect:true,error:"explicit unshare"})}}targetLookupId(e){return e.deviceId||e.deviceIdHint||e.peerId||e.nodeId||e.connectionId||""}upsertDevice(e){return this.upsert({deviceId:e.deviceId,nodeId:e.nodeId,ticket:e.ticket,online:e.online,deviceName:e.deviceName,platformType:e.platformType,status:e.online?void 0:"disconnected",health:"unknown",lastSeenAt:typeof e.updatedAt=="number"?e.updatedAt:typeof e.lastSeenAt=="number"?e.lastSeenAt:Date.now()})}watch(e){return this.disposed?()=>{}:(this.watchers.add(e),e(this.list()),()=>{this.watchers.delete(e);})}dispose(){this.disposed=true,this.watchers.clear();}get(e){let t=Pe(e),n=t?this.aliases.get(t):void 0,i=n&&this.peers.get(n)||this.peers.get(e);return i?this.snapshot(i):void 0}list(){return Array.from(this.peers.values()).map(e=>this.snapshot(e)).sort((e,t)=>{let n=e.lastSeenAt??0,i=t.lastSeenAt??0;return n!==i?i-n:e.peerId.localeCompare(t.peerId)})}listConnected(){return this.list().filter(e=>e.status==="connected")}addScope(e,t="persistent"){let n=this.resolveRecord(e);if(!n)return;let i=this.snapshot(n);n.scopes.add(t);let o=this.snapshot(n);return Ne(i,o)||this.emit(),o}releaseScope(e,t){let n=this.resolveRecord(e);if(!n)return;let i=this.snapshot(n);t?n.scopes.delete(t):n.scopes.clear();let o=this.snapshot(n);return Ne(i,o)||this.emit(),o}hasScopes(e){return (this.resolveRecord(e)?.scopes.size??0)>0}removeConnection(e){let t=this.resolveRecord(e);if(!t)return;let n=this.snapshot(t),i=Pe(e);if(i){let s=Array.from(t.connectionIds).find(a=>Pe(a)===i);s&&t.connectionIds.delete(s);}t.connectionId&&Pe(t.connectionId)===i&&(t.connectionId=Array.from(t.connectionIds)[0]),t.connectionIds.size===0&&t.status==="connected"&&(t.status="closed",t.routable=false,t.transportState="closed",t.protocolState="closed");let o=this.snapshot(t);return Ne(n,o)||this.emit(),o}updateHealth(e,t,n){let i=this.resolveRecord(e);if(!i)return;let o=this.snapshot(i);i.health=t,n&&(i.status=n),i.lastSeenAt=Date.now();let s=this.snapshot(i);return Ne(o,s)||this.emit(),s}resolveRecord(e){let t=Pe(e),n=t?this.aliases.get(t):void 0;return n&&this.peers.get(n)||this.peers.get(e)}};function mi(r){return r.webRtcDataPlaneLive&&!r.routeReady?{activeTransport:r.parallelTransport??"iroh-relay",fallbackTransport:"webrtc",parallelTransport:"webrtc"}:{activeTransport:r.activeTransport??void 0,fallbackTransport:r.parallelTransport??null,parallelTransport:r.parallelTransport??null}}function lr(r){return r.settledReady?"routable":r.hasActiveConnection?"transport-only":r.rustStatusIsConnecting?"connecting":"closed"}function pr(r){return r.hasActiveConnection?"connected":r.rustStatusIsConnecting?"connecting":r.mappedStatusIsTerminal?"closed":"unknown"}function ur(r){return r.routeReady?"ready":r.webRtcDataPlaneLive?"route-probing":r.anyWebRtcTransportLabel?"connecting":"unknown"}function gr(r){return r.terminal?"closed":r.activeIsWebRtc?r.routeReady?"ready":"route-probing":r.parallelIsWebRtc?"route-probing":"unknown"}function Ia(r,e){let t=b$3(r)??"",n=[r,e].map(b$3).filter(i=>!!i);return {activeTransportLabel:t,labels:n}}function tn(r){let{activeTransportLabel:e,labels:t}=Ia(r.activeTransport,r.parallelTransport),n=t.some(f);return {webRtcDataPlaneLive:r.source==="rust-session"?!!r.activeConnectionId&&r.activeTransportStableId!==null&&r.activeTransportStableId!==void 0&&(r.sessionStatusNormalized==="connected"||r.sessionStatusNormalized==="connecting")&&r.mappedHealth==="healthy"&&f(e):f(r.activeTransport),routeReady:r.routeReady,anyWebRtcTransportLabel:n}}function wa(r){if(r.isClosed)return "closed";let e=r.getUpgradeState();return e==="upgraded"?"webrtc":e==="upgrading"?"webrtc-upgrading":e==="failed"?"iroh-fallback":"connected"}function hr(r){let{connection:e,trustProjection:t,existingProjection:n,terminalTransportClose:i}=r;if(i){let c=n?.peerId??r.peerId??r.deviceId??r.deviceIdHint??e.id;return !c&&!r.deviceId&&!r.deviceIdHint?null:{event:{type:"ConnectionStateProjected",peerId:c,deviceId:n?.deviceId??r.deviceId,deviceIdHint:n?.deviceIdHint??r.deviceIdHint,nodeId:n?.nodeId??e.deviceId,connectionId:e.id,status:"closed",health:"stale",baseTransportState:"closed",transportState:"closed",protocolState:"closed",routable:false,promotionEligible:r.promotionEligible,lastSeenAt:Date.now()}}}if(t)return {event:{type:"ConnectionStateProjected",peerId:t.deviceId??e.remoteNodeId??e.id,deviceId:t.deviceId??void 0,deviceIdHint:t.deviceId??e.remoteNodeId??void 0,nodeId:e.remoteNodeId||e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:t.health,transportState:wa(e),activeTransport:e.getTransportStatus().activeTransport,protocolState:t.protocolState,routable:t.routable,promotionEligible:r.promotionEligible,error:t.error,lastSeenAt:Date.now()}};if(r.peerId||r.deviceId)return {event:{type:"ConnectionStateProjected",peerId:r.peerId??r.deviceId??e.remoteNodeId??e.id,deviceId:r.deviceId,nodeId:e.deviceId,connectionId:e.id,ticket:r.ticket,status:e.isClosed?"closed":"connected",health:"healthy",activeTransport:e.getTransportStatus().activeTransport,promotionEligible:r.promotionEligible,scopes:r.scopes,lastSeenAt:Date.now()}};let o=n?.peerId||n?.deviceId||n?.deviceIdHint,s=n?.deviceId,a=n?.deviceIdHint;return !o&&!s&&!a?null:{event:{type:"ConnectionStateProjected",peerId:o,deviceId:s,deviceIdHint:a,nodeId:e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:e.isClosed?"stale":"healthy",activeTransport:e.getTransportStatus().activeTransport,promotionEligible:r.promotionEligible,lastSeenAt:Date.now()}}}function mr(r,e){let t=r.activeConnectionId||r.candidateConnectionIds?.[0]||void 0,n=e.mapRustPeerStatus(r.status),i=String(n).trim().toLowerCase(),o=typeof r.readinessState=="string"&&r.readinessState.trim().length>0,s=e.mapRustPeerHealth(r.health),a=e.localTerminalClosed===true&&!!t,c=tn({source:"rust-session",activeConnectionId:t,activeTransportStableId:r.activeTransportStableId,sessionStatusNormalized:i,mappedHealth:s,activeTransport:r.activeTransport,parallelTransport:r.parallelTransport,routeReady:e.webRtcApplicationRouteReady}),d=o?r.readinessState==="routable":!!r.settledReady,p=a?false:e.trustProjection?e.trustProjection.routable&&e.applicationRouteReady:d&&e.applicationRouteReady,u=r.status==="connecting",g=lr({settledReady:p,hasActiveConnection:!!t,rustStatusIsConnecting:u}),f=mi({webRtcDataPlaneLive:c.webRtcDataPlaneLive,routeReady:c.routeReady,activeTransport:r.activeTransport,parallelTransport:r.parallelTransport});return {event:{type:"ConnectionStateProjected",peerId:r.peerId??e.transientPeerId??e.anonymousSpacePeerId,deviceId:e.trustProjection?.deviceId??r.deviceId??void 0,deviceIdHint:r.deviceIdHint,nodeId:r.nodeId,connectionId:t,status:a?"closed":e.applicationRouteFailed?"failed":p?"connected":n,health:a||e.applicationRouteFailed?"stale":e.trustProjection?.health??s,generation:r.transportGeneration,baseTransportState:a?"closed":pr({hasActiveConnection:!!t,rustStatusIsConnecting:u,mappedStatusIsTerminal:n==="closed"||n==="failed"||n==="disconnected"}),admissionState:a?"unknown":p||t?"admitted":"unknown",transportState:a?"closed":t?"connected":r.status==="connecting"?"connecting":"closed",protocolState:a?"closed":g,routable:p,activeTransportStableId:a?void 0:r.activeTransportStableId??void 0,transportGeneration:r.transportGeneration,activeTransport:a?void 0:f.activeTransport,fallbackTransport:a?void 0:f.fallbackTransport,parallelTransport:a?void 0:f.parallelTransport,webrtcState:a?"closed":ur({routeReady:c.routeReady,webRtcDataPlaneLive:c.webRtcDataPlaneLive,anyWebRtcTransportLabel:c.anyWebRtcTransportLabel}),promotionEligible:e.promotionEligible,scopes:e.sessionScopes,error:a?"local-transport-closed":e.applicationRouteFailed?"application-route-timeout":e.trustProjection?.error??(p?void 0:r.error??void 0),clearError:p,lastSeenAt:r.lastSeenAtMs},clearApplicationRouteFailure:!a&&e.applicationRouteReady&&t?t:void 0}}function Pa(r){return !(!r.projectedDeviceId&&!r.projectedDeviceIdHint&&!r.existingProjection&&!r.anonymousTerminalProjectionAllowed&&!r.localTerminalClosed)}function fr(r,e){if(!Pa(e))return null;let t=e.localTerminalClosed===true,n=e.terminalState||t,i=n?false:e.trustProjection?e.trustProjection.routable:r.routable,o=i&&e.applicationRouteReady,s=t?"closed":e.terminalState?r.protocolState??"closed":o?"routable":r.transportState==="connected"?"transport-only":e.trustProjection?.protocolState??r.protocolState,a=n?t?"local-transport-closed":r.error??r.lastDisconnectReason??e.trustProjection?.error:e.trustProjection?.error??r.error,c=n?"stale":e.trustProjection?.health??(o||r.transportState==="connected"?"healthy":r.state==="failed"||r.state==="closed"?"stale":"unknown"),d=tn({source:"backend-state",activeTransport:r.activeTransport,parallelTransport:r.parallelTransport,routeReady:e.webRtcApplicationRouteReady}),p=mi({webRtcDataPlaneLive:d.webRtcDataPlaneLive,routeReady:d.routeReady,activeTransport:r.activeTransport,parallelTransport:r.parallelTransport});return {event:{type:"ConnectionStateProjected",peerId:e.existingProjection?.peerId??(e.anonymousTerminalProjectionAllowed?r.remoteNodeId??r.connectionId:void 0),deviceId:e.projectedDeviceId,deviceIdHint:e.projectedDeviceIdHint,nodeId:r.remoteNodeId??e.existingProjection?.nodeId??void 0,connectionId:r.connectionId,status:t?"closed":r.state==="connected"?"connected":r.state==="connecting"||r.state==="new"?"connecting":r.state==="failed"?"failed":r.state==="closed"?"closed":"disconnected",health:c,generation:r.transportGeneration,baseTransportState:n?"closed":r.transportState==="connected"?"connected":r.transportState==="connecting"||r.state==="connecting"||r.state==="new"?"connecting":r.transportState==="failed"?"degraded":"unknown",admissionState:i||r.readinessState==="routable"?"admitted":n?"unknown":"pending",transportState:t?"closed":r.transportState,protocolState:s,webrtcState:gr({terminal:n,activeIsWebRtc:d.webRtcDataPlaneLive,routeReady:d.routeReady,parallelIsWebRtc:f(r.parallelTransport)}),routable:o,activeTransportStableId:t?void 0:r.activeTransportStableId??void 0,transportGeneration:r.transportGeneration,activeTransport:t?void 0:p.activeTransport,fallbackTransport:t?void 0:p.fallbackTransport,parallelTransport:t?void 0:p.parallelTransport,error:a,lastAuthoritativeEventAt:r.updatedAt??Date.now(),lastSeenAt:r.updatedAt??Date.now()}}}function yr(r,e,t){let n=Ra(e,{status:r.status,health:r.health,routable:r.routable,protocolState:r.protocolState},t);return n?{...r,...n}:r}function Ra(r,e,t){if(!r||r.isClosed)return null;let{activeTransport:n,parallelTransport:i}=r.getTransportStatus();if(!(f(n)||f(i))||!r.getWebRTCTransport()||e.status==="closed"||e.status==="failed"||e.status==="disconnected")return null;let c=t.applicationRouteReady&&(e.routable===true||e.protocolState==="routable"),d=t.webRtcApplicationRouteReady;return {status:e.status==="connected"||c?"connected":e.status,health:e.health==="stale"?"healthy":e.health,baseTransportState:"connected",transportState:"connected",protocolState:c?"routable":e.protocolState,webrtcState:d?"ready":"route-probing",routable:c,activeTransport:d?n:"iroh-relay",fallbackTransport:i,parallelTransport:d?i:"webrtc",clearError:c&&d,lastTransientEventAt:Date.now()}}var fi=2e3,yi=3e3,nn=class{constructor(e=fi,t=yi){this.tsGraceMs=e;this.rustGraceMs=t;this.tsOrphanSince=new Map;this.rustOrphanSince=new Map;this.reportedRustOrphans=new Set;}evaluateTsOrphans(e,t){let n=new Set(e);for(let o of [...this.tsOrphanSince.keys()])n.has(o)||this.tsOrphanSince.delete(o);for(let o of n)this.tsOrphanSince.has(o)||this.tsOrphanSince.set(o,t);let i=[];for(let o of n){let s=this.tsOrphanSince.get(o);s!==void 0&&t-s>=this.tsGraceMs&&i.push(o);}return {toDisconnect:i}}evaluateRustOrphans(e,t){let n=new Set(e);for(let o of [...this.rustOrphanSince.keys()])n.has(o)||(this.rustOrphanSince.delete(o),this.reportedRustOrphans.delete(o));for(let o of n)this.rustOrphanSince.has(o)||this.rustOrphanSince.set(o,t);let i=[];for(let o of n){let s=this.rustOrphanSince.get(o);s!==void 0&&t-s>=this.rustGraceMs&&!this.reportedRustOrphans.has(o)&&(this.reportedRustOrphans.add(o),i.push(o));}return {toReport:i}}clear(){this.tsOrphanSince.clear(),this.rustOrphanSince.clear(),this.reportedRustOrphans.clear();}};function vr(r){let e=String(r??"").trim().toLowerCase();return e==="connected"||e==="connecting"||e==="new"}function _a(r){let e=String(r.state??"").trim().toLowerCase();return e==="connected"||e==="connecting"||e==="new"}function vi(r){return r.activeConnectionId||r.candidateConnectionIds?.[0]||void 0}function Ta(r,e,t){return e.some(i=>vi(i)===r&&vr(i.status))?true:t.some(i=>i.connectionId===r&&_a(i))}function Aa(r,e){return r.routable===true&&(r.connectionId===e||r.connectionIds.includes(e))}function ka(r){let e=[],t=[];if(r.hasRustProjection)for(let[n,i]of r.connections)i.isClosed||Ta(n,r.rustSessions,r.backendStates)||e.push(n);for(let n of r.rustSessions){let i=vi(n);if(!i||!vr(n.status)||!(n.settledReady===true||n.readinessState==="routable"||r.peerStates.some(a=>Aa(a,i))))continue;let s=r.connections.get(i);(!s||s.isClosed)&&t.push(i);}return {orphanTsConnectionIds:e,orphanRustRecordConnectionIds:t}}function Na(r,e,t,n=Date.now()){if(!r.hasRustPeerLifecycleProjection())return t.clear(),{reportedDrift:{orphanTsConnectionIds:[],orphanRustRecordConnectionIds:[]},closedTsConnectionIds:[]};let{toDisconnect:i}=t.evaluateTsOrphans(e.orphanTsConnectionIds,n),o=[];for(let a of i)r.healOrphanTsConnection?.(a),o.push(a);let{toReport:s}=t.evaluateRustOrphans(e.orphanRustRecordConnectionIds,n);return {reportedDrift:{orphanTsConnectionIds:e.orphanTsConnectionIds,orphanRustRecordConnectionIds:s},closedTsConnectionIds:o}}var on=class{constructor(e){this.run=e;this.inFlight=null;this.queuedReason=null;this.disposed=false;this.stats={scheduled:0,coalesced:0,ran:0,orphanTsConnection:0,orphanRustRecord:0,orphanTsConnectionHealed:0};}getStats(){return this.stats}dispose(){this.disposed=true,this.queuedReason=null;}recordDrift(e){e.orphanTsConnectionIds.length>0&&(this.stats.orphanTsConnection+=e.orphanTsConnectionIds.length,c("[Client][PEER-RECONCILE] orphan_ts_connection",{count:e.orphanTsConnectionIds.length,connectionIds:e.orphanTsConnectionIds})),e.orphanRustRecordConnectionIds.length>0&&(this.stats.orphanRustRecord+=e.orphanRustRecordConnectionIds.length,c("[Client][PEER-RECONCILE] orphan_rust_record",{count:e.orphanRustRecordConnectionIds.length,connectionIds:e.orphanRustRecordConnectionIds}));}recordSelfHeal(e){e.closedTsConnectionIds.length>0&&(this.stats.orphanTsConnectionHealed+=e.closedTsConnectionIds.length,c("[Client][PEER-RECONCILE] orphan_ts_connection_healed",{count:e.closedTsConnectionIds.length,connectionIds:e.closedTsConnectionIds})),this.recordDrift(e.reportedDrift);}schedule(e){return this.disposed?Promise.resolve([]):(this.stats.scheduled+=1,this.inFlight?(this.stats.coalesced+=1,this.queuedReason=e,c("[Client][PEER-RECONCILE] coalesced",{reason:e}),this.inFlight):(c("[Client][PEER-RECONCILE] started",{reason:e}),this.inFlight=this.executeRun(e),this.inFlight))}async executeRun(e){let t=e;try{for(;;){this.stats.ran+=1;let n=await this.run(t);c("[Client][PEER-RECONCILE] finished",{reason:t,stats:this.getStats()});let i=this.queuedReason;if(this.queuedReason=null,this.disposed)return [];if(!i)return n;t=i,c("[Client][PEER-RECONCILE] rerun",{reason:t});}}finally{this.inFlight=null;}}};async function br(r,e){let t=r.hasRustPeerLifecycleProjection(),n=false,i=[];if(r.wasmClient&&typeof r.wasmClient.peer_sessions=="function"){let p=await r.wasmClient.peer_sessions();Array.isArray(p)&&(i=p,p.forEach(u=>{let g=vi(u);if(!r.hasResolvablePeerIdentity({deviceId:u.deviceId,deviceIdHint:u.deviceIdHint,nodeId:u.nodeId,connectionId:g})){c("[Client][PEER-SNAPSHOT] skipping rust session without identity",{status:u.status,health:u.health,settledReady:u.settledReady});return}r.applyComposedRustSession(u),n=true;}));}(await r.searchDevices().catch(()=>[])).forEach(p=>{if(!r.hasResolvablePeerIdentity({deviceId:p.deviceId??null,nodeId:p.nodeId??null})){c("[Client][PEER-SNAPSHOT] skipping device projection without identity",{deviceName:p.deviceName??null,online:p.online??null});return}r.peerLifecycle.upsertDevice(p);}),t||r.connections.forEach(p=>{r.syncConnectionPeerLifecycle(p);});let s=await r.signaling.getConnectionStates().catch(()=>[]);s.forEach(p=>{r.applyBackendConnectionState(p);});let a=r.peerLifecycle.list(),c$1=ka({hasRustProjection:t,connections:r.connections,rustSessions:i,backendStates:s,peerStates:a}),d=r.getOrphanDriftTracker?.();if(d&&r.healOrphanTsConnection){let p=Na(r,c$1,d);r.recordReconciliationSelfHeal?.(p);}else r.recordReconciliationDrift?.(c$1);return t&&!n&&s.length===0,a}function bi(r,e){return r&&typeof r.supportsRustPeerLifecycleProjection=="function"&&r.supportsRustPeerLifecycleProjection()?true:!!(e&&typeof e.peer_sessions=="function")}var rn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.orphanDriftTracker=new nn(t.orphanReconciliationGrace?.tsConnectionMs??fi,t.orphanReconciliationGrace?.rustRecordMs??yi),this.scheduler=new on(n=>br(this.asReconciliationHost())),this.ctx.registerDisposer(()=>this.dispose());}schedule(e){return this.scheduler.schedule(e)}dispose(){this.disposed=true,this.scheduler.dispose(),this.orphanDriftTracker.clear();}getStats(){return this.scheduler.getStats()}hasRustPeerLifecycleProjection(){return bi(this.deps.getSignaling(),this.getPeerSessionReader())}dispatchLiveConnectionProjection(e,t){if(this.disposed)return;let n=hr({connection:e,...t});n&&this.dispatchComposedConnectionState(n.event,e,{applicationRouteReady:t.applicationRouteReady,webRtcApplicationRouteReady:t.webRtcApplicationRouteReady});}applyConnectionTrustProjection(e){if(this.disposed||this.hasRustPeerLifecycleProjection())return;let t=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.deps.getConnectionTrustProjection({connectionId:e.id,nodeId:e.remoteNodeId}),i=this.deps.hasApplicationRouteForConnection(e),o=this.deps.isWebRtcApplicationRouteReadyForConnection(e);if(!n){this.syncConnectionPeerLifecycle(e);return}this.dispatchLiveConnectionProjection(e,{trustProjection:n,promotionEligible:t,applicationRouteReady:i,webRtcApplicationRouteReady:o});}applyBackendConnectionStateSideEffects(e){if(this.disposed||!e?.connectionId||!(e.state==="closed"||e.state==="failed"||e.state==="disconnected"))return;let n=this.ctx.registry.get(e.connectionId)??(e.remoteNodeId?this.deps.getConnectionForPeer(void 0,e.remoteNodeId):null);n&&!n.isClosed&&this.disconnectBestEffort(n);}applyBackendConnectionState(e){if(this.disposed||!e?.connectionId)return;let t=this.deps.getConnectionTrustProjection({connectionId:e.connectionId,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.remoteNodeId??void 0}),n=this.getPeerState(e.connectionId)??(e.remoteNodeId?this.getPeerState(e.remoteNodeId):void 0),i=e.deviceId??t?.deviceId??n?.deviceId??void 0,o=e.deviceIdHint??n?.deviceIdHint??void 0,s=e.state==="closed"||e.state==="failed"||e.state==="disconnected",a=this.deps.hasLocalTerminalConnectionClose(e.connectionId),c$1=(s||a)&&!!(e.connectionId||e.remoteNodeId);if(!i&&!o&&!n&&!c$1)return;c("[Client] applyBackendConnectionState",{connectionId:e.connectionId,deviceId:i??null,deviceIdHint:o??null,remoteNodeId:e.remoteNodeId??null,state:e.state,transportState:e.transportState??null,protocolState:e.protocolState??null,routable:e.routable??null,updatedAt:e.updatedAt??null,error:e.error??null,mappedPeerId:n?.peerId??null});let d=this.ctx.registry.get(e.connectionId)??(e.remoteNodeId?this.deps.getConnectionForPeer(void 0,e.remoteNodeId):null),p=this.deps.hasApplicationRouteForConnection(d),u=this.deps.isWebRtcApplicationRouteReadyForConnection(d),g=fr(e,{trustProjection:t,existingProjection:n,applicationRouteReady:p,webRtcApplicationRouteReady:u,terminalState:s,localTerminalClosed:a,anonymousTerminalProjectionAllowed:c$1,projectedDeviceId:i,projectedDeviceIdHint:o});g&&this.dispatchComposedConnectionState(g.event,d,{applicationRouteReady:p,webRtcApplicationRouteReady:u});}applyComposedRustSession(e){if(this.disposed)return;let t=e.activeConnectionId||e.candidateConnectionIds?.[0],n=this.deps.hasLocalTerminalConnectionClose(t),i=e.scopes??[],o=!!e.nodeId&&this.deps.sessionTokenApprovedNodes().has(e.nodeId)||!!t&&this.deps.sessionTokenApprovedConnectionIds().has(t),s=!e.peerId&&!e.deviceId&&!e.deviceIdHint&&o?`session-token:${i[0]??"unscoped"}:${e.nodeId??t}`:void 0,a=!e.peerId&&!e.deviceId&&!e.deviceIdHint&&this.ctx.discoveryMode==="space"?e.nodeId??t:void 0,c=this.deps.resolvePromotionEligibility({connectionId:t||void 0,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.nodeId??void 0}),d=this.deps.getConnectionTrustProjection({connectionId:t||void 0,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.nodeId??void 0}),p=this.deps.getConnectionForPeer(t||void 0,e.nodeId??void 0),u=this.deps.hasApplicationRouteForConnection(p),g=!!t&&!u&&this.deps.hasApplicationRouteFailure(t),f=String(this.mapRustPeerStatus(e.status)).trim().toLowerCase(),y=tn({source:"rust-session",activeConnectionId:t,activeTransportStableId:e.activeTransportStableId,sessionStatusNormalized:f,mappedHealth:this.mapRustPeerHealth(e.health),activeTransport:e.activeTransport,parallelTransport:e.parallelTransport,routeReady:false}).webRtcDataPlaneLive&&this.deps.isWebRtcApplicationRouteReadyForConnection(p),C=mr(e,{trustProjection:d,promotionEligible:c,liveConnection:p,applicationRouteReady:u,webRtcApplicationRouteReady:y,applicationRouteFailed:g,localTerminalClosed:n,mapRustPeerStatus:I=>this.mapRustPeerStatus(I),mapRustPeerHealth:I=>this.mapRustPeerHealth(I),peerId:e.peerId,transientPeerId:s,anonymousSpacePeerId:a,sessionScopes:i});C.clearApplicationRouteFailure&&this.deps.clearApplicationRouteFailure(C.clearApplicationRouteFailure),this.dispatchComposedConnectionState(C.event,p,{applicationRouteReady:u,webRtcApplicationRouteReady:y});}syncConnectionPeerLifecycle(e){if(this.disposed)return;let t=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.getPeerState(e.id)||this.listPeerStates().find(i=>i.connectionIds.includes(e.id)||i.nodeId===e.deviceId);this.dispatchLiveConnectionProjection(e,{trustProjection:null,promotionEligible:t,existingProjection:n,applicationRouteReady:this.deps.hasApplicationRouteForConnection(e),webRtcApplicationRouteReady:this.deps.isWebRtcApplicationRouteReadyForConnection(e)});}mapRustPeerStatus(e){switch((e||"").toLowerCase()){case "connected":return "connected";case "connecting":case "pending":return "connecting";case "failed":return "failed";case "closing":case "closed":return "closed";default:return "disconnected"}}mapRustPeerHealth(e){switch((e||"").toLowerCase()){case "healthy":return "healthy";case "suspect":return "suspect";case "stale":return "stale";default:return "unknown"}}asReconciliationHost(){return {hasRustPeerLifecycleProjection:()=>this.hasRustPeerLifecycleProjection(),wasmClient:this.getPeerSessionReader(),signaling:this.deps.getSignaling(),peerLifecycle:this.deps.peerLifecycle,connections:this.ctx.registry,discoveryMode:this.ctx.discoveryMode,sessionTokenApprovedNodes:this.deps.sessionTokenApprovedNodes(),sessionTokenApprovedConnectionIds:this.deps.sessionTokenApprovedConnectionIds(),hasResolvablePeerIdentity:e=>this.hasResolvablePeerIdentity(e),applyComposedRustSession:e=>this.applyComposedRustSession(e),applyBackendConnectionState:e=>this.applyBackendConnectionState(e),searchDevices:()=>this.deps.searchDevices(),syncConnectionPeerLifecycle:e=>this.syncConnectionPeerLifecycle(e),getOrphanDriftTracker:()=>this.orphanDriftTracker,healOrphanTsConnection:e=>this.deps.healOrphanTsConnection(e),recordReconciliationSelfHeal:e=>this.scheduler.recordSelfHeal(e),recordReconciliationDrift:e=>this.scheduler.recordDrift(e)}}getPeerSessionReader(){return this.ctx.wasmClient&&typeof this.ctx.wasmClient=="object"?this.ctx.wasmClient:null}hasResolvablePeerIdentity(e){if(e.deviceId||e.deviceIdHint)return true;let t=[e.nodeId,e.connectionId].map(o=>typeof o=="string"?o.trim():"").filter(o=>o.length>0);if(this.ctx.discoveryMode==="space"&&t.length>0)return true;let n=this.deps.sessionTokenApprovedNodes(),i=this.deps.sessionTokenApprovedConnectionIds();return t.some(o=>!!this.getPeerState(o)||n.has(o)||i.has(o))}dispatchComposedConnectionState(e,t,n){let i=yr(e,t,n);this.deps.peerLifecycle.dispatch(i);}getPeerState(e){let t=this.deps.peerLifecycle;return typeof t.get=="function"?t.get(e):void 0}listPeerStates(){let e=this.deps.peerLifecycle;return typeof e.list=="function"?e.list():[]}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}};function Cr(r){return new Ci({getContext:()=>r.getClientContext(),getWasmClient:()=>r.wasmClient,getSignaling:()=>r.signaling,getConnections:()=>r.registry.values(),disconnectNode:e=>r.runtimeConnections.disconnectNode(e),registerDisposer:e=>r.lifecycleScope.register(e),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),getOrphanReconciliationGrace:()=>r.options?.orphanReconciliationGrace,getSessionTokenApprovedNodes:()=>r.sessionTokens.getApprovedNodes(),getSessionTokenApprovedConnectionIds:()=>r.sessionTokens.getApprovedConnectionIds(),resolvePromotionEligibility:e=>r.connectionChannelPolicy.resolvePromotionEligibility(e),getConnectionTrustProjection:e=>r.connectionTrust.getProjection(e),getConnectionForPeer:(e,t)=>r.registry.getForPeer(e??void 0,t??void 0),hasApplicationRouteForConnection:e=>r.transportServices.hasApplicationRouteForConnectionSnapshot(e,e?.id,e?.remoteNodeId),isWebRtcApplicationRouteReadyForConnection:e=>r.transportServices.isWebRtcApplicationRouteReadyForConnectionSnapshot(e),hasLocalTerminalConnectionClose:e=>r.registry.hasLocalTerminalClose(e),hasApplicationRouteFailure:e=>r.transportServices.hasApplicationRouteFailure(e),clearApplicationRouteFailure:e=>r.transportServices.clearApplicationRouteFailure(e),searchDevices:()=>r.deviceDirectory.searchDevices(),healOrphanTsConnection:e=>r.connectionLifecycle.healOrphanTsConnection(e)})}var Ci=class{constructor(e){this.host=e;this.store=new en;this.host.registerDisposer(()=>{this.store.dispose();});}get projection(){return this._projection||(this._projection=new rn(this.host.getContext(),{orphanReconciliationGrace:this.host.getOrphanReconciliationGrace(),sessionTokenApprovedNodes:()=>this.host.getSessionTokenApprovedNodes(),sessionTokenApprovedConnectionIds:()=>this.host.getSessionTokenApprovedConnectionIds(),resolvePromotionEligibility:e=>this.host.resolvePromotionEligibility(e),getConnectionTrustProjection:e=>this.host.getConnectionTrustProjection(e),getConnectionForPeer:(e,t)=>this.host.getConnectionForPeer(e,t),hasApplicationRouteForConnection:e=>this.host.hasApplicationRouteForConnection(e),isWebRtcApplicationRouteReadyForConnection:e=>this.host.isWebRtcApplicationRouteReadyForConnection(e),hasLocalTerminalConnectionClose:e=>this.host.hasLocalTerminalConnectionClose(e),hasApplicationRouteFailure:e=>this.host.hasApplicationRouteFailure(e),clearApplicationRouteFailure:e=>this.host.clearApplicationRouteFailure(e),searchDevices:()=>this.host.searchDevices(),healOrphanTsConnection:e=>this.host.healOrphanTsConnection(e),getSignaling:()=>this.host.getSignaling(),peerLifecycle:this.store})),this._projection}get client(){return this._client||(this._client=new Jt(this.store,{getWasmClient:()=>this.host.getWasmClient(),getConnections:()=>this.host.getConnections(),disconnectNode:e=>this.host.disconnectNode(e),hasRustPeerLifecycleProjection:()=>this.host.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>this.projection.schedule(e),scheduleRefreshPeerSnapshot:()=>this.projection.schedule("peer-lifecycle-client").then(()=>{}),registerDisposer:e=>this.host.registerDisposer(e),resolvePromotionEligibility:e=>this.host.resolvePromotionEligibility(e)})),this._client}getProjectionStats(){return this._projection?.getStats()}watchPeerStates(e){return this.store.watch?.(e)??(()=>{})}getPeerState(e){return this.store.get?.(e)}listConnectedPeers(){return this.store.listConnected?.()??[]}listPeerStates(){return this.store.list?.()??[]}getPeerScopes(e){return this.getPeerState(e)?.scopes??[]}getPeerStatus(e){return this.getPeerState(e)?.status}hasPeerScopes(e){return this.store.hasScopes?.(e)??this.getPeerScopes(e).length>0}isSamePeer(e,t){let n=this.getPeerState(e),i=this.getPeerState(t);return !!n&&!!i&&n.peerId===i.peerId}getPeerHealth(e){return this.getPeerState(e)?.health??"unknown"}isPeerPromotionEligible(e){return this.client.isPeerPromotionEligible(e)}addPeerScope(e,t="persistent"){return this.client.addPeerScope(e,t)}releasePeerScope(e,t){return this.client.releasePeerScope(e,t)}clearManualDisconnectProjection(e){this.client.clearManualDisconnectProjection(e);}disconnectPeer(e,t="persistent"){return this.client.disconnectPeer(e,t)}forceDisconnectPeer(e){return this.client.forceDisconnectPeer(e)}applyDiscoveredDevice(e){this.store.upsertDevice?.(e);}};function Da(r){return fo({get wasmClient(){return r.getWasmClient()},get roomCreationMode(){return r.getRoomCreationMode()},get appLimits(){return r.getAppLimits()},ensureAuthenticated:e=>r.ensureAuthenticated(e),getTicket:()=>r.getTicket(),getNodeId:()=>r.getNodeId(),connect:(e,t)=>r.connect(e,t),refreshHostedAppSettings:e=>r.refreshHostedAppSettings(e),usesDirectRoomBackend:()=>r.usesDirectRoomBackend(),getRoomBackendTag:()=>r.getRoomBackendTag()})}function Sr(r){return Da({getWasmClient:()=>r.wasmClient,getRoomCreationMode:()=>r.getRoomCreationMode(),getAppLimits:()=>r.getAppLimits(),ensureAuthenticated:e=>r.auth.ensureAuthenticated(e),getTicket:()=>r.runtimeIdentity.getTicket(),getNodeId:()=>r.runtimeIdentity.getNodeId(),connect:(e,t)=>r.connectionDialer.connect(e,t),refreshHostedAppSettings:e=>r.signalingBackendController.refreshHostedAppSettings(e),usesDirectRoomBackend:()=>r.runtimeStatus.usesDirectRoomBackend(),getRoomBackendTag:()=>r.runtimeStatus.getRoomBackendTag()})}var sn=class{constructor(e){this.ctx=e;this.browserBackgrounded=false;this.disposed=false;this.removeBrowserListeners=null;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.removeBrowserListeners?.(),this.removeBrowserListeners=null);}installListeners(){if(this.disposed||this.removeBrowserListeners||typeof document>"u"||typeof window>"u")return;let e=()=>{if(this.disposed)return;let n=document.visibilityState==="hidden";this.handleBackgroundState(n,"visibilitychange");},t=()=>{this.disposed||this.handleBackgroundState(false,"pageshow");};e(),document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",t),this.removeBrowserListeners=()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",t);};}async handleBackgroundState(e,t){if(this.disposed)return;let n=this.browserBackgrounded!==e;this.browserBackgrounded=e;let i=this.ctx.wasmClient;if(i&&typeof i.set_app_backgrounded=="function")try{await i.set_app_backgrounded(e);}catch(o){console.warn("[Client][APP] Failed to propagate background state to wasm runtime",{backgrounded:e,source:t,error:o});}this.disposed||!e&&n&&this.reconcileConnectionsAfterForeground(t);}reconcileConnectionsAfterForeground(e){if(!this.disposed)for(let t of this.ctx.registry.values()){if(t.isClosed)continue;let n=t.getUpgradeState();d("[Client][APP] Foreground recovery reconcile",{source:e,connectionId:t.id,remoteNodeId:t.remoteNodeId,upgradeState:n}),n!=="upgrading"&&t.handleAppForeground();}}};var an=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Managed transport dialer is disposed")}normalizeConnectResult(e,t,n,i){let o=e&&typeof e=="object"?e:{},s=typeof o.connectionId=="string"&&o.connectionId.trim()?o.connectionId.trim():t,a=typeof o.remoteNodeId=="string"&&o.remoteNodeId.trim()?o.remoteNodeId.trim():n,c=typeof o.deviceId=="string"&&o.deviceId.trim()?o.deviceId.trim():i??null,d=typeof o.deviceIdHint=="string"&&o.deviceIdHint.trim()?o.deviceIdHint.trim():c,p=typeof o.state=="string"&&o.state.trim()?o.state.trim():"connected",u=typeof o.approvedScope=="string"&&o.approvedScope.trim()?o.approvedScope.trim():typeof o.approved_scope=="string"&&o.approved_scope.trim()?o.approved_scope.trim():null;return {connectionId:s,deviceId:c,deviceIdHint:d,remoteNodeId:a,state:p,approvedScope:u}}async ensureWasmManagedTransport(e,t,n){this.assertActive();let i=this.ctx.wasmClient;if(!i||typeof i.connect_device!="function")throw new Error("[Client] WASM managed transport requires connect_device()");let o=n?.timeoutMs??2e4,s=e.trim(),{irohTicket:a,tokenSuffix:c}=se(s),d=c!==null?Ie(a,c):null;if(c!==null&&!d)throw new Error("invalid compound ticket payload for endpoint ticket");let p=typeof d?.t=="string"&&d.t.trim()?d.t.trim():null;if(c!==null&&!p)throw new Error("invalid compound ticket payload for endpoint ticket");let u=await i.endpoint_id_from_ticket(a);this.assertActive();let g=this.deps.getDeterministicConnectionId(u);if(n?.skipIfConnected&&typeof i.is_connected=="function")try{let I=await i.is_connected(u);if(this.assertActive(),I){let k=this.deps.getApprovedScope(g);if(!(c!==null&&!k&&!n?.admissionAlreadyPresented))return {connectionId:g,deviceId:t??null,deviceIdHint:t??null,remoteNodeId:u,state:"connected",approvedScope:k}}}catch(I){if(this.disposed)throw I}let f=await B$1(i.connect_device(t??null,s),o,"wasmClient.connect_device");this.assertActive();let v=this.normalizeConnectResult(f,g,u,t??null),y=v.approvedScope??this.deps.getApprovedScope(v.connectionId);c!==null&&!y&&!n?.admissionAlreadyPresented&&(y=await this.presentSessionTokenToHost(i,u,p,c,t??null,o),this.assertActive());let C=y?{...v,approvedScope:y}:v;if(c!==null&&!C.approvedScope&&!n?.admissionAlreadyPresented)throw new Error("Failed to present session token: session token admission failed");return C}async presentSessionTokenToHost(e,t,n,i,o,s){try{if(typeof e.present_session_token_to_host_with_payload_and_device_id=="function"){let a=await B$1(e.present_session_token_to_host_with_payload_and_device_id(t,n,i,o),s,"wasmClient.present_session_token_to_host_with_payload_and_device_id");return this.normalizeApprovedScope(a)}if(typeof e.present_session_token_to_host_with_payload=="function"){let a=await B$1(e.present_session_token_to_host_with_payload(t,n,i),s,"wasmClient.present_session_token_to_host_with_payload");return this.normalizeApprovedScope(a)}if(typeof e.present_session_token_to_host=="function"){let a=await B$1(e.present_session_token_to_host(t,n),s,"wasmClient.present_session_token_to_host");return this.normalizeApprovedScope(a)}}catch(a){let c=a instanceof Error?a.message:String(a);throw new Error(`Failed to present session token: ${c}`)}return null}normalizeApprovedScope(e){return typeof e=="string"&&e.trim()?e.trim():null}isLocalIrohRuntimeNotInitializedError(e){let t=e instanceof Error?e.message:typeof e=="string"?e:String(e?.message??e??"");return /\bIroh node not initialized\b|\bNode not initialized\b/i.test(t)}};var et=class r{static __wrap(e){let t=Object.create(r.prototype);return t.__wbg_ptr=e,Ir.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Ir.unregister(this),e}free(){let e=this.__destroy_into_raw();l.__wbg_bistream_free(e,0);}get applicationCryptoWrapped(){return l.bistream_applicationCryptoWrapped(this.__wbg_ptr)!==0}get endpoint_id(){let e,t;try{let o=l.__wbindgen_add_to_stack_pointer(-16);l.bistream_endpoint_id(o,this.__wbg_ptr);var n=M().getInt32(o+0,!0),i=M().getInt32(o+4,!0);return e=n,t=i,H(n,i)}finally{l.__wbindgen_add_to_stack_pointer(16),l.__wbindgen_export4(e,t,1);}}get recv(){let e=l.bistream_recv(this.__wbg_ptr);return R(e)}get send(){let e=l.bistream_send(this.__wbg_ptr);return R(e)}};Symbol.dispose&&(et.prototype[Symbol.dispose]=et.prototype.free);var tt=class r{static __wrap(e){let t=Object.create(r.prototype);return t.__wbg_ptr=e,wr.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,wr.unregister(this),e}free(){let e=this.__destroy_into_raw();l.__wbg_intounderlyingsink_free(e,0);}abort(e){let t=this.__destroy_into_raw(),n=l.intounderlyingsink_abort(t,w(e));return R(n)}close(){let e=this.__destroy_into_raw(),t=l.intounderlyingsink_close(e);return R(t)}write(e){let t=l.intounderlyingsink_write(this.__wbg_ptr,w(e));return R(t)}};Symbol.dispose&&(tt.prototype[Symbol.dispose]=tt.prototype.free);var nt=class r{static __wrap(e){let t=Object.create(r.prototype);return t.__wbg_ptr=e,Pr.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Pr.unregister(this),e}free(){let e=this.__destroy_into_raw();l.__wbg_intounderlyingsource_free(e,0);}cancel(){let e=this.__destroy_into_raw();l.intounderlyingsource_cancel(e);}pull(e){let t=l.intounderlyingsource_pull(this.__wbg_ptr,w(e));return R(t)}};Symbol.dispose&&(nt.prototype[Symbol.dispose]=nt.prototype.free);var it=class r{static __wrap(e){let t=Object.create(r.prototype);return t.__wbg_ptr=e,Rr.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Rr.unregister(this),e}free(){let e=this.__destroy_into_raw();l.__wbg_peerunistream_free(e,0);}get applicationCryptoWrapped(){return l.peerunistream_applicationCryptoWrapped(this.__wbg_ptr)!==0}get writable(){let e=l.peerunistream_writable(this.__wbg_ptr);return R(e)}};Symbol.dispose&&(it.prototype[Symbol.dispose]=it.prototype.free);var Ee=class r{static __wrap(e){let t=Object.create(r.prototype);return t.__wbg_ptr=e,Si.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Si.unregister(this),e}free(){let e=this.__destroy_into_raw();l.__wbg_wasmclient_free(e,0);}add_peer_scope(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_add_peer_scope(this.__wbg_ptr,n,i,o,s);return R(a)}bind_connection_device_id(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_bind_connection_device_id(this.__wbg_ptr,n,i,o,s);return R(a)}clear_session_tokens(){l.wasmclient_clear_session_tokens(this.__wbg_ptr);}connect(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_connect(this.__wbg_ptr,t,n);return R(i)}connect_device(e,t){var n=B(e)?0:S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b;let o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_connect_device(this.__wbg_ptr,n,i,o,s);return R(a)}connection_state(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_connection_state(this.__wbg_ptr,t,n);return R(i)}connection_states(){let e=l.wasmclient_connection_states(this.__wbg_ptr);return R(e)}create_room(e,t,n,i,o,s){let a=S(e,l.__wbindgen_export,l.__wbindgen_export2),c=b,d=S(t,l.__wbindgen_export,l.__wbindgen_export2),p=b,u=S(n,l.__wbindgen_export,l.__wbindgen_export2),g=b,f=S(i,l.__wbindgen_export,l.__wbindgen_export2),v=b,y=S(o,l.__wbindgen_export,l.__wbindgen_export2),C=b,I=l.wasmclient_create_room(this.__wbg_ptr,a,c,d,p,u,g,f,v,y,C,B(s)?Number.MAX_SAFE_INTEGER:s>>>0);return R(I)}create_session(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_create_session(this.__wbg_ptr,t,n);return R(i)}delete_device(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_delete_device(this.__wbg_ptr,n,i,o,s);return R(a)}devices_with_status(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_devices_with_status(this.__wbg_ptr,t,n);return R(i)}disconnect(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_disconnect(this.__wbg_ptr,t,n);return R(i)}disconnect_device(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b;var o=B(t)?0:S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b;let a=l.wasmclient_disconnect_device(this.__wbg_ptr,n,i,o,s);return R(a)}disconnect_transient(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_disconnect_transient(this.__wbg_ptr,t,n);return R(i)}endpoint_id_from_ticket(e){let t,n;try{let p=l.__wbindgen_add_to_stack_pointer(-16),u=S(e,l.__wbindgen_export,l.__wbindgen_export2),g=b;l.wasmclient_endpoint_id_from_ticket(p,this.__wbg_ptr,u,g);var i=M().getInt32(p+0,!0),o=M().getInt32(p+4,!0),s=M().getInt32(p+8,!0),a=M().getInt32(p+12,!0),c=i,d=o;if(a)throw c=0,d=0,R(s);return t=c,n=d,H(c,d)}finally{l.__wbindgen_add_to_stack_pointer(16),l.__wbindgen_export4(t,n,1);}}endpoint_ticket(){let e=l.wasmclient_endpoint_ticket(this.__wbg_ptr);return R(e)}endpoint_ticket_with_token(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_endpoint_ticket_with_token(this.__wbg_ptr,n,i,t);return R(o)}force_reconnect_snapshot(){l.wasmclient_force_reconnect_snapshot(this.__wbg_ptr);}get_members(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b,p=l.wasmclient_get_members(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}heartbeat_tick(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b,p=l.wasmclient_heartbeat_tick(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}incoming_streams(){let e=l.wasmclient_incoming_streams(this.__wbg_ptr);return R(e)}init_iroh(e){var t=B(e)?0:Ii(e,l.__wbindgen_export),n=b;let i=l.wasmclient_init_iroh(this.__wbg_ptr,t,n);return R(i)}iroh_path_kind(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_iroh_path_kind(this.__wbg_ptr,t,n);return R(i)}iroh_secret_key(){let e=l.wasmclient_iroh_secret_key(this.__wbg_ptr);return R(e)}iroh_transport_rtt_ms(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_iroh_transport_rtt_ms(this.__wbg_ptr,t,n);return R(i)}is_auto_connect_excluded(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b;return l.wasmclient_is_auto_connect_excluded(this.__wbg_ptr,t,n)!==0}is_connected(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_is_connected(this.__wbg_ptr,t,n);return R(i)}join_room(e,t,n,i,o){let s=S(e,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(t,l.__wbindgen_export,l.__wbindgen_export2),d=b,p=S(n,l.__wbindgen_export,l.__wbindgen_export2),u=b,g=S(i,l.__wbindgen_export,l.__wbindgen_export2),f=b,v=S(o,l.__wbindgen_export,l.__wbindgen_export2),y=b,C=l.wasmclient_join_room(this.__wbg_ptr,s,a,c,d,p,u,g,f,v,y);return R(C)}leave_room(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b,p=l.wasmclient_leave_room(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}list_managed_connections(){let e=l.wasmclient_list_managed_connections(this.__wbg_ptr);return R(e)}constructor(e,t){try{let s=l.__wbindgen_add_to_stack_pointer(-16),a=S(e,l.__wbindgen_export,l.__wbindgen_export2),c=b,d=S(t,l.__wbindgen_export,l.__wbindgen_export2),p=b;l.wasmclient_new(s,a,c,d,p);var n=M().getInt32(s+0,!0),i=M().getInt32(s+4,!0),o=M().getInt32(s+8,!0);if(o)throw R(i);return this.__wbg_ptr=n,Si.register(this,this.__wbg_ptr,this),this}finally{l.__wbindgen_add_to_stack_pointer(16);}}static newWithAppTag(e,t){try{let s=l.__wbindgen_add_to_stack_pointer(-16),a=S(e,l.__wbindgen_export,l.__wbindgen_export2),c=b,d=S(t,l.__wbindgen_export,l.__wbindgen_export2),p=b;l.wasmclient_newWithAppTag(s,a,c,d,p);var n=M().getInt32(s+0,!0),i=M().getInt32(s+4,!0),o=M().getInt32(s+8,!0);if(o)throw R(i);return r.__wrap(n)}finally{l.__wbindgen_add_to_stack_pointer(16);}}node_addr(){let e=l.wasmclient_node_addr(this.__wbg_ptr);return R(e)}open_bi(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_open_bi(this.__wbg_ptr,t,n);return R(i)}open_native_main_control_bi(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_open_native_main_control_bi(this.__wbg_ptr,t,n);return R(i)}open_peer_bi(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_open_peer_bi(this.__wbg_ptr,n,i,B(t)?Number.MAX_SAFE_INTEGER:t>>>0);return R(o)}open_peer_bi_explicit_file_sender(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_open_peer_bi_explicit_file_sender(this.__wbg_ptr,n,i,B(t)?Number.MAX_SAFE_INTEGER:t>>>0);return R(o)}open_peer_bi_transport_only(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_open_peer_bi_transport_only(this.__wbg_ptr,n,i,B(t)?Number.MAX_SAFE_INTEGER:t>>>0);return R(o)}open_peer_native_bi(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=l.wasmclient_open_peer_native_bi(this.__wbg_ptr,i,o,s,a,B(n)?Number.MAX_SAFE_INTEGER:n>>>0);return R(c)}open_peer_uni(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_open_peer_uni(this.__wbg_ptr,n,i,B(t)?Number.MAX_SAFE_INTEGER:t>>>0);return R(o)}open_uni(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_open_uni(this.__wbg_ptr,t,n);return R(i)}peer_scopes(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_peer_scopes(this.__wbg_ptr,t,n);return R(i)}peer_session(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_peer_session(this.__wbg_ptr,t,n);return R(i)}peer_sessions(){let e=l.wasmclient_peer_sessions(this.__wbg_ptr);return R(e)}peer_snapshot(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_peer_snapshot(this.__wbg_ptr,t,n);return R(i)}present_session_token_to_host(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_present_session_token_to_host(this.__wbg_ptr,n,i,o,s);return R(a)}present_session_token_to_host_with_payload(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b;var c=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b;let p=l.wasmclient_present_session_token_to_host_with_payload(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}present_session_token_to_host_with_payload_and_device_id(e,t,n,i){let o=S(e,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=S(t,l.__wbindgen_export,l.__wbindgen_export2),c=b;var d=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),p=b,u=B(i)?0:S(i,l.__wbindgen_export,l.__wbindgen_export2),g=b;let f=l.wasmclient_present_session_token_to_host_with_payload_and_device_id(this.__wbg_ptr,o,s,a,c,d,p,u,g);return R(f)}register_session_token(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b;l.wasmclient_register_session_token(this.__wbg_ptr,i,o,s,a,n);}register_session_token_with_expiry_ms(e,t,n,i){let o=S(e,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=S(t,l.__wbindgen_export,l.__wbindgen_export2),c=b;l.wasmclient_register_session_token_with_expiry_ms(this.__wbg_ptr,o,s,a,c,n,i);}release_peer_scope(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b;var o=B(t)?0:S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b;let a=l.wasmclient_release_peer_scope(this.__wbg_ptr,n,i,o,s);return R(a)}report_managed_connection_settled(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b;var s=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),a=b;let c=l.wasmclient_report_managed_connection_settled(this.__wbg_ptr,i,o,t,s,a);return R(c)}report_transport_status(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b;var c=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b;let p=l.wasmclient_report_transport_status(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}resolve_peer_connection_records(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_resolve_peer_connection_records(this.__wbg_ptr,t,n);return R(i)}revoke_session_token(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b;l.wasmclient_revoke_session_token(this.__wbg_ptr,t,n);}revoke_tokens_by_scope(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_revoke_tokens_by_scope(this.__wbg_ptr,t,n);return R(i)}runtime_policy(){try{let i=l.__wbindgen_add_to_stack_pointer(-16);l.wasmclient_runtime_policy(i,this.__wbg_ptr);var e=M().getInt32(i+0,!0),t=M().getInt32(i+4,!0),n=M().getInt32(i+8,!0);if(n)throw R(t);return R(e)}finally{l.__wbindgen_add_to_stack_pointer(16);}}same_peer(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_same_peer(this.__wbg_ptr,n,i,o,s);return R(a)}search_devices(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_search_devices(this.__wbg_ptr,t,n);return R(i)}send_message(e,t,n,i){let o=S(e,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=S(t,l.__wbindgen_export,l.__wbindgen_export2),c=b;var d=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),p=b,u=B(i)?0:S(i,l.__wbindgen_export,l.__wbindgen_export2),g=b;let f=l.wasmclient_send_message(this.__wbg_ptr,o,s,a,c,d,p,u,g);return R(f)}send_peer(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=Ii(t,l.__wbindgen_export),s=b,a=l.wasmclient_send_peer(this.__wbg_ptr,n,i,o,s);return R(a)}setConnectionApplicationCryptoKey(e,t){try{let o=l.__wbindgen_add_to_stack_pointer(-16),s=S(e,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=Ii(t,l.__wbindgen_export),d=b;l.wasmclient_setConnectionApplicationCryptoKey(o,this.__wbg_ptr,s,a,c,d);var n=M().getInt32(o+0,!0),i=M().getInt32(o+4,!0);if(i)throw R(n)}finally{l.__wbindgen_add_to_stack_pointer(16);}}setConnectionApplicationCryptoRequired(e){try{let i=l.__wbindgen_add_to_stack_pointer(-16),o=S(e,l.__wbindgen_export,l.__wbindgen_export2),s=b;l.wasmclient_setConnectionApplicationCryptoRequired(i,this.__wbg_ptr,o,s);var t=M().getInt32(i+0,!0),n=M().getInt32(i+4,!0);if(n)throw R(t)}finally{l.__wbindgen_add_to_stack_pointer(16);}}set_auth_token(e){var t=B(e)?0:S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b;l.wasmclient_set_auth_token(this.__wbg_ptr,t,n);}set_auto_connect_excluded(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_set_auto_connect_excluded(this.__wbg_ptr,n,i,t);return R(o)}set_offline(e){let t=S(e,l.__wbindgen_export,l.__wbindgen_export2),n=b,i=l.wasmclient_set_offline(this.__wbg_ptr,t,n);return R(i)}start_auto_connect(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b;l.wasmclient_start_auto_connect(this.__wbg_ptr,n,i,o,s);}start_presence_loop(e,t,n,i){let o=S(e,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=S(t,l.__wbindgen_export,l.__wbindgen_export2),c=b,d=S(n,l.__wbindgen_export,l.__wbindgen_export2),p=b;var u=B(i)?0:S(i,l.__wbindgen_export,l.__wbindgen_export2),g=b;l.wasmclient_start_presence_loop(this.__wbg_ptr,o,s,a,c,d,p,u,g);}stop_auth_scoped_activity(){l.wasmclient_stop_auth_scoped_activity(this.__wbg_ptr);}stop_auto_connect(){l.wasmclient_stop_auto_connect(this.__wbg_ptr);}stop_presence_loop(){l.wasmclient_stop_presence_loop(this.__wbg_ptr);}update_device(e,t,n,i,o){let s=S(e,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(t,l.__wbindgen_export,l.__wbindgen_export2),d=b;var p=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),u=b,g=B(o)?0:S(o,l.__wbindgen_export,l.__wbindgen_export2),f=b;let v=l.wasmclient_update_device(this.__wbg_ptr,s,a,c,d,p,u,B(i)?0:w(i),g,f);return R(v)}update_presence(e,t,n,i,o){let s=S(e,l.__wbindgen_export,l.__wbindgen_export2),a=b,c=S(t,l.__wbindgen_export,l.__wbindgen_export2),d=b,p=S(n,l.__wbindgen_export,l.__wbindgen_export2),u=b;var g=B(i)?0:S(i,l.__wbindgen_export,l.__wbindgen_export2),f=b;let v=l.wasmclient_update_presence(this.__wbg_ptr,s,a,c,d,p,u,g,f,!B(o),B(o)?BigInt(0):o);return R(v)}update_session(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_update_session(this.__wbg_ptr,n,i,o,s);return R(a)}validate_session_token(e){let t,n;try{let p=l.__wbindgen_add_to_stack_pointer(-16),u=S(e,l.__wbindgen_export,l.__wbindgen_export2),g=b;l.wasmclient_validate_session_token(p,this.__wbg_ptr,u,g);var i=M().getInt32(p+0,!0),o=M().getInt32(p+4,!0),s=M().getInt32(p+8,!0),a=M().getInt32(p+12,!0),c=i,d=o;if(a)throw c=0,d=0,R(s);return t=c,n=d,H(c,d)}finally{l.__wbindgen_add_to_stack_pointer(16),l.__wbindgen_export4(t,n,1);}}validate_session_token_for_connection(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=S(t,l.__wbindgen_export,l.__wbindgen_export2),s=b,a=l.wasmclient_validate_session_token_for_connection(this.__wbg_ptr,n,i,o,s);return R(a)}validate_session_token_for_connection_with_payload(e,t,n){let i=S(e,l.__wbindgen_export,l.__wbindgen_export2),o=b,s=S(t,l.__wbindgen_export,l.__wbindgen_export2),a=b;var c=B(n)?0:S(n,l.__wbindgen_export,l.__wbindgen_export2),d=b;let p=l.wasmclient_validate_session_token_for_connection_with_payload(this.__wbg_ptr,i,o,s,a,c,d);return R(p)}wait_for_settled_peer(e,t){let n=S(e,l.__wbindgen_export,l.__wbindgen_export2),i=b,o=l.wasmclient_wait_for_settled_peer(this.__wbg_ptr,n,i,B(t)?Number.MAX_SAFE_INTEGER:t>>>0);return R(o)}};Symbol.dispose&&(Ee.prototype[Symbol.dispose]=Ee.prototype.free);function Tr(){l.start();}function Ma(){return {__proto__:null,"./openrtc_bg.js":{__proto__:null,__wbg_Error_9dc85fe1bc224456:function(e,t){let n=Error(H(e,t));return w(n)},__wbg_String_8564e559799eccda:function(e,t){let n=String(m(t)),i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg___wbindgen_boolean_get_b131b2f36d6b2f55:function(e){let t=m(e),n=typeof t=="boolean"?t:void 0;return B(n)?16777215:n?1:0},__wbg___wbindgen_debug_string_56c147eb1a51f0c4:function(e,t){let n=Pi(m(t)),i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg___wbindgen_in_ce8569b2fc6f5088:function(e,t){return m(e)in m(t)},__wbg___wbindgen_is_function_147961669f068cd4:function(e){return typeof m(e)=="function"},__wbg___wbindgen_is_null_ced4761460071341:function(e){return m(e)===null},__wbg___wbindgen_is_object_3a2c414391dbf751:function(e){let t=m(e);return typeof t=="object"&&t!==null},__wbg___wbindgen_is_string_6541b0f6ecd4e8e5:function(e){return typeof m(e)=="string"},__wbg___wbindgen_is_undefined_4410e3c20a99fa97:function(e){return m(e)===void 0},__wbg___wbindgen_jsval_eq_174c93ec61bab0c5:function(e,t){return m(e)===m(t)},__wbg___wbindgen_jsval_loose_eq_e07e3b1f5db6da6c:function(e,t){return m(e)==m(t)},__wbg___wbindgen_number_get_588ed6b97f0d7e14:function(e,t){let n=m(t),i=typeof n=="number"?n:void 0;M().setFloat64(e+8,B(i)?0:i,true),M().setInt32(e+0,!B(i),true);},__wbg___wbindgen_string_get_fa2687d531ed17a5:function(e,t){let n=m(t),i=typeof n=="string"?n:void 0;var o=B(i)?0:S(i,l.__wbindgen_export,l.__wbindgen_export2),s=b;M().setInt32(e+4,s,true),M().setInt32(e+0,o,true);},__wbg___wbindgen_throw_bbadd78c1bac3a77:function(e,t){throw new Error(H(e,t))},__wbg__wbg_cb_unref_c2301a3c9b78104b:function(e){m(e)._wbg_cb_unref();},__wbg_abort_56c00f462c9261d9:function(e,t){m(e).abort(m(t));},__wbg_abort_f2416f4a9852003e:function(e){m(e).abort();},__wbg_addEventListener_b635263c509aa7de:function(){return F(function(e,t,n,i){m(e).addEventListener(H(t,n),m(i));},arguments)},__wbg_append_c5a0c94a6a73b22e:function(){return F(function(e,t,n,i,o){m(e).append(H(t,n),H(i,o));},arguments)},__wbg_arrayBuffer_cc7704fa158b907a:function(){return F(function(e){let t=m(e).arrayBuffer();return w(t)},arguments)},__wbg_bistream_new:function(e){let t=et.__wrap(e);return w(t)},__wbg_body_442a47f02322d7b0:function(e){let t=m(e).body;return B(t)?0:w(t)},__wbg_buffer_8524b3453cde4918:function(e){let t=m(e).buffer;return w(t)},__wbg_byobRequest_cc72d210de793e64:function(e){let t=m(e).byobRequest;return B(t)?0:w(t)},__wbg_byteLength_96807b1d9ab24a4c:function(e){return m(e).byteLength},__wbg_byteOffset_a9c7002428843c41:function(e){return m(e).byteOffset},__wbg_call_91f00ddc43e01490:function(){return F(function(e,t){let n=m(e).call(m(t));return w(n)},arguments)},__wbg_call_ec09a4cf93377d3a:function(){return F(function(e,t,n){let i=m(e).call(m(t),m(n));return w(i)},arguments)},__wbg_cancel_f3a197b26dc88b39:function(e){let t=m(e).cancel();return w(t)},__wbg_catch_66060324c27be6f7:function(e,t){let n=m(e).catch(m(t));return w(n)},__wbg_clearTimeout_113b1cde814ec762:function(e){let t=clearTimeout(R(e));return w(t)},__wbg_clearTimeout_333bba87532ab9d3:function(e){let t=clearTimeout(R(e));return w(t)},__wbg_clearTimeout_47a40e3be01ed7a3:function(){return F(function(e,t){m(e).clearTimeout(R(t));},arguments)},__wbg_clearTimeout_6b8d9a38b9263d65:function(e){let t=clearTimeout(R(e));return w(t)},__wbg_close_296263cfe1bb2999:function(){return F(function(e){m(e).close();},arguments)},__wbg_close_388d99468213b286:function(){return F(function(e){m(e).close();},arguments)},__wbg_close_4857e22d08b71356:function(){return F(function(e){m(e).close();},arguments)},__wbg_code_1cda2855fcd9b009:function(e){return m(e).code},__wbg_code_70beb7b22374d55e:function(e){return m(e).code},__wbg_createDataChannel_122bd3d8aacee49b:function(e,t,n){let i=m(e).createDataChannel(H(t,n));return w(i)},__wbg_crypto_38df2bab126b63dc:function(e){let t=m(e).crypto;return w(t)},__wbg_data_8a04443c1e5a8cd3:function(e){let t=m(e).data;return w(t)},__wbg_debug_de823612d4d12f74:function(e){console.debug(m(e));},__wbg_dispatchEvent_cc62a6a43d28b01c:function(){return F(function(e,t){return m(e).dispatchEvent(m(t))},arguments)},__wbg_done_6a8439e544ec6206:function(e){return m(e).done},__wbg_enqueue_bbeb09ba0b140f76:function(){return F(function(e,t){m(e).enqueue(m(t));},arguments)},__wbg_entries_4e00eefd3fd54cf1:function(e){let t=m(e).entries();return w(t)},__wbg_error_6651fee1c71e5da9:function(e){console.error(m(e));},__wbg_error_a6fa202b58aa1cd3:function(e,t){let n,i;try{n=e,i=t,console.error(H(e,t));}finally{l.__wbindgen_export4(n,i,1);}},__wbg_fetch_074561c3e313c86f:function(e){let t=fetch(m(e));return w(t)},__wbg_fetch_22858a12fcf93152:function(e,t){let n=m(e).fetch(m(t));return w(n)},__wbg_fetch_9dad4fe911207b37:function(e){let t=fetch(m(e));return w(t)},__wbg_fetch_c374c6d9532750f2:function(e,t){let n=m(e).fetch(m(t));return w(n)},__wbg_getRandomValues_76dfc69825c9c552:function(){return F(function(e,t){globalThis.crypto.getRandomValues(Re(e,t));},arguments)},__wbg_getRandomValues_c44a50d8cfdaebeb:function(){return F(function(e,t){m(e).getRandomValues(m(t));},arguments)},__wbg_getReader_0cd37e95fbf00f7f:function(e){let t=m(e).getReader();return w(t)},__wbg_getReader_9facd4f899beac89:function(){return F(function(e){let t=m(e).getReader();return w(t)},arguments)},__wbg_get_44e98e27bda25b5b:function(){return F(function(e,t){let n=Reflect.get(m(e),m(t));return w(n)},arguments)},__wbg_get_4b90d6d8c5deb5d5:function(e,t){let n=m(e)[t>>>0];return w(n)},__wbg_get_52a8a619f7b88df6:function(){return F(function(e,t){let n=Reflect.get(m(e),m(t));return w(n)},arguments)},__wbg_get_a82defe8d6b5b2e5:function(){return F(function(e,t,n,i){let o=m(t).get(H(n,i));var s=B(o)?0:S(o,l.__wbindgen_export,l.__wbindgen_export2),a=b;M().setInt32(e+4,a,true),M().setInt32(e+0,s,true);},arguments)},__wbg_get_done_c21b9933fc9a9e9c:function(e){let t=m(e).done;return B(t)?16777215:t?1:0},__wbg_get_value_ad568c7d3db9073f:function(e){let t=m(e).value;return w(t)},__wbg_get_with_ref_key_6412cf3094599694:function(e,t){let n=m(e)[m(t)];return w(n)},__wbg_has_14676d88c1340d2c:function(){return F(function(e,t){return Reflect.has(m(e),m(t))},arguments)},__wbg_headers_5b19cf40627ae54d:function(e){let t=m(e).headers;return w(t)},__wbg_info_a2b5f8a5dae8b26c:function(e){console.info(m(e));},__wbg_instanceof_ArrayBuffer_a581da923203f29f:function(e){let t;try{t=m(e)instanceof ArrayBuffer;}catch{t=false;}return t},__wbg_instanceof_Blob_5c4e145be35f9b1e:function(e){let t;try{t=m(e)instanceof Blob;}catch{t=false;}return t},__wbg_instanceof_ReadableStreamDefaultReader_2ab4b6bb85f96463:function(e){let t;try{t=m(e)instanceof ReadableStreamDefaultReader;}catch{t=false;}return t},__wbg_instanceof_Response_36a65a969abaa7c6:function(e){let t;try{t=m(e)instanceof Response;}catch{t=false;}return t},__wbg_instanceof_Uint8Array_b6fe1ac89eba107e:function(e){let t;try{t=m(e)instanceof Uint8Array;}catch{t=false;}return t},__wbg_instanceof_Window_9e0fe7d3d1ff4342:function(e){let t;try{t=m(e)instanceof Window;}catch{t=false;}return t},__wbg_isArray_139f48e3c057ede8:function(e){return Array.isArray(m(e))},__wbg_iterator_9b36cebf3be7b7cd:function(){return w(Symbol.iterator)},__wbg_length_68a9d5278d084f4f:function(e){return m(e).length},__wbg_log_6614a4effdb4e983:function(e){console.log(m(e));},__wbg_message_12958526424a887b:function(e,t){let n=m(t).message,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_msCrypto_bd5a034af96bcba6:function(e){let t=m(e).msCrypto;return w(t)},__wbg_new_0_878c6ec3a1c600f3:function(){return w(new Date)},__wbg_new_0b303268aa395a38:function(){let e=new Array;return w(e)},__wbg_new_189262ff31890c23:function(){return F(function(){let e=new Headers;return w(e)},arguments)},__wbg_new_20b778a4c5c691c3:function(){let e=new Object;return w(e)},__wbg_new_227d7c05414eb861:function(){let e=new Error;return w(e)},__wbg_new_24739629d416f982:function(){return F(function(){let e=new AbortController;return w(e)},arguments)},__wbg_new_5fae30e6b23db8df:function(e,t){let n=new Error(H(e,t));return w(n)},__wbg_new_883c0db065f06efd:function(){return w(new Map)},__wbg_new_a3e5112401a82338:function(){return F(function(e,t){let n=new WebSocket(H(e,t));return w(n)},arguments)},__wbg_new_b06772b280cc6e52:function(e){let t=new Uint8Array(m(e));return w(t)},__wbg_new_from_slice_bb2d1778c0b87eb1:function(e,t){let n=new Uint8Array(Re(e,t));return w(n)},__wbg_new_typed_90c3f6c29ba36d19:function(e,t){try{var n={a:e,b:t},i=(s,a)=>{let c=n.a;n.a=0;try{return ja(c,n.b,s,a)}finally{n.a=c;}};let o=new Promise(i);return w(o)}finally{n.a=0;}},__wbg_new_with_byte_offset_and_length_9e1e664fe1a5d385:function(e,t,n){let i=new Uint8Array(m(e),t>>>0,n>>>0);return w(i)},__wbg_new_with_configuration_3a96aa953ca17197:function(){return F(function(e){let t=new RTCPeerConnection(m(e));return w(t)},arguments)},__wbg_new_with_event_init_dict_bd850674488710b1:function(){return F(function(e,t,n){let i=new CustomEvent(H(e,t),m(n));return w(i)},arguments)},__wbg_new_with_into_underlying_sink_2596343f9b6c8e58:function(e){let t=new WritableStream(tt.__wrap(e));return w(t)},__wbg_new_with_into_underlying_source_fd904252f385f59c:function(e,t){let n=new ReadableStream(nt.__wrap(e),R(t));return w(n)},__wbg_new_with_length_4b57a7a5dc67221c:function(e){let t=new Uint8Array(e>>>0);return w(t)},__wbg_new_with_str_and_init_df876572184fe639:function(){return F(function(e,t,n){let i=new Request(H(e,t),m(n));return w(i)},arguments)},__wbg_new_with_str_sequence_505a4829cc247e79:function(){return F(function(e,t,n){let i=new WebSocket(H(e,t),m(n));return w(i)},arguments)},__wbg_next_8cb028b6ba50743f:function(){return F(function(e){let t=m(e).next();return w(t)},arguments)},__wbg_next_cfd0b146c9538df8:function(e){let t=m(e).next;return w(t)},__wbg_node_84ea875411254db1:function(e){let t=m(e).node;return w(t)},__wbg_now_bce4dc999095ea77:function(){return Date.now()},__wbg_now_e7c6795a7f81e10f:function(e){return m(e).now()},__wbg_ok_2279b99c57bfdfba:function(e){return m(e).ok},__wbg_parse_a5c06e19bc1187fd:function(e,t){return Date.parse(H(e,t))},__wbg_peerunistream_new:function(e){let t=it.__wrap(e);return w(t)},__wbg_performance_3fcf6e32a7e1ed0a:function(e){let t=m(e).performance;return w(t)},__wbg_process_44c7a14e11e9f69e:function(e){let t=m(e).process;return w(t)},__wbg_protocol_28aaef5ea42981d6:function(e,t){let n=m(t).protocol,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_prototypesetcall_956c7493c68e29b4:function(e,t,n){Uint8Array.prototype.set.call(Re(e,t),m(n));},__wbg_push_ceb8ef046afb2041:function(e,t){return m(e).push(m(t))},__wbg_queueMicrotask_4698f900840e3286:function(e){queueMicrotask(m(e));},__wbg_queueMicrotask_477a5533c7100338:function(e){let t=m(e).queueMicrotask;return w(t)},__wbg_randomFillSync_6c25eac9869eb53c:function(){return F(function(e,t){m(e).randomFillSync(R(t));},arguments)},__wbg_read_8426c146431f2905:function(e){let t=m(e).read();return w(t)},__wbg_readyState_25243ad6ce649774:function(e){return m(e).readyState},__wbg_reason_4ec455bac79b33ce:function(e,t){let n=m(t).reason,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_releaseLock_188846ef719acb10:function(e){m(e).releaseLock();},__wbg_removeEventListener_016c1d24523b4730:function(){return F(function(e,t,n,i){m(e).removeEventListener(H(t,n),m(i));},arguments)},__wbg_require_b4edbdcf3e2a1ef0:function(){return F(function(){let e=module.require;return w(e)},arguments)},__wbg_resolve_0183de2e8c6b1d54:function(e){let t=Promise.resolve(m(e));return w(t)},__wbg_respond_3cdb4cf32683fd79:function(){return F(function(e,t){m(e).respond(t>>>0);},arguments)},__wbg_send_99d049cae69c53cc:function(){return F(function(e,t,n){m(e).send(Re(t,n));},arguments)},__wbg_send_bac9d3dc4f21ef28:function(){return F(function(e,t,n){m(e).send(H(t,n));},arguments)},__wbg_setTimeout_3a808dd861dd3c12:function(e,t){let n=setTimeout(m(e),t);return w(n)},__wbg_setTimeout_6613a51400c1bf9f:function(){return F(function(e,t,n){let i=m(e).setTimeout(R(t),n);return w(i)},arguments)},__wbg_setTimeout_ef24d2fc3ad97385:function(){return F(function(e,t){let n=setTimeout(m(e),t);return w(n)},arguments)},__wbg_setTimeout_f757f00851f76c42:function(e,t){let n=setTimeout(m(e),t);return w(n)},__wbg_set_3ab3dfede3bae139:function(){return F(function(e,t,n,i,o){m(e).set(H(t,n),H(i,o));},arguments)},__wbg_set_5f806304fb633ab3:function(e,t,n){let i=m(e).set(m(t),m(n));return w(i)},__wbg_set_6be42768c690e380:function(e,t,n){m(e)[R(t)]=R(n);},__wbg_set_86698c227e5b9dad:function(e,t,n){m(e).set(Re(t,n));},__wbg_set_a6ba3ac0e634b822:function(){return F(function(e,t,n){return Reflect.set(m(e),m(t),m(n))},arguments)},__wbg_set_binaryType_8c2dd2cf1cfc2e28:function(e,t){m(e).binaryType=Ka[t];},__wbg_set_body_d1153b16a2b95ca1:function(e,t){m(e).body=m(t);},__wbg_set_cache_5a01a8b5e6ca6cf2:function(e,t){m(e).cache=qa[t];},__wbg_set_credentials_e9120ed88b1fc0b8:function(e,t){m(e).credentials=Va[t];},__wbg_set_da33c120a6584674:function(e,t,n){m(e)[t>>>0]=R(n);},__wbg_set_detail_c7af5edea934390b:function(e,t){m(e).detail=m(t);},__wbg_set_handle_event_6147c38b782c7b42:function(e,t){m(e).handleEvent=m(t);},__wbg_set_headers_877ed41890d28af2:function(e,t){m(e).headers=m(t);},__wbg_set_high_water_mark_77da20c49668427d:function(e,t){m(e).highWaterMark=t;},__wbg_set_method_b4ede299b2064f37:function(e,t,n){m(e).method=H(t,n);},__wbg_set_mode_d6c2e1991aa963c6:function(e,t){m(e).mode=$a[t];},__wbg_set_onclose_9cb5c3372e16c192:function(e,t){m(e).onclose=m(t);},__wbg_set_onerror_190fe67e911ebf28:function(e,t){m(e).onerror=m(t);},__wbg_set_onmessage_96337495f0bfb796:function(e,t){m(e).onmessage=m(t);},__wbg_set_onopen_3e2bf6b11d434c2d:function(e,t){m(e).onopen=m(t);},__wbg_set_signal_9022b5aa06a6ce5b:function(e,t){m(e).signal=m(t);},__wbg_signal_41dd1a8913cd0b7d:function(e){let t=m(e).signal;return w(t)},__wbg_stack_3b0d974bbf31e44f:function(e,t){let n=m(t).stack,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_static_accessor_GLOBAL_60a4124bab7dcc9a:function(){let e=typeof global>"u"?null:global;return B(e)?0:w(e)},__wbg_static_accessor_GLOBAL_THIS_95ca6460658b5d13:function(){let e=typeof globalThis>"u"?null:globalThis;return B(e)?0:w(e)},__wbg_static_accessor_SELF_4c95f759a91e9aae:function(){let e=typeof self>"u"?null:self;return B(e)?0:w(e)},__wbg_static_accessor_WINDOW_44b435597f9e9ee7:function(){let e=typeof window>"u"?null:window;return B(e)?0:w(e)},__wbg_status_9e6505cfa3e73a7c:function(e){return m(e).status},__wbg_stringify_a42c95ea9a7591c9:function(){return F(function(e){let t=JSON.stringify(m(e));return w(t)},arguments)},__wbg_subarray_42216645a367cd7a:function(e,t,n){let i=m(e).subarray(t>>>0,n>>>0);return w(i)},__wbg_text_d0039cf442b19ec4:function(){return F(function(e){let t=m(e).text();return w(t)},arguments)},__wbg_then_254bab9b266a77a5:function(e,t,n){let i=m(e).then(m(t),m(n));return w(i)},__wbg_then_3ea18602c6a5123b:function(e,t){let n=m(e).then(m(t));return w(n)},__wbg_toISOString_1c29c14154d57c76:function(e){let t=m(e).toISOString();return w(t)},__wbg_url_72c67c175685a054:function(e,t){let n=m(t).url,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_url_d0b8042af0d1bbba:function(e,t){let n=m(t).url,i=S(n,l.__wbindgen_export,l.__wbindgen_export2),o=b;M().setInt32(e+4,o,true),M().setInt32(e+0,i,true);},__wbg_value_3d3defe09fb1ffca:function(e){let t=m(e).value;return w(t)},__wbg_versions_276b2795b1c6a219:function(e){let t=m(e).versions;return w(t)},__wbg_view_15fa5865c6b336e3:function(e){let t=m(e).view;return B(t)?0:w(t)},__wbg_warn_633bacc13ba7e6c3:function(e){console.warn(m(e));},__wbg_wasClean_f17429d064911939:function(e){return m(e).wasClean},__wbindgen_cast_0000000000000001:function(e,t){let n=me(e,t,Oa);return w(n)},__wbindgen_cast_0000000000000002:function(e,t){let n=me(e,t,Ha);return w(n)},__wbindgen_cast_0000000000000003:function(e,t){let n=me(e,t,Wa);return w(n)},__wbindgen_cast_0000000000000004:function(e,t){let n=me(e,t,Ua);return w(n)},__wbindgen_cast_0000000000000005:function(e,t){let n=me(e,t,Ea);return w(n)},__wbindgen_cast_0000000000000006:function(e,t){let n=me(e,t,xa);return w(n)},__wbindgen_cast_0000000000000007:function(e,t){let n=Ya(e,t,La);return w(n)},__wbindgen_cast_0000000000000008:function(e,t){let n=me(e,t,Ba);return w(n)},__wbindgen_cast_0000000000000009:function(e,t){let n=me(e,t,Fa);return w(n)},__wbindgen_cast_000000000000000a:function(e){return w(e)},__wbindgen_cast_000000000000000b:function(e){return w(e)},__wbindgen_cast_000000000000000c:function(e,t){let n=Re(e,t);return w(n)},__wbindgen_cast_000000000000000d:function(e,t){let n=H(e,t);return w(n)},__wbindgen_cast_000000000000000e:function(e){let t=BigInt.asUintN(64,e);return w(t)},__wbindgen_cast_000000000000000f:function(e,t){var n=Re(e,t).slice();return l.__wbindgen_export4(e,t*1,1),w(n)},__wbindgen_object_clone_ref:function(e){let t=m(e);return w(t)},__wbindgen_object_drop_ref:function(e){R(e);}}}}function Ea(r,e){l.__wasm_bindgen_func_elem_8875(r,e);}function xa(r,e){l.__wasm_bindgen_func_elem_9997(r,e);}function La(r,e){l.__wasm_bindgen_func_elem_10066(r,e);}function Ba(r,e){l.__wasm_bindgen_func_elem_17622(r,e);}function Fa(r,e){l.__wasm_bindgen_func_elem_4463(r,e);}function Oa(r,e,t){l.__wasm_bindgen_func_elem_9075(r,e,w(t));}function Wa(r,e,t){l.__wasm_bindgen_func_elem_6553(r,e,w(t));}function Ua(r,e,t){l.__wasm_bindgen_func_elem_10704(r,e,w(t));}function Ha(r,e,t){try{let o=l.__wbindgen_add_to_stack_pointer(-16);l.__wasm_bindgen_func_elem_17768(o,r,e,w(t));var n=M().getInt32(o+0,!0),i=M().getInt32(o+4,!0);if(i)throw R(n)}finally{l.__wbindgen_add_to_stack_pointer(16);}}function ja(r,e,t,n){l.__wasm_bindgen_func_elem_17770(r,e,w(t),w(n));}var Ka=["blob","arraybuffer"],qa=["default","no-store","reload","no-cache","force-cache","only-if-cached"],Va=["omit","same-origin","include"],$a=["same-origin","no-cors","cors","navigate"],Ir=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbg_bistream_free(r,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(r=>l.__wbg_intounderlyingbytesource_free(r,1));var wr=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbg_intounderlyingsink_free(r,1)),Pr=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbg_intounderlyingsource_free(r,1)),Rr=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbg_peerunistream_free(r,1)),Si=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbg_wasmclient_free(r,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(r=>l.__wbg_wasmconnection_free(r,1));function w(r){Je===de.length&&de.push(de.length+1);let e=Je;return Je=de[e],de[e]=r,e}var pn=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(r=>l.__wbindgen_export5(r.a,r.b));function Pi(r){let e=typeof r;if(e=="number"||e=="boolean"||r==null)return `${r}`;if(e=="string")return `"${r}"`;if(e=="symbol"){let i=r.description;return i==null?"Symbol":`Symbol(${i})`}if(e=="function"){let i=r.name;return typeof i=="string"&&i.length>0?`Function(${i})`:"Function"}if(Array.isArray(r)){let i=r.length,o="[";i>0&&(o+=Pi(r[0]));for(let s=1;s<i;s++)o+=", "+Pi(r[s]);return o+="]",o}let t=/\[object ([^\]]+)\]/.exec(toString.call(r)),n;if(t&&t.length>1)n=t[1];else return toString.call(r);if(n=="Object")try{return "Object("+JSON.stringify(r)+")"}catch{return "Object"}return r instanceof Error?`${r.name}: ${r.message}
3
- ${r.stack}`:n}function Qa(r){r<1028||(de[r]=Je,Je=r);}function Re(r,e){return r=r>>>0,Me().subarray(r/1,r/1+e)}var _e=null;function M(){return (_e===null||_e.buffer.detached===true||_e.buffer.detached===void 0&&_e.buffer!==l.memory.buffer)&&(_e=new DataView(l.memory.buffer)),_e}function H(r,e){return Ja(r>>>0,e)}var Xe=null;function Me(){return (Xe===null||Xe.byteLength===0)&&(Xe=new Uint8Array(l.memory.buffer)),Xe}function m(r){return de[r]}function F(r,e){try{return r.apply(this,e)}catch(t){l.__wbindgen_export3(w(t));}}var de=new Array(1024).fill(void 0);de.push(void 0,null,true,false);var Je=de.length;function B(r){return r==null}function Ya(r,e,t){let n={a:r,b:e,cnt:1},i=(...o)=>{n.cnt++;try{return t(n.a,n.b,...o)}finally{i._wbg_cb_unref();}};return i._wbg_cb_unref=()=>{--n.cnt===0&&(l.__wbindgen_export5(n.a,n.b),n.a=0,pn.unregister(n));},pn.register(i,n,n),i}function me(r,e,t){let n={a:r,b:e,cnt:1},i=(...o)=>{n.cnt++;let s=n.a;n.a=0;try{return t(s,n.b,...o)}finally{n.a=s,i._wbg_cb_unref();}};return i._wbg_cb_unref=()=>{--n.cnt===0&&(l.__wbindgen_export5(n.a,n.b),n.a=0,pn.unregister(n));},pn.register(i,n,n),i}function Ii(r,e){let t=e(r.length*1,1)>>>0;return Me().set(r,t/1),b=r.length,t}function S(r,e,t){if(t===void 0){let a=Ze.encode(r),c=e(a.length,1)>>>0;return Me().subarray(c,c+a.length).set(a),b=a.length,c}let n=r.length,i=e(n,1)>>>0,o=Me(),s=0;for(;s<n;s++){let a=r.charCodeAt(s);if(a>127)break;o[i+s]=a;}if(s!==n){s!==0&&(r=r.slice(s)),i=t(i,n,n=s+r.length*3,1)>>>0;let a=Me().subarray(i+s,i+n),c=Ze.encodeInto(r,a);s+=c.written,i=t(i,n,s,1)>>>0;}return b=s,i}function R(r){let e=m(r);return Qa(r),e}var cn=new TextDecoder("utf-8",{ignoreBOM:true,fatal:true});cn.decode();var Xa=2146435072,wi=0;function Ja(r,e){return wi+=e,wi>=Xa&&(cn=new TextDecoder("utf-8",{ignoreBOM:true,fatal:true}),cn.decode(),wi=e),cn.decode(Me().subarray(r,r+e))}var Ze=new TextEncoder;"encodeInto"in Ze||(Ze.encodeInto=function(r,e){let t=Ze.encode(r);return e.set(t),{read:r.length,written:t.length}});var b=0,l;function tc(r,e){return l=r.exports,_e=null,Xe=null,l.__wbindgen_start(),l}async function nc(r,e){if(typeof Response=="function"&&r instanceof Response){if(typeof WebAssembly.instantiateStreaming=="function")try{return await WebAssembly.instantiateStreaming(r,e)}catch(i){if(r.ok&&t(r.type)&&r.headers.get("Content-Type")!=="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",i);else throw i}let n=await r.arrayBuffer();return await WebAssembly.instantiate(n,e)}else {let n=await WebAssembly.instantiate(r,e);return n instanceof WebAssembly.Instance?{instance:n,module:r}:n}function t(n){switch(n){case "basic":case "cors":case "default":return true}return false}}async function Ar(r){if(l!==void 0)return l;r!==void 0&&(Object.getPrototypeOf(r)===Object.prototype?{module_or_path:r}=r:console.warn("using deprecated parameters for the initialization function; pass a single object instead")),r===void 0&&(r=new URL("openrtc_bg.wasm",import.meta.url));let e=Ma();(typeof r=="string"||typeof Request=="function"&&r instanceof Request||typeof URL=="function"&&r instanceof URL)&&(r=fetch(r));let{instance:t,module:n}=await nc(await r,e);return tc(t)}function ic(){if(!(typeof window>"u"))try{if(new URL(import.meta.url).pathname.includes("/node_modules/.vite/deps/"))return new URL("/node_modules/openrtc/dist/openrtc_bg.wasm",window.location.origin)}catch{}}function oc(r){let t=(Array.isArray(r.urls)?r.urls:[r.urls]).filter(n=>typeof n=="string"&&!n.startsWith("stun:"));return t.length===0?null:{...r,urls:Array.isArray(r.urls)?t:t[0]}}function kr(r){if(r)return r.map(e=>oc(e)).filter(e=>e!==null)}async function Nr(r$1,e,t){for(let n=0;n<e;n+=1){if(await r$1().catch(()=>false))return true;n<e-1&&await r(t);}return false}function Ri(r){return !!r?.signaling?.nativeIpc&&r?.transport?.wasm===false&&r?.fallback?.wasm===false}var un=class{constructor(e){this.host=e;this.wasmLoaded=false;this.initPromise=null;this.initPendingTimer=null;this.disposed=false;this.host.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true,this.initPromise=null,this.clearInitPendingTimer();}clearInitPendingTimer(){this.initPendingTimer&&(clearInterval(this.initPendingTimer),this.initPendingTimer=null);}async bootstrapRuntime(e){let t=e.initializeClient??true;if(e.platform==="web")return await e.initializeWeb?.(),t&&await this.init(),{ready:true,mode:"web"};let n=e.quickPollAttempts??5,i=e.quickPollIntervalMs??300,o=e.retryPollAttempts??8,s=e.retryPollIntervalMs??300,a=e.nativeInitEventTimeoutMs??4e3;if(!e.isNativeReady)return console.warn("[Client][INIT] No isNativeReady callback provided for native platform; treating runtime as not ready"),{ready:false,mode:"native"};if(!await Nr(e.isNativeReady,n,i)){await e.retryNativeInit?.();let[d,p]=await Promise.all([e.waitForNativeInitEvent?.(a)??Promise.resolve(false),Nr(e.isNativeReady,o,s)]);if(!(d||p))return {ready:false,mode:"native"}}return t&&await this.init(),{ready:true,mode:"native"}}async init(){if(!this.disposed){if(this.initPromise)return this.initPromise;if(!(this.wasmLoaded&&this.host.wasmClient&&this.host.localNodeId)){if(this.usesNativeIpcRuntimeWithoutWasmFallback())throw this.nativeWasmInitForbiddenError("Client.init()");return this.initPromise=(async()=>{try{if(e("[Client][INIT] Loading WASM module..."),await Ar(ic()),this.disposed)return;Tr(),this.wasmLoaded=!0,e("[Client][INIT] WASM module loaded");let e$2=e$1(this.host.options),t=typeof this.host.options.apiKey=="string"?this.host.options.apiKey.trim():"",n=typeof this.host.options.spaceKey=="string"?this.host.options.spaceKey.trim():"",i=(this.host.options.discoveryMode===void 0||this.host.options.discoveryMode==="space")&&!!t&&!!n,o=c$1(this.host.options);if(i){let g=await b$1(t,n);if(this.disposed)return;o=`space::${g}`,e(`[Client][INIT] space mode: WASM rooms routed to spaces/${g.slice(0,8)}...`);}if(this.disposed)return;this.host.setEffectiveRoomBackendTag(o);let s=new Ee(e$2,o);if(this.disposed)return;if(this.host.setWasmClient(s),e("PlutoRTC WASM Core Initialized"),this.host.setSignalingWasmClient(s),this.host.installAppLifecycleListeners(),!this.host.usesTicketOnlySignalingMode()){if(await this.host.ensureAuthenticated("init"),this.disposed||(await this.host.syncAuthTokenToWasm("init"),this.disposed))return;this.host.installAuthTokenSync();}let a=`iroh_secret_key_${f$2(this.host.options)}`,c=this.resolveIrohPersistenceMode(),d$1=await this.resolveIrohSecretKeyBytes(a,c);if(this.disposed||(this.host.setDeviceId(await this.host.getLocalDeviceId().catch(()=>null)),this.disposed))return;let p=Date.now();e(`[Client][INIT][IROH] start persistence=${c} hasSecretKey=${!!d$1} secretKeyLen=${d$1?.length||0} hasStoredDeviceId=${!!this.host.deviceId}`),this.clearInitPendingTimer(),this.initPendingTimer=setInterval(()=>{let g=Date.now()-p;console.warn(`[Client][INIT][IROH] pending elapsedMs=${g} hasWasmClient=${!!this.host.wasmClient}`);},5e3);let u="";try{u=await B$1(s.init_iroh(d$1),2e4);}catch(g){let f=Date.now()-p;throw new Error(`[Client] init_iroh stalled or failed: ${g?.message||g}; elapsed_ms=${f}; persistence=${c}; has_secret_key=${!!d$1}`)}finally{this.clearInitPendingTimer();}if(this.disposed)return;if(e(`[Client][INIT][IROH] complete elapsedMs=${Date.now()-p} nodeId=${u}`),!u)throw new Error("[Client] init_iroh returned empty node id");if(this.host.setLocalNodeId(u),this.host.deviceId||this.host.setDeviceId(await this.host.getLocalDeviceId().catch(()=>null)),this.disposed||(this.host.setNode({initialized:!0,localNodeId:u}),c==="persistent"&&!this.host.options.secretKey&&(await this.persistCurrentIrohSecret(a,d$1,u),this.disposed)))return;if(this.host.options.transports?.moq)try{Promise.resolve(this.host.initMoQ()).catch(g=>{this.disposed||d("[Client][INIT] MoQ startup handoff failed",g);});}catch(g){if(this.disposed)return;d("[Client][INIT] MoQ startup handoff failed",g);}if(await this.configureWebRtcIceServers(),this.disposed)return;this.host.isWebRTCTransportEnabled()&&this.broadcastWebRtcReadyCapabilityInBackground();}catch(e){throw console.error("Failed to initialize PlutoRTC:",e),this.initPromise=null,e}})(),this.initPromise}}}broadcastWebRtcReadyCapabilityInBackground(){try{Promise.resolve(this.host.broadcastTransportCapabilityUpdate("webrtc-ready")).catch(e=>{this.disposed||d("[Client] Late WebRTC capability update failed",e);});}catch(e){if(this.disposed)return;d("[Client] Late WebRTC capability update failed",e);}}async recoverLocalIrohRuntime(e){if(this.disposed)return false;let t=this.host.wasmClient;if(!t||typeof t.init_iroh!="function")return false;try{let n=`iroh_secret_key_${f$2(this.host.options)}`,i=this.resolveIrohPersistenceMode(),o=await this.resolveIrohSecretKeyBytes(n,i);d("[Client][CONNECT] recovering local Iroh runtime",{reason:e,hadLocalNodeId:!!this.host.localNodeId,nodeInitialized:!!this.host.node?.initialized,persistenceMode:i,hasSecretKey:!!o});let s=await B$1(t.init_iroh(o),2e4);return this.disposed||typeof s!="string"||!s?!1:(this.host.setLocalNodeId(s),this.host.setNode({initialized:!0,localNodeId:s}),i==="persistent"&&!this.host.options.secretKey&&await this.persistCurrentIrohSecret(n,o,s),!0)}catch(n){return d("[Client][CONNECT] local Iroh runtime recovery failed",{reason:e,error:n instanceof Error?n.message:String(n)}),false}}usesNativeIpcRuntimeWithoutWasmFallback(){return Ri(this.host.getRuntimeCapabilities())}nativeWasmInitForbiddenError(e){let t=this.host.getRuntimeCapabilities(),n=`[Client][NATIVE-GUARD] Refusing WASM runtime init during ${e}. This OpenRTC client is using the native IPC runtime with WASM fallback disabled; desktop/Tauri must initialize Iroh through the Rust backend only.`;return console.error(n,{capabilities:t}),new Error(n)}async resolveIrohSecretKeyBytes(e,t){if(this.host.options.secretKey){let o=this.host.options.secretKey.match(/.{1,2}/g);return o?new Uint8Array(o.map(s=>parseInt(s,16))):void 0}if(t!=="persistent")return;let i=(await this.loadPersistedIrohSecretHex(e))?.match(/.{1,2}/g);return i?new Uint8Array(i.map(o=>parseInt(o,16))):void 0}async persistCurrentIrohSecret(e$1,t,n){let i=t??(typeof this.host.wasmClient?.iroh_secret_key=="function"?await this.host.wasmClient.iroh_secret_key().catch(()=>{}):void 0);if(i&&i.length>0){let o=Array.from(i).map(s=>Number(s).toString(16).padStart(2,"0")).join("");await this.persistIrohSecretHex(e$1,o),e(`[Client][INIT][IROH] persisted secret key bytes=${i.length} nodeId=${n}`);}else console.warn(`[Client][INIT][IROH] unable to persist secret key for nodeId=${n}`);}resolveIrohPersistenceMode(){return this.host.options.nodeIdPersistence??(typeof this.host.options.transports?.iroh=="object"?this.host.options.transports.iroh.persistenceMode:void 0)??"persistent"}getTauriInvoke(){if(typeof window>"u")return null;let e=window.__TAURI_INTERNALS__;return !e||typeof e.invoke!="function"?null:e.invoke.bind(e)}async loadPersistedIrohSecretHex(e){let t=a$3()?this.getTauriInvoke():null;if(t){let n=await t("openrtc_load_iroh_secret",{namespaceKey:e}).catch(()=>null);if(typeof n=="string"&&n.trim().length>0)return n.trim()}if(typeof sessionStorage<"u"){let n=sessionStorage.getItem(e);if(n)return n}if(typeof localStorage<"u"){let n=localStorage.getItem(e);if(n)return typeof sessionStorage<"u"&&sessionStorage.setItem(e,n),localStorage.removeItem(e),n}return null}async persistIrohSecretHex(e,t){let n=a$3()?this.getTauriInvoke():null;if(n){await n("openrtc_save_iroh_secret",{namespaceKey:e,secretHex:t}),typeof localStorage<"u"&&localStorage.removeItem(e);return}typeof sessionStorage<"u"&&sessionStorage.setItem(e,t),typeof localStorage<"u"&&localStorage.removeItem(e);}async getTurnCredentialsForTransportConfig(){return typeof this.host.options.turnCredentialsProvider=="function"?await this.host.options.turnCredentialsProvider()??null:await this.host.getTurnCredentials()??null}async configureWebRtcIceServers(){let e$1=this.host.options.transports?.webrtc;if(!!e$1&&(e$1.useTurn===true||e$1.privacyMode===true||this.host.options.strictMode===true))try{let n=await this.getTurnCredentialsForTransportConfig();if(this.disposed)return;if(n&&n.iceServers){let i=Array.isArray(n.iceServers)?n.iceServers:[n.iceServers];e$1?.privacyMode||this.host.options.strictMode?(i=kr(i)??[],e(`[Client] Strict / Privacy Mode: Filtered STUN servers. Remaining=${i.length}`)):e(`[Client] Automatically fetched ${i.length} TURN servers.`),this.host.options.transports||(this.host.options.transports={}),this.host.options.transports.webrtc||(this.host.options.transports.webrtc={});let o=this.host.options.transports.webrtc||i$1;o.iceServers||(o.iceServers=[]),(this.host.options.strictMode||o.privacyMode)&&(o.iceServers=kr(o.iceServers)??[]),o.iceServers.push(...i);}}catch(n){console.warn("[Client] Failed to auto-fetch TURN credentials:",n);}if(!this.host.options.strictMode&&!e$1?.privacyMode){if(this.disposed)return;let n=this.host.options.transports?.webrtc;n&&(!n.iceServers||Array.isArray(n.iceServers)&&n.iceServers.length===0)&&(e("[Client] No ICE servers provided. Using default public STUN servers."),n.iceServers=[...h$2]);}}};var gn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime connection service is disposed")}async connectRaw(e,t=2e4){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let n=await this.deps.ensureWasmManagedTransport(e,null,{timeoutMs:t});return this.assertActive(),{connectionId:n.connectionId,localNodeId:this.ctx.localNodeId??"",remoteNodeId:n.remoteNodeId??n.deviceId??""}}async startAutoConnect(e){if(this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("watch"),this.disposed))return;let t=this.deps.getCurrentUserId();if(!t)throw new Error("startAutoConnect requires an authenticated user");let n=e||await this.deps.getLocalDeviceId()||this.deps.getFallbackDeviceId();if(!this.disposed){if(!n)throw new Error("startAutoConnect requires a local device identity");this.deps.startAutoConnect(t,n);}}async isConnected(e){if(this.disposed||(await this.deps.ensureWasmRuntimeForP2P(),this.disposed)||!e||!e.trim())return false;let t=this.ctx.wasmClient;if(t&&typeof t.is_connected=="function"){let i=await t.is_connected(e);return this.disposed?false:!!i}let n=await this.deps.isConnected(e);return this.disposed?false:!!n}async disconnectNode(e){if(this.disposed||!e||!e.trim())return;let t=Array.from(this.ctx.registry.values()).filter(n=>n.deviceId===e);await Promise.allSettled(t.map(n=>this.disconnectConnectionBestEffort(n))),!this.disposed&&await this.deps.disconnectNodeTransport(e);}disconnectNodeBestEffort(e){try{this.disconnectNode(e).catch(()=>{});}catch{}}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};var hn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime identity service is disposed")}async getTicket(){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let e=await d$1(()=>this.ctx.wasmClient.endpoint_ticket(),{isActive:()=>!this.disposed});return this.assertActive(),e}async getNodeId(){return this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive(),this.ctx.localNodeId??""}async getNodeIdFromTicket(e){if(this.disposed)return null;let t=e.trim();if(!t)return null;let{irohTicket:n}=se(t),i=this.ctx.wasmClient;if(!i||typeof i.endpoint_id_from_ticket!="function")return null;try{let o=await i.endpoint_id_from_ticket(n);return this.disposed?null:o}catch{return null}}};var mn=class{constructor(e,t){this.ctx=e;this.deps=t;this.loggedNativeDiscoveryWasmSkip=false;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime readiness service is disposed")}async ensureWasmRuntimeForP2P(){if(this.assertActive(),!(this.ctx.wasmClient&&this.ctx.localNodeId)&&(await this.deps.init(),this.assertActive(),!this.ctx.wasmClient||!this.ctx.localNodeId))throw new Error("Node not initialized")}async ensureSignalingReadyForDiscovery(e){if(this.disposed||this.deps.usesTicketOnlySignalingMode())return;let t=this.deps.usesNativeIpcRuntimeWithoutWasmFallback();if(!this.deps.getWasmLoaded()&&t)this.loggedNativeDiscoveryWasmSkip||(this.loggedNativeDiscoveryWasmSkip=true,d(`[Client][NATIVE-GUARD] Discovery ${e} is using native IPC readiness; skipped WASM init.`));else if(!this.deps.getWasmLoaded()&&!(this.ctx.wasmClient&&this.ctx.localNodeId)&&(await this.deps.init(),this.disposed))return;try{await this.deps.ensureAuthenticated("discovery");}catch(n){console.warn(`[Client][AUTH] ensureAuthenticated failed for ${e}:`,n);}if(!this.disposed)try{this.ctx.wasmClient&&await this.deps.syncAuthTokenToWasm("auth-change");}catch(n){console.warn(`[Client][WASM-AUTH] Token sync failed for ${e}:`,n);}}};var rc={scheduled:0,coalesced:0,ran:0,orphanTsConnection:0,orphanRustRecord:0,orphanTsConnectionHealed:0},fn=class{constructor(e){this.deps=e;}usesTicketOnlySignalingMode(){return (this.deps.getOptions()?.signalingMode??"hosted")==="ticket-only"}usesDirectRoomBackend(){let e=this.deps.getOptions();return this.getRoomBackendTag().startsWith("space::")||(e.discoveryMode===void 0||e.discoveryMode==="space")&&typeof e.spaceKey=="string"&&e.spaceKey.trim().length>0}getRoomBackendTag(){return this.deps.getEffectiveRoomBackendTag()}requiresManagedTransportTrust(e){return !this.usesTicketOnlySignalingMode()&&!this.usesDirectRoomBackend()&&e!=="space"&&!!this.deps.getSignalingCurrentUser()?.id}getSignalingTelemetry(){return {transport:"runtime-bridge",wasmLoaded:this.deps.getWasmLoaded(),peerReconciliation:this.getPeerReconciliationStats()}}getPeerReconciliationStats(){return this.deps.getPeerReconciliationStats()??rc}getProtocolCapabilities(){return ue.getProtocolCapabilities()}async getRuntimeStatus(){let e="unknown";return typeof window<"u"&&(e=window.__TAURI__?"tauri":"browser"),{runtime:e,wasmLoaded:this.deps.getWasmLoaded(),localNodeId:this.deps.getLocalNodeId()||void 0,userId:this.deps.getSignalingCurrentUser()?.id??void 0}}};function Dr(r){let{host:e}=r;return new un({get options(){return e.getOptions()},get wasmClient(){return e.getWasmClient()},get node(){return e.getNode()},get localNodeId(){return e.getLocalNodeId()},get deviceId(){return e.getDeviceId()},setWasmClient:t=>e.setWasmClient(t),setSignalingWasmClient:t=>e.setSignalingWasmClient(t),setNode:t=>e.setNode(t),setLocalNodeId:t=>e.setLocalNodeId(t),setDeviceId:t=>e.setDeviceId(t),setEffectiveRoomBackendTag:t=>e.setEffectiveRoomBackendTag(t),usesTicketOnlySignalingMode:()=>r.getStatus().usesTicketOnlySignalingMode(),ensureAuthenticated:t=>e.ensureAuthenticated(t),syncAuthTokenToWasm:(t,n)=>e.syncAuthTokenToWasm(t,n),installAuthTokenSync:()=>e.installAuthTokenSync(),installAppLifecycleListeners:()=>r.getAppLifecycle().installListeners(),initMoQ:()=>e.initMoQ(),isWebRTCTransportEnabled:()=>e.isWebRTCTransportEnabled(),getLocalDeviceId:()=>e.getLocalDeviceId(),getTurnCredentials:()=>e.getTurnCredentials(),getRuntimeCapabilities:()=>e.getRuntimeCapabilities(),broadcastTransportCapabilityUpdate:t=>e.broadcastTransportCapabilityUpdate(t),registerDisposer:t=>e.registerDisposer(t)})}function Mr(r){let{host:e}=r;return new gn(e.getContext(),{ensureWasmRuntimeForP2P:()=>r.getReadiness().ensureWasmRuntimeForP2P(),ensureSignalingReadyForDiscovery:t=>r.getReadiness().ensureSignalingReadyForDiscovery(t),ensureWasmManagedTransport:(t,n,i)=>r.getManagedDialer().ensureWasmManagedTransport(t,n,i),getCurrentUserId:()=>e.getCurrentUserId(),getLocalDeviceId:()=>e.getLocalDeviceId(),getFallbackDeviceId:()=>e.getDeviceId(),startAutoConnect:(t,n)=>e.startAutoConnect(t,n),isConnected:t=>e.isConnected(t),disconnectNodeTransport:t=>e.disconnectNodeTransport(t)})}function Er(r){return new an(r.getContext(),{getDeterministicConnectionId:e=>r.getDeterministicConnectionId(e),getApprovedScope:e=>r.getApprovedScope(e)})}function xr(r){return new hn(r.host.getContext(),{ensureWasmRuntimeForP2P:()=>r.getReadiness().ensureWasmRuntimeForP2P()})}function Lr(r){let{host:e}=r;return new mn(e.getContext(),{init:()=>r.getBootstrap().init(),usesTicketOnlySignalingMode:()=>r.getStatus().usesTicketOnlySignalingMode(),usesNativeIpcRuntimeWithoutWasmFallback:()=>Ri(e.getRuntimeCapabilities()),getWasmLoaded:()=>r.getBootstrapWasmLoaded(),ensureAuthenticated:t=>e.ensureAuthenticated(t),syncAuthTokenToWasm:t=>e.syncAuthTokenToWasm(t)})}function Br(r){let{host:e}=r;return new fn({getEffectiveRoomBackendTag:()=>e.getEffectiveRoomBackendTag(),getLocalNodeId:()=>e.getLocalNodeId(),getOptions:()=>e.getOptions(),getPeerReconciliationStats:()=>e.getPeerReconciliationStats(),getSignalingCurrentUser:()=>({id:e.getCurrentUserId()}),getWasmLoaded:()=>r.getBootstrapWasmLoaded()})}function Fr(r){return new sn(r.getContext())}function Or(r){return new _i({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,setWasmClient:e=>{r.wasmClient=e;},getNode:()=>r.node,setNode:e=>{r.node=e;},getLocalNodeId:()=>r.localNodeId,setLocalNodeId:e=>{r.localNodeId=e;},getDeviceId:()=>r.deviceId,setDeviceId:e=>{r.deviceId=e;},setEffectiveRoomBackendTag:e=>{r.setEffectiveRoomBackendTag(e);},getEffectiveRoomBackendTag:()=>r.getEffectiveRoomBackendTag(),getPeerReconciliationStats:()=>r.getExistingPeerReconciliationStats(),getCurrentUserId:()=>r.signalingBackendController.getCurrentUser()?.id??null,getRuntimeCapabilities:()=>r.signalingBackendController.getRuntimeCapabilities(),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),getTurnCredentials:()=>r.signalingBackendController.getTurnCredentials(),setSignalingWasmClient:e=>r.signalingBackendController.setWasmClient(e),startAutoConnect:(e,t)=>r.signalingBackendController.startAutoConnect(e,t),isConnected:e=>r.signalingBackendController.isConnected(e),disconnectNodeTransport:e=>r.transportHealth.disconnectNodeTransport(e),getDeterministicConnectionId:e=>r.peerIdentity.getDeterministicConnectionId(e),getApprovedScope:e=>r.sessionTokens.getApprovedScope(e),ensureAuthenticated:e=>r.auth.ensureAuthenticated(e),syncAuthTokenToWasm:(e,t)=>r.auth.syncAuthTokenToWasm(e,t),installAuthTokenSync:()=>r.auth.installAuthTokenSync(),initMoQ:()=>r.moqServices.init(),isWebRTCTransportEnabled:()=>k$1(r.options),broadcastTransportCapabilityUpdate:e=>r.transportHandshake.broadcastTransportCapabilityUpdate(e),registerDisposer:e=>r.lifecycleScope.register(e)})}var _i=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getBootstrap:()=>this.bootstrap,getBootstrapWasmLoaded:()=>this._bootstrap?.wasmLoaded??false,getManagedDialer:()=>this.managedDialer,getReadiness:()=>this.readiness,getStatus:()=>this.status,getAppLifecycle:()=>this.appLifecycle}}get bootstrap(){return this._bootstrap??(this._bootstrap=Dr(this.factoryHost))}get connections(){return this._connections??(this._connections=Mr(this.factoryHost))}get managedDialer(){return this._managedDialer??(this._managedDialer=Er(this.host))}get identity(){return this._identity??(this._identity=xr(this.factoryHost))}get readiness(){return this._readiness??(this._readiness=Lr(this.factoryHost))}get status(){return this._status??(this._status=Br(this.factoryHost))}get appLifecycle(){return this._appLifecycle??(this._appLifecycle=Fr(this.host))}};var yn=class{constructor(e,t){this.ctx=e;this.deps=t;this.connectionKeyAgreementById=new Map;this.connectionKeyAgreementRemotePublicById=new Map;this.negotiatedByConnectionId=new Map;this.negotiatedByPeerId=new Map;this.waiters=[];this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}getApplicationCrypto(e){return e?this.deps.getConfiguredApplicationCrypto()??this.negotiatedByConnectionId.get(e.id):this.deps.getConfiguredApplicationCrypto()}getNegotiatedForPeer(e){let t=typeof e=="string"?e.trim():"";if(!t)return;let n=this.negotiatedByPeerId.get(t);if(n)return n;let i=this.deps.getKnownDeviceNodeId(t),o=[this.deps.getPeerState(t),i?this.deps.getPeerState(i):void 0].filter(a=>!!a);for(let a of o){let c=a.connectionId?.trim();if(c){let d=this.negotiatedByConnectionId.get(c);if(d)return d}for(let d of [...a.connectionIds??[]].reverse()){let p=d?.trim();if(!p)continue;let u=this.negotiatedByConnectionId.get(p);if(u)return u}}let s=Array.from(this.ctx.registry.values()).filter(a=>{let c=this.deps.getKnownDeviceIdForNode(a.remoteNodeId);return a.id===t||a.remoteNodeId===t||a.deviceId===t||i&&a.remoteNodeId===i||c===t});for(let a of s.reverse()){let c=this.negotiatedByConnectionId.get(a.id);if(c)return c}}resolveForPeer(e,t){let n=this.deps.getConfiguredApplicationCrypto();if(n)return n;if(t)return this.negotiatedByConnectionId.get(t.id);if(e)return this.getNegotiatedForPeer(e)}waitForPeer(e,t=1e4){let n=this.resolveForPeer(e);return n||!e||t<=0||this.disposed?Promise.resolve(n):new Promise(i=>{let o={peerId:e,resolve:i,timer:setTimeout(()=>{this.waiters=this.waiters.filter(s=>s!==o),i(void 0);},t)};this.waiters.push(o);})}dispose(){if(this.disposed)return;this.disposed=true;let e=this.waiters.splice(0);for(let t of e)clearTimeout(t.timer),t.resolve(void 0);}notifyWaiters(){if(this.waiters.length===0)return;let e=[];for(let t of this.waiters){let n=this.resolveForPeer(t.peerId);if(!n){e.push(t);continue}clearTimeout(t.timer),t.resolve(n);}this.waiters=e;}resolveStreamTools(e,t){let n=this.resolveForPeer(e,t);return n?h$1(n):void 0}shouldNegotiateKeyAgreement(){if(this.deps.getConfiguredApplicationCrypto())return false;if(this.deps.getAutomaticApplicationKeyAgreement()===false)throw new Error("[OpenRTC] automaticApplicationKeyAgreement cannot be disabled; configure applicationCrypto only for explicit pre-shared-key mode");return true}async ensureConnectionKeyAgreementState(e){let t=this.connectionKeyAgreementById.get(e.id);if(t)return t;let n=lo();return this.connectionKeyAgreementById.set(e.id,n),n}async handleKeyAgreement(e,t){if(!this.shouldNegotiateKeyAgreement())return {remotePublicChanged:false,cryptoReady:false};await this.ensureConnectionKeyAgreementState(e);let n=go(t.applicationKeyAgreement),i=t.capabilities?.applicationKeyAgreement===true||!!n;if(!n||!i||!this.ctx.localNodeId){if((typeof e.getControlFrameMode=="function"?e.getControlFrameMode():"typed")==="native-main"&&!i&&!n)return {remotePublicChanged:false,cryptoReady:false};throw new Error("Peer does not support mandatory application key agreement")}let o=this.connectionKeyAgreementById.get(e.id);if(!o)return {remotePublicChanged:false,cryptoReady:false};let s=t.applicationKeyAgreement?.publicKey?.trim()??"",a=this.connectionKeyAgreementRemotePublicById.get(e.id)??null,c=!!s&&a!==s,d$1=po(o.secretKey,n,this.ctx.localNodeId,e.remoteNodeId);s&&this.connectionKeyAgreementRemotePublicById.set(e.id,s);let p=g$1(d$1,{requireEncrypted:true,replayProtection:true});this.index(e,p),this.notifyWaiters(),e.setApplicationCrypto(p);let u=this.ctx.registry.get(e.id);return u&&u!==e&&!u.isClosed&&typeof u.setApplicationCrypto=="function"&&u.setApplicationCrypto(p),await this.syncKeyToNative(e.id,d$1),this.deps.notifyApplicationRouteReady(e,`key-agreement:${t.action??"hello"}`),d("[Client][KEY-AGREEMENT] Application crypto ready",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:t.action??"hello",remoteSupports:i,remotePublicChanged:c}),{remotePublicChanged:c,cryptoReady:true}}index(e,t){this.negotiatedByConnectionId.set(e.id,t);let n=new Set([e.id,e.remoteNodeId,e.deviceId,this.deps.getKnownDeviceIdForNode(e.remoteNodeId)??""]);for(let i of n){let o=typeof i=="string"?i.trim():"";o&&this.negotiatedByPeerId.set(o,t);}}getForConnectionOrPeer(e,t){return this.negotiatedByConnectionId.get(e)??this.negotiatedByPeerId.get(t)}indexPeer(e,t){let n=typeof e=="string"?e.trim():"";n&&this.negotiatedByPeerId.set(n,t);}reindexDevice(e){let t=typeof e.nodeId=="string"?e.nodeId.trim():"";if(!t||!e.deviceId)return;let n=this.getNegotiatedForPeer(t);n&&this.negotiatedByPeerId.set(e.deviceId,n);}async syncRequiredToNative(e){let t=this.wasmClient;!t||typeof t.setConnectionApplicationCryptoRequired!="function"||await t.setConnectionApplicationCryptoRequired(e);}async syncKeyToNative(e,t){let n=this.wasmClient;if(!(!n||typeof n.setConnectionApplicationCryptoKey!="function")){await this.syncRequiredToNative(e);try{await n.setConnectionApplicationCryptoKey(e,Array.from(t));}catch(i){let o=this.ctx.registry.get(e);throw o&&typeof o.requireApplicationCrypto=="function"&&o.requireApplicationCrypto(),console.error("[Client][KEY-AGREEMENT] Failed to sync derived key to native runtime",{connectionId:e,error:i}),i}}}markRequired(e){typeof e.requireApplicationCrypto=="function"&&e.requireApplicationCrypto(),this.syncRequiredToNative(e.id).catch(t=>{console.warn("[Client][KEY-AGREEMENT] Failed to sync required-crypto flag to native runtime",{connectionId:e.id,error:t});});}hydrateAdoptedConnection(e,t){if(e.isClosed||this.resolveForPeer(e.remoteNodeId,e))return false;let n=this.getNegotiatedForPeer(e.remoteNodeId);return n?(this.negotiatedByConnectionId.set(e.id,n),e.setApplicationCrypto(n),this.notifyWaiters(),this.deps.notifyApplicationRouteReady(e,t),d("[Client][HANDSHAKE] hydrated adopted connection application crypto from peer index",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t}),true):false}openWebRTCExplicitTransferPayload(e,t){let n=this.resolveForPeer(t?.remoteNodeId,t);return n?h$1(n).openFrame(e):e}protectDirectMoQPayload(e,t,n){return this.resolveForPeer(t,n)?.protectPayload(3,e)??e}openDirectMoQPayload(e,t,n){let i=this.resolveForPeer(t,n);return !i||!f$1(e)?{payload:e,encrypted:false}:{payload:i.openPayload(3,e)??i.openPayload(0,e),encrypted:true}}get wasmClient(){return this.ctx.wasmClient}};var ac=15e3,cc=2,dc=150,vn=class{constructor(e,t){this.ctx=e;this.deps=t;this.pendingTrustApprovals=new Map;this.pendingTrustApprovalScopes=new Map;this.rejectionCooldowns=new Map;this.approvedNodes=new Set;this.approvedConnectionIds=new Set;this.approvedScopesByConnectionId=new Map;this.pendingTokenByNodeId=new Map;this.pendingTokenPayloadByNodeId=new Map;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true,this.deps.clearManagedPresenceTicket(),this.clearInMemoryState();let e=this.wasmClient;e&&typeof e.clear_session_tokens=="function"&&e.clear_session_tokens();}async getEndpointTicketWithToken(e,t=0){if(this.disposed)throw new Error("Session token service is disposed");await this.deps.ensureWasmRuntimeForP2P();let n=this.wasmClient;if(n&&typeof n.endpoint_ticket_with_token=="function"){let o=n.endpoint_ticket_with_token.bind(n);return await d$1(()=>o(e,t),{isActive:()=>!this.disposed})}if(e.trim()==="user-device")throw new Error("Managed user-device admission requires Rust/WASM endpoint_ticket_with_token support.");let i=await this.deps.getTicket();return this.buildCompoundTicketWithToken(i,e,t)}buildCompoundTicketWithToken(e,t,n=0){if(this.disposed)throw new Error("Session token service is disposed");let i=Bo(),o=t.trim()==="user-device"?void 0:Date.now()+9e5,s=this.wasmClient;return s&&typeof s.register_session_token=="function"&&(typeof o=="number"&&typeof s.register_session_token_with_expiry_ms=="function"?s.register_session_token_with_expiry_ms(i,t,n,o):s.register_session_token(i,t,n)),Ct(e,i,t,n,o)}registerSessionToken(e,t,n){if(this.disposed)return;let i=this.wasmClient;i&&typeof i.register_session_token=="function"&&i.register_session_token(e,t,n);}revokeSessionToken(e){if(this.disposed)return;i("Client.revokeSessionToken",{tokenLength:e.length});let t=this.wasmClient;t&&typeof t.revoke_session_token=="function"&&t.revoke_session_token(e);}async revokeTokensByScope(e){if(this.disposed)return [];i("Client.revokeTokensByScope",{grantScope:e});let t=e.trim(),n=Array.from(this.approvedScopesByConnectionId.entries()).filter(([,c])=>c===t).map(([c])=>c);if(await this.deps.ensureWasmRuntimeForP2P(),this.disposed)return [];let i$1=this.wasmClient,o=i$1&&typeof i$1.revoke_tokens_by_scope=="function"?await i$1.revoke_tokens_by_scope(e):[],s=Array.from(new Set([...Array.isArray(o)?o:[],...n]));if(s.length===0)return [];for(let c of s)this.clearConnectionApproval(c);let a=s.map(c=>this.ctx.registry.get(c)).filter(c=>!!c);return await Promise.allSettled(a.map(c=>this.disconnectConnectionBestEffort(c))),s}async clearSessionTokens(){if(i("Client.clearSessionTokens",{}),this.disposed){this.clearInMemoryState();return}if(await this.deps.ensureWasmRuntimeForP2P(),this.deps.clearManagedPresenceTicket(),this.disposed){this.clearInMemoryState();return}this.clearInMemoryState();let e=this.wasmClient;e&&typeof e.clear_session_tokens=="function"&&e.clear_session_tokens();}async validateIncomingSessionToken(e,t,n){if(this.disposed)return {ok:false,reason:"session-token-service-disposed"};let i=this.wasmClient;if(!i||typeof i.validate_session_token!="function")return {ok:true};try{let o="";return t&&n&&typeof i.validate_session_token_for_connection_with_payload=="function"?o=await i.validate_session_token_for_connection_with_payload(e,t,n):t&&typeof i.validate_session_token_for_connection=="function"?o=await i.validate_session_token_for_connection(e,t):o=i.validate_session_token(e),{ok:!0,scope:o||void 0}}catch(o){return {ok:false,reason:o?.message||`${o}`}}}async validateIncomingSessionTokenWithRetry(e,t,n){if(this.disposed)return {ok:false,reason:"session-token-service-disposed"};let i=await this.validateIncomingSessionToken(e,t,n?.tokenPayload);if(i.ok||!e||!(i.reason??"").toLowerCase().includes("unknown session token"))return i;for(let s=1;s<=cc;s+=1){if(await r(dc*s),this.disposed)return {ok:false,reason:"session-token-service-disposed"};if(i=await this.validateIncomingSessionToken(e,t,n?.tokenPayload),i.ok)return d("[Client][SESSION-TOKEN] validation recovered after retry",{source:n?.source??"unknown",remoteNodeId:n?.remoteNodeId??null,connectionId:t??null,attempt:s}),i}return i}rememberPendingTrustApproval(e,t){if(this.disposed||!e)return;this.pendingTrustApprovals.set(e,Date.now());let n=typeof t=="string"?t.trim():"";n?this.pendingTrustApprovalScopes.set(e,n):this.pendingTrustApprovalScopes.delete(e);}consumePendingTrustApproval(e){if(this.disposed)return {approved:false};let t=this.pendingTrustApprovals.get(e);if(!t)return {approved:false};let n=this.pendingTrustApprovalScopes.get(e)??null;return this.pendingTrustApprovals.delete(e),this.pendingTrustApprovalScopes.delete(e),Date.now()-t>ac?{approved:false}:{approved:true,scope:n}}applyTrustApproval(e,t,n="session-token"){if(this.disposed||!e||e.isClosed)return;let i=typeof t=="string"?t.trim():"";this.rememberPendingTrustApproval(e.id,i),this.rejectionCooldowns.delete(e.remoteNodeId),this.deps.clearTrustFailureCooldown(e.remoteNodeId),this.approvedNodes.add(e.remoteNodeId),this.approvedConnectionIds.add(e.id),i?this.approvedScopesByConnectionId.set(e.id,i):this.approvedScopesByConnectionId.delete(e.id);let s=this.deps.sessionTokenScopeAllowsDeviceBinding(i)?this.deps.getKnownDeviceIdForNode(e.remoteNodeId):null,a=this.deps.initializeConnectionTrust(e,s);a.required=false,a.verified=true,a.failed=false,a.failureReason=void 0,a.issuedChallenge=null,a.verifiedDeviceId=a.verifiedDeviceId??a.expectedDeviceId??s??null,this.deps.applyConnectionTrustProjection(e);let c=a.verifiedDeviceId??a.expectedDeviceId??s??null;c&&this.deps.bindConnectionDeviceIdInRust(e,c),i&&this.deps.addPeerScope(e.id,i),d("[Client][AUTH] session-token approval applied to connection trust",{connectionId:e.id,remoteNodeId:e.remoteNodeId,scope:t??null,source:n}),this.deps.isWebRTCTransportEnabled()&&e.remoteSupportsWebRTC&&e.requestWebRTCUpgrade("session-token-trust-applied");}clearConnectionApproval(e){this.disposed||(this.approvedConnectionIds.delete(e),this.approvedScopesByConnectionId.delete(e),this.pendingTrustApprovals.delete(e),this.pendingTrustApprovalScopes.delete(e));}approveNode(e){this.disposed||this.approvedNodes.add(e);}approveConnection(e){this.disposed||this.approvedConnectionIds.add(e);}isApproved(e,t){return this.approvedConnectionIds.has(e)||this.approvedNodes.has(t)}isApprovedNode(e){return this.approvedNodes.has(e)}isApprovedConnection(e){return this.approvedConnectionIds.has(e)}getApprovedNodes(){return this.approvedNodes}getApprovedConnectionIds(){return this.approvedConnectionIds}clearRejectionCooldown(e){this.rejectionCooldowns.delete(e);}getRejectionCooldown(e){return this.rejectionCooldowns.get(e)}setRejectionCooldown(e,t){this.disposed||this.rejectionCooldowns.set(e,t);}getApprovedScope(e){return this.approvedScopesByConnectionId.get(e)??null}setApprovedScope(e,t){this.disposed||this.approvedScopesByConnectionId.set(e,t);}rememberPendingTokenForNode(e,t,n){this.disposed||(this.pendingTokenByNodeId.set(e,t),this.pendingTokenPayloadByNodeId.set(e,n));}getPendingTokenForNode(e){return this.pendingTokenByNodeId.get(e)}getPendingTokenPayloadForNode(e){return this.pendingTokenPayloadByNodeId.get(e)}clearPendingTokenForNode(e){this.disposed||(this.pendingTokenByNodeId.delete(e),this.pendingTokenPayloadByNodeId.delete(e));}clearInMemoryState(){this.pendingTokenByNodeId.clear(),this.pendingTokenPayloadByNodeId.clear(),this.pendingTrustApprovals.clear(),this.pendingTrustApprovalScopes.clear(),this.rejectionCooldowns.clear(),this.approvedNodes.clear(),this.approvedConnectionIds.clear(),this.approvedScopesByConnectionId.clear();}get wasmClient(){return this.ctx.wasmClient}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};function Wr(r){return new Ti({getContext:()=>r.getClientContext(),getOptions:()=>r.options,ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getTicket:()=>r.runtimeIdentity.getTicket(),clearManagedPresenceTicketIfExists:()=>r.accessServices.clearManagedPresenceTicketIfExists(),clearTrustFailureCooldown:e=>{r.connectionTrust.clearFailureCooldown(e);},sessionTokenScopeAllowsDeviceBinding:e=>r.connectionTrust.sessionTokenScopeAllowsDeviceBinding(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),initializeConnectionTrust:(e,t)=>r.connectionTrust.initialize(e,t),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>r.connectionDeviceBinder.bindConnectionDeviceIdInRust(e,t),addPeerScope:(e,t)=>{r.peerServices.addPeerScope(e,t);},isWebRTCTransportEnabled:()=>k$1(r.options),getConfiguredApplicationCrypto:()=>r.options?.applicationCrypto,getAutomaticApplicationKeyAgreement:()=>r.options?.automaticApplicationKeyAgreement,getKnownDeviceNodeId:e=>r.deviceDirectory.getKnownDeviceNodeId(e),getPeerState:e=>r.peerServices.getPeerState(e),notifyApplicationRouteReady:(e,t)=>r.transportUpgrade.notifyApplicationRouteReady(e,t)})}var Ti=class{constructor(e){this.host=e;}get sessionTokens(){return this._sessionTokens||(this._sessionTokens=new vn(this.host.getContext(),{ensureWasmRuntimeForP2P:()=>this.host.ensureWasmRuntimeForP2P(),getTicket:()=>this.host.getTicket(),clearManagedPresenceTicket:()=>this.host.clearManagedPresenceTicketIfExists(),clearTrustFailureCooldown:e=>this.host.clearTrustFailureCooldown(e),sessionTokenScopeAllowsDeviceBinding:e=>this.host.sessionTokenScopeAllowsDeviceBinding(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),initializeConnectionTrust:(e,t)=>this.host.initializeConnectionTrust(e,t),applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>this.host.bindConnectionDeviceIdInRust(e,t),addPeerScope:(e,t)=>this.host.addPeerScope(e,t),isWebRTCTransportEnabled:()=>this.host.isWebRTCTransportEnabled()})),this._sessionTokens}get applicationCrypto(){return this._applicationCrypto||(this._applicationCrypto=new yn(this.host.getContext(),{getConfiguredApplicationCrypto:()=>this.host.getConfiguredApplicationCrypto(),getAutomaticApplicationKeyAgreement:()=>this.host.getAutomaticApplicationKeyAgreement(),getKnownDeviceNodeId:e=>this.host.getKnownDeviceNodeId(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),getPeerState:e=>this.host.getPeerState(e),notifyApplicationRouteReady:(e,t)=>this.host.notifyApplicationRouteReady(e,t)})),this._applicationCrypto}resolveExistingApplicationCryptoForPeer(e,t){return this._applicationCrypto?.resolveForPeer(e,t)}getApplicationCrypto(e){return this.host.getConfiguredApplicationCrypto()||!e?this.host.getConfiguredApplicationCrypto():this.applicationCrypto.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.host.getConfiguredApplicationCrypto()||!e&&!t?this.host.getConfiguredApplicationCrypto():this.applicationCrypto.resolveForPeer(e,t)}waitForApplicationCryptoForPeer(e,t=0){return this.host.getConfiguredApplicationCrypto()||!e||t<=0?Promise.resolve(this.host.getConfiguredApplicationCrypto()):this.applicationCrypto.waitForPeer(e,t)}};var bn=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}buildApplicationIncomingStreamEvent(e){if(this.disposed||this.shouldTreatIncomingStreamAsTransportOnly(e))return e;let t=this.deps.resolveApplicationCryptoStreamTools(e.remoteNodeId);if(!t||e.invalid||e.protocolHint==="explicit"||e.protocolHint==="native-main")return e;try{if(e.type==="uni"){let n=e.stream;return !n||typeof n.getReader!="function"?e:{...e,stream:t.wrapReadable(n),applicationCrypto:t}}if(e.type==="bi"&&v(e.stream)){let n=e.stream;return n?.applicationCryptoWrapped===!0?{...e,applicationCrypto:t}:e.protocolHint==="control"?{...e,applicationCrypto:t}:{...e,stream:{...n,send:t.wrapWritable(n.send),recv:t.wrapReadable(n.recv)},applicationCrypto:t}}}catch(n){this.deps.logIncomingDiagnostic("application-crypto:wrap-listener-stream-failed",{remoteNodeId:e.remoteNodeId||"unknown",traceId:e.traceId||null,protocolHint:e.protocolHint??null,error:n});}return e}shouldTreatIncomingStreamAsTransportOnly(e){return this.disposed||e.type!=="bi"?false:this.deps.isTransportOnlyChannel(e.channel?.channelId)?true:e.protocolHint!=="explicit"?false:this.deps.usesTicketOnlySignalingMode()?true:this.deps.hasTransportOnlyConnectionForRemoteNode(e.remoteNodeId)}dispatchSyntheticExplicitIncomingStream(e,t){if(this.disposed)return;d("[Client][WebRTC][transfer] Dispatching synthetic explicit stream from WebRTC datachannel",{connectionId:e.id,remoteNodeId:e.remoteNodeId,payloadBytes:t.byteLength});let n={send:new WritableStream({write(){}}),recv:new ReadableStream({start(a){a.enqueue(t),a.close();}}),endpoint_id:e.remoteNodeId},i=this.deps.getConnectionChannelId(e.id),o={type:"bi",stream:n,remoteNodeId:e.remoteNodeId,protocolHint:"explicit",traceId:`webrtc-explicit-${Date.now()}`,channel:i?{channelId:i}:null};if(this.deps.dispatchIncomingChannelListeners(o)||this.disposed)return;this.deps.dispatchIncomingGenericListeners(o)||this.handleSyntheticExplicitFallbackInBackground(e,o);}handleSyntheticExplicitFallbackInBackground(e,t){let n=i=>{this.disposed||d("[Client][INCOMING] Failed to process synthetic explicit stream",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:i});};try{Promise.resolve(this.deps.handleUnhandledIncomingStreamEvent(t)).catch(n);}catch(i){n(i);}}};var Cn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Application stream controller is disposed")}async closeWritableBestEffort(e){if(e)try{let t=e.getWriter?.();if(!t)return;try{await t.close();}catch{}finally{try{t.releaseLock();}catch{}}}catch{}}async openBi(e){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.ctx.wasmClient;d("[Client][OPEN-BI] Opening bidirectional application stream",{peerId:e,hasOpenPeerBi:typeof t.open_peer_bi=="function"});let n=typeof t.open_peer_bi=="function"?await t.open_peer_bi(e,5e3):await t.open_bi(e);this.disposed&&(await y(n,"application-stream-controller-disposed-after-open-bi"),this.assertActive()),d("[Client][OPEN-BI] Bidirectional application stream opened",{peerId:e,endpointId:n?.endpoint_id??n?.endpointId??null,applicationCryptoWrapped:n?.applicationCryptoWrapped===true});let i=this.deps.getApplicationCryptoForPeer(e),o=n?.applicationCryptoWrapped===true;if(i&&!o){let s=h$1(i);return {readable:s.wrapReadable(n.recv),writable:s.wrapWritable(n.send)}}return {readable:n.recv,writable:n.send}}async openUni(e){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.deps.getApplicationCryptoForPeer(e),n=(a,c)=>!t||c?a:h$1(t).wrapWritable(a),i=this.ctx.wasmClient;if(typeof i.open_peer_uni=="function"){let a=await i.open_peer_uni(e,5e3),c=a?.writable??a;return this.disposed&&(await this.closeWritableBestEffort(c),this.assertActive()),n(c,a?.applicationCryptoWrapped===true)}let o=await i.open_uni(e),s=o?.writable??o;return this.disposed&&(await this.closeWritableBestEffort(s),this.assertActive()),n(s,o?.applicationCryptoWrapped===true)}};function ot(r){try{let e=r?.type;return typeof e=="string"?e:"unknown"}catch{return "unknown"}}function Le(r){try{let e=r?.endpointId;if(typeof e=="string"&&e.trim().length>0)return e}catch{}try{let e=r?.endpoint_id;if(typeof e=="string"&&e.trim().length>0)return e}catch{}return "unknown"}function Ur(r){try{let e=r?.protocolHint;if(e==="control"||e==="explicit"||e==="native-main")return e}catch{}return null}function Hr(r){try{if(!r||!("channel"in r))return {present:!1,channel:null};let e=r.channel;if(e==null)return {present:!0,channel:null};if(typeof e!="object")return {present:!1,channel:null};let t=typeof e.channelId=="string"?e.channelId.trim():"";if(!t)return {present:!1,channel:null};let n=e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)?e.metadata:null;return {present:!0,channel:{channelId:t,metadata:n}}}catch{return {present:false,channel:null}}}var xe=class xe{constructor(e){this.wasmClient=e;this.clients=new Set;this.listenLoopTask=null;this.activeDispatches=new Set;}addClient(e){this.clients.has(e)||(this.clients.add(e),this.ensureListening());}removeClient(e){this.clients.delete(e);}dispatchIncomingAsync(e,t){let n=Le(e),i=performance.now(),o=this.dispatchIncoming(e).then(()=>{let s=performance.now()-i;s>50&&console.warn(`[PERFORMANCE] handleIncomingStream loop took abnormally long: ${Math.round(s)}ms`,{endpointId:n,type:t});}).catch(s=>{console.error("[Client][INCOMING] Failed to handle incoming stream via shared hub",{remoteNodeId:n,type:t,error:s});}).finally(()=>{this.activeDispatches.delete(o);});this.activeDispatches.add(o);}ensureListening(){this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null,this.clients.size>0&&this.ensureListening();}));}getPrimaryClient(){let e=this.clients.values().next();return e.done?null:e.value}getChannelTargetClients(e){return Array.from(this.clients).reverse().filter(t=>t.hasIncomingChannelListener(e))}async dispatchIncoming(e){let t=this.getPrimaryClient();if(!t)return;let n=Array.from(this.clients).some(a=>a.hasAnyIncomingChannelListeners()),i=await t.normalizeIncomingStreamEvent(e,{inspectChannelEnvelope:n}),o=i.channel?.channelId?.trim();if(o){for(let a of this.getChannelTargetClients(o))if(a.dispatchIncomingChannelListeners(i))return}let s=this.getPrimaryClient();if(s){if(i.protocolHint==="native-main"){await s.handleUnhandledIncomingStreamEvent(i);return}s.dispatchIncomingGenericListeners(i)||await s.handleUnhandledIncomingStreamEvent(i);}}async listenLoop(){let e=0;for(;;){if(this.clients.size===0)return;let t=null;try{let i=(await this.wasmClient.incoming_streams()).getReader();for(t=i,e=0,ae()&&Ht()&&d("[Client][INCOMING][MOBILE] shared-hub reader acquired",{sharedHubClients:this.clients.size});this.clients.size>0;){let{done:o,value:s}=await i.read();if(o)throw new Error("incoming stream reader closed unexpectedly");if(!s)continue;let a=ot(s);a!=="uni"&&d("[Client][INCOMING] Received stream from WASM node",{type:a,endpointId:Le(s),sharedHubClients:this.clients.size}),this.dispatchIncomingAsync(s,a);}}catch(n){if(this.clients.size===0)return;e+=1;let i=u(e,xe.RETRY_MIN_DELAY_MS,xe.RETRY_MAX_DELAY_MS);console.warn("[Client][INCOMING] Shared listen loop restarting after stream failure",{attempt:e,delayMs:i,mobile:ae(),error:n}),await r(i);}finally{if(t)try{t.releaseLock(),ae()&&Ht()&&d("[Client][INCOMING][MOBILE] shared-hub reader released",{sharedHubClients:this.clients.size});}catch{}}}}};xe.RETRY_MIN_DELAY_MS=250,xe.RETRY_MAX_DELAY_MS=2e3;var Sn=xe;var rt=class rt{constructor(e,t){this.ctx=e;this.deps=t;this.listening=false;this.presenceStarted=false;this.listenLoopTask=null;this.hubClient={hasIncomingChannelListener:n=>this.deps.hasIncomingChannelListener(n),hasAnyIncomingChannelListeners:()=>this.deps.hasAnyIncomingChannelListeners(),normalizeIncomingStreamEvent:(n,i)=>this.deps.normalizeIncomingStreamEvent(n,i),dispatchIncomingChannelListeners:n=>this.deps.dispatchIncomingChannelListeners(n),dispatchIncomingGenericListeners:n=>this.deps.dispatchIncomingGenericListeners(n),handleUnhandledIncomingStreamEvent:n=>this.deps.handleUnhandledIncomingStreamEvent(n)},this.ctx.registerDisposer(()=>this.stop());}async start(e={}){if(this.listening)return;await this.deps.ensureWasmRuntimeForP2P();let t=false;this.markListening(false);try{let n=this.getSharedIncomingStreamHub();n?(n.addClient(this.hubClient),t=!0):this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null;})),e.startPresence!==!1&&(await this.deps.startPresenceForListen(),this.presenceStarted=!0);}catch(n){throw this.markStopped(),this.presenceStarted=false,t&&this.getSharedIncomingStreamHub()?.removeClient(this.hubClient),n}}stop(){let e=this.listening;if(this.markStopped(),e)for(let t of Array.from(this.ctx.registry.values()))t.isClosed||this.disconnectBestEffort(t);this.getSharedIncomingStreamHub()?.removeClient(this.hubClient),e&&this.presenceStarted&&this.deps.setOfflinePresence(),this.presenceStarted=false;}prepareForSignOut(){this.markStopped(),this.presenceStarted=false;}isListening(){return this.listening}markListening(e=true){this.listening=true,this.presenceStarted=e;}markStopped(){this.listening=false;}getSharedIncomingStreamHub(){let e=this.ctx.wasmClient;if(!e||typeof e.incoming_streams!="function")return null;let t=e,n=rt.incomingStreamHubs.get(t);return n||(n=new Sn(e),rt.incomingStreamHubs.set(t,n)),n}async listenLoop(){await this.deps.getIncomingStreamRouter().listenLoop({isListening:()=>this.listening,getWasmClient:()=>this.ctx.wasmClient,handleIncomingStream:e=>this.handleIncomingStream(e),shouldVerboseIncomingDiagnostics:()=>this.deps.shouldVerboseIncomingDiagnostics(),getLocalNodeId:()=>this.ctx.localNodeId||null,retryMinDelayMs:this.deps.retryMinDelayMs,retryMaxDelayMs:this.deps.retryMaxDelayMs});}async handleIncomingStream(e){return this.deps.handleIncomingStream(e)}shouldInspectIncomingChannelEnvelope(){return this.deps.shouldInspectIncomingChannelEnvelope()}normalizeIncomingStreamEvent(e,t={}){return this.deps.normalizeIncomingStreamEvent(e,t)}dispatchIncomingChannelListeners(e){return this.deps.dispatchIncomingChannelListeners(e)}dispatchIncomingGenericListeners(e){return this.deps.dispatchIncomingGenericListeners(e)}handleUnhandledIncomingStreamEvent(e){return this.deps.handleUnhandledIncomingStreamEvent(e)}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}};rt.incomingStreamHubs=new WeakMap;var In=rt;var wn=class{constructor(e){this.deps=e;this.traceSequence=0;}getRuntimeSafetyProfile(){return this.deps.getRuntimeSafetyProfileOverride()??ze(this.deps.getOptions()??{})}shouldVerboseIncomingDiagnostics(){return this.getRuntimeSafetyProfile().diagnosticsMode}shouldInspectIncomingChannelEnvelope(){return !(!this.deps.hasAnyIncomingChannelListeners()||this.getRuntimeSafetyProfile().skipIncomingChannelEnvelopeInspection)}nextIncomingTraceId(e,t){Number.isFinite(this.traceSequence)||(this.traceSequence=0),this.traceSequence+=1;let n=t&&t.length>0?t.slice(0,8):"unknown";return `${e}-${n}-${this.traceSequence.toString(36)}`}logIncomingDiagnostic(e,t){this.shouldVerboseIncomingDiagnostics()&&d(`[Client][INCOMING][MOBILE] ${e}`,t);}safeReleaseReaderLock(e,t,n,i=(o,s)=>this.logIncomingDiagnostic(o,s)){try{e.releaseLock(),i("releaseLock:ok",{context:t,traceId:n||null});}catch(o){console.warn("[Client][INCOMING] releaseLock failed",{context:t,traceId:n||null,error:o});}}async cancelUnhandledIncomingUniStream(e$1,t,n=(i,o)=>this.logIncomingDiagnostic(i,o)){if(!(!e$1||typeof e$1!="object")){if(this.shouldVerboseIncomingDiagnostics()){n("uni:drop-unhandled",{remoteNodeId:t||"unknown"});return}try{let i=e$1;if(typeof i.cancel=="function")return;if(typeof i.getReader=="function"){let o=i.getReader();try{await o.read().catch(()=>{});}finally{try{o.releaseLock();}catch{}}e("[Client][INCOMING] Released unhandled uni stream reader",{remoteNodeId:t});}}catch(i){console.warn("[Client][INCOMING] Failed to cancel unhandled uni stream",{remoteNodeId:t,error:i});}}}shouldSkipIncomingStreamProbe(){return this.getRuntimeSafetyProfile().skipIncomingBiProbe===true}};var Pn=class{constructor(e,t){this.config=e;this.deps=t;}async normalize(e,t){return this.deps.router.normalizeIncomingStreamEvent(e,t,this.normalizationDeps())}async extractIncomingChannelEnvelope(e,t,n){return this.deps.router.extractIncomingChannelEnvelope(e,t,this.channelInspectionDeps(),n)}async classifyBiIncomingStream(e,t){return this.deps.router.classifyBiIncomingStream(e,this.channelInspectionDeps(),t)}async maybeOpenEncryptedExplicitBiStream(e,t,n){return this.deps.router.maybeOpenEncryptedExplicitBiStream(e,this.cryptoProbeConfig(),this.cryptoProbeDeps(),t,n)}maybeWrapIncomingBiStreamWithApplicationCrypto(e,t,n){return this.deps.router.maybeWrapIncomingBiStreamWithApplicationCrypto(e,this.cryptoProbeDeps(),t,n)}async maybeOpenEncryptedControlBiStream(e,t,n){return this.deps.router.maybeOpenEncryptedControlBiStream(e,this.cryptoProbeConfig(),this.cryptoProbeDeps(),t,n)}async detectNativeMainStream(e,t,n){return this.deps.router.detectNativeMainStream(e,t,{nativeMainProtocolByte:this.config.nativeMainProtocolByte,explicitProtocolByte:this.config.explicitProtocolByte,label:this.config.nativeMainLabel,maxLabelBytes:this.config.nativeMainMaxLabelBytes},this.channelInspectionDeps(),n)}channelInspectionDeps(){return {logIncomingDiagnostic:(e,t)=>this.deps.logIncomingDiagnostic(e,t),releaseReaderLock:(e,t,n)=>this.deps.releaseReaderLock(e,t,n)}}cryptoProbeConfig(){return {explicitProtocolByte:this.config.explicitProtocolByte,maxEncryptedFrameBytes:this.config.maxEncryptedFrameBytes,probeDeadlineMs:this.config.probeDeadlineMs}}cryptoProbeDeps(){return {...this.channelInspectionDeps(),resolveApplicationCryptoForPeer:e=>this.deps.resolveApplicationCryptoForPeer(e),waitForApplicationCryptoForPeer:e=>this.deps.waitForApplicationCryptoForPeer(e,this.config.explicitApplicationCryptoWaitMs),resolveApplicationCryptoStreamTools:e=>this.deps.resolveApplicationCryptoStreamTools(e)}}normalizationDeps(){return {...this.cryptoProbeDeps(),nextIncomingTraceId:(e,t)=>this.deps.nextIncomingTraceId(e,t),normalizeAuthoritativeIncomingProtocolHint:(e,t,n)=>Mt(e),shouldStripIncomingMainLabel:()=>$o(this.deps.shouldSkipIncomingStreamProbe()),shouldSkipIncomingBiProbeForRemoteNode:e=>this.deps.shouldSkipIncomingBiProbeForRemoteNode(e),inferTicketFlowBiProtocolHint:e=>this.deps.inferTicketFlowBiProtocolHint(e),shouldSkipIncomingStreamProbe:()=>this.deps.shouldSkipIncomingStreamProbe(),isTransportOnlyChannel:e=>this.deps.isTransportOnlyChannel(e),detectNativeMainStream:(e,t,n)=>this.detectNativeMainStream(e,t,n),extractIncomingChannelEnvelope:(e,t,n)=>this.extractIncomingChannelEnvelope(e,t,n),classifyBiIncomingStream:(e,t)=>this.classifyBiIncomingStream(e,t),maybeWrapIncomingBiStreamWithApplicationCrypto:(e,t,n)=>this.maybeWrapIncomingBiStreamWithApplicationCrypto(e,t,n),maybeOpenEncryptedExplicitBiStream:(e,t,n)=>this.maybeOpenEncryptedExplicitBiStream(e,t,n),maybeOpenEncryptedControlBiStream:(e,t,n)=>this.maybeOpenEncryptedControlBiStream(e,t,n)}}};var Rn=class{maybeWrapIncomingBiStreamWithApplicationCrypto(e,t,n,i){if(!v(e)||e?.applicationCryptoWrapped===true)return e;let o=t.resolveApplicationCryptoStreamTools(n);if(!o)return e;try{return {...e,send:o.wrapWritable(e.send),recv:o.wrapReadable(e.recv),applicationCryptoWrapped:!0}}catch(s){return t.logIncomingDiagnostic("application-crypto:early-wrap-incoming-bi-failed",{remoteNodeId:n||"unknown",traceId:i||null,error:s}),e}}async maybeOpenEncryptedExplicitBiStream(e,t$1,n,i,o){let s=n.resolveApplicationCryptoForPeer(o);if(!v(e))return e;let a;try{a=e.recv.getReader();}catch{return e}let c=(C,I,k=null)=>z(a,C,{context:I,traceId:i,pendingRead:k,release:T=>n.releaseReaderLock(a,`${I}:${T}`,i),log:(T,_)=>n.logIncomingDiagnostic(T,_)}),d=C=>x(e,C),p=[],u=new Uint8Array(0),g=null,f=Date.now()+t$1.probeDeadlineMs,v$1=async()=>{let C=await A(a,f);return C.status==="timeout"?(g=C.pendingRead??null,false):C.status==="done"?false:(C.value&&C.value.byteLength>0&&(p.push(C.value),u=t(p)),true)},y=()=>g?(n.logIncomingDiagnostic("explicit-crypto:probe-deadline",{traceId:i||null,endpointId:o||"unknown",bufferedBytes:u.byteLength}),d(c(u,"explicit-crypto:probe-deadline",g))):null;try{for(;u.byteLength<5&&await v$1(););let C=y();if(C)return C;if(u.byteLength<5||u[0]!==t$1.explicitProtocolByte)return d(c(u,"explicit-crypto:not-probeable"));let I=new DataView(u.buffer,u.byteOffset+1,u.byteLength-1).getUint32(0,!1);if(I===0||I>t$1.maxEncryptedFrameBytes){let E=u.slice(1);return this.looksLikeApplicationCryptoEnvelope(E)&&(s||(n.logIncomingDiagnostic("explicit-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),s=await n.waitForApplicationCryptoForPeer(o)),s)?(n.logIncomingDiagnostic("explicit-crypto:unframed-encrypted-body",{traceId:i||null,endpointId:o||"unknown"}),d(this.unframedEncryptedExplicitReadable(a,E,s,t$1.explicitProtocolByte,n,i))):d(c(u,"explicit-crypto:not-encrypted-length"))}let k=5+I;for(;u.byteLength<k&&await v$1(););let T=y();if(T)return T;if(u.byteLength<k)return d(c(u,"explicit-crypto:truncated-probe"));let _=u.slice(5,k);if(!f$1(_))return d(c(u,"explicit-crypto:legacy-plaintext"));if(s||(n.logIncomingDiagnostic("explicit-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),s=await n.waitForApplicationCryptoForPeer(o)),!s)return n.logIncomingDiagnostic("explicit-crypto:encrypted-body-missing-key",{traceId:i||null,endpointId:o||"unknown"}),d(c(u,"explicit-crypto:encrypted-body-missing-key"));let A=c(u.slice(1),"explicit-crypto:encrypted-body");return d(this.encryptedExplicitReadable(A,s,t$1.explicitProtocolByte,n,i))}catch(C){return n.logIncomingDiagnostic("explicit-crypto:probe-error",{traceId:i||null,error:C?.message||String(C)}),d(c(u,"explicit-crypto:probe-error"))}}async maybeOpenEncryptedControlBiStream(e,t$1,n,i,o){if(!v(e)||e?.applicationCryptoWrapped===true)return e;let s;try{s=e.recv.getReader();}catch{return e}let a=(y,C,I=null)=>z(s,y,{context:C,traceId:i,pendingRead:I,release:k=>n.releaseReaderLock(s,`${C}:${k}`,i),log:(k,T)=>n.logIncomingDiagnostic(k,T)}),c=y=>x(e,y),d=[],p=new Uint8Array(0),u=null,g=Date.now()+t$1.probeDeadlineMs,f=async()=>{let y=await A(s,g);return y.status==="timeout"?(u=y.pendingRead??null,false):y.status==="done"?false:(y.value&&y.value.byteLength>0&&(d.push(y.value),p=t(d)),true)},v$1=()=>u?(n.logIncomingDiagnostic("control-crypto:probe-deadline",{traceId:i||null,endpointId:o||"unknown",bufferedBytes:p.byteLength}),c(a(p,"control-crypto:probe-deadline",u))):null;try{for(;p.byteLength<4&&await f(););let y=v$1();if(y)return y;if(p.byteLength<4)return c(a(p,"control-crypto:not-probeable"));let C=new DataView(p.buffer,p.byteOffset,p.byteLength).getUint32(0,!1);if(C===0||C>t$1.maxEncryptedFrameBytes)return c(a(p,"control-crypto:plaintext-length"));let I=4+Math.min(C,7);for(;p.byteLength<I&&await f(););let k=v$1();if(k)return k;if(p.byteLength<I)return c(a(p,"control-crypto:truncated-probe"));let T=p.slice(4,I);if(!this.looksLikeApplicationCryptoEnvelope(T))return c(a(p,"control-crypto:plaintext-frame"));let _=n.resolveApplicationCryptoForPeer(o);if(_||(n.logIncomingDiagnostic("control-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),_=await n.waitForApplicationCryptoForPeer(o)),!_)return n.logIncomingDiagnostic("control-crypto:encrypted-body-missing-key",{traceId:i||null,endpointId:o||"unknown"}),c(a(p,"control-crypto:encrypted-body-missing-key"));n.logIncomingDiagnostic("control-crypto:encrypted-frame",{traceId:i||null,endpointId:o||"unknown",frameLength:C});let A=h$1(_);return {...e,send:A.wrapWritable(e.send),recv:A.wrapReadable(a(p,"control-crypto:encrypted-frame")),applicationCryptoWrapped:!0}}catch(y){return n.logIncomingDiagnostic("control-crypto:probe-error",{traceId:i||null,endpointId:o||"unknown",error:y?.message||String(y)}),c(a(p,"control-crypto:probe-error"))}}encryptedExplicitReadable(e,t,n,i,o){let a=h$1(t).wrapReadable(e).getReader(),c=false;return new ReadableStream({async pull(d){if(!c){c=true,d.enqueue(new Uint8Array([n]));return}try{let{done:p,value:u}=await a.read();if(p){d.close(),a.releaseLock();return}u&&d.enqueue(u);}catch(p){d.error(p);try{a.releaseLock();}catch{}}},async cancel(d){try{await a.cancel(d);}catch{}try{a.releaseLock();}catch{}i.logIncomingDiagnostic("explicit-crypto:cancel",{traceId:o||null});}})}unframedEncryptedExplicitReadable(e,t$1,n,i,o,s){let a=false,c=false;return new ReadableStream({async pull(d){if(!a){a=true,d.enqueue(new Uint8Array([i]));return}if(c){d.close();return}c=true;let p=[t$1];try{for(;;){let{done:f,value:v}=await e.read();if(f)break;v&&v.byteLength>0&&p.push(new Uint8Array(v));}let u=t(p),g=n.openPayload(3,u);if(!g)throw new Error("[OpenRTC] encrypted explicit body failed authentication");d.enqueue(g),d.close();}catch(u){d.error(u);}finally{try{e.releaseLock();}catch{}}},async cancel(d){try{await e.cancel(d);}catch{}try{e.releaseLock();}catch{}o.logIncomingDiagnostic("explicit-crypto:unframed-cancel",{traceId:s||null});}})}looksLikeApplicationCryptoEnvelope(e){return e.byteLength>=7&&e[0]===79&&e[1]===82&&e[2]===84&&e[3]===67&&e[4]===69&&e[5]===49}};var _n=class{async extractIncomingChannelEnvelope(e,t$1,n,i){if(!v(e))return {stream:e,channel:null};let o;try{o=e.recv.getReader(),n.logIncomingDiagnostic("channel-envelope:reader-acquired",{traceId:i||null,remoteNodeId:t$1||"unknown"});}catch(x){return console.warn("[Client][CHANNEL] Incoming stream recv reader unavailable; skipping channel envelope inspection",{remoteNodeId:t$1,traceId:i||null,error:x}),{stream:e,channel:null}}let s=(x,j)=>z(o,x,{context:j,traceId:i,release:D=>n.releaseReaderLock(o,`${j}:${D}`,i),log:(D,O)=>n.logIncomingDiagnostic(D,O)}),a=x$1=>x(e,x$1),c=[],d$1=0;try{for(;d$1<6;){let{done:x,value:j}=await o.read();if(x)break;if(!j||j.byteLength===0)continue;let D=new Uint8Array(j);c.push(D),d$1+=D.byteLength;}}catch(x){return console.warn("[Client][CHANNEL] Failed reading incoming channel envelope prefix",{remoteNodeId:t$1,traceId:i||null,error:x}),n.releaseReaderLock(o,"extractIncomingChannelEnvelope:read-prefix-failed",i),{stream:e,channel:null}}let p=t(c);if(p.byteLength<6||p[0]!==127||p[1]!==1)return d("[Client][CHANNEL] Incoming stream did not start with channel envelope",{remoteNodeId:t$1,traceId:i||null,bufferedBytes:p.byteLength,firstBytes:Array.from(p.slice(0,Math.min(p.byteLength,8))).map(x=>x.toString(16).padStart(2,"0")).join(" ")}),{stream:a(s(p,"extractIncomingChannelEnvelope:not-envelope")),channel:null};let u=new DataView(p.buffer,p.byteOffset,p.byteLength),g=u.getUint16(2,false),f=u.getUint16(4,false),v$1=6+g+f,y=p;if(y.byteLength<v$1)try{for(;y.byteLength<v$1;){let{done:x,value:j}=await o.read();if(x)break;!j||j.byteLength===0||(y=t([y,new Uint8Array(j)]));}}catch(x){console.warn("[Client][CHANNEL] Failed extending incoming channel envelope read",{remoteNodeId:t$1,error:x});}if(y.byteLength<v$1||g===0)return {stream:a(s(y,"extractIncomingChannelEnvelope:truncated-envelope")),channel:null};let C=6,I=C+g,k=I+f,T=new TextDecoder,_=T.decode(y.slice(C,I)).trim(),A=null;if(f>0)try{let x=JSON.parse(T.decode(y.slice(I,k)));x&&typeof x=="object"&&!Array.isArray(x)&&(A=x);}catch(x){console.warn("[Client][CHANNEL] Failed to parse incoming channel metadata",{remoteNodeId:t$1,channelId:_,error:x});}if(!_)return {stream:a(s(y,"extractIncomingChannelEnvelope:empty-channel-id")),channel:null};let E=a(s(y.slice(v$1),"extractIncomingChannelEnvelope:channel-envelope-consumed"));return d("[Client][CHANNEL] Incoming channel envelope consumed",{remoteNodeId:t$1,traceId:i||null,channelId:_,metadata:A?Object.keys(A):[],bufferedBytes:y.byteLength,remainingBytes:Math.max(0,y.byteLength-v$1)}),{stream:E,channel:{channelId:_,metadata:A}}}async classifyBiIncomingStream(e,t,n,i){if(!v(e))return {stream:e,protocolHint:"unknown"};let o;try{o=e.recv.getReader();}catch{return {stream:e,protocolHint:"unknown"}}let s;try{s=await o.read();}catch{return n.releaseReaderLock(o,"classifyBiIncomingStream:read-failed",i),{stream:e,protocolHint:"unknown"}}if(s.done||!s.value||s.value.byteLength===0)return n.releaseReaderLock(o,"classifyBiIncomingStream:empty-first-read",i),d("[Client][INCOMING] classifyBiIncomingStream: empty read",{traceId:i||null,done:s.done,hasValue:!!s.value,byteLength:s.value?.byteLength}),{stream:e,protocolHint:"unknown"};let a=new Uint8Array(s.value),c=a[0];d("[Client][INCOMING] classifyBiIncomingStream: first byte",{traceId:i||null,firstByte:"0x"+c.toString(16),EXPLICIT_PROTOCOL_BYTE:"0x"+t.toString(16),isExplicit:c===t,chunkLength:a.length});let d$1=x(e,z(o,a,{context:"classifyBiIncomingStream:first-chunk",traceId:i,release:p=>n.releaseReaderLock(o,`classifyBiIncomingStream:first-chunk:${p}`,i),log:(p,u)=>n.logIncomingDiagnostic(p,u)}));return c===t?{stream:d$1,protocolHint:"explicit"}:{stream:d$1,protocolHint:"control"}}async detectNativeMainStream(e,t$1,n,i,o){if(!v(e))return {handled:false,stream:e,protocolHint:"unknown"};let s;try{s=e.recv.getReader();}catch(_){return console.warn("[Client][NATIVE-MAIN] Incoming stream recv reader unavailable",{remoteNodeId:t$1,traceId:o||null,error:_}),{handled:false,stream:e,protocolHint:"control"}}let a=(_,A)=>z(s,_,{context:A,traceId:o,release:E=>i.releaseReaderLock(s,`${A}:${E}`,o),log:(E,x)=>i.logIncomingDiagnostic(E,x)}),c=_=>x(e,_),d$1=[],p=0,u=5,g=false;try{for(;p<u;){let{done:_,value:A}=await s.read();if(_){g=!0;break}!A||A.byteLength===0||(d$1.push(new Uint8Array(A)),p+=A.byteLength);}}catch(_){return console.warn("[Client][NATIVE-MAIN] Failed reading incoming prefix",{remoteNodeId:t$1,traceId:o||null,error:_}),i.releaseReaderLock(s,"detectNativeMainStream:read-prefix-failed",o),{handled:false,stream:e,protocolHint:"control"}}let f=t(d$1);if(f.byteLength<u||f[0]!==n.nativeMainProtocolByte)return {handled:false,stream:c(a(f,"detectNativeMainStream:not-native-main")),protocolHint:f[0]===n.explicitProtocolByte?"explicit":"control"};let v$1=new DataView(f.buffer,f.byteOffset,f.byteLength).getUint32(1,false);if(v$1===0||v$1>n.maxLabelBytes)return {handled:false,stream:c(a(f,"detectNativeMainStream:invalid-label-length")),protocolHint:"control"};let y=5+v$1,C=f;if(C.byteLength<y&&!g){let _=[C],A=C.byteLength;try{for(;A<y;){let{done:E,value:x}=await s.read();if(E){g=!0;break}if(!x||x.byteLength===0)continue;let j=new Uint8Array(x);_.push(j),A+=j.byteLength;}}catch(E){console.warn("[Client][NATIVE-MAIN] Failed extending prefix read",{remoteNodeId:t$1,error:E});}C=t(_);}if(C.byteLength<y)return {handled:false,stream:c(a(C,"detectNativeMainStream:truncated-label")),protocolHint:"control"};let I=C.slice(5,y),k=new TextDecoder().decode(I);if(k!==n.label)return {handled:false,stream:c(a(C,"detectNativeMainStream:label-mismatch")),protocolHint:"control"};let T=c(a(C.slice(y),"detectNativeMainStream:label-consumed"));return d("[Client][NATIVE-MAIN] Detected desktop native main stream",{remoteNodeId:t$1,traceId:o||null,label:k}),{handled:true,stream:T,protocolHint:"native-main"}}};var Tn=class{constructor(){this.transfers=new Map;}clear(){this.transfers.clear();}maybeHandle(e,t,n){if(t.byteLength<25||t[0]!==n.explicitProtocolByte)return false;let i=t.slice(1,17),o=Array.from(i).map(g=>g.toString(16).padStart(2,"0")).join(""),s=`${e.id}:${o}`,a=new DataView(t.buffer,t.byteOffset,t.byteLength),c=a.getUint32(17,false),d$1=a.getUint32(21,false);if(c===4294967295){if(t.byteLength<29)return true;let g=a.getUint32(25,false),f=29,v=f+g;if(v>t.byteLength)return true;let y=n.openWebRTCExplicitTransferPayload(t.slice(f,v),e);return y?(this.transfers.set(s,{headerBytes:y,chunks:new Map,total:0,received:0}),d("[Client][WebRTC][transfer] Incoming WebRTC explicit transfer header received",{connectionId:e.id,remoteNodeId:e.remoteNodeId,transferIdKey:o,headerBytes:g}),true):(this.transfers.delete(s),true)}let p=this.transfers.get(s);if(!p)return true;if(p.total===0)p.total=d$1;else if(p.total!==d$1)return this.transfers.delete(s),true;if(p.chunks.has(c))return true;let u=n.openWebRTCExplicitTransferPayload(t.slice(25),e);if(!u)return this.transfers.delete(s),true;if(p.chunks.set(c,u),p.received+=1,p.total>0&&p.received>=p.total){let g=this.reassemble(p,n.explicitProtocolByte);this.transfers.delete(s),g&&(d("[Client][WebRTC][transfer] Incoming WebRTC transfer assembled in browser",{connectionId:e.id,remoteNodeId:e.remoteNodeId,transferIdKey:o,chunks:p.total,payloadBytes:g.byteLength}),n.dispatchSyntheticExplicitIncomingStream(e,g));}return true}reassemble(e,t){let n=[],i=0;for(let a=0;a<e.total;a+=1){let c=e.chunks.get(a);if(!c)return null;n.push(c),i+=c.byteLength;}let o=new Uint8Array(5+e.headerBytes.byteLength+i);o[0]=t,new DataView(o.buffer).setUint32(1,e.headerBytes.byteLength,false),o.set(e.headerBytes,5);let s=5+e.headerBytes.byteLength;for(let a of n)o.set(a,s),s+=a.byteLength;return o}};var An=class{constructor(e){this.deps=e;this.messageListeners=[];this.roomRequestListeners=[];this.streamListeners=[];this.channelStreamListeners=new Map;this.registeredChannels=new Map;this.protocolInspector=new _n;this.cryptoProbe=new Rn;this.webRTCExplicitTransferAssembler=new Tn;this.disposed=false;this.deps?.registerDisposer(()=>this.dispose());for(let t of this.deps?.defaultChannels??[])this.registerChannel(t);}dispose(){this.disposed||(this.disposed=true,this.messageListeners=[],this.roomRequestListeners=[],this.streamListeners=[],this.channelStreamListeners.clear(),this.registeredChannels.clear(),this.webRTCExplicitTransferAssembler.clear());}get webrtcIncomingExplicitTransfers(){return this.webRTCExplicitTransferAssembler.transfers}set webrtcIncomingExplicitTransfers(e){this.webRTCExplicitTransferAssembler.transfers=e;}onMessage(e){return this.disposed?()=>{}:(this.messageListeners.push(e),()=>{this.messageListeners=this.messageListeners.filter(t=>t!==e);})}dispatchMessage(e,t){if(!this.disposed)for(let n of [...this.messageListeners])try{n(e,t);}catch(i){console.warn("[Client] message listener failed",i);}}onIncomingStream(e){return this.disposed?()=>{}:(this.streamListeners.push(e),()=>{this.streamListeners=this.streamListeners.filter(t=>t!==e);})}hasIncomingStreamListeners(){return this.streamListeners.length>0}getRegisteredChannel(e){let t=typeof e=="string"?e.trim():"";return t?this.registeredChannels.get(t)??null:null}registerChannel(e){if(this.disposed)return;let t=e.id.trim();if(!t)throw new Error("Channel registration requires a non-empty channel id.");this.registeredChannels.set(t,{...e,id:t});}unregisterChannel(e){let t=e.trim();t&&(this.registeredChannels.delete(t),this.channelStreamListeners.delete(t));}listChannels(){return Array.from(this.registeredChannels.values())}onIncomingChannelStream(e,t){if(this.disposed)return ()=>{};let n=e.trim();if(!n)throw new Error("Channel stream listener requires a non-empty channel id.");let i=this.channelStreamListeners.get(n)??new Set;return i.add(t),this.channelStreamListeners.set(n,i),()=>{let o=this.channelStreamListeners.get(n);o&&(o.delete(t),o.size===0&&this.channelStreamListeners.delete(n));}}hasIncomingChannelListener(e){let t=e.trim();return t?(this.channelStreamListeners.get(t)?.size??0)>0:false}hasAnyIncomingChannelListeners(){for(let e of this.channelStreamListeners.values())if(e.size>0)return true;return false}dispatchIncomingChannelListeners(e){let t=e.channel?.channelId?.trim();if(!t)return false;let n=this.channelStreamListeners.get(t);if(!n)return false;for(let i of [...n])try{if(i(e)===!0)return !0}catch(o){console.warn("[Client] incoming channel stream listener failed",o);}return false}dispatchIncomingGenericListeners(e){for(let t of [...this.streamListeners])try{if(t(e)===!0)return !0}catch(n){console.warn("[Client] incoming stream listener failed",n);}return false}onRoomJoinRequest(e){return this.disposed?()=>{}:(this.roomRequestListeners.push(e),()=>{this.roomRequestListeners=this.roomRequestListeners.filter(t=>t!==e);})}async listenLoop(e){let t=0;for(;e.isListening();){let n=e.getWasmClient();if(!n||typeof n.incoming_streams!="function"){console.warn("[Client][INCOMING] incoming_streams is unavailable; stopping listen loop");return}let i=null;try{i=(await n.incoming_streams()).getReader();let s=i;for(t=0,e.shouldVerboseIncomingDiagnostics()&&d("[Client][INCOMING][MOBILE] direct listen reader acquired",{localNodeId:e.getLocalNodeId()});e.isListening();){let{done:a,value:c}=await s.read();if(a)throw new Error("incoming stream reader closed unexpectedly");if(!c)continue;let d$1=ot(c);d$1!=="uni"&&d("[Client][INCOMING] Received stream from WASM node",{type:d$1,endpointId:Le(c)});try{await e.handleIncomingStream(c);}catch(p){let u=c,g=ot(u),f=Le(u);console.error("[Client][INCOMING] Failed to handle incoming stream",{remoteNodeId:f,type:g,error:p});}}}catch(o){if(!e.isListening())break;t+=1;let s=u(t,e.retryMinDelayMs,e.retryMaxDelayMs);console.warn("[Client][INCOMING] Listen loop restarting after stream failure",{attempt:t,delayMs:s,mobile:ae(),error:o}),await r(s);}finally{if(i)try{i.releaseLock(),e.shouldVerboseIncomingDiagnostics()&&d("[Client][INCOMING][MOBILE] direct listen reader released",{localNodeId:e.getLocalNodeId()});}catch{}}}}async handleIncomingStream(e,t){let n=await t.normalizeIncomingStreamEvent(e,{inspectChannelEnvelope:t.shouldInspectIncomingChannelEnvelope()}),i=t.buildApplicationIncomingStreamEvent(n);if(this.dispatchIncomingChannelListeners(i))return;if(n.protocolHint==="native-main"){await t.handleUnhandledIncomingStreamEvent(n);return}this.dispatchIncomingGenericListeners(i)||await t.handleUnhandledIncomingStreamEvent(n);}async normalizeIncomingStreamEvent(e,t,n){let i="bi",o=e,s="",a=null,c=null,d$1={present:false,channel:null},p=false;try{p="type"in e;}catch{p=false;}if(p){i=ot(e);try{o=e.stream;}catch{o=null;}let y=Le(e);s=y==="unknown"?"":y,c=Ur(e),d$1=Hr(e);}else try{s=e.endpoint_id??"";}catch{s="";}let u=n.nextIncomingTraceId("incoming",s);c=n.normalizeAuthoritativeIncomingProtocolHint(c,s,u);let g=d$1.present&&d$1.channel!==null;n.logIncomingDiagnostic("normalize:start",{traceId:u,hasType:p,type:i,endpointId:s||"unknown",inspectChannelEnvelope:!!t?.inspectChannelEnvelope,authoritativeProtocolHint:c??null,authoritativeChannel:g}),i!=="uni"&&d("[Client][INCOMING] handleIncomingStream called",{hasType:p,type:i,endpointId:s});let f="unknown",v$1=c===null&&!!t?.inspectChannelEnvelope;if(i==="bi"){let y=w$2(o,s);if(!y||!v(y)){let k=false,T=false;try{k=!!o?.send;}catch{}try{T=!!o?.recv;}catch{}return console.error("[Client][INCOMING] Invalid bidirectional stream payload",{remoteNodeId:s,hasSend:k,hasRecv:T}),{type:"bi",stream:o,remoteNodeId:s,traceId:u,protocolHint:"unknown",channel:null,applicationCrypto:n.resolveApplicationCryptoStreamTools(s),invalid:true}}o=y;let C=false;if(c===null&&!g&&n.shouldStripIncomingMainLabel()){let k=await n.detectNativeMainStream(o,s,u);o=k.stream,C=true,f=k.protocolHint;}else c==="native-main"&&(f="native-main");if(f!=="native-main"){if(g)a=d$1.channel;else if(v$1){let _=await n.extractIncomingChannelEnvelope(o,s,u);o=_.stream,a=_.channel;}if(!(c==="explicit"||c==="control"||c==="native-main")&&!n.isTransportOnlyChannel(a?.channelId)&&(c!==null||g||a)&&(o=n.maybeWrapIncomingBiStreamWithApplicationCrypto(o,s,u)),c!==null)f=c,n.logIncomingDiagnostic("bi:use-authoritative-metadata",{traceId:u,endpointId:s||"unknown",protocolHint:f,hasChannelEnvelope:!!a});else if(n.shouldSkipIncomingBiProbeForRemoteNode(s)){let _=n.inferTicketFlowBiProtocolHint(s);if(f=_.protocolHint,n.logIncomingDiagnostic("bi:skip-probe-ticket-flow",{traceId:u,endpointId:s||"unknown",inferredProtocolHint:f,hasExistingConnection:_.hasExistingConnection,hasMagicLinkScope:_.hasMagicLinkScope}),!a&&!C&&n.shouldStripIncomingMainLabel()){let A=await n.detectNativeMainStream(o,s,u);o=A.stream,f=A.protocolHint;}}else {let _=await n.classifyBiIncomingStream(o,u);if(o=_.stream,f=_.protocolHint,f!=="explicit"&&!C&&n.shouldStripIncomingMainLabel()){let A=await n.detectNativeMainStream(o,s,u);o=A.stream,f=A.protocolHint;}}}let I=!n.shouldSkipIncomingStreamProbe()&&!n.isTransportOnlyChannel(a?.channelId);if(I&&f==="explicit"&&o?.applicationCryptoWrapped!==true?o=await n.maybeOpenEncryptedExplicitBiStream(o,u,s):I&&f==="control"&&o?.applicationCryptoWrapped!==true&&(o=await n.maybeOpenEncryptedControlBiStream(o,u,s)),!a&&v$1&&o?.applicationCryptoWrapped===true){let k=await n.extractIncomingChannelEnvelope(o,s,u);o=k.stream,a=k.channel;}}return n.logIncomingDiagnostic("normalize:done",{traceId:u,endpointId:s||"unknown",type:i,protocolHint:f,hasChannelEnvelope:!!a}),{type:i,stream:o,remoteNodeId:s,traceId:u,protocolHint:f,channel:a,applicationCrypto:n.resolveApplicationCryptoStreamTools(s)}}async extractIncomingChannelEnvelope(e,t,n,i){return this.protocolInspector.extractIncomingChannelEnvelope(e,t,n,i)}async classifyBiIncomingStream(e,t,n){let i=this.deps?.explicitProtocolByte??0;return this.protocolInspector.classifyBiIncomingStream(e,i,t,n)}maybeWrapIncomingBiStreamWithApplicationCrypto(e,t,n,i){return this.cryptoProbe.maybeWrapIncomingBiStreamWithApplicationCrypto(e,t,n,i)}async maybeOpenEncryptedExplicitBiStream(e,t,n,i,o){return this.cryptoProbe.maybeOpenEncryptedExplicitBiStream(e,t,n,i,o)}async maybeOpenEncryptedControlBiStream(e,t,n,i,o){return this.cryptoProbe.maybeOpenEncryptedControlBiStream(e,t,n,i,o)}async detectNativeMainStream(e,t,n,i,o){return this.protocolInspector.detectNativeMainStream(e,t,n,i,o)}maybeHandleWebRTCExplicitFileEnvelope(e,t){return this.disposed||!this.deps?false:this.webRTCExplicitTransferAssembler.maybeHandle(e,t,this.deps)}};function Gr(r){let{host:e}=r;return new An({explicitProtocolByte:2,defaultChannels:Eo,registerDisposer:t=>e.registerDisposer(t),openWebRTCExplicitTransferPayload:(t,n)=>e.openWebRTCExplicitTransferPayload(t,n),dispatchSyntheticExplicitIncomingStream:(t,n)=>r.getApplicationIncoming().dispatchSyntheticExplicitIncomingStream(t,n)})}function qr(r){let{host:e}=r,t=e.getPresenceForIncomingListen();return new In(e.getContext(),{ensureWasmRuntimeForP2P:()=>e.ensureWasmRuntimeForP2P(),startPresenceForListen:()=>t.startPresenceLoopForListen(),setOfflinePresence:()=>{t.setOffline();},shouldInspectIncomingChannelEnvelope:()=>r.getDiagnostics().shouldInspectIncomingChannelEnvelope(),handleIncomingStream:n=>r.getRouter().handleIncomingStream(n,{shouldInspectIncomingChannelEnvelope:()=>r.getDiagnostics().shouldInspectIncomingChannelEnvelope(),normalizeIncomingStreamEvent:(i,o)=>r.getNormalizer().normalize(i,o),buildApplicationIncomingStreamEvent:i=>r.getApplicationIncoming().buildApplicationIncomingStreamEvent(i),handleUnhandledIncomingStreamEvent:i=>e.handleUnhandledIncomingStreamEvent(i)}),hasIncomingChannelListener:n=>r.getRouter().hasIncomingChannelListener(n),hasAnyIncomingChannelListeners:()=>r.getRouter().hasAnyIncomingChannelListeners(),normalizeIncomingStreamEvent:(n,i)=>r.getNormalizer().normalize(n,i),dispatchIncomingChannelListeners:n=>r.getRouter().dispatchIncomingChannelListeners(n),dispatchIncomingGenericListeners:n=>r.getRouter().dispatchIncomingGenericListeners(n),handleUnhandledIncomingStreamEvent:n=>e.handleUnhandledIncomingStreamEvent(n),shouldVerboseIncomingDiagnostics:()=>r.getDiagnostics().shouldVerboseIncomingDiagnostics(),getIncomingStreamRouter:()=>r.getRouter(),retryMinDelayMs:_o,retryMaxDelayMs:To})}function Vr(r,e){return new wn({getOptions:()=>r.getOptions(),getRuntimeSafetyProfileOverride:()=>r.getRuntimeSafetyProfile(),hasAnyIncomingChannelListeners:()=>e().hasAnyIncomingChannelListeners()})}function $r(r){let{host:e}=r;return new Pn({explicitProtocolByte:2,maxEncryptedFrameBytes:16777216,probeDeadlineMs:vo,nativeMainProtocolByte:yt,nativeMainLabel:vt,nativeMainMaxLabelBytes:bt,explicitApplicationCryptoWaitMs:1500},{router:r.getRouter(),nextIncomingTraceId:(t,n)=>r.getDiagnostics().nextIncomingTraceId(t,n),logIncomingDiagnostic:(t,n)=>r.getDiagnostics().logIncomingDiagnostic(t,n),releaseReaderLock:(t,n,i)=>r.getDiagnostics().safeReleaseReaderLock(t,n,i),shouldSkipIncomingStreamProbe:()=>r.getDiagnostics().shouldSkipIncomingStreamProbe(),shouldSkipIncomingBiProbeForRemoteNode:t=>e.shouldSkipIncomingBiProbeForRemoteNode(t),inferTicketFlowBiProtocolHint:t=>e.inferTicketFlowBiProtocolHint(t),isTransportOnlyChannel:t=>e.isTransportOnlyChannel(t),resolveApplicationCryptoForPeer:t=>e.resolveApplicationCryptoForPeer(t),waitForApplicationCryptoForPeer:(t,n)=>e.waitForApplicationCryptoForPeer(t,n),resolveApplicationCryptoStreamTools:t=>e.resolveApplicationCryptoStreamTools(t)})}function zr(r){let{host:e}=r;return new bn({registerDisposer:t=>e.registerDisposer(t),resolveApplicationCryptoStreamTools:t=>e.resolveApplicationCryptoStreamTools(t),logIncomingDiagnostic:(t,n)=>r.getDiagnostics().logIncomingDiagnostic(t,n),isTransportOnlyChannel:t=>e.isTransportOnlyChannel(t),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),hasTransportOnlyConnectionForRemoteNode:t=>e.hasTransportOnlyConnectionForRemoteNode(t),getConnectionChannelId:t=>e.getConnectionChannelId(t),dispatchIncomingChannelListeners:t=>r.getRouter().dispatchIncomingChannelListeners(t),dispatchIncomingGenericListeners:t=>r.getRouter().dispatchIncomingGenericListeners(t),handleUnhandledIncomingStreamEvent:t=>e.handleUnhandledIncomingStreamEvent(t)})}function Qr(r){return new Cn(r.getContext(),{ensureWasmRuntimeForP2P:()=>r.ensureWasmRuntimeForP2P(),getApplicationCryptoForPeer:e=>r.resolveApplicationCryptoForPeer(e)})}function Yr(r){return new ki({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getRuntimeSafetyProfile:()=>r.runtimeSafetyProfile,registerDisposer:e=>r.lifecycleScope.register(e),ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getPresenceForIncomingListen:()=>r.presence,openWebRTCExplicitTransferPayload:(e,t)=>r.applicationCrypto.openWebRTCExplicitTransferPayload(e,t),dispatchSyntheticExplicitIncomingStream:(e,t)=>r.applicationIncomingStreams.dispatchSyntheticExplicitIncomingStream(e,t),handleUnhandledIncomingStreamEvent:e=>r.incomingConnectionAcceptor.handleUnhandledIncomingStreamEvent(e),shouldSkipIncomingBiProbeForRemoteNode:e=>r.transportHealth.shouldSkipIncomingBiProbeForRemoteNode(e),inferTicketFlowBiProtocolHint:e=>r.peerIdentity.inferTicketFlowBiProtocolHint(e),isTransportOnlyChannel:e=>r.connectionChannelPolicy.isTransportOnlyChannel(e),hasTransportOnlyConnectionForRemoteNode:e=>r.transportHealth.hasTransportOnlyConnectionForRemoteNode(e),getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),resolveApplicationCryptoForPeer:e=>r.applicationCrypto.resolveForPeer(e),waitForApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.waitForPeer(e,t),resolveApplicationCryptoStreamTools:e=>r.applicationCrypto.resolveStreamTools(e)})}var ki=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getRouter:()=>this.router,getDiagnostics:()=>this.diagnostics,getNormalizer:()=>this.normalizer,getApplicationIncoming:()=>this.applicationIncoming}}get router(){return this._router??(this._router=Gr(this.factoryHost))}get listen(){return this._listen??(this._listen=qr(this.factoryHost))}get diagnostics(){return this._diagnostics??(this._diagnostics=Vr(this.host,()=>this.router))}get normalizer(){return this._normalizer??(this._normalizer=$r(this.factoryHost))}get applicationIncoming(){return this._applicationIncoming??(this._applicationIncoming=zr(this.factoryHost))}get applicationStreams(){return this._applicationStreams??(this._applicationStreams=Qr(this.host))}prepareListenForSignOut(){this._listen?.prepareForSignOut();}stopListenIfExists(){this._listen?.stop();}};function kn(r,e,t,n){if(!r||r.isClosed)return false;if(!(typeof r.isApplicationCryptoRequired=="function"?r.isApplicationCryptoRequired():false))return true;let o=n??r.remoteNodeId??t??r.deviceId;return !!e(o,r)}function Ni(r){return !r||r.isClosed?false:typeof r.isWebRtcApplicationRouteReady=="function"?r.isWebRtcApplicationRouteReady():false}var Nn=class{constructor(e,t){this.ctx=e;this.deps=t;this.recoveryInFlight=new Set;this.failedConnectionIds=new Set;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true,this.recoveryInFlight.clear(),this.failedConnectionIds.clear();}hasApplicationRouteForPeer(e,t){let n=this.deps.getConnectionForPeer(e,t);return kn(n,this.deps.resolveApplicationCryptoForPeer,e,t)}hasApplicationRouteForConnection(e){return kn(e,this.deps.resolveApplicationCryptoForPeer,e?.id,e?.remoteNodeId)}notifyApplicationRouteReady(e,t){this.disposed||e.isClosed||!this.hasApplicationRouteForConnection(e)||(this.failedConnectionIds.delete(e.id),d("[Client][HANDSHAKE] application route ready",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t}),this.deps.hasRustPeerLifecycleProjection()?this.schedulePeerReconciliationBestEffort("application-route-ready"):this.deps.applyConnectionTrustProjection(e),this.deps.isConnectionAnnounced(e.id)||this.deps.announceConnectionWhenStable(e));}async waitForApplicationRouteForConnection(e,t,n){let i=Date.now()+t;for(;!e.isClosed;){if(this.disposed)return false;if(this.hasApplicationRouteForConnection(e))return true;if(Date.now()>=i)return false;await r(n);}return false}isWebRtcApplicationRouteReadyForConnection(e){return Ni(e)}async sendApplicationRouteHandshakeAttempt(e,t,n,i,o,s="capability-update"){if(!this.disposed){d("[Client][HANDSHAKE] refreshing application route handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t,action:s,attempt:n+1,maxAttempts:i,preferNativeSignalRoute:o});try{o?await this.deps.sendTransportHandshake(e,s,null,{preferNativeSignalRoute:!0}):await this.deps.sendTransportHandshake(e,s);}catch(a){if(this.disposed)return;console.warn("[Client][HANDSHAKE] application route handshake send failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t,action:s,attempt:n+1,error:a});}}}async refreshApplicationRouteHandshake(e,t){if(this.disposed||e.isClosed||!this.deps.shouldNegotiateApplicationKeyAgreement())return;let n=this.deps.resolveApplicationCryptoForPeer(e.remoteNodeId,e);if(n&&e.setApplicationCrypto(n),this.hasApplicationRouteForConnection(e)){this.notifyApplicationRouteReady(e,t);return}if(this.recoveryInFlight.has(e.id))return;this.failedConnectionIds.delete(e.id);let i=this.deps.getConnectionControlFrameMode(e),o=t==="connect-existing"?"hello":"capability-update";if(await this.sendApplicationRouteHandshakeAttempt(e,t,0,this.deps.maxRecoveryAttempts,false,o),!this.disposed){if(await this.waitForApplicationRouteForConnection(e,this.deps.attemptWaitMs,50)){this.notifyApplicationRouteReady(e,t);return}if(!this.disposed){if(this.deps.hydrateAdoptedConnectionApplicationCrypto(e,t)){this.failedConnectionIds.delete(e.id);return}if(i==="native-main"&&!e.isClosed&&!this.hasApplicationRouteForConnection(e)){if(await this.sendApplicationRouteHandshakeAttempt(e,t,1,this.deps.maxRecoveryAttempts,true,o),this.disposed)return;if(await this.waitForApplicationRouteForConnection(e,this.deps.attemptWaitMs,50)){this.notifyApplicationRouteReady(e,t);return}if(this.disposed)return;if(this.deps.hydrateAdoptedConnectionApplicationCrypto(e,t)){this.failedConnectionIds.delete(e.id);return}}e.isClosed||this.hasApplicationRouteForConnection(e)||this.driveApplicationRouteRecoveryInBackground(e,t);}}}handleApplicationRouteMissing(e,t){if(this.disposed)return;let n=this.ctx.registry.get(e);!n||n.isClosed||n.id!==t.connectionId||n.remoteNodeId===t.remoteNodeId&&(d("[Client][HANDSHAKE] WebRTC route proof is waiting on application crypto; refreshing handshake",{connectionId:e,remoteNodeId:t.remoteNodeId,reason:t.reason,negotiationId:t.negotiationId??null}),this.refreshApplicationRouteAfterProofInBackground(n,t));}refreshApplicationRouteAfterProofInBackground(e,t){let n=i=>{this.disposed||console.warn("[Client][HANDSHAKE] application route refresh after WebRTC proof failed",{connectionId:t.connectionId,remoteNodeId:t.remoteNodeId,reason:t.reason,error:i});};try{Promise.resolve(this.refreshApplicationRouteHandshake(e,t.reason)).catch(n);}catch(i){n(i);}}async driveApplicationRouteRecovery(e,t){if(this.disposed||this.recoveryInFlight.has(e.id))return;this.recoveryInFlight.add(e.id);let n=this.deps.getConnectionControlFrameMode(e),i=this.deps.maxRecoveryAttempts;try{for(let o=2;o<i;o+=1){if(this.disposed||e.isClosed)return;if(this.hasApplicationRouteForConnection(e)){this.notifyApplicationRouteReady(e,t);return}let s=this.deps.backoffMs[Math.min(o,this.deps.backoffMs.length-1)];if(s>0){if(await r(s),this.disposed)return;if(e.isClosed||this.hasApplicationRouteForConnection(e)){e.isClosed||this.notifyApplicationRouteReady(e,t);return}}let a=n==="native-main"&&o%2===1;if(await this.sendApplicationRouteHandshakeAttempt(e,t,o,i,a),this.disposed)return;if(await this.waitForApplicationRouteForConnection(e,this.deps.attemptWaitMs,50)){this.notifyApplicationRouteReady(e,t);return}if(this.disposed)return;if(this.deps.hydrateAdoptedConnectionApplicationCrypto(e,t)){this.failedConnectionIds.delete(e.id);return}}if(e.isClosed||this.hasApplicationRouteForConnection(e)){e.isClosed||this.notifyApplicationRouteReady(e,t);return}this.failedConnectionIds.add(e.id),console.warn("[Client][HANDSHAKE] application route recovery exhausted; marking route failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t,controlFrameMode:n,attempts:i}),this.schedulePeerReconciliationBestEffort("application-route-handshake-exhausted");}finally{this.recoveryInFlight.delete(e.id);}}clearFailure(e){let t=typeof e=="string"?e.trim():"";t&&this.failedConnectionIds.delete(t);}hasFailure(e){let t=typeof e=="string"?e.trim():"";return !!t&&this.failedConnectionIds.has(t)}driveApplicationRouteRecoveryInBackground(e,t){if(!this.disposed)try{Promise.resolve(this.driveApplicationRouteRecovery(e,t)).catch(()=>{});}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var Dn=class{constructor(e,t){this.ctx=e;this.deps=t;}getDeterministicConnectionId(e){return this.ctx.localNodeId?this.ctx.localNodeId<=e?`${this.ctx.localNodeId}-${e}`:`${e}-${this.ctx.localNodeId}`:`native-main-${e}`}getNativeMainConnectionId(e){return this.getDeterministicConnectionId(e)}findManualDisconnectProjectionForNativeNode(e){let t=typeof e=="string"?e.trim().toLowerCase():"";if(!t)return null;let n=this.getNativeMainConnectionId(e).trim().toLowerCase(),i=o=>{if(!o)return false;let s=String(o.status??"").toLowerCase(),a=String(o.error??"").toLowerCase();return (s==="closed"||s==="disconnected"||s==="failed")&&a.includes("manual disconnect")};for(let o of [e,n]){let s=this.deps.getPeerState(o);if(i(s))return s}return this.deps.listPeerStates().find(o=>{if(!i(o))return false;let s=String(o.nodeId??"").trim().toLowerCase(),a=String(o.connectionId??"").trim().toLowerCase(),c=Array.isArray(o.connectionIds)?o.connectionIds.map(d=>String(d??"").trim().toLowerCase()):[];return s===t||a===n||a.endsWith(`-${t}`)||c.includes(n)||c.some(d=>d.endsWith(`-${t}`))})??null}hasKnownConnectionForRemoteNode(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;if(this.ctx.registry.has(this.getDeterministicConnectionId(t)))return true;for(let n of this.ctx.registry.values()){let i=n;if(i.id===t||i.remoteNodeId===t||i.deviceId===t)return true}return false}inferTicketFlowBiProtocolHint(e){let t=typeof e=="string"?e.trim():"",n=this.hasKnownConnectionForRemoteNode(t),i=false;try{let o=this.deps.getPeerState(t);i=Array.isArray(o?.scopes)&&o.scopes.includes("magic-link");}catch{i=false;}return {protocolHint:this.deps.hasAnyIncomingChannelListeners()||this.deps.hasIncomingStreamListeners()||i?"explicit":"control",hasExistingConnection:n,hasMagicLinkScope:i}}};var Mn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}hasTransportOnlyConnectionForRemoteNode(e){if(this.disposed)return false;let t=typeof e=="string"?e.trim():"";if(!t)return false;for(let n of this.ctx.registry.values())if(n.remoteNodeId===t&&this.deps.isTransportOnlyConnectionId(n.id))return true;return false}shouldSkipIncomingBiProbeForRemoteNode(e){return this.disposed||!this.deps.getRuntimeSafetyProfile().skipIncomingBiProbe?false:this.deps.usesTicketOnlySignalingMode()?true:this.hasTransportOnlyConnectionForRemoteNode(e)}async disconnectNodeTransport(e){if(this.disposed||!e||!e.trim())return;let t=this.ctx.wasmClient;if(t&&typeof t.disconnect=="function")try{await t.disconnect(e);}catch{}this.disposed||this.deps.notifyDisconnectRequested(e);}async isCoreConnectionHealthy(e){if(this.disposed||!e)return false;let t=this.ctx.wasmClient;if(t&&typeof t.is_connected=="function")try{let n=!!await t.is_connected(e);return this.disposed?!1:n}catch{}try{let n=await this.deps.isConnected(e);return this.disposed?!1:n}catch{return false}}handleConnectionTransportStatus(e,t,n){this.disposed||this.reportConnectionTransportStatus(e,t,n);}async reportConnectionTransportStatus(e,t,n){if(this.disposed)return;let i=this.ctx.wasmClient;if(!(!i||typeof i.report_transport_status!="function"))try{if(await i.report_transport_status(e,t,n??null),this.disposed)return;this.deps.hasRustPeerLifecycleProjection()&&this.schedulePeerReconciliationBestEffort("transport-status-report");}catch(o){if(this.disposed)return;d("[Client] Failed to report active transport to Rust",{connectionId:e,activeTransport:t,parallelTransport:n??null,error:o});}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var pc=["iroh-lan","webrtc-lan","ble","webrtc","moq","iroh"];function Xr({transportPriority:r,disableIrohFallback:e,runtimeSafetyProfile:t,isMoQReady:n,isMoQDataReady:i,sendMoQ:o}){return {priorities:r||pc,disableIrohFallback:e||false,isMoQReady:n,isMoQDataReady:i,sendMoQ:o,runtimeFlow:t.flow,readerCloseStrategy:t.readerCloseStrategy}}var En=class{constructor(e){this.deps=e;}create(e){let t=this.deps.getOptions();return Xr({transportPriority:t?.transportPriority,disableIrohFallback:t?.disableIrohFallback,runtimeSafetyProfile:this.deps.getRuntimeSafetyProfile(),isMoQReady:()=>this.deps.isMoQReady(),isMoQDataReady:()=>this.deps.isMoQDataReady(e),sendMoQ:(n,i)=>this.deps.sendMoQ(e,n,i)})}};var xn=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}getConnectionControlFrameMode(e){return typeof e.getControlFrameMode=="function"?e.getControlFrameMode():"typed"}async sendConnectionControlEnvelope(e,t,n={}){if(this.disposed)return;if(this.getConnectionControlFrameMode(e)==="native-main"){if(n.preferNativeSignalRoute&&(typeof e.sendNativeControlEnvelope=="function"?await e.sendNativeControlEnvelope(t):false))return;try{await e.sendRawIrohFrame(ce(we(t)));return}catch(o){if(typeof e.sendNativeControlEnvelope=="function"?await e.sendNativeControlEnvelope(t):false)return;throw o}}if(typeof e.sendControl=="function"){await e.sendControl(t);return}await e.send(t);}async sendTransportHandshake(e,t,n,i={}){if(this.disposed)return;let o=this.deps.shouldNegotiateApplicationKeyAgreement()?await this.deps.ensureConnectionKeyAgreementState(e):null;if(this.disposed)return;let s={webrtc:this.deps.isWebRTCTransportEnabled(),moq:this.deps.isMoQReady(),...o?{applicationKeyAgreement:true}:{}},a=t==="hello"?this.deps.getPendingSessionToken(e.remoteNodeId):void 0,c=t==="hello"?this.deps.getPendingSessionTokenPayload(e.remoteNodeId):void 0;d("[Client][HANDSHAKE] sending",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId,channelId:this.deps.getConnectionChannelId(e.id)??null,capabilities:s,hasSessionToken:!!a,hasSessionTokenPayload:!!c,hasChallengeToSign:!!n});let d$1={type:"handshake",action:t,capabilities:s,moq:s.moq,channelId:this.deps.getConnectionChannelId(e.id)??void 0,...a?{sessionToken:a}:{},...a&&c?{sessionTokenPayload:c}:{},...o?{applicationKeyAgreement:uo(o.publicKey)}:{}},p=await this.deps.buildLocalTransportTrustPayload(e);if(!this.disposed){if(d("[Client][HANDSHAKE] local trust payload status",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId,hasTransportTrustPayload:!!p,hasChallengeInPayload:!!p?.challenge}),!p){if(this.deps.requiresManagedTransportTrust()){let u=this.deps.initializeConnectionTrust(e);u.failed=true,u.failureReason="local-trusted-identity-unavailable",console.warn("[Client][TRUST] Unable to attach local transport trust payload for managed trust handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:t});}await this.sendConnectionControlEnvelope(e,d$1,i),o&&this.deps.markConnectionApplicationCryptoRequired(e);return}n&&(p.signedChallenge=await this.deps.signTransportTrustChallenge(n)??void 0,this.disposed)||(await this.sendConnectionControlEnvelope(e,{...d$1,transportTrust:p},i),o&&this.deps.markConnectionApplicationCryptoRequired(e),d("[Client][HANDSHAKE] sent OK",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId}));}}async sendTransportHandshakeWithRecovery(e,t,n,i){for(let o=0;o<this.deps.maxRecoveryAttempts;o+=1){if(this.disposed)return;if(e.isClosed)throw new Error("[Client][HANDSHAKE] connection closed before handshake recovery completed");let s=this.getConnectionControlFrameMode(e)==="native-main"&&o%2===1;try{await this.sendTransportHandshake(e,t,n,{preferNativeSignalRoute:s});return}catch(a){let c=o>=this.deps.maxRecoveryAttempts-1;if(console.warn("[Client][HANDSHAKE] control handshake send failed; retrying if budget remains",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:t,reason:i,attempt:o+1,maxAttempts:this.deps.maxRecoveryAttempts,preferNativeSignalRoute:s,finalAttempt:c,error:a}),c)throw a;let d=this.deps.recoveryBackoffMs[Math.min(o,this.deps.recoveryBackoffMs.length-1)]??0;if(d>0&&(await r(d),this.disposed))return}}}async broadcastTransportCapabilityUpdate(e){if(this.disposed)return;if(this.deps.isWebRTCTransportEnabled()){let o=this.deps.getRTCConfig();for(let s of this.deps.getConnections()){if(this.disposed)return;s.updateRTCConfig(o);}}if(this.disposed)return;let t=Array.from(this.deps.getConnections()).filter(o=>!o.isClosed).map(async o=>{await this.sendTransportHandshake(o,"capability-update");}),i=(await Promise.allSettled(t)).filter(o=>o.status==="rejected");i.length>0&&d("[Client] Some transport capability updates failed",{reason:e,failures:i.length});}requestProtectedWebRTCUpgradeIfInitiator(e,t){if(this.disposed)return;let n=this.deps.isSessionTokenApproved(e.id,e.remoteNodeId),i=this.deps.getLocalNodeId();!this.deps.usesTicketOnlySignalingMode()&&!n||!this.deps.isWebRTCTransportEnabled()||!i||!e.remoteNodeId||i.localeCompare(e.remoteNodeId)<=0||e.requestWebRTCUpgrade(t);}};function Zr(r){let{host:e}=r;return new Nn(e.getContext(),{getConnectionForPeer:(t,n)=>e.getConnectionForPeer(t,n)??null,resolveApplicationCryptoForPeer:(t,n)=>e.resolveApplicationCryptoForPeer(t,n),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),hydrateAdoptedConnectionApplicationCrypto:(t,n)=>e.hydrateAdoptedConnectionApplicationCrypto(t,n),sendTransportHandshake:(t,n,i,o)=>r.getHandshake().sendTransportHandshake(t,n,i,o),getConnectionControlFrameMode:t=>r.getHandshake().getConnectionControlFrameMode(t),applyConnectionTrustProjection:t=>e.applyConnectionTrustProjection(t),announceConnectionWhenStable:t=>e.announceConnectionWhenStable(t),isConnectionAnnounced:t=>e.isConnectionAnnounced(t),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:t=>e.schedulePeerReconciliation(t),maxRecoveryAttempts:15,attemptWaitMs:1e3,backoffMs:ii})}function es(r){let{host:e}=r;return new xn({shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),ensureConnectionKeyAgreementState:t=>e.ensureConnectionKeyAgreementState(t),isWebRTCTransportEnabled:()=>k$1(e.getOptions()),isMoQReady:()=>e.isMoQReady(),getConnectionChannelId:t=>e.getConnectionChannelId(t),getPendingSessionToken:t=>e.getPendingSessionToken(t),getPendingSessionTokenPayload:t=>e.getPendingSessionTokenPayload(t),buildLocalTransportTrustPayload:t=>e.buildLocalTransportTrustPayload(t),requiresManagedTransportTrust:()=>e.requiresManagedTransportTrust(e.getDiscoveryMode()),initializeConnectionTrust:t=>e.initializeConnectionTrust(t),signTransportTrustChallenge:t=>e.signTransportTrustChallenge(t),markConnectionApplicationCryptoRequired:t=>e.markConnectionApplicationCryptoRequired(t),getRTCConfig:()=>r.getRTCConfig(),getConnections:()=>e.getConnections(),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),isSessionTokenApproved:(t,n)=>e.isSessionTokenApproved(t,n),getLocalNodeId:()=>e.getLocalNodeId()||null,maxRecoveryAttempts:15,recoveryBackoffMs:ii,registerDisposer:t=>e.registerDisposer(t)})}function ts(r){return new Mn(r.getContext(),{getRuntimeSafetyProfile:()=>r.getRuntimeSafetyProfile(),usesTicketOnlySignalingMode:()=>r.usesTicketOnlySignalingMode(),isTransportOnlyConnectionId:e=>r.isTransportOnlyConnectionId(e),notifyDisconnectRequested:e=>r.notifyDisconnectRequested(e),isConnected:e=>r.isBackendConnected(e),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>r.schedulePeerReconciliation(e)})}function ns(r){return new En({getOptions:()=>r.getOptions(),getRuntimeSafetyProfile:()=>r.getRuntimeSafetyProfile(),isMoQReady:()=>r.isMoQReady(),isMoQDataReady:e=>r.isMoQDataReady(e),sendMoQ:(e,t,n)=>r.sendMoQData(e,t,n)})}function is(r){return new Dn(r.getContext(),{getPeerState:e=>r.getPeerState(e),listPeerStates:()=>r.listPeerStates(),hasAnyIncomingChannelListeners:()=>r.hasAnyIncomingChannelListeners(),hasIncomingStreamListeners:()=>r.hasIncomingStreamListeners()})}function os(r){return new Di({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getRuntimeSafetyProfile:()=>r.runtimeSafetyProfile,registerDisposer:e=>r.lifecycleScope.register(e),getLocalNodeId:()=>r.localNodeId,getDiscoveryMode:()=>r.discoveryMode,hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),getPeerState:e=>r.peerServices.getPeerState(e),listPeerStates:()=>r.peerServices.listPeerStates(),getConnectionForPeer:(e,t)=>r.registry.getForPeer(e,t),getConnections:()=>r.registry.values(),getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),isTransportOnlyConnectionId:e=>r.connectionChannelPolicy.isTransportOnlyConnectionId(e),getConnectionTrustState:e=>r.connectionTrust.getStateByConnectionId(e),buildLocalTransportTrustPayload:e=>r.connectionTrust.buildLocalTransportTrustPayload(e),initializeConnectionTrust:e=>r.connectionTrust.initialize(e),signTransportTrustChallenge:e=>r.connectionTrust.signTransportTrustChallenge(e),resolveApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.resolveForPeer(e,t),resolveExistingApplicationCryptoForPeer:(e,t)=>r.securityServices.resolveExistingApplicationCryptoForPeer(e,t),getConfiguredApplicationCrypto:()=>r.options?.applicationCrypto,shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),hydrateAdoptedConnectionApplicationCrypto:(e,t)=>r.applicationCrypto.hydrateAdoptedConnection(e,t),ensureConnectionKeyAgreementState:e=>r.applicationCrypto.ensureConnectionKeyAgreementState(e),markConnectionApplicationCryptoRequired:e=>r.applicationCrypto.markRequired(e),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),announceConnectionWhenStable:e=>r.connectionLifecycle.announceConnectionWhenStable(e),isConnectionAnnounced:e=>r.connectionLifecycle.isConnectionAnnounced(e),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),isMoQReady:()=>r.moqServices.isReady(),isMoQDataReady:e=>r.moqServices.isDataReady(e),sendMoQData:(e,t,n)=>r.moqServices.sendData(e,t,n),getPendingSessionToken:e=>r.sessionTokens.getPendingTokenForNode(e)??void 0,getPendingSessionTokenPayload:e=>r.sessionTokens.getPendingTokenPayloadForNode(e)??void 0,requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),isSessionTokenApproved:(e,t)=>r.sessionTokens.isApproved(e,t),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),notifyDisconnectRequested:e=>r.signalingBackendController.notifyDisconnectRequested(e),isBackendConnected:e=>r.signalingBackendController.isConnected(e),hasAnyIncomingChannelListeners:()=>r.incomingStreamRouter.hasAnyIncomingChannelListeners(),hasIncomingStreamListeners:()=>r.incomingStreamRouter.hasIncomingStreamListeners()})}var Di=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getHandshake:()=>this.handshake,getRTCConfig:()=>this.getRTCConfig()}}get upgrade(){return this._upgrade??(this._upgrade=Zr(this.factoryHost))}get handshake(){return this._handshake??(this._handshake=es(this.factoryHost))}get health(){return this._health??(this._health=ts(this.host))}get contexts(){return this._contexts??(this._contexts=ns(this.host))}get peerIdentity(){return this._peerIdentity??(this._peerIdentity=is(this.host))}getRTCConfig(){return l$1(this.host.getOptions(),e=>d(e))}hasApplicationRouteForConnectionSnapshot(e,t,n){return kn(e,(i,o)=>this.host.getConfiguredApplicationCrypto()??this.host.resolveExistingApplicationCryptoForPeer(i,o),t,n)}hasApplicationRouteForPeer(e,t){return this.hasApplicationRouteForConnectionSnapshot(this.host.getConnectionForPeer(e,t),e,t)}isWebRtcApplicationRouteReadyForConnectionSnapshot(e){return Ni(e)}hasApplicationRouteFailure(e){return this._upgrade?.hasFailure(e)??false}clearApplicationRouteFailure(e){this._upgrade?.clearFailure(e);}};var Ln=class{constructor(e){this.deps=e;this.channelIds=new Map;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.channelIds.clear());}isChannelPromotionEligible(e){let t=this.deps.getRegisteredChannel(e);return t?t.promotionPolicy!=="never":true}isTransportOnlyChannel(e){return or(this.deps.getRegisteredChannel(e))}getConnectionChannelId(e){if(this.disposed)return null;let t=typeof e=="string"?e.trim():"";return t?this.channelIds.get(t)??null:null}isTransportOnlyConnectionId(e){return this.isTransportOnlyChannel(this.getConnectionChannelId(e))}allowsTransportOnlyStability(e){return this.deps.usesTicketOnlySignalingMode()||this.isTransportOnlyConnectionId(e.id)}resolvePromotionEligibility(e){if(this.disposed)return false;let t=this.getConnectionChannelId(e.connectionId);if(t)return this.isChannelPromotionEligible(t);let n=typeof e.nodeId=="string"?e.nodeId.trim():"";for(let i of this.deps.getConnections()){if(e.connectionId&&i.id===e.connectionId)return this.isChannelPromotionEligible(this.getConnectionChannelId(i.id));if(n&&i.remoteNodeId===n)return this.isChannelPromotionEligible(this.getConnectionChannelId(i.id))}return true}assign(e,t){if(this.disposed)return;let n=typeof t=="string"?t.trim():"";if(!n)return;this.channelIds.set(e.id,n);let i=this.deps.getConnectionTrustState(e.id);if(i&&!this.isChannelPromotionEligible(n)&&(i.required=false,i.verified=true,i.failed=false,i.failureReason=void 0,i.issuedChallenge=null,i.verifiedDeviceId||(i.verifiedDeviceId=i.expectedDeviceId||this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId)||null)),this.deps.hasRustPeerLifecycleProjection())this.schedulePeerReconciliationBestEffort("session-token-trust-approved");else for(let o of this.deps.getConnections())if(o.id===e.id){this.deps.applyConnectionTrustProjection(o);break}}forget(e){if(this.disposed)return;let t=typeof e=="string"?e.trim():"";t&&this.channelIds.delete(t);}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var Bn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}bindConnectionDeviceIdInRust(e,t){if(this.disposed)return;let n=t.trim();if(!n)return;let i=this.ctx.wasmClient,o=!!i&&typeof i.bind_connection_device_id=="function";d("[Client][BIND] bindConnectionDeviceIdInRust entered",{connectionId:e.id,remoteNodeId:e.remoteNodeId,deviceId:n,hasWasmClient:!!i,hasMethod:o}),this.deps.rememberKnownDeviceForNode(e.remoteNodeId,n);let s=this.deps.getApplicationCryptoForConnectionOrPeer(e.id,e.remoteNodeId);if(s&&this.deps.indexApplicationCryptoForPeer(n,s),!!o)try{Promise.resolve(i.bind_connection_device_id(e.id,n)).then(()=>{this.disposed||d("[Client][BIND] bind_connection_device_id resolved",{connectionId:e.id,deviceId:n});}).catch(a=>{this.disposed||console.warn("[Client][TRUST] Failed to bind deviceId on Rust connection record",{connectionId:e.id,remoteNodeId:e.remoteNodeId,deviceId:n,error:a});});}catch(a){if(this.disposed)return;console.warn("[Client][TRUST] Failed to bind deviceId on Rust connection record",{connectionId:e.id,remoteNodeId:e.remoteNodeId,deviceId:n,error:a});}}retireSupersededConnections(e,t,n){if(this.disposed)return;let i=t.trim();if(i)for(let o of this.ctx.registry.values())o.id===e.id||o.isClosed||this.deps.getLogicalDeviceIdForConnection(o.id)===i&&(d("[Client][CONNECTION] Retiring superseded connection for logical device",{keptConnectionId:e.id,retiredConnectionId:o.id,logicalDeviceId:i,reason:n}),this.disconnectBestEffort(o));}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}};var gc="trustedDevice",hc="plutonium:e2ee:identity:v1",mc="plutonium:e2ee:identity:session:v1",fc="openrtc-trust",Fe="identity",rs="transport-trust:v1";var oe=null;function Be(r){let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n+=1)t[n]=e.charCodeAt(n);return t}function Mi(r){let e="";for(let t=0;t<r.length;t+=1)e+=String.fromCharCode(r[t]);return btoa(e)}async function ss(r){let e=await crypto.subtle.digest("SHA-256",r),t=new Uint8Array(e);return Array.from(t).map(n=>n.toString(16).padStart(2,"0")).join("")}function yc(){return typeof sessionStorage>"u"?null:sessionStorage}function vc(){if(!(typeof localStorage>"u"))try{localStorage.removeItem(hc);}catch{}}var Fn=null;async function as(){return Fn||(Fn=(async()=>{let r=globalThis.crypto?.subtle;if(!r||typeof r.generateKey!="function")return false;try{let e=await r.generateKey({name:"Ed25519"},!1,["sign","verify"]);return !!(e&&e.privateKey&&e.publicKey)}catch{return false}})(),Fn)}async function bc(r){let e=await crypto.subtle.exportKey("raw",r);return new Uint8Array(e)}function Cc(){try{return typeof indexedDB<"u"?indexedDB:null}catch{return null}}function cs(){let r=Cc();return r?new Promise(e=>{let t;try{t=r.open(fc,1);}catch{e(null);return}t.onupgradeneeded=()=>{let n=t.result;n.objectStoreNames.contains(Fe)||n.createObjectStore(Fe);},t.onsuccess=()=>e(t.result),t.onerror=()=>e(null),t.onblocked=()=>e(null);}):Promise.resolve(null)}async function Sc(){let r=await cs();if(!r)return null;try{return await new Promise(e=>{let i=r.transaction(Fe,"readonly").objectStore(Fe).get(rs);i.onsuccess=()=>{let o=i.result;e(o&&o.privateKey&&o.publicKey?o:null);},i.onerror=()=>e(null);})}catch{return null}finally{r.close();}}async function Ic(r){let e=await cs();if(!e)return false;try{return await new Promise(t=>{let n=e.transaction(Fe,"readwrite");n.objectStore(Fe).put(r,rs),n.oncomplete=()=>t(!0),n.onerror=()=>t(!1),n.onabort=()=>t(!1);})}catch{return false}finally{e.close();}}async function ds(r,e){let t=await bc(r.publicKey),n=await ss(t),i=r.privateKey;return {publicKey:t,fingerprint:n,backend:"webcrypto-nonextractable",durable:e,privateKey:i,async signChallenge(o){let s=await crypto.subtle.sign({name:"Ed25519"},i,Be(o));return Mi(new Uint8Array(s))}}}function wc(r,e,t){let n=r.secretKey;return {publicKey:r.publicKey,secretKey:n,fingerprint:e,backend:"tweetnacl",durable:t,async signChallenge(i){return Pc(i,n)}}}function ls(r=32){let e=crypto.getRandomValues(new Uint8Array(r));return Mi(e)}function Pc(r,e){let t=On.sign.detached(Be(r),e);return Mi(t)}function ps(r,e,t){try{return On.sign.detached.verify(Be(r),Be(e),Be(t))}catch{return false}}function us(r){if(!r||!r.trim())return null;try{let e=JSON.parse(r),t=e&&typeof e=="object"&&!Array.isArray(e)?e[gc]:null;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t,i=typeof n.version=="number"?n.version:null,o=typeof n.identityPublicKey=="string"?n.identityPublicKey:null,s=typeof n.identityFingerprint=="string"?n.identityFingerprint:null;return !i||!o||!s?null:{version:i,identityPublicKey:o,identityFingerprint:s}}catch{return null}}function Rc(){if(typeof window>"u")return null;let r=window.__TAURI_INTERNALS__;return !r||typeof r.invoke!="function"?null:r.invoke.bind(r)}async function _c(){if(!a$3()||typeof window>"u"||/iPhone|iPad|iPod|Android/i.test(navigator.userAgent||""))return null;let r=Rc();if(!r)return null;try{let e=await r("openrtc_get_transport_trust_identity");return {publicKey:Be(e.publicKeyBase64),fingerprint:e.fingerprint,backend:"native-keychain",durable:!0,async signChallenge(n){return r("openrtc_sign_transport_trust_challenge",{challenge:n})}}}catch{return null}}function Tc(){let r=yc();r&&r.removeItem(mc);}async function Ac(){if(vc(),Tc(),oe)return oe;let r=await _c();if(r)return oe=r,oe;if(await as()){let e=await Sc();if(e)return oe=await ds(e,true),oe}return null}async function Ei(r={}){let e=await Ac();if(e)return e;let t=r.ephemeral===true;if(await as())try{let n=await crypto.subtle.generateKey({name:"Ed25519"},!1,["sign","verify"]),i=!1;return t||(i=await Ic(n)),oe=await ds(n,i),oe}catch{}if(!t)return console.warn("[OpenRTC][TRUST] Managed transport trust requires WebCrypto Ed25519 or native keychain; refusing extractable fallback storage"),null;try{let n=On.sign.keyPair(),i=await ss(s$1(n.publicKey));return oe=wc(n,i,!1),oe}catch{return null}}var Wn=class{constructor(e,t){this.ctx=e;this.deps=t;this.states=new Map;this.failureCooldowns=new Map;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.states.clear(),this.failureCooldowns.clear());}initialize(e,t){if(this.disposed)return {required:false,verified:false,failed:true,failureReason:"connection-trust-manager-disposed",expectedDeviceId:t??null,verifiedDeviceId:null,issuedChallenge:null};let n=this.states.get(e.id);if(n)return t&&!n.expectedDeviceId&&(n.expectedDeviceId=t),n;let i=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId,deviceId:t??void 0}),o=this.deps.consumePendingSessionTokenTrustApproval(e.id),s=o.approved,a=this.deps.getKnownDeviceIdForNode(e.remoteNodeId),c=!s&&i&&this.deps.requiresManagedTransportTrust(),d={required:c,verified:!c,failed:false,expectedDeviceId:t||a||null,verifiedDeviceId:c?null:t||a||null,issuedChallenge:c?ls():null};return this.states.set(e.id,d),o.scope&&this.deps.addPeerScope(e.id,o.scope),d}sessionTokenScopeAllowsDeviceBinding(e){let t=typeof e=="string"?e.trim():"";return t==="user-device"||t==="persistent"||t==="trusted-device"||t.startsWith("trusted-device:")}resolveExpectedDeviceIdForSessionTokenScope(e,t,n,i){let o=typeof e=="string"?e.trim():"";if(!o)return null;if(!n)return o;let s=new Set,a=c=>{let d=typeof c=="string"?c.trim():"";d&&s.add(d);};if(a(t),i){a(this.deps.getSessionTokenApprovedScope(i.id));for(let c of this.deps.getPeerScopes(i.id))a(c);for(let c of this.deps.getPeerScopes(i.remoteNodeId))a(c);}return Array.from(s).some(c=>this.sessionTokenScopeAllowsDeviceBinding(c))?o:null}getState(e){if(this.disposed)return null;let t=typeof e.connectionId=="string"?e.connectionId.trim():"";if(t)return this.states.get(t)??null;for(let[n,i]of this.states.entries())if(i.verifiedDeviceId&&(i.verifiedDeviceId===e.deviceId||i.verifiedDeviceId===e.deviceIdHint)||i.expectedDeviceId&&(i.expectedDeviceId===e.deviceId||i.expectedDeviceId===e.deviceIdHint))return this.states.get(n)??null;return null}getProjection(e){if(this.disposed)return null;let t=this.getState(e);return t?t.verified&&!t.failed?{routable:true,protocolState:"routable",health:"healthy",deviceId:t.verifiedDeviceId??t.expectedDeviceId??e.deviceId??null}:t.required?{routable:false,protocolState:"unverified",health:t.failed?"stale":"unknown",error:t.failureReason??"trusted-device-proof-pending",deviceId:t.expectedDeviceId??e.deviceId??e.deviceIdHint??null}:null:null}async buildLocalTransportTrustPayload(e){if(this.disposed)return null;let t=await Ei().catch(()=>null),n=await this.deps.getLocalDeviceId().catch(()=>null)||this.ctx.deviceId||this.deps.getFallbackLocalDeviceId()||null;if(!t||!n)return null;let i=this.initialize(e);return {version:1,deviceId:n,identityFingerprint:t.fingerprint,challenge:i.issuedChallenge??void 0}}async signTransportTrustChallenge(e){if(this.disposed)throw new Error("Connection trust manager is disposed");let t=await Ei().catch(()=>null);if(!t)throw new Error("Local trusted identity unavailable for handshake proof");return t.signChallenge(e)}async verifyRemoteTransportTrust(e,t){if(this.disposed)return {verified:false,reason:"connection-trust-manager-disposed"};let n=this.initialize(e);if(!n.required)return {verified:true,deviceId:t?.deviceId??n.expectedDeviceId??null};if(!t)return {verified:false,reason:"missing-transport-trust-payload"};let i=typeof t.deviceId=="string"?t.deviceId.trim():"";if(!i)return {verified:false,reason:"missing-remote-device-id"};if(n.expectedDeviceId&&n.expectedDeviceId!==i)return {verified:false,reason:`expected-device-mismatch:${n.expectedDeviceId}:${i}`};let o=this.deps.getKnownDevice(i,e.remoteNodeId);if(!o){if(await this.deps.refreshKnownDeviceCache(),this.disposed)return {verified:false,reason:"connection-trust-manager-disposed"};o=this.deps.getKnownDevice(i,e.remoteNodeId);}if(!o)return {verified:false,reason:`unknown-trusted-device:${i}`};let s=us(o.metadata);if(!s)return {verified:false,reason:`missing-trusted-device-metadata:${i}`};if(t.identityFingerprint&&s.identityFingerprint!==t.identityFingerprint)return {verified:false,reason:`trusted-device-fingerprint-mismatch:${i}`};let a=n.issuedChallenge;return !a||!t.signedChallenge?{verified:false,reason:"missing-signed-transport-challenge"}:ps(a,t.signedChallenge,s.identityPublicKey)?{verified:true,deviceId:i}:{verified:false,reason:`invalid-transport-proof:${i}`}}async enforceFailure(e,t){if(this.disposed)return;let n=this.initialize(e);n.failed=true,n.verified=false,n.failureReason=t,this.deps.applyConnectionTrustProjection(e),console.warn("[Client][TRUST] Disconnecting unverified connection",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t}),this.failureCooldowns.set(e.remoteNodeId,Date.now()),await Promise.allSettled([this.disconnectConnectionBestEffort(e),this.disconnectNodeBestEffort(e.remoteNodeId)]);}markVerified(e,t){if(this.disposed)return;this.failureCooldowns.delete(e.remoteNodeId);let n=this.initialize(e,t);n.verified=true,n.failed=false,n.failureReason=void 0,n.verifiedDeviceId=t||n.verifiedDeviceId||n.expectedDeviceId||null,t&&!n.expectedDeviceId&&(n.expectedDeviceId=t),this.deps.applyConnectionTrustProjection(e);let i=n.verifiedDeviceId??n.expectedDeviceId??t??null;i&&(this.deps.bindConnectionDeviceIdInRust(e,i),this.deps.requiresManagedTransportTrust()&&this.deps.addPeerScope(e.id,"user-device"),this.deps.retireSupersededConnections(e,i,"trusted-device-replacement"));}clearForConnection(e){this.disposed||this.states.delete(e);}getStateByConnectionId(e){if(!this.disposed)return this.states.get(e)}getLogicalDeviceIdForConnection(e){let t=this.states.get(e);return t?.verifiedDeviceId??t?.expectedDeviceId??null}clearFailureCooldown(e){this.disposed||this.failureCooldowns.delete(e);}getFailureCooldown(e){if(!this.disposed)return this.failureCooldowns.get(e)}shouldSuppressConnectionRebuild(e,t,n,i=Date.now()){if(this.disposed)return {suppress:false,remainingMs:0};let o=this.failureCooldowns.get(e);return o===void 0||i-o>=t||n?{suppress:false,remainingMs:0}:{suppress:true,remainingMs:t-(i-o)}}logConnectionRebuildSuppressed(e,t){this.disposed||d("[Client][TRUST] Skipping connection rebuild for node in trust-failure cooldown",{remoteNodeId:e,cooldownRemainingMs:t});}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}disconnectNodeBestEffort(e){try{return Promise.resolve(this.deps.disconnectNode(e)).catch(()=>{})}catch{return Promise.resolve()}}};function gs(r){return new xi({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getDeviceId:()=>r.deviceId,getDiscoveryMode:()=>r.discoveryMode,registerDisposer:e=>r.lifecycleScope.register(e),getRegisteredChannel:e=>r.incomingStreamRouter.getRegisteredChannel(e),getConnections:()=>r.registry.values(),requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),consumePendingSessionTokenTrustApproval:e=>r.sessionTokens.consumePendingTrustApproval(e),getSessionTokenApprovedScope:e=>r.sessionTokens.getApprovedScope(e),addPeerScope:(e,t)=>r.peerServices.addPeerScope(e,t),getPeerScopes:e=>r.peerServices.getPeerScopes(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),getKnownDevice:(e,t)=>r.deviceDirectory.getKnownDevice(e,t),refreshKnownDeviceCache:()=>r.deviceDirectory.refreshKnownDeviceCache(),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),disconnectRuntimeNode:e=>r.runtimeConnections.disconnectNode(e),rememberKnownDeviceForNode:(e,t)=>r.deviceDirectory.rememberKnownDeviceForNode(e,t),getApplicationCryptoForConnectionOrPeer:(e,t)=>r.applicationCrypto.getForConnectionOrPeer(e,t),indexApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.indexPeer(e,t),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode()})}var xi=class{constructor(e){this.host=e;}get trust(){return this._trust||(this._trust=new Wn(this.host.getContext(),{requiresManagedTransportTrust:()=>this.host.requiresManagedTransportTrust(this.host.getDiscoveryMode()),resolvePromotionEligibility:e=>this.channelPolicy.resolvePromotionEligibility(e),consumePendingSessionTokenTrustApproval:e=>this.host.consumePendingSessionTokenTrustApproval(e),getSessionTokenApprovedScope:e=>this.host.getSessionTokenApprovedScope(e),addPeerScope:(e,t)=>this.host.addPeerScope(e,t),getPeerScopes:e=>this.host.getPeerScopes(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),getKnownDevice:(e,t)=>this.host.getKnownDevice(e,t),refreshKnownDeviceCache:()=>this.host.refreshKnownDeviceCache(),getLocalDeviceId:()=>this.host.getLocalDeviceId(),getFallbackLocalDeviceId:()=>this.host.getDeviceId()??this.host.getOptions()?.localDeviceId??null,applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>this.deviceBinder.bindConnectionDeviceIdInRust(e,t),retireSupersededConnections:(e,t,n)=>this.deviceBinder.retireSupersededConnections(e,t,n),disconnectNode:e=>this.host.disconnectRuntimeNode(e)})),this._trust}get deviceBinder(){return this._deviceBinder||(this._deviceBinder=new Bn(this.host.getContext(),{rememberKnownDeviceForNode:(e,t)=>this.host.rememberKnownDeviceForNode(e,t),getApplicationCryptoForConnectionOrPeer:(e,t)=>this.host.getApplicationCryptoForConnectionOrPeer(e,t),indexApplicationCryptoForPeer:(e,t)=>{this.host.indexApplicationCryptoForPeer(e,t);},getLogicalDeviceIdForConnection:e=>this.trust.getLogicalDeviceIdForConnection(e)})),this._deviceBinder}get channelPolicy(){return this._channelPolicy||(this._channelPolicy=new Ln({registerDisposer:e=>this.host.registerDisposer(e),getRegisteredChannel:e=>this.host.getRegisteredChannel(e),getConnections:()=>this.host.getConnections(),getConnectionTrustState:e=>this.trust.getStateByConnectionId(e),getKnownDeviceIdByNodeId:e=>this.host.getKnownDeviceIdForNode(e),hasRustPeerLifecycleProjection:()=>this.host.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),schedulePeerReconciliation:e=>this.host.schedulePeerReconciliation(e),usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode()})),this._channelPolicy}};var Un=class{constructor(e){this.host=e;this.kernelHandles=new Et;this.lifecycleScope=new xt;}get wasmClient(){return this.kernelHandles.wasmClient}set wasmClient(e){this.kernelHandles.wasmClient=e;}get node(){return this.kernelHandles.node}set node(e){this.kernelHandles.node=e;}get localNodeId(){return this.kernelHandles.localNodeId}set localNodeId(e){this.kernelHandles.localNodeId=e;}get deviceId(){return this.kernelHandles.deviceId}set deviceId(e){this.kernelHandles.deviceId=e;}get runtimeServices(){return this._runtimeServices??(this._runtimeServices=Or(this))}get runtimeBootstrap(){return this.runtimeServices.bootstrap}get runtimeConnections(){return this.runtimeServices.connections}get managedTransportDialer(){return this.runtimeServices.managedDialer}get runtimeIdentity(){return this.runtimeServices.identity}get runtimeReadiness(){return this.runtimeServices.readiness}get runtimeStatus(){return this.runtimeServices.status}get connectionServices(){return this._connectionServices??(this._connectionServices=tr(this))}get moqServices(){return this._moqServices??(this._moqServices=ir(this))}get transportServices(){return this._transportServices??(this._transportServices=os(this))}get trustServices(){return this._trustServices??(this._trustServices=gs(this))}get registry(){return this.connectionServices.registry}get connectionDialer(){return this.connectionServices.dialer}get connectionMessageHandler(){return this.connectionServices.messageHandler}get incomingConnectionAcceptor(){return this.connectionServices.incomingAcceptor}get appLifecycle(){return this.runtimeServices.appLifecycle}get roomClientHost(){return this._roomClientHost??(this._roomClientHost=Sr(this))}get accessServices(){return this._accessServices??(this._accessServices=Wo(this))}get auth(){return this.accessServices.auth}get signalingBackendController(){return this.accessServices.backend}get peerServices(){return this._peerServices??(this._peerServices=Cr(this))}get peerProjection(){return this.peerServices.projection}get connectionLifecycle(){return this.connectionServices.lifecycle}get streamServices(){return this._streamServices??(this._streamServices=Yr(this))}get incomingStreamRouter(){return this.streamServices.router}get incomingListen(){return this.streamServices.listen}get incomingDiagnostics(){return this.streamServices.diagnostics}get incomingStreamNormalizer(){return this.streamServices.normalizer}get applicationIncomingStreams(){return this.streamServices.applicationIncoming}get applicationStreams(){return this.streamServices.applicationStreams}get deviceDirectory(){return this.accessServices.devices}get connectionTrust(){return this.trustServices.trust}get connectionDeviceBinder(){return this.trustServices.deviceBinder}get connectionChannelPolicy(){return this.trustServices.channelPolicy}get nativeMainServices(){return this._nativeMainServices??(this._nativeMainServices=sr(this))}get nativeMain(){return this.nativeMainServices.controller}get presence(){return this.accessServices.presence}get securityServices(){return this._securityServices??(this._securityServices=Wr(this))}get sessionTokens(){return this.securityServices.sessionTokens}get applicationCrypto(){return this.securityServices.applicationCrypto}get transportUpgrade(){return this.transportServices.upgrade}get transportHandshake(){return this.transportServices.handshake}get transportHealth(){return this.transportServices.health}get transportContexts(){return this.transportServices.contexts}get peerIdentity(){return this.transportServices.peerIdentity}get options(){return this.host.getOptions()}get runtimeSafetyProfile(){return this.host.getRuntimeSafetyProfile()}get discoveryMode(){return this.options.discoveryMode??"space"}get signaling(){return this.host.getSignaling()}get rooms(){return this.host.getRooms()}getRoomCreationMode(){return this.host.getRoomCreationMode()}getAppLimits(){return this.host.getAppLimits()}setSignaling(e){this.host.setSignaling(e);}setRooms(e){this.host.setRooms(e);}setAppLimits(e){this.host.setAppLimits(e);}setRoomCreationMode(e){this.host.setRoomCreationMode(e);}prepareStreamListenForSignOutIfExists(){this._streamServices?.prepareListenForSignOut();}getEffectiveRoomBackendTag(){return this.host.getEffectiveRoomBackendTag()}setEffectiveRoomBackendTag(e){this.host.setEffectiveRoomBackendTag(e);}getExistingPeerReconciliationStats(){return this._peerServices?.getProjectionStats()}hasRustPeerLifecycleProjection(){return bi(this.signaling,this.wasmClient)}getClientContext(){return this._clientContext||(this._clientContext=xo({getRegistry:()=>this.registry,getWasmClient:()=>this.wasmClient,getNode:()=>this.node,getDiscoveryMode:()=>this.discoveryMode,getLocalNodeId:()=>this.localNodeId,getDeviceId:()=>this.deviceId,registerDisposer:e=>this.lifecycleScope.register(e)})),this._clientContext}getApplicationCrypto(e){return this.securityServices.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.securityServices.resolveApplicationCryptoForPeer(e,t)}waitForApplicationCryptoForPeer(e,t=0){return this.securityServices.waitForApplicationCryptoForPeer(e,t)}stopListenIfExists(){this._streamServices?.stopListenIfExists();}hasApplicationRouteForPeer(e,t){return this.transportServices.hasApplicationRouteForPeer(e,t)}};function Li(){return new Proxy({},{get(){}})}function kc(){let r=globalThis,e=r.process?.env;return e?.NODE_ENV==="test"||e?.VITEST==="true"||typeof e?.VITEST_WORKER_ID=="string"||typeof r.__vitest_worker__<"u"||typeof r.__vitest_index__<"u"}function N(r){return r.services}var hs={localNodeId:{get(){return N(this).localNodeId},set(r){N(this).localNodeId=r;}},deviceId:{get(){return N(this).deviceId},set(r){N(this).deviceId=r;}},registry:{get(){return N(this).registry}},__registry:{get(){return N(this).registry}},runtimeBootstrap:{get(){return N(this).runtimeBootstrap}},runtimeConnections:{get(){return N(this).runtimeConnections}},runtimeIdentity:{get(){return N(this).runtimeIdentity}},runtimeReadiness:{get(){return N(this).runtimeReadiness}},runtimeStatus:{get(){return N(this).runtimeStatus}},connectionDialer:{get(){return N(this).connectionDialer}},connectionMessageHandler:{get(){return N(this).connectionMessageHandler},set(r){N(this).connectionServices._messageHandler=r;}},connectionLifecycle:{get(){return N(this).connectionLifecycle}},transportUpgrade:{get(){return N(this).transportUpgrade}},transportHandshake:{get(){return N(this).transportHandshake}},transportHealth:{get(){return N(this).transportHealth}},transportContexts:{get(){return N(this).transportContexts}},peerIdentity:{get(){return N(this).peerIdentity}},peerProjection:{get(){return N(this).peerProjection}},peerLifecycle:{get(){return N(this).peerServices.store},set(r){N(this).peerServices.store=r;}},peerLifecycleClient:{get(){return N(this).peerServices.client}},connectionTrust:{get(){return N(this).connectionTrust}},connectionDeviceBinder:{get(){return N(this).connectionDeviceBinder}},connectionChannelPolicy:{get(){return N(this).connectionChannelPolicy}},incomingListen:{get(){return N(this).incomingListen}},incomingStreamRouter:{get(){return N(this).incomingStreamRouter}},incomingDiagnostics:{get(){return N(this).incomingDiagnostics}},incomingStreamNormalizer:{get(){return N(this).incomingStreamNormalizer}},applicationIncomingStreams:{get(){return N(this).applicationIncomingStreams}},applicationCrypto:{get(){return N(this).applicationCrypto}},sessionTokens:{get(){return N(this).sessionTokens}},nativeMain:{get(){return N(this).nativeMain}},auth:{get(){return N(this).auth}},deviceDirectory:{get(){return N(this).deviceDirectory}},presence:{get(){return N(this).presence}},appLifecycle:{get(){return N(this).appLifecycle}},moqController:{get(){return N(this).moqServices.controller}},_runtimeBootstrap:{get(){return N(this)._runtimeServices?._bootstrap}},_auth:{get(){return N(this)._accessServices?._auth}},_presence:{get(){return N(this)._accessServices?._presence}},_peerProjection:{get(){return N(this)._peerServices?._projection},set(r){N(this).peerServices._projection=r;}},_peerLifecycleClient:{get(){return N(this)._peerServices?._client}},_incomingListen:{get(){return N(this)._streamServices?._listen}},_connectionDialer:{get(){return N(this)._connectionServices?._dialer}},_connectionMessageHandler:{get(){return N(this)._connectionServices?._messageHandler},set(r){N(this).connectionServices._messageHandler=r;}},_transportUpgrade:{get(){return N(this)._transportServices?._upgrade}},_applicationCrypto:{get(){return N(this)._securityServices?._applicationCrypto},set(r){N(this).securityServices._applicationCrypto=r;}},_transportContexts:{set(r){N(this).transportServices._contexts=r;}}};function ms(r){if(kc()){for(let e of Object.values(hs))e.configurable=true;Object.defineProperties(r.prototype,hs);}}var st=class{constructor(e){this.appLimits={...g};this.roomCreationMode="client-open";let t=n(e);this.options=t.options,this.runtimeSafetyProfile=ze(this.options),this.effectiveRoomBackendTag=t.appTag,this.roomCreationMode=t.roomCreationMode,this.signaling=new Se(o(t),Li()),this._services=this.createServiceGraph(),this.rooms=new ke(this.services.roomClientHost,this.signaling),this.services.signalingBackendController;}get services(){return this._services??(this._services=this.createServiceGraph())}createServiceGraph(){let e=()=>({...this.options??{},apiKey:this.options?.apiKey??"test"});return new Un({getOptions:()=>this.options??e(),getRuntimeSafetyProfile:()=>this.runtimeSafetyProfile??ze(e()),getSignaling:()=>this.signaling??(this.signaling=new Se(o(e()),Li())),setSignaling:t=>{this.signaling=t;},getRooms:()=>this.rooms,setRooms:t=>{this.rooms=t;},getAppLimits:()=>this.appLimits??(this.appLimits={...g}),setAppLimits:t=>{this.appLimits=t;},getRoomCreationMode:()=>this.roomCreationMode??"client-open",setRoomCreationMode:t=>{this.roomCreationMode=t;},getEffectiveRoomBackendTag:()=>this.effectiveRoomBackendTag??"openrtc",setEffectiveRoomBackendTag:t=>{this.effectiveRoomBackendTag=t;}})}get wasmClient(){return this.services.wasmClient}set wasmClient(e){this.services.wasmClient=e;}get node(){return this.services.node}set node(e){this.services.node=e;}attachIncomingStreamSource(e,t){this.services.wasmClient=e,this.services.localNodeId=t;}getApplicationCrypto(e){return this.services.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.services.resolveApplicationCryptoForPeer(e,t)}waitForApplicationCryptoForPeer(e,t=1500){return this.services.waitForApplicationCryptoForPeer(e,t)}destroy(){this.services.lifecycleScope.destroy();}dispose(){this.destroy();}get apiKey(){return this.options.apiKey}get discoveryMode(){return this.options.discoveryMode??"space"}usesDirectRoomBackend(){return this.services.runtimeStatus.usesDirectRoomBackend()}getRoomBackendTag(){return this.services.runtimeStatus.getRoomBackendTag()}async refreshHostedAppSettings(e=false){return this.services.signalingBackendController.refreshHostedAppSettings(e)}setSignalingBackend(e){this.services.signalingBackendController.setSignalingBackend(e);}get currentUser(){return this.services.signalingBackendController.getCurrentUser()??null}onAuthChange(e){return this.services.auth.onAuthChange(e)}async signInAnonymously(){return this.services.auth.signInAnonymously()}async signInWithPluto(){return this.services.auth.signInWithPluto()}async signOut(){return this.services.auth.signOut()}getSignalingTelemetry(){return this.services.runtimeStatus.getSignalingTelemetry()}getPeerReconciliationStats(){return this.services.runtimeStatus.getPeerReconciliationStats()}getProtocolCapabilities(){return this.services.runtimeStatus.getProtocolCapabilities()}async getRuntimeStatus(){return this.services.runtimeStatus.getRuntimeStatus()}async searchDevices(){return this.services.deviceDirectory.searchDevices()}async updateDevice(e,t){return this.services.deviceDirectory.updateDevice(e,t)}async deleteDevice(e){return this.services.deviceDirectory.deleteDevice(e)}async cleanupStaleDevices(){return this.services.deviceDirectory.cleanupStaleDevices()}onDevicesChange(e){return this.services.deviceDirectory.onDevicesChange(e)}async subscribeSessions(e,t){return this.services.deviceDirectory.subscribeSessions(e,t)}async startScanningLoop(e){return this.services.deviceDirectory.startScanningLoop(e)}async connectDeviceWithRetry(e,t,n){return this.services.deviceDirectory.connectDeviceWithRetry(e,t,n)}async bootstrapRuntime(e){return this.services.runtimeBootstrap.bootstrapRuntime(e)}updateTransportConfig(e){p(this.options,e);}async init(){return this.services.runtimeBootstrap.init()}async ensureAuthenticated(e){return this.services.auth.ensureAuthenticated(e)}async refreshRuntimeAuthToken(e="runtime-start"){return this.services.auth.refreshRuntimeAuthToken(e)}get moqState(){return this.services.moqServices.state}get moq(){return this.services.moqServices.bundle}onMoQReady(e){return this.services.moqServices.onReady(e)}onMoQFailed(e){return this.services.moqServices.onFailed(e)}onMoQObject(e){return this.services.moqServices.onObject(e)}subscribeMoQPeer(e){this.services.moqServices.enableForConnection(e);}subscribeMoQPeerNode(e,t){this.services.moqServices.subscribePeerNode(e,t);}async connect(e,t=2e4,n,i,o){return this.services.connectionDialer.connect(e,t,n,i,o)}async connectRaw(e,t=2e4){return this.services.runtimeConnections.connectRaw(e,t)}async startAutoConnect(e){return this.services.runtimeConnections.startAutoConnect(e)}async openBi(e){return this.services.applicationStreams.openBi(e)}async openUni(e){return this.services.applicationStreams.openUni(e)}getConnections(){return this.services.registry.all()}getApplicationReadyConnections(e={}){return this.services.registry.applicationReady(e)}getConnectionForPeer(e,t){return this.services.registry.getForPeer(e,t)}hasApplicationRouteForPeer(e,t){return this.services.hasApplicationRouteForPeer(e,t)}watchPeerStates(e){return this.services.peerServices.watchPeerStates(e)}getPeerState(e){return this.services.peerServices.getPeerState(e)}listConnectedPeers(){return this.services.peerServices.listConnectedPeers()}isPeerPromotionEligible(e){return this.services.peerServices.isPeerPromotionEligible(e)}addPeerScope(e,t="persistent"){return this.services.peerServices.addPeerScope(e,t)}releasePeerScope(e,t){return this.services.peerServices.releasePeerScope(e,t)}getPeerScopes(e){return this.services.peerServices.getPeerScopes(e)}isSamePeer(e,t){return this.services.peerServices.isSamePeer(e,t)}async refreshPeerSnapshot(){return this.services.peerProjection.schedule("refresh")}async connectPeer(e){return this.services.connectionDialer.connectPeer(e)}clearManualDisconnectProjection(e){this.services.peerServices.clearManualDisconnectProjection(e);}async disconnectPeer(e,t="persistent"){await this.services.peerServices.disconnectPeer(e,t);}async forceDisconnectPeer(e){await this.services.peerServices.forceDisconnectPeer(e);}async getPeerHealth(e){return this.services.peerServices.getPeerHealth(e)}async getTicket(){return this.services.runtimeIdentity.getTicket()}async getNodeId(){return this.services.runtimeIdentity.getNodeId()}async getNodeIdFromTicket(e){return this.services.runtimeIdentity.getNodeIdFromTicket(e)}async getEndpointTicketWithToken(e,t=0){return this.services.sessionTokens.getEndpointTicketWithToken(e,t)}buildCompoundTicketWithToken(e,t,n=0){return this.services.sessionTokens.buildCompoundTicketWithToken(e,t,n)}setManagedPresenceTicket(e){this.services.presence.setManagedPresenceTicket(e);}clearManagedPresenceTicket(){this.services.presence.clearManagedPresenceTicket();}registerSessionToken(e,t,n){this.services.sessionTokens.registerSessionToken(e,t,n);}revokeSessionToken(e){this.services.sessionTokens.revokeSessionToken(e);}async revokeTokensByScope(e){return this.services.sessionTokens.revokeTokensByScope(e)}async clearSessionTokens(){return this.services.sessionTokens.clearSessionTokens()}async startPresenceLoop(e){return this.services.presence.startPresenceLoop(e)}async setOffline(){return this.services.presence.setOffline()}async isConnected(e){return this.services.runtimeConnections.isConnected(e)}async disconnectNode(e){return this.services.runtimeConnections.disconnectNode(e)}async getLocalDeviceId(){return this.services.signalingBackendController.getLocalDeviceId()}async acceptNativeMessage(e,t,n){return this.services.nativeMain.acceptNativeMessage(e,t,n)}async startListening(e){return this.services.incomingListen.start(e)}stopListening(){this.services.stopListenIfExists();}forceReconnectSnapshot(){this.services.signalingBackendController.forceReconnectSnapshot();}wrapChannelWritable(e,t,n){return yo(e,t,n)}async updatePresence(e=true,t=3e5,n,i){return this.services.presence.updatePresence(e,t,n,i)}onConnection(e){return this.services.connectionLifecycle.onConnection(e)}onDisconnection(e){return this.services.connectionLifecycle.onDisconnection(e)}onMessage(e){return this.services.incomingStreamRouter.onMessage(e)}onIncomingStream(e){return this.services.incomingStreamRouter.onIncomingStream(e)}registerChannel(e){this.services.incomingStreamRouter.registerChannel(e);}unregisterChannel(e){this.services.incomingStreamRouter.unregisterChannel(e);}listChannels(){return this.services.incomingStreamRouter.listChannels()}onIncomingChannelStream(e,t){return this.services.incomingStreamRouter.onIncomingChannelStream(e,t)}onRoomJoinRequest(e){return this.services.incomingStreamRouter.onRoomJoinRequest(e)}isMoQDataReady(e){return this.services.moqServices.isDataReady(e)}async sendMoQData(e,t,n={}){return this.services.moqServices.sendData(e,t,n)}};ms(st);var Hn=class{constructor(e){this.locallyDeletedDeviceIds=new Set;this.client=e.client,this.backend=e.backend,this.peerApi=e.peerApi,this.connectToDevice=e.connectToDevice,this.startManagedReconciliation=e.startManagedReconciliation,this.deviceStatusRefreshDebounceMs=e.deviceStatusRefreshDebounceMs;}deviceStatusSnapshotKey(e){return JSON.stringify([...e].map(t=>({deviceId:t.deviceId,deviceName:t.deviceName??null,platformType:t.platformType??null,online:!!t.online,presenceStatus:t.presenceStatus??null,presenceUpdatedAt:t.presenceUpdatedAt??null,presenceExpiresAt:t.presenceExpiresAt??null,connectable:t.connectable??null,connectionStatus:t.connectionStatus??null,settledReady:!!t.settledReady,readinessState:t.readinessState??null,readinessReason:t.readinessReason??null,peerHealth:t.peerHealth??null,peerId:t.peerId??null,promotionEligible:t.promotionEligible??true,connectionId:t.connectionId??null,deviceIdHint:t.deviceIdHint??null,nodeId:t.nodeId??null,ticket:t.ticket??null,activeTransportStableId:t.activeTransportStableId??null,transportGeneration:t.transportGeneration??null,activeTransport:t.activeTransport??null,parallelTransport:t.parallelTransport??null,scopes:[...t.scopes??[]].sort()})).sort((t,n)=>t.deviceId.localeCompare(n.deviceId)))}buildLookup(e,t){let n=new Map,i=(o,s)=>{let a=this.normalizeLookupKey(o);!a||n.has(a)||n.set(a,s);};for(let o of e)for(let s of t(o))i(s,o);return n}normalizeLookupKey(e){return typeof e=="string"?e.trim().toLowerCase():""}isLocallyDeletedDevice(e){let t=this.normalizeLookupKey(e);return !!t&&this.locallyDeletedDeviceIds.has(t)}filterLocallyDeletedDevices(e){return (e??[]).filter(t=>!this.isLocallyDeletedDevice(t.deviceId))}isDurableUserDevicePeer(e){return (e.scopes??[]).some(t=>t==="user-device")}matchItem(e,t){return e.get(this.normalizeLookupKey(t.deviceId))??e.get(this.normalizeLookupKey(t.deviceIdHint))??e.get(this.normalizeLookupKey(t.nodeId))??e.get(this.normalizeLookupKey(t.connectionId))??e.get(this.normalizeLookupKey(t.peerId))??null}buildFinalDeviceStatusSnapshots(e,t,n){let i=this.buildLookup(t,c=>[c.peerId,c.deviceId,c.deviceIdHint,c.nodeId,c.activeConnectionId]),o=this.buildLookup(n,c=>[c.peerId,c.deviceId,c.deviceIdHint,c.nodeId,c.connectionId,...c.connectionIds??[]]),s=this.filterLocallyDeletedDevices(e).map(c=>{let d=this.matchItem(o,c);return this.applyTerminalPeerTransportState(k({device:c,session:this.matchItem(i,c),peer:d,isPromotionEligible:p=>this.client.isPeerPromotionEligible(p)}),d)}),a=new Set(s.map(c=>this.normalizeLookupKey(c.deviceId)));for(let c of n){if(!this.isDurableUserDevicePeer(c))continue;let d=this.statusDeviceFromPeer(c),p=this.normalizeLookupKey(d?.deviceId);!d||!p||a.has(p)||this.isLocallyDeletedDevice(p)||(a.add(p),s.push(k({device:d,session:this.matchItem(i,d),peer:c,isPromotionEligible:u=>this.client.isPeerPromotionEligible(u)})));}return s}applyTerminalPeerTransportState(e,t){let n=String(t?.status??"").trim().toLowerCase();return n!=="closed"&&n!=="disconnected"&&n!=="failed"?e:{...e,activeTransportStableId:null,activeTransport:void 0,parallelTransport:void 0}}statusDeviceFromPeer(e){let t=e.deviceId?.trim()||e.deviceIdHint?.trim(),n=String(e.status??"").trim().toLowerCase();return !t||n==="closed"||n==="disconnected"||n==="failed"?null:{deviceId:t,deviceName:e.deviceName?.trim()||"Unknown Device",online:e.online??true,ticket:e.ticket??"",nodeId:e.nodeId,platformType:e.platformType,presenceStatus:e.online===false?"offline":"online",connectable:!!e.ticket,connectionStatus:e.status,settledReady:e.routable===true||e.protocolState==="routable",readinessState:e.protocolState,peerHealth:e.health,peerId:e.peerId,scopes:[...e.scopes??[]],connectionId:e.connectionId,deviceIdHint:e.deviceIdHint,activeTransportStableId:e.activeTransportStableId,transportGeneration:e.transportGeneration,activeTransport:e.activeTransport,parallelTransport:e.parallelTransport}}runtimeDeviceToStatusSnapshot(e){return k({device:e})}isRoutableDeviceStatus(e){return e.settledReady===true||String(e.readinessState??"").trim().toLowerCase()==="routable"}mergeWatchedDevicesIntoStatusSnapshots(e,t){if(!e)return t;let n=new Map(t.map(c=>[c.deviceId,c])),i=this.filterLocallyDeletedDevices(e),o=new Set(i.map(c=>this.normalizeLookupKey(c.deviceId))),s=this.filterLocallyDeletedDevices(t.filter(c=>!o.has(this.normalizeLookupKey(c.deviceId))));return [...i.map(c=>{let d=c,p=this.runtimeDeviceToStatusSnapshot(c),u=n.get(c.deviceId);if(!u)return p;let{connectionStatus:g,settledReady:f,readinessState:v,readinessReason:y,peerHealth:C,peerId:I,promotionEligible:k$1,connectionId:T,activeTransportStableId:_,transportGeneration:A,activeTransport:E,parallelTransport:x,presenceStatus:j,presenceUpdatedAt:D,presenceExpiresAt:O,connectable:Q,...Bi}=u,{connectionStatus:Te,settledReady:ys,readinessState:vs,readinessReason:bs,peerHealth:Cs,peerId:Ss,promotionEligible:Is,connectionId:ws,activeTransportStableId:Ps,transportGeneration:Rs,activeTransport:_s,parallelTransport:Ts,presenceStatus:Fi,presenceUpdatedAt:Oi,presenceExpiresAt:As,connectable:ks,deviceIdHint:Ns,scopes:Ds,...Ms}=p,Es=d.connectionStatus!==void 0||d.settledReady!==void 0||d.readinessState!==void 0||d.readinessReason!==void 0||d.peerHealth!==void 0||d.peerId!==void 0||d.promotionEligible!==void 0||d.connectionId!==void 0||d.activeTransportStableId!==void 0||d.transportGeneration!==void 0||d.activeTransport!==void 0||d.parallelTransport!==void 0,xs=this.isRoutableDeviceStatus(u),Wi=d.settledReady===true||String(d.readinessState??"").trim().toLowerCase()==="routable",Y=Es&&(!xs||Wi),at=Y&&(Wi||String(Te??"").trim().toLowerCase()==="connected"),Ui=u.presenceUpdatedAt,Hi=Oi,Oe=Fi!==void 0&&Hi!==void 0&&(Ui===void 0||Hi>=Ui);return k({device:{...Bi,...Ms,connectionStatus:Y?Te:u.connectionStatus,settledReady:Y?ys:u.settledReady,readinessState:Y?vs:u.readinessState,readinessReason:Y?bs:u.readinessReason,peerHealth:Y?Cs:u.peerHealth,peerId:Y?Ss:u.peerId,promotionEligible:Y?Is:u.promotionEligible,connectionId:Y?ws:u.connectionId,activeTransportStableId:at?Ps:Y?void 0:u.activeTransportStableId,transportGeneration:at?Rs:Y?void 0:u.transportGeneration,activeTransport:at?_s:Y?void 0:u.activeTransport,parallelTransport:at?Ts:Y?void 0:u.parallelTransport,online:Oe?p.online:u.online,presenceStatus:Oe?Fi:u.presenceStatus,presenceUpdatedAt:Oe?Oi:u.presenceUpdatedAt,presenceExpiresAt:Oe?As:u.presenceExpiresAt,connectable:Oe?ks:u.connectable,platformType:u.platformType??p.platformType,deviceIdHint:Ns??u.deviceIdHint,scopes:Ds??u.scopes}})}),...s]}async listDevices(){return this.filterLocallyDeletedDevices(await this.client.searchDevices())}async listDevicesWithStatus(){let e=this.backend;if(e&&typeof e.listDevicesWithStatus=="function"){let t=await e.listDevicesWithStatus(),[n,i]=await Promise.allSettled([typeof e.listPeerSessions=="function"?e.listPeerSessions():Promise.resolve([]),this.peerApi.refreshPeerSnapshot().catch(d=>{let p=this.peerApi.listConnectedPeers();return console.warn(`[RuntimeClient] refreshPeerSnapshot failed during listDevicesWithStatus(); using ${p.length} cached connected peers`,d),p})]),o=n.status==="fulfilled"?n.value:[],s=i.status==="fulfilled"?i.value:[],a=this.filterLocallyDeletedDevices(this.buildFinalDeviceStatusSnapshots(t,o,s));return (a.some(d=>f(d.activeTransport))||o.some(d=>f(d.activeTransport))||s.some(d=>f(d.activeTransport)))&&c("[RuntimeClient] device status snapshot with transport labels",{devices:a.map(d=>({deviceId:d.deviceId,connectionStatus:d.connectionStatus,settledReady:!!d.settledReady,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null,connectionId:d.connectionId??null})),peerSessions:o.map(d=>({peerId:d.peerId,deviceId:d.deviceId??null,activeConnectionId:d.activeConnectionId??null,status:d.status,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null})),peers:s.map(d=>({peerId:d.peerId,deviceId:d.deviceId??null,connectionId:d.connectionId??null,status:d.status,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null}))}),a}throw new Error("[pluto-rtc] listDevicesWithStatus() requires a Rust-backed runtime adapter that implements listDevicesWithStatus().")}async updateDevice(e,t){await this.client.updateDevice(e,t);}async deleteDevice(e){let t=this.normalizeLookupKey(e);await this.client.deleteDevice(e),t&&this.locallyDeletedDeviceIds.add(t);}watchDevices(e){return this.client.onDevicesChange(t=>e(this.filterLocallyDeletedDevices(t)))}watchDevicesWithStatus(e){let t=this.backend;if(!t||typeof t.listDevicesWithStatus!="function")throw new Error("[pluto-rtc] watchDevicesWithStatus() requires a Rust-backed runtime adapter that implements listDevicesWithStatus().");let n=true,i=null,o=[],s=null,a=[],c=null,d=null,p=false,u=false,g=A=>{let E=this.filterLocallyDeletedDevices(this.buildFinalDeviceStatusSnapshots(A,[],a));v(E);let x=this.deviceStatusSnapshotKey(E);x!==i&&(i=x,e(E));},f=()=>{d&&(clearTimeout(d),d=null);},v=A=>{if(f(),!n)return;let E=Date.now(),x=A.filter(D=>D.presenceStatus==="online").map(D=>typeof D.presenceUpdatedAt=="number"?D.presenceUpdatedAt+3e5:null).filter(D=>typeof D=="number"&&Number.isFinite(D)).sort((D,O)=>D-O)[0];if(x===void 0)return;let j=Math.max(25,x-E+5);d=setTimeout(()=>{d=null,I();},j);},y=()=>{p=false,!(!n||!u)&&(u=false,I());},C=()=>{if(n){if(p){u=true;return}p=true,this.listDevicesWithStatus().then(A=>{n&&(o=A,g(this.mergeWatchedDevicesIntoStatusSnapshots(s,A)));}).catch(A=>{console.warn("[RuntimeDeviceManager] device-status refresh failed",A);}).finally(()=>y());}},I=()=>{!n||c||(c=setTimeout(()=>{c=null,C();},this.deviceStatusRefreshDebounceMs));},k=this.client.onDevicesChange(A=>{if(Array.isArray(A)){let E=this.filterLocallyDeletedDevices(A);s=E,g(this.mergeWatchedDevicesIntoStatusSnapshots(E,o));}I();}),T=this.peerApi.watchPeerStates(A=>{a=Array.isArray(A)?A:[],g(this.mergeWatchedDevicesIntoStatusSnapshots(s,o)),I();}),_=this.startManagedReconciliation(()=>I());return C(),()=>{n=false,c&&clearTimeout(c),f(),_(),k(),T();}}async connectDeviceWithRetry(e,t,n){return this.client.connectDeviceWithRetry(e,t,n)}async connectDevice(e,t){let n=e,i=typeof e.ticket=="string"?e.ticket.trim():"";if(!i){let d=(await this.listDevicesWithStatus().catch(()=>this.listDevices().catch(()=>[]))).find(p=>p.deviceId===e.deviceId);d&&(n={...e,...d},i=typeof d.ticket=="string"?d.ticket.trim():"");}if(!i)return {success:false,error:`Cannot connect to ${e.deviceId}: missing endpoint ticket`,attempts:1};let o=this.peerApi.getPeerState(e.deviceId),s=o?.status,a=this.client.hasApplicationRouteForPeer?.(o?.connectionId??void 0)??false;if(s==="connected"&&a)return {success:true,skipped:"already-connecting",attempts:0};this.client.clearManualDisconnectProjection?.(n.deviceId);try{return await this.connectToDevice({deviceId:n.deviceId,endpointTicket:i}),await this.peerApi.refreshPeerSnapshot().catch(()=>{}),await t.onConnected?.(n),{success:!0,attempts:1}}catch(c){return {success:false,error:c instanceof Error?c.message:`Cannot connect to ${e.deviceId}`,attempts:1}}}};var jn=class{constructor(e,t){this.client=e;this.backend=t;}normalizeUiConnectionStatus(e){switch((e||"disconnected").trim().toLowerCase()){case "connected":return "connected";case "connecting":return "connecting";case "failed":return "failed";default:return "disconnected"}}buildLookup(e,t){let n=new Map,i=(o,s)=>{let a=typeof o=="string"?o.trim():"";!a||n.has(a)||n.set(a,s);};for(let o of e)for(let s of t(o))i(s,o);return n}uniqueLookupIds(...e){let t=new Set,n=[];for(let i of e){let o=typeof i=="string"?i.trim():"";!o||t.has(o)||(t.add(o),n.push(o));}return n}matchSessionByLookupId(e,t){if(!e.length||!t.length)return null;let n=this.buildLookup(e,i=>[i.peerId,i.deviceId,i.deviceIdHint,i.nodeId,i.activeConnectionId]);for(let i of t){let o=n.get(i);if(o)return o}return null}async resolvePeerLookupIds(e,t){let n=typeof t.resolvePeerIdentity=="function"?await t.resolvePeerIdentity(e).catch(()=>null):null,i=this.uniqueLookupIds(e,n?.peerId,n?.deviceId,n?.deviceIdHint,n?.nodeId);if(typeof t.listPeerSessions!="function")return i;let o=this.matchSessionByLookupId(await t.listPeerSessions().catch(()=>[]),i);return this.uniqueLookupIds(...i,o?.peerId,o?.deviceId,o?.deviceIdHint,o?.nodeId,o?.activeConnectionId)}async resolvePeerConnectionRecords(e){let t=this.backend;if(!t||typeof t.resolvePeerConnectionRecords!="function")throw new Error("[pluto-rtc] resolvePeerConnectionRecords() requires a Rust-backed runtime adapter that implements resolvePeerConnectionRecords().");return t.resolvePeerConnectionRecords(e)}async getPeerSession(e){let t=this.backend;if(!t||typeof t.getPeerSession!="function")throw new Error("[pluto-rtc] getPeerSession() requires a Rust-backed runtime adapter that implements getPeerSession().");let n=await this.resolvePeerLookupIds(e,t);for(let i of n){let o=await t.getPeerSession(i);if(o)return o}return typeof t.listPeerSessions=="function"?this.matchSessionByLookupId(await t.listPeerSessions(),n):null}async listPeerSessions(){let e=this.backend;if(!e||typeof e.listPeerSessions!="function")throw new Error("[pluto-rtc] listPeerSessions() requires a Rust-backed runtime adapter that implements listPeerSessions().");return e.listPeerSessions()}async waitForConnectedPeer(e,t){let n=this.backend;if(!n||typeof n.waitForSettledPeer!="function")throw new Error("[pluto-rtc] waitForConnectedPeer() requires a Rust-backed runtime adapter that implements waitForSettledPeer().");let i=typeof n.resolvePeerIdentity=="function"?await n.resolvePeerIdentity(e).catch(()=>null):null,o=this.uniqueLookupIds(i?.peerId,i?.deviceId,i?.deviceIdHint,i?.nodeId,e)[0]??e;return n.waitForSettledPeer(o,t)}async getPeerReadiness(e,t){let n=this.client.getPeerState(e)??null,i=typeof t=="number"?await this.waitForConnectedPeer(e,t).catch(()=>null):await this.getPeerSession(e).catch(()=>null),o=this.normalizeUiConnectionStatus(i?.status??n?.status??"disconnected"),s=n?.routable===false&&n?.protocolState==="unverified";return {requestedId:e,connected:o==="connected",settledReady:s?false:!!i?.settledReady,status:o,health:i?.health??n?.health??"unknown",deviceId:i?.deviceId??n?.deviceId??null,deviceIdHint:i?.deviceIdHint??n?.deviceIdHint??null,activeConnectionId:i?.activeConnectionId??n?.connectionId??null,readinessState:s?n?.protocolState:i?.readinessState??n?.protocolState,readinessReason:s?n?.error:i?.readinessReason??n?.error,scopes:[...i?.scopes??n?.scopes??[]]}}async resolvePeerIdentity(e){let t=this.backend;if(!t||typeof t.resolvePeerIdentity!="function")throw new Error("[pluto-rtc] resolvePeerIdentity() requires a Rust-backed runtime adapter that implements resolvePeerIdentity().");return t.resolvePeerIdentity(e)}async resolveIncomingStreamPeer(e){return this.resolvePeerIdentity(e)}addPeerScope(e,t){return this.client.addPeerScope(e,t)}releasePeerScope(e,t){return this.client.releasePeerScope(e,t)}getPeerScopes(e){return this.client.getPeerScopes(e)}isSamePeer(e,t){return this.client.isSamePeer(e,t)}};var U=class U{constructor(e,t){this.managedSessionKey=null;this.managedSessionUserId=null;this.managedSessionOptions=null;this.managedSessionTransition=Promise.resolve();this.managedSessionStartInFlight=new Map;this.managedReconciliationTasks=new Set;this.managedReconciliationTimer=null;this.managedReconciliationFollowupTimers=new Set;this.nativeIncomingMessageSubscriptionAttached=false;this.scopedConnectionActorRegistry=null;this.client=new st(e),this.backend=t??null,t&&this.client.setSignalingBackend(t),this.peerManager=new jn(this.client,this.backend),this.connectionController=new mt(this.client,this.backend),this.deviceManager=new Hn({client:this.client,backend:this.backend,peerApi:{watchPeerStates:n=>this.client.watchPeerStates(n),refreshPeerSnapshot:()=>this.client.refreshPeerSnapshot(),listConnectedPeers:()=>this.client.listConnectedPeers(),getPeerState:n=>this.client.getPeerState(n)},connectToDevice:n=>this.connectionController.connectToDevice(n),startManagedReconciliation:n=>this.startManagedReconciliation(n),deviceStatusRefreshDebounceMs:U.DEVICE_STATUS_REFRESH_DEBOUNCE_MS});}static describeTicketForLogs(e){let t=typeof e=="string"?e.trim():"";if(!t)return {hasTicket:false,isCompound:false,scope:null};let n=t.indexOf(".");if(n<0)return {hasTicket:true,isCompound:false,scope:null};try{let i=t.slice(n+1).replace(/-/g,"+").replace(/_/g,"/"),o=(4-i.length%4)%4,s=JSON.parse(atob(i+"=".repeat(o)));return {hasTicket:!0,isCompound:!0,scope:typeof s?.s=="string"?s.s:null}}catch{return {hasTicket:true,isCompound:true,scope:null}}}async serializeManagedSessionOperation(e){let t=this.managedSessionTransition,n,i=new Promise(o=>{n=o;});this.managedSessionTransition=i,await t.catch(()=>{});try{return await e()}finally{n(),this.managedSessionTransition===i&&(this.managedSessionTransition=Promise.resolve());}}get identity(){return this.client.currentUser}resolveManagedSessionUserId(e,t){return e==="native"?this.identity?.id??t??null:t??this.identity?.id??null}resolveManagedAutoConnectEnabled(e){return e.autoConnectPolicy==="disabled"?false:e.autoConnectPolicy==="enabled"?true:e.autoConnectPolicy==="scoped-only"?false:e.autoConnect!==false}resolveManagedPresenceEnabled(e){return e.presencePolicy==="disabled"?false:e.presencePolicy==="online"?true:e.presence!==false}getEffectiveRuntimeUserId(){return this.identity?.id??this.managedSessionUserId??this.managedSessionOptions?.userId??null}async fetchAndApplyAppLimits(){try{await this.client.refreshHostedAppSettings();}catch(e){console.warn("[pluto-rtc] Could not fetch app limits, using free-tier defaults.",e);}}async resolvePeerStreamTarget(e){let t=this.client.getPeerState(e)??null,n=await this.getPeerSession(e).catch(()=>null),i=n?.activeConnectionId?.trim()||null,o=(i?this.client.getConnections().find(a=>!a.isClosed&&a.id===i):void 0)??null,s=n?.nodeId?.trim()||o?.remoteNodeId?.trim()||t?.nodeId?.trim()||null;return {peer:t,session:n,connection:o,remoteNodeId:s}}compatPeerConnectionFromTarget(e,t){let n=e.session?.activeConnectionId?.trim()||`peer-stream:${t}`,i=e.remoteNodeId||t;return {id:n,deviceId:i,remoteNodeId:i,isClosed:false}}nextNativeStartRetryDelayMs(e){return u(e,U.NATIVE_START_RETRY_MIN_DELAY_MS,U.NATIVE_START_RETRY_MAX_DELAY_MS)}hasManagedSession(){return !!(this.managedSessionKey||this.managedSessionUserId)}usesNativeIpcBackend(){let t=this.backend?.getRuntimeCapabilities?.();return t?.adapter==="native-ipc"||t?.adapter==="tauri-ipc"||t?.signaling.nativeIpc===true}startManagedReconciliation(e){return this.managedReconciliationTasks.add(e),this.managedReconciliationTimer||(this.managedReconciliationTimer=setInterval(()=>{this.notifyManagedReconciliation();},U.MANAGED_RECONCILIATION_INTERVAL_MS)),()=>{this.managedReconciliationTasks.delete(e),this.managedReconciliationTasks.size===0&&this.managedReconciliationTimer&&(clearInterval(this.managedReconciliationTimer),this.managedReconciliationTimer=null);}}scheduleManagedReconciliationFollowups(){this.notifyManagedReconciliation();for(let e of this.managedReconciliationFollowupTimers)clearTimeout(e);this.managedReconciliationFollowupTimers.clear();for(let e of [1500,5e3]){let t=setTimeout(()=>{this.managedReconciliationFollowupTimers.delete(t),this.notifyManagedReconciliation();},e);this.managedReconciliationFollowupTimers.add(t);}}stopManagedReconciliation(){this.managedReconciliationTimer&&(clearInterval(this.managedReconciliationTimer),this.managedReconciliationTimer=null);for(let e of this.managedReconciliationFollowupTimers)clearTimeout(e);this.managedReconciliationFollowupTimers.clear(),this.managedReconciliationTasks.clear();}notifyManagedReconciliation(){this.hasManagedSession()&&this.managedReconciliationTasks.forEach(e=>{if(this.hasManagedSession())try{e();}catch{}});}async reconcileNativeManagedSession(e="frontend"){let t=this.backend;t&&typeof t.reconcileNativeManagedSession=="function"&&await t.reconcileNativeManagedSession({reason:e}),await this.refreshPeerSnapshot().catch(()=>[]),this.scheduleManagedReconciliationFollowups();}connectionStateSnapshotKey(e){return JSON.stringify({connectionId:e.connectionId,deviceId:e.deviceId??null,deviceIdHint:e.deviceIdHint??null,remoteNodeId:e.remoteNodeId??null,state:e.state,transportState:e.transportState??null,protocolState:e.protocolState??null,routable:e.routable??null,readinessState:e.readinessState??null,readinessReason:e.readinessReason??null,transportGeneration:e.transportGeneration??null,activeTransport:e.activeTransport??null,parallelTransport:e.parallelTransport??null,replacementInProgress:e.replacementInProgress??null,error:e.error??null,updatedAt:e.updatedAt??null})}async runNativeStartLoop(e){let t=Date.now(),n=0;for(;Date.now()-t<=U.NATIVE_START_RETRY_WINDOW_MS;){n+=1;try{await e.start(),n>1&&d(`[RuntimeClient] ${e.label} recovered after ${n} attempts`);return}catch(i){if(this.isUnsupportedRuntimeAdapterError(i,e.label))throw i;let o=this.nextNativeStartRetryDelayMs(n);console.warn(`[RuntimeClient] ${e.label} failed attempt=${n} retry_in_ms=${o}:`,i),await r(o);}}throw new Error(e.exhaustedMessage)}isUnsupportedRuntimeAdapterError(e,t){if(!(e instanceof Error))return false;let n=e.message||"",i=t==="startPresenceLoop"?"startPresenceLoopOnce":t==="startAutoConnect"?"startAutoConnectOnce":null;return !!i&&n.includes(`does not support ${i}`)}isRecoverableNativeManagedSessionStartError(e){let t=e instanceof Error?e.message.toLowerCase():String(e??"").toLowerCase();return t.includes("start_rtc_managed_session")&&t.includes("timeout after")}onIdentityChange(e){return this.client.onAuthChange(e)}async signInAnonymously(){await this.client.signInAnonymously();}async signInWithPluto(){await this.client.signInWithPluto();}async setAuthContext(e){let t=this.backend;if(!t||typeof t.setAuthContext!="function")throw new Error("RuntimeClient auth context requires a runtime adapter that supports setAuthContext().");await t.setAuthContext(e);}async signOut(){await this.stopManagedSession().catch(()=>{}),await this.client.signOut();}async initialize(){if(this.usesNativeIpcBackend()){console.info("[RuntimeClient][native] initialize() skipped; native IPC backend owns runtime startup");return}await this.client.init();}async getRuntimeStatus(){return this.client.getRuntimeStatus()}getPeerReconciliationStats(){return this.client.getPeerReconciliationStats()}getRuntimePolicy(){return q}getRuntimeCapabilities(){let e=this.backend;return typeof e?.getRuntimeCapabilities=="function"?e.getRuntimeCapabilities():u$1(s)}getCapabilityProfile(){return w$1(this.getRuntimeCapabilities())}async attachNativeIncomingMessageSubscription(){if(this.nativeIncomingMessageSubscriptionAttached)return;let e=this.backend;e?.onIncomingNativeMessage&&(this.nativeIncomingMessageSubscriptionAttached=true,e.onIncomingNativeMessage((t,n,i)=>{(async()=>await this.client.acceptNativeMessage(t,n,i)&&e.disconnectDevice&&e.disconnectDevice(t).catch(()=>{}))();}).catch(()=>{this.nativeIncomingMessageSubscriptionAttached=false;}));}async attachNativeIncomingStreamSource(e){let t=e?.trim();if(!t)throw new Error("Native incoming stream startup requires a local node id");let n=this.resolveNativeIncomingStreamSource();if(!n)throw new Error("Native IPC backend does not expose incoming_streams(); update openrtc-tauri-plugin.");this.client.attachIncomingStreamSource(n,t),await this.client.startListening({startPresence:false});}resolveNativeIncomingStreamSource(){let e=this.backend;if(e&&typeof e.incoming_streams=="function")return e;let t=e?.backend;return t&&typeof t.incoming_streams=="function"?t:null}async start(e){if(this.usesNativeIpcBackend()){let t=await this.getManagedNodeId({initializeIfMissing:true});await this.attachNativeIncomingStreamSource(t),await this.attachNativeIncomingMessageSubscription();return}e?.clearSessionTokens!==false&&await this.client.clearSessionTokens().catch(()=>{}),await this.client.refreshRuntimeAuthToken("runtime-start"),await this.client.startListening(),await this.attachNativeIncomingMessageSubscription();}stop(){this.client.stopListening();}async getNodeId(){if(this.usesNativeIpcBackend()){let e=await this.getManagedNodeId({initializeIfMissing:true});if(!e)throw new Error("Native node id unavailable from IPC backend");return e}return this.client.getNodeId()}async getNodeIdFromTicket(e){return this.client.getNodeIdFromTicket(e)}async getLocalDeviceId(){return this.client.getLocalDeviceId()}async getLocalDeviceInfo(){let e=this.backend;return !e||typeof e.getLocalDeviceInfo!="function"?null:e.getLocalDeviceInfo()}async getLocalDeviceProfile(e){let t=await this.getLocalDeviceInfo().catch(()=>null),n=e?.localDeviceId??t?.deviceId??await this.getLocalDeviceId().catch(()=>null)??null,i=await this.getRuntimeStatus().catch(()=>({runtime:"unknown",wasmLoaded:false,localNodeId:void 0,userId:void 0})),o=e?.platform??(i.runtime==="tauri"?"native":"web");return {deviceId:n,deviceName:e?.deviceName||t?.deviceName||"Unknown Device",platformType:t?.platformType||(o==="native"?"desktop":"web"),userId:e?.userId??this.identity?.id??i.userId??null,capabilities:t?.capabilities??{can_host:o==="native",can_sync:o==="native",read_only:o!=="native"},lastSeenAt:t?.lastSeenAt||new Date().toISOString(),localNodeId:i.localNodeId||null}}async updateLocalDeviceName(e){let t=this.backend;return !t||typeof t.updateLocalDeviceName!="function"?null:t.updateLocalDeviceName(e)}async getManagedNodeId(e){let t=this.backend;if(console.info("[RuntimeClient][getManagedNodeId] enter",{hasBackend:!!t,hasMethod:!!(t&&typeof t.getManagedNodeId=="function"),backendCtor:t?.constructor?.name??null}),!t||typeof t.getManagedNodeId!="function")return null;let n=await t.getManagedNodeId(e);return console.info("[RuntimeClient][getManagedNodeId] resolved",{result:n}),n}async getTicket(){return this.usesNativeIpcBackend()?this.getEndpointTicket():this.client.getTicket()}async getTicketWithToken(e,t=0){let n=this.backend;if(n?.getEndpointTicketWithToken)try{let i=await n.getEndpointTicketWithToken(e,t);if(i)return i}catch(i){if(this.usesNativeIpcBackend())throw i}if(this.usesNativeIpcBackend())throw new Error("Native endpoint ticket with token unavailable from IPC backend");return this.client.getEndpointTicketWithToken(e,t)}async revokeTokensByScope(e){return this.revokeTokensByScopeInternal(e,{rotateManagedScopeIfActive:true})}async revokeTokensByScopeInternal(e,t){i("revokeTokensByScopeInternal",{grantScope:e,rotateManagedScopeIfActive:t?.rotateManagedScopeIfActive!==false,hasManagedSessionOptions:!!this.managedSessionOptions});let n=this.usesNativeIpcBackend(),i$1=n?[]:await this.client.revokeTokensByScope(e),o=this.backend,s=[];if(o?.revokeSessionTokensByScope)s=await o.revokeSessionTokensByScope(e).catch(()=>[]);else if(n)throw new Error("Native token revoke requires revokeSessionTokensByScope() on the IPC backend.");let a=Array.from(new Set([...i$1,...s]));return t?.rotateManagedScopeIfActive!==false&&e===U.MANAGED_USER_DEVICE_SCOPE&&this.managedSessionOptions&&this.managedSessionOptions.presence!==false&&await this.rotateManagedUserDeviceGrant(),a}revokeSessionToken(e){this.client.revokeSessionToken(e);}watchFriendDevices(e,t){let n=this.backend;return n?.watchFriendDevices?n.watchFriendDevices(e,t):()=>{}}async getFriendTicket(e=0){return this.getTicketWithToken(U.MANAGED_FRIEND_SCOPE,e)}async revokeFriendTokens(){return this.revokeTokensByScope(U.MANAGED_FRIEND_SCOPE)}async updateFriendTicket(e){let t=this.backend;t?.updateFriendTicket&&await t.updateFriendTicket(e);}async getEndpointTicket(){let e=this.backend;if(e&&typeof e.getEndpointTicket=="function")try{return await e.getEndpointTicket()}catch(t){if(this.usesNativeIpcBackend())throw t}if(this.usesNativeIpcBackend())throw new Error("Native endpoint ticket unavailable from IPC backend");return this.client.getTicket()}async startManagedSession(e){let t=this.resolveManagedSessionUserId(e.platform,e.userId??null),n=JSON.stringify({platform:e.platform,sessionKind:e.sessionKind??"app-user-device",scope:e.scope??null,userId:t,deviceName:e.deviceName??null,localDeviceId:e.localDeviceId??null,metadata:e.metadata??null,autoConnect:this.resolveManagedAutoConnectEnabled(e),autoConnectPolicy:e.autoConnectPolicy??null,presence:this.resolveManagedPresenceEnabled(e),presencePolicy:e.presencePolicy??null}),i$1=this.managedSessionStartInFlight.get(n);if(i$1)return i$1;let o=this.serializeManagedSessionOperation(async()=>{if(this.managedSessionKey===n){if(e.platform==="native"&&t){let d=this.backend;if(d&&typeof d.startManagedSessionNative=="function")try{let p=await d.startManagedSessionNative({userId:t,deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,metadata:e.metadata,autoConnect:this.resolveManagedAutoConnectEnabled(e),presence:this.resolveManagedPresenceEnabled(e)});console.info("[RuntimeClient][managed-session][native-replayed]",{userId:t,localNodeId:p.localNodeId,presenceStarted:p.presenceStarted,autoConnectStarted:p.autoConnectStarted,localDeviceId:p.localDevice?.deviceId??null});}catch(p){console.warn("[RuntimeClient][managed-session][native-replay-failed]",{userId:t,message:p instanceof Error?p.message:String(p)});}}let c=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:t});return {mode:e.platform,device:c,stop:async()=>this.stopManagedSession()}}i("managed-session-replace",{previousSessionKey:this.managedSessionKey,nextSessionKey:n}),await this.stopManagedSessionInternal(),this.managedSessionKey=n,this.managedSessionUserId=t,this.managedSessionOptions={...e,userId:t};let s=null,a=null;console.info("[RuntimeClient][managed-session][start]",{platform:e.platform,requestedUserId:e.userId??null,runtimeUserId:this.identity?.id??null,effectiveUserId:this.managedSessionUserId,sessionKind:e.sessionKind??"app-user-device",scope:e.scope??null,localDeviceId:e.localDeviceId??null,deviceName:e.deviceName??null,presence:this.resolveManagedPresenceEnabled(e),presencePolicy:e.presencePolicy??null,autoConnect:this.resolveManagedAutoConnectEnabled(e),autoConnectPolicy:e.autoConnectPolicy??null});try{if(e.platform==="web")await this.initialize(),this.resolveManagedPresenceEnabled(e)?(await this.client.clearSessionTokens().catch(()=>{}),s=await this.getTicketWithToken(U.MANAGED_USER_DEVICE_SCOPE,0),this.client.setManagedPresenceTicket(s),await this.start({clearSessionTokens:!1})):(this.client.clearManagedPresenceTicket(),await this.start());else {if(!this.managedSessionUserId)throw new Error("Native managed session startup requires an authenticated user id.");await this.client.ensureAuthenticated("discovery");let d=this.backend;if(!d||typeof d.startManagedSessionNative!="function")throw new Error("Native managed session startup requires a native backend-owned startManagedSessionNative() surface.");a=await d.startManagedSessionNative({userId:this.managedSessionUserId,deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,metadata:e.metadata,autoConnect:this.resolveManagedAutoConnectEnabled(e),presence:this.resolveManagedPresenceEnabled(e)}),console.info("[RuntimeClient][managed-session][native-started]",{userId:this.managedSessionUserId,localNodeId:a.localNodeId,ticketScope:a.ticketScope??null,presenceStarted:a.presenceStarted,autoConnectStarted:a.autoConnectStarted,localDeviceId:a.localDevice?.deviceId??null}),await this.attachNativeIncomingStreamSource(a.localNodeId),await this.attachNativeIncomingMessageSubscription();}this.fetchAndApplyAppLimits();let c=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:this.managedSessionUserId});return e.platform==="native"?(this.resolveManagedPresenceEnabled(e)&&!a?.presenceStarted&&console.warn("[RuntimeClient][managed-session][native-presence-missing]",{userId:this.managedSessionUserId,deviceId:c.deviceId}),this.resolveManagedAutoConnectEnabled(e)&&c.deviceId&&!a?.autoConnectStarted&&console.warn("[RuntimeClient][managed-session][native-auto-connect-missing]",{userId:this.managedSessionUserId,deviceId:c.deviceId})):this.resolveManagedPresenceEnabled(e)&&(console.info("[RuntimeClient][managed-session][start-presence]",{platform:e.platform,sessionKind:e.sessionKind??"app-user-device",scope:e.scope??null,userId:this.managedSessionUserId,deviceId:c.deviceId,deviceName:c.deviceName,ticketScope:U.describeTicketForLogs(s).scope}),await this.startPresenceLoop({deviceName:c.deviceName,ticket:s,metadata:e.metadata}),console.info("[RuntimeClient][managed-session][presence-started]",{platform:e.platform,userId:this.managedSessionUserId,deviceId:c.deviceId})),e.platform!=="native"&&this.resolveManagedAutoConnectEnabled(e)&&c.deviceId&&(await this.startAutoConnect(c.deviceId),console.info("[RuntimeClient][managed-session][auto-connect-started]",{platform:e.platform,sessionKind:e.sessionKind??"app-user-device",scope:e.scope??null,userId:this.managedSessionUserId,deviceId:c.deviceId})),await this.refreshPeerSnapshot().catch(()=>[]),this.scheduleManagedReconciliationFollowups(),{mode:e.platform,device:c,stop:async()=>this.stopManagedSession()}}catch(c){if(console.warn("[RuntimeClient][managed-session][start-failed-cleanup]",{platform:e.platform,requestedUserId:e.userId??null,runtimeUserId:this.identity?.id??null,effectiveUserId:this.managedSessionUserId,message:c instanceof Error?c.message:String(c)}),e.platform==="native"&&this.isRecoverableNativeManagedSessionStartError(c)){let d=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:this.managedSessionUserId});return console.warn("[RuntimeClient][managed-session][native-start-degraded]",{userId:this.managedSessionUserId,deviceId:d.deviceId,message:c instanceof Error?c.message:String(c)}),this.scheduleManagedReconciliationFollowups(),{mode:e.platform,device:d,stop:async()=>this.stopManagedSession()}}throw await this.stopManagedSessionInternal().catch(()=>{}),c}});this.managedSessionStartInFlight.set(n,o);try{return await o}finally{this.managedSessionStartInFlight.delete(n);}}async stopManagedSession(e){return this.serializeManagedSessionOperation(()=>this.stopManagedSessionInternal(e))}async stopManagedSessionInternal(e){if(!this.managedSessionKey&&!this.managedSessionUserId)return;let t=!!e?.preserveBackendSession;i("stopManagedSessionInternal",{preserveBackendSession:t,managedSessionKey:this.managedSessionKey,managedSessionUserId:this.managedSessionUserId??null});let n=this.backend;this.managedSessionOptions;if(this.client.clearManagedPresenceTicket(),t?console.info("[RuntimeClient] Preserving native backend-managed session across frontend teardown",{userId:this.managedSessionUserId??this.identity?.id??null,scope:U.MANAGED_USER_DEVICE_SCOPE}):(await this.revokeTokensByScopeInternal(U.MANAGED_USER_DEVICE_SCOPE,{rotateManagedScopeIfActive:false}).catch(()=>[]),this.stop(),n&&typeof n.stopAuthScopedActivity=="function"?await n.stopAuthScopedActivity({userId:this.managedSessionUserId??this.identity?.id??null}):await this.setOffline().catch(()=>{})),t){this.notifyManagedReconciliation();return}await this.scopedConnectionActorRegistry?.shutdownAll().catch(o=>{console.warn("[RuntimeClient] scoped connection actor shutdown failed",o);}),this.scopedConnectionActorRegistry=null,this.managedSessionKey=null,this.managedSessionUserId=null,this.managedSessionOptions=null;}async rotateManagedUserDeviceGrant(){let e=this.managedSessionOptions;if(!e||!this.resolveManagedPresenceEnabled(e))return;if(e.platform==="native"){let o=this.backend;if(!o||typeof o.startManagedSessionNative!="function")throw new Error("Native managed ticket rotation requires a native backend-owned startManagedSessionNative() surface.");let s=this.managedSessionUserId??e.userId??this.identity?.id??null;if(!s)throw new Error("Native managed ticket rotation requires an authenticated user id.");await o.startManagedSessionNative({userId:s,deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,metadata:e.metadata,autoConnect:this.resolveManagedAutoConnectEnabled(e),presence:this.resolveManagedPresenceEnabled(e)}),console.info("[RuntimeClient][managed-ticket][rotate]",{scope:U.MANAGED_USER_DEVICE_SCOPE,platform:e.platform,userId:s});return}let t=await this.getTicketWithToken(U.MANAGED_USER_DEVICE_SCOPE,0),n=this.managedSessionUserId??e.userId??this.identity?.id??null;this.client.setManagedPresenceTicket(t);let i=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:e.userId??null});await this.startPresenceLoop({deviceName:i.deviceName,ticket:t,metadata:e.metadata}),console.info("[RuntimeClient][managed-ticket][rotate]",{scope:U.MANAGED_USER_DEVICE_SCOPE,platform:e.platform,userId:n});}async listDevices(){return this.deviceManager.listDevices()}async listDevicesWithStatus(){return this.deviceManager.listDevicesWithStatus()}async updateDevice(e,t){await this.deviceManager.updateDevice(e,t);}async deleteDevice(e){await this.deviceManager.deleteDevice(e);}watchDevices(e){return this.deviceManager.watchDevices(e)}watchDevicesWithStatus(e){return this.deviceManager.watchDevicesWithStatus(e)}async connectDeviceWithRetry(e,t,n){return this.deviceManager.connectDeviceWithRetry(e,t,n)}async connectDevice(e,t){return this.deviceManager.connectDevice(e,t)}watchPeerStates(e){return this.client.watchPeerStates(e)}watchPeerLifecycle(e){return this.watchPeerStates(e)}getPeerState(e){return this.client.getPeerState(e)}async resolvePeerConnectionRecords(e){return this.peerManager.resolvePeerConnectionRecords(e)}async getPeerSession(e){return this.peerManager.getPeerSession(e)}async listPeerSessions(){return this.peerManager.listPeerSessions()}async waitForConnectedPeer(e,t){return this.peerManager.waitForConnectedPeer(e,t)}async getPeerReadiness(e,t){return this.peerManager.getPeerReadiness(e,t)}async resolvePeerIdentity(e){return this.peerManager.resolvePeerIdentity(e)}async resolveIncomingStreamPeer(e){return this.peerManager.resolveIncomingStreamPeer(e)}listConnectedPeers(){return this.client.listConnectedPeers()}addPeerScope(e,t){return this.peerManager.addPeerScope(e,t)}releasePeerScope(e,t){return this.peerManager.releasePeerScope(e,t)}getPeerScopes(e){return this.peerManager.getPeerScopes(e)}isSamePeer(e,t){return this.peerManager.isSamePeer(e,t)}async refreshPeerSnapshot(){return this.client.refreshPeerSnapshot()}async subscribeSessions(e,t){return this.client.subscribeSessions(e,t)}getAppLimits(){return this.client.appLimits}syncRoomRtdbPresenceFromBackend(){let e=this.backend?.rtdbPresence;e&&this.client.rooms.setRtdbPresence(e);}async createRoom(e){return this.syncRoomRtdbPresenceFromBackend(),this.client.rooms.createRoom(e)}async joinRoom(e,t){return this.syncRoomRtdbPresenceFromBackend(),this.client.rooms.joinRoom(e,t)}async leaveRoom(e){return this.client.rooms.leaveRoom(e)}async getRoomMembers(e){return this.client.rooms.getRoomMembers(e)}watchRoom(e,t){return this.client.rooms.watchRoom(e,t)}async connectByTicket(e){return this.client.connect(e.ticket,e.timeoutMs)}async connectPeer(e){return this.client.connectPeer(e)}async connectScopedChannel(e){let t=e.scope,n=e.channelId.trim();if(!n)throw new Error("connectScopedChannel requires a channelId");let i=e.peerId??e.peerNodeId??e.deviceId??(e.ticket?await this.getNodeIdFromTicket(e.ticket).catch(()=>null):null);if(!i)throw new Error("connectScopedChannel requires peerId, peerNodeId, deviceId, or a ticket with an embedded node id");let o=this.client.getConnections().find(T=>!T.isClosed&&(T.remoteNodeId===i||T.deviceId===i))??null,s=null;if(!o)if(this.usesNativeIpcBackend()){if(!e.ticket)throw new Error("native connectScopedChannel requires an endpoint ticket when no connection exists");let T=await this.connectToDevice({endpointTicket:e.ticket,deviceId:e.deviceId??i}),_=T.remoteNodeId??T.deviceId??T.deviceIdHint??i;o=this.client.getConnections().find(A=>!A.isClosed&&(A.id===T.connectionId||A.remoteNodeId===_||A.deviceId===_||A.deviceId===e.deviceId))??null;}else s=this.getScopedConnectionActor({scope:t,peerNodeId:i},{ticket:e.ticket,timeoutMs:e.timeoutMs,channelId:n,dial:async()=>{o=await this.connectPeer({ticket:e.ticket,deviceId:e.deviceId??i,scope:t,channelId:n,respectManualDisconnect:e.respectManualDisconnect??true});}}),await s.ensureReady();o||(this.usesNativeIpcBackend()?o=this.client.getConnections().find(T=>!T.isClosed&&(T.remoteNodeId===i||T.deviceId===i))??null:o=await this.connectPeer({ticket:e.ticket,deviceId:e.deviceId??i,scope:t,channelId:n,respectManualDisconnect:e.respectManualDisconnect??true}));let a=o?.remoteNodeId??i,c=e.nativeLabel===true,d$1=e.framing??"raw",p,u,g=false;if(c)try{let T=await this.openPeerNativeBi(a,n,{timeoutMs:e.timeoutMs,scope:t});o=T.connection,p=T.readable,u=T.writable.getWriter(),g=!0;}catch(T){d("[RuntimeClient][connectScopedChannel] native-labelled stream open failed; falling back",{peerId:a,channelId:n,error:String(T)});let _=await this.openPeerBiTransportOnly(a,{timeoutMs:e.timeoutMs,scope:t,channelId:n});o=_.connection,p=_.readable,u=_.writable.getWriter();}else {let T=await this.openPeerBi(a,{timeoutMs:e.timeoutMs,scope:t,channelId:n});o=T.connection,p=T.readable,u=T.writable.getWriter();}let f=new Set,v=false,y=Promise.resolve(),C=new Uint8Array(0),I=p.getReader();return (async()=>{try{for(;!v;){let{value:T,done:_}=await I.read();if(_)break;if(!(!T||T.byteLength===0)){if(d$1==="raw"){for(let A of [...f])A(T);continue}for(C=ti(C,T);C.byteLength>=4;){let A=ni(C,0);if(C.byteLength<4+A)break;let E=C.slice(4,4+A);C=C.slice(4+A);for(let x of [...f])x(E);}}}}catch(T){v||d("[RuntimeClient][connectScopedChannel] read loop ended with error",{peerId:a,channelId:n,error:String(T)});}finally{v=true,f.clear();try{I.releaseLock();}catch{}}})(),{channelId:n,peerId:a,connection:o,send:async T=>{let _=d$1==="u32be"?ei(T):T,A=y.then(async()=>{if(v)throw new Error(`Scoped channel '${n}' is closed`);await u.write(_);});y=A.catch(()=>{}),await A;},onMessage(T){return f.add(T),()=>f.delete(T)},async close(){if(!v){v=true,f.clear();try{await I.cancel("scoped channel closed");}catch{}try{await u.abort("scoped channel closed");}catch{}try{u.releaseLock();}catch{}await s?.shutdown().catch(()=>{});}},diagnostics:()=>({connectionId:o?.id??null,remoteNodeId:o?.remoteNodeId??null,transports:o?.getAvailableTransports?.()??[],framing:d$1,nativeLabel:g||c})}}getScopedConnectionActor(e,t){let n=a=>{let c=t?.ticket,d=t?.channelId,p=t?.dial;return new Ke({key:a,dial:async u=>{if(this.assertScopedDialAllowed(u),p){await p(u);return}await this.connectPeer({deviceId:u.peerNodeId,ticket:c,scope:u.scope,channelId:d,respectManualDisconnect:true});},close:async()=>{}})};this.scopedConnectionActorRegistry||(this.scopedConnectionActorRegistry=new Ge(n));let i=Zn(e.scope,e.peerNodeId),o=this.scopedConnectionActorRegistry.get(i),s=this.scopedConnectionActorRegistry.getOrSpawn(i,n);return (o===null||o!==null&&o!==s)&&X("[runtime-client][scoped-connection-actor]",je(i.scope,{peerNodeId:i.peerNodeId}),"spawn"),s}assertScopedDialAllowed(e){let t=this.scopedDialCandidateIds(e).find(n=>this.hasManualDisconnectSuppression(n));if(t)throw X("[runtime-client][scoped-connection-actor]",je(e.scope,{peerNodeId:e.peerNodeId}),"dial_suppressed_manual_disconnect peerId={}",t),new Error(`scoped connection dial suppressed by manual disconnect for peer ${t}`)}scopedDialCandidateIds(e){let t=new Set,n=e.peerNodeId.trim();n&&t.add(n);let i=e.scope.trim();if(i.startsWith("trusted-device:")){let o=i.slice(15).split(":")[0]?.trim();o&&t.add(o);}return [...t]}hasManualDisconnectSuppression(e){let t=this.client.getPeerState(e);if(!t)return false;if(t.manualDisconnect===true)return true;let n=t,i=[t.error,n.lastDisconnectReason].filter(o=>typeof o=="string"&&o.length>0).join(" ");return /manual disconnect/i.test(i)}async shutdownScopedConnectionActors(){if(!this.scopedConnectionActorRegistry)return;let e=this.scopedConnectionActorRegistry.size();X("[runtime-client][scoped-connection-actor]",{sessionKind:"drive-grant-guest"},"shutdown_all count={}",e),await this.scopedConnectionActorRegistry.shutdownAll();}async openPeerBi(e,t){let n=this.backend;if(n&&typeof n.openPeerBi=="function"){let i=await n.openPeerBi(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),readable:i.readable,writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId):i.writable}}throw new Error("[pluto-rtc] openPeerBi() requires a Rust-backed runtime adapter that implements openPeerBi().")}async openPeerNativeBi(e,t,n){let i=this.backend;if(i&&typeof i.openPeerNativeBi=="function"){let o=await i.openPeerNativeBi(e,t,n?.timeoutMs),s=await this.resolvePeerStreamTarget(e);return {connection:s.connection??this.compatPeerConnectionFromTarget(s,e),readable:o.readable,writable:o.writable}}throw new Error("[pluto-rtc] openPeerNativeBi() requires a Rust-backed runtime adapter that implements openPeerNativeBi().")}async openPeerBiTransportOnly(e,t){let n=this.backend;if(n&&typeof n.openPeerBiTransportOnly=="function"){let i=await n.openPeerBiTransportOnly(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),readable:i.readable,writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId):i.writable}}return this.openPeerBi(e,t)}async openPeerUni(e,t){let n=this.backend;if(n&&typeof n.openPeerUni=="function"){let i=await n.openPeerUni(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId):i.writable}}throw new Error("[pluto-rtc] openPeerUni() requires a Rust-backed runtime adapter that implements openPeerUni().")}async connectToDevice(e){return this.connectionController.connectToDevice(e)}async connectRaw(e){return this.connectionController.connectRaw(e)}async openBi(e){return this.connectionController.openBi(e)}async openUni(e){return this.connectionController.openUni(e)}onIncomingStream(e){return this.client.onIncomingStream(e)}registerChannel(e){this.client.registerChannel(e);}unregisterChannel(e){this.client.unregisterChannel(e);}listChannels(){return this.client.listChannels()}onIncomingChannelStream(e,t){return this.client.onIncomingChannelStream(e,t)}async sendExplicitFilePath(e,t,n){let i=this.backend;if(!i||typeof i.sendExplicitFilePath!="function")throw new Error("Selected runtime adapter does not support sendExplicitFilePath().");return i.sendExplicitFilePath(e,t,n)}async sendExplicitFileData(e){let t=this.backend;if(!t||typeof t.sendExplicitFileData!="function")throw new Error("Selected runtime adapter does not support sendExplicitFileData().");let n=this.client.getConnectionForPeer(e.connectionId,e.remoteNodeId),i=e.requireApplicationCrypto??(typeof n?.isApplicationCryptoRequired=="function"?n.isApplicationCryptoRequired():void 0),o=e.remoteNodeId??n?.remoteNodeId??e.connectionId??n?.deviceId,s=e.applicationCrypto??this.client.getApplicationCrypto(n??void 0)??this.client.resolveApplicationCryptoForPeer(o,n??void 0)??(i?await this.client.waitForApplicationCryptoForPeer(o):void 0),a={...e,connection:e.connection??n,remoteNodeId:e.remoteNodeId??n?.remoteNodeId,applicationCrypto:s,requireApplicationCrypto:i};return t.sendExplicitFileData(a)}async getTransferHistory(e){let t=this.backend;return !t||typeof t.getTransferHistory!="function"?[]:t.getTransferHistory(e)}async deleteTransferJob(e){let t=this.backend;if(!(!t||typeof t.deleteTransferJob!="function"))return t.deleteTransferJob(e)}async startPresenceLoop(e){let t=this.backend;if(t&&typeof t.startPresenceLoopOnce=="function"){let n=this.getEffectiveRuntimeUserId();if(!n){await this.client.startPresenceLoop(e);return}let i=await this.getManagedNodeId({initializeIfMissing:true}).catch(()=>null),o=i||await this.getNodeId(),s=e?.ticket||await this.getEndpointTicket(),a=await this.getLocalDeviceProfile({deviceName:e?.deviceName,platform:"native",userId:n}),c=U.describeTicketForLogs(s);console.info("[RuntimeClient][native-presence][start]",{userId:n,localNodeId:o,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:a.deviceId,deviceName:e?.deviceName||a.deviceName,ticketScope:c.scope,isCompoundTicket:c.isCompound});try{await this.runNativeStartLoop({label:"startPresenceLoop",exhaustedMessage:`[RuntimeClient] startPresenceLoop exhausted retries user_id=${n} local_node_id=${o}`,start:()=>t.startPresenceLoopOnce(n,o,e?.deviceName||a.deviceName,s,e?.metadata)});}catch(p){if(!this.isUnsupportedRuntimeAdapterError(p,"startPresenceLoop"))throw p;await this.client.startPresenceLoop(e);return}console.info("[RuntimeClient][native-presence][started]",{userId:n,localNodeId:o,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:a.deviceId});let d=t.rtdbPresence;d&&this.client.rooms.setRtdbPresence(d);return}await this.client.startPresenceLoop(e);}async updatePresence(e){await this.client.updatePresence(e?.isOnline,e?.ttlMs,e?.metadata,e?.ticket);}async setOffline(){await this.client.setOffline();}async cleanupStaleDevices(){await this.client.cleanupStaleDevices();}async startAutoConnect(e){await this.client.refreshRuntimeAuthToken("runtime-start");let t=this.backend;if(t&&typeof t.startAutoConnectOnce=="function"){let n=this.getEffectiveRuntimeUserId();if(!n)throw new Error("startAutoConnect requires an authenticated user");let i=e||await this.getLocalDeviceId();if(!i)throw new Error("startAutoConnect requires a local device id");try{await this.runNativeStartLoop({label:"startAutoConnect",exhaustedMessage:`[RuntimeClient] startAutoConnect exhausted retries user_id=${n} local_device_id=${i}`,start:()=>t.startAutoConnectOnce(n,i)});}catch(o){if(!this.isUnsupportedRuntimeAdapterError(o,"startAutoConnect"))throw o;await this.client.startAutoConnect(e);return}return}await this.client.startAutoConnect(e);}async isConnected(e){return this.connectionController.isConnected(e)}async disconnectNode(e){await this.connectionController.disconnectNode(e);}async disconnectDevice(e){return this.connectionController.disconnectDevice(e)}async setAutoConnectExcluded(e,t){await this.connectionController.setAutoConnectExcluded(e,t);}async disconnectPeer(e,t){await this.connectionController.disconnectPeer(e,t);}async forceDisconnectPeer(e){await this.connectionController.forceDisconnectPeer(e);}async getPeerHealth(e){return this.client.getPeerHealth(e)}async getConnectionStates(){return this.client.signaling.getConnectionStates()}onConnectionStateChange(e){let t=true,n=new Map,i=d=>{if(!t)return;let p=this.connectionStateSnapshotKey(d);n.get(d.connectionId)!==p&&(n.set(d.connectionId,p),e(d));},o=()=>{t&&this.getConnectionStates().then(d=>{d.forEach(p=>i(p));}).catch(()=>{});},s=d=>()=>{t=false,a(),d?.();},a=this.startManagedReconciliation(()=>o()),c=this.client.signaling.onConnectionStateChange(d=>i(d));return o(),typeof c=="function"?s(c):Promise.resolve(c).then(d=>s(typeof d=="function"?d:null))}getConnections(){return this.client.getConnections()}getApplicationReadyConnections(e={}){return this.client.getApplicationReadyConnections(e)}onConnection(e){return this.client.onConnection(e)}onDisconnection(e){return this.client.onDisconnection(e)}onConnectionEvent(e){let t=this.client.onConnection(i=>{let{activeTransport:o}=i.getTransportStatus();e({type:"connected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:o});}),n=this.client.onDisconnection(i=>{let{activeTransport:o}=i.getTransportStatus();e({type:"disconnected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:o});});return ()=>{t(),n();}}forceReconnectSnapshot(){this.client.forceReconnectSnapshot();}async connect(){await this.initialize(),await this.start();}disconnect(){this.stop();}destroy(){this.stopManagedReconciliation(),this.stop();let e=this.client;e&&typeof e.destroy=="function"&&e.destroy();}dispose(){this.destroy();}onAuthChange(e){return this.onIdentityChange(e)}async setAuth(e){return this.setAuthContext(e)}async signIn(){return this.signInWithPluto()}async getDevices(){return this.listDevices()}onDevices(e,t){return t?.status?this.watchDevicesWithStatus(e):this.watchDevices(e)}async getInvite(){return this.getTicket()}async connectTo(e){return this.connectPeer(e)}async waitFor(e,t){return this.waitForConnectedPeer(e,t)}async openStream(e,t){return t?.direction==="send"?this.openPeerUni(e,t):this.openPeerBi(e,t)}async openChannelStream(e,t,n){return this.openStream(t,{...n,channelId:e})}onStream(e){return this.onIncomingStream(e)}onChannelStream(e,t){return this.onIncomingChannelStream(e,t)}onRoomChange(e,t){return this.watchRoom(e,t)}createSession(e){return new ht(this,e)}};U.NATIVE_START_RETRY_WINDOW_MS=q.managedSession.nativeStartRetryWindowMs,U.NATIVE_START_RETRY_MIN_DELAY_MS=q.managedSession.nativeStartRetryMinDelayMs,U.NATIVE_START_RETRY_MAX_DELAY_MS=q.managedSession.nativeStartRetryMaxDelayMs,U.MANAGED_RECONCILIATION_INTERVAL_MS=q.managedSession.reconciliationIntervalMs,U.DEVICE_STATUS_REFRESH_DEBOUNCE_MS=q.managedSession.deviceStatusRefreshDebounceMs,U.MANAGED_USER_DEVICE_SCOPE="user-device",U.MANAGED_FRIEND_SCOPE="friend";var Kn=U;function fs(r,e){let t=new Kn(r,e),n=r.spaceKey??r.space,i=(r.discoveryMode===void 0||r.discoveryMode==="space")&&typeof r.apiKey=="string"&&r.apiKey.trim().length>0&&typeof n=="string"&&n.trim().length>0,o={runtime:t,async setAuthContext(s){if(typeof e.setAuthContext!="function")throw new Error("Selected runtime adapter does not support auth context injection.");await e.setAuthContext(s);},async syncPlutoAuth(s){if(i)return;let a=D(),c=a.getCurrentUser(),p=(typeof s?.userId=="string"?s.userId.trim():"")||c?.uid||null;if(!p){await o.setAuthContext(null);return}let u=await a.getIdToken({forceRefresh:s?.forceRefresh??false}).catch(()=>null),g=a.getCurrentUser()?.refreshToken??null,f=a.getCurrentUser()?.stsTokenManager?.expirationTime??null;await o.setAuthContext({userId:p,token:u,refreshToken:g,tokenProvider:async v=>a.getIdToken({forceRefresh:v??true}),expiresAtMs:f});},bindPlutoAuthHost(){let s=D();return o.syncPlutoAuth({userId:s.getCurrentUser()?.uid??null,forceRefresh:false}),s.onIdTokenChanged(a=>{o.syncPlutoAuth({userId:a?.uid??null,forceRefresh:false});})},signInWithPluto:()=>t.signInWithPluto(),signOut:()=>t.signOut(),stopManagedSession:()=>t.stopManagedSession(),startManagedSession:s=>t.startManagedSession(s),onAuthChange:s=>t.onIdentityChange(s),getManagedNodeId:s=>t.getManagedNodeId(s),getRuntimeStatus:()=>t.getRuntimeStatus(),listDevicesWithStatus:()=>t.listDevicesWithStatus(),watchDevicesWithStatus:s=>t.watchDevicesWithStatus(s),connectDevice:(s,a)=>t.connectDevice(s,a),setAutoConnectExcluded:(s,a)=>t.setAutoConnectExcluded(s,a)};return Object.defineProperty(o,"identity",{get:()=>t.identity,enumerable:true}),o}function bf(r){let e=q$1(r);return fs(e,new a(e))}function Cf(r,e){let t=q$1(r);return fs(t,new h({...t,bridge:e}))}function If(r,e={}){if(r.online!==true)return false;let t=e.now??Date.now(),n=Gn(r.expiresAt);if(typeof n=="number")return n>t;if(typeof e.staleAfterMs!="number"||!Number.isFinite(e.staleAfterMs))return true;let i=Gn(r.updatedAt)??Gn(r.lastSeenAt)??Gn(r.createdAt);return typeof i!="number"||i+e.staleAfterMs>t}function wf(r){return r.settledReady===true||String(r.readinessState??"").trim().toLowerCase()==="routable"||String(r.connectionStatus??"").trim().toLowerCase()==="connected"}function Pf(r){if(r.connectable!==void 0)return r.connectable===true;let e=typeof r.ticket=="string"?r.ticket.trim():"";return r.online===true&&e.length>0&&String(r.presenceStatus??"online").trim().toLowerCase()!=="offline"}function Gn(r){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"){let e=Date.parse(r);return Number.isNaN(e)?void 0:e}if(r instanceof Date)return r.getTime();if(r&&typeof r=="object"&&typeof r.toMillis=="function"){let e=r.toMillis();return Number.isFinite(e)?e:void 0}}export{Cf as A,If as B,wf as C,Pf as D,Ec as a,ut as b,co as c,lo as d,po as e,uo as f,ht as g,mt as h,Ws as i,je as j,X as k,ee as l,Zn as m,Jn as n,Ke as o,Ge as p,ei as q,Gs as r,qs as s,Vs as t,$c as u,zc as v,ti as w,ni as x,Kn as y,bf as z};