openrtc 0.1.1 → 0.1.2

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.
@@ -1,4 +1,4 @@
1
1
  import {a}from'./chunk-D54VGRRH.js';import {b as b$2}from'./chunk-DIQYFAGL.js';import {p,b as b$1,t,r,i,e,f,a as a$1,c as c$2,g,d,h,j}from'./chunk-PZ25OCVG.js';import {c as c$1,e as e$1}from'./chunk-4MH42GUI.js';import {getFirestore,collection,onSnapshot}from'firebase/firestore';import*as He from'tweetnacl';var Ie=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(r=>this.matchesPeer(r));e(i);});return this.cleanups.push(t),t}onConnectionStateChange(e){this.assertNotDisposed();let t=r=>{this._disposed||this.matchesConnectionState(r)&&e(r);},n=this.runtime.onConnectionStateChange(t);return typeof n=="function"?(this.cleanups.push(n),n):n.then(r=>this._disposed?(r(),()=>{}):(this.cleanups.push(r),r))}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;}}assertNotDisposed(){if(this._disposed)throw new Error(`[Session] Session '${this.scope}' has been disposed.`)}};var Se=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 Rt={classifyScope(l){return l.startsWith("drive-grant:")?{sessionKind:"drive-grant-guest",grantId:l.slice(12),scope:l}:l==="user-device"?{sessionKind:"app-user-device",scope:l}:{scope:l}}},Xt=[["sessionKind","session_kind"],["grantId","grant_id"],["scope","scope"],["peerNodeId","peer_node_id"],["connectionId","connection_id"],["transportEpoch","transport_epoch"],["channel","channel"],["tokenFp","token_fp"]];function Zt(l){let e=[];for(let[t,n]of Xt){let i=l[t];i==null||i===""||e.push(`${n}=${i}`);}return e.join(" ")}function en(l,e,t=Rt){let n=t.classifyScope(l);return {...{sessionKind:n.sessionKind,grantId:n.grantId,scope:n.scope??l},...e??{}}}function Ce(l,e){return en(l,e,Rt)}function x(l,e,t,...n){let i=Zt(e),r=tn(t,n);console.log(i&&r?`${l} ${i} ${r}`:i?`${l} ${i}`:r?`${l} ${r}`:l);}function tn(l,e){if(!l)return "";if(e.length===0)return l;if(/\{\}/.test(l)){let n=0;return l.replace(/\{\}/g,()=>{let i=n<e.length?e[n]:"";return n+=1,Tt(i)})}return [l,...e.map(Tt)].join(" ")}function Tt(l){if(l==null)return String(l);if(typeof l=="string")return l;if(typeof l=="number"||typeof l=="boolean")return String(l);try{return JSON.stringify(l)}catch{return String(l)}}var W=class extends Error{constructor(e,t){super(t),this.kind=e,this.name="DriveGrantActorError";}};function kt(l,e){return {scope:l,peerNodeId:e}}function Pt(l){return `${l.scope}@${l.peerNodeId}`}var Te=class{constructor(e){this.state="idle";this.inFlight=null;this.webrtcState="unknown";this.webrtcListeners=new Set;this.key=e.key,this.dial=e.dial,this.close=e.close??(async()=>{});}isReady(){return this.state==="ready"}isClosed(){return this.state==="closed"}correlation(e){return Ce(this.key.scope,{peerNodeId:this.key.peerNodeId,...e??{}})}async ensureReady(){if(this.state==="closed")throw new W("shutdown","drive-grant actor: already shut down");if(this.state!=="ready")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="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 W?e:new W("dial-failed",`drive-grant actor: dial failed: ${t}`)}),this.inFlight)}observeWebRtc(e){this.webrtcListeners.add(e);try{e(this.webrtcState);}catch{}return ()=>{this.webrtcListeners.delete(e);}}getWebRtcState(){return this.webrtcState}setWebRtcState(e){if(this.webrtcState!==e){this.webrtcState=e,x("[drive-grant-actor][webrtc]",this.correlation(),"state={}",e);for(let t of [...this.webrtcListeners])try{t(e);}catch{}}}async openLogicalChannel(e){if(this.state==="closed")throw new W("shutdown","drive-grant actor: already shut down");if(this.state!=="ready")throw new W("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 W("shutdown","drive-grant actor: already shut down");if(this.state!=="ready")throw new W("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"),this.setWebRtcState("failed");try{await this.close(this.key);}catch{}x("[drive-grant-actor][shutdown]",this.correlation(),"complete");}}},Re=class{constructor(e){this.actors=new Map;this.factory=e;}getOrSpawn(e,t){let n=Pt(e),i=this.actors.get(n);if(i&&!i.isClosed())return i;let r=(t??this.factory)(e);return this.actors.set(n,r),r}get(e){return this.actors.get(Pt(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 et=3e4,Q=class Q{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.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,t,n){this.closePeerResources();let i=++this.activeAttemptId;this.localNodeId=e,this.remoteNodeId=t,this.candidatesGathered=0,this.sdpOfferSent=false,this.sdpAnswerReceived=false,this._terminalFailure=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 r=n.rtcConfig||{},o=typeof n?.forceRole=="string"&&(n.forceRole==="initiator"||n.forceRole==="responder")?n.forceRole:null,s=o?o==="initiator":e>t;console.log(`[WebRTCTransport] init \u2014 role=${s?"initiator":"responder"}`,{local:e.slice(0,12),remote:t.slice(0,12),negotiationId:this.negotiationId,forcedRole:o});try{console.log("[WebRTCTransport] Creating RTCPeerConnection",{iceServers:r.iceServers?.length??0}),this.pc=new RTCPeerConnection(r);}catch(d){console.error("[WebRTCTransport] RTCPeerConnection constructor failed",d),this.setState("failed");return}let a=this.pc.createDataChannel("pluto-dc",{negotiated:true,id:0});this.setupDataChannel(a,i),this.setupPCHandlers(s,i);}setupDataChannel(e,t){this.dc=e,e.onopen=()=>{this.isCurrentAttempt(t,e)&&(console.log("[WebRTCTransport] DataChannel opened \u2014 upgrade complete"),this.promoteConnectedIfReady("datachannel-open"));},e.onmessage=n=>{if(!this.isCurrentAttempt(t,e))return;let i=typeof n.data=="string"?new TextEncoder().encode(n.data):new Uint8Array(n.data);this.messageListeners.forEach(r=>r(i));},e.onclose=()=>{this.isCurrentAttempt(t,e)&&(c$2("[WebRTCTransport] DataChannel closed"),(this.state==="connected"||this.state==="connecting")&&this.setState("disconnected"));},e.onerror=n=>{if(!this.isCurrentAttempt(t,e))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.readyState!=="open"){console.warn("[WebRTCTransport] DataChannel aborted post-connect; forcing disconnected state",{readyState:e.readyState,connectionState:this.pc?.connectionState,iceConnectionState:this.pc?.iceConnectionState}),this.setState("disconnected");return}this.state==="connecting"&&this.setState("failed");};}setupPCHandlers(e,t){let n=this.pc;n&&(n.onicecandidate=i=>{this.isCurrentAttempt(t,void 0,n)&&(i.candidate?(this.candidatesGathered++,c$2(`[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(r=>{console.warn("[WebRTCTransport] Failed sending local ICE candidate signal",{error:r,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")):c$2(`[WebRTCTransport] ICE gathering complete \u2014 ${this.candidatesGathered} candidate(s)`));},n.onnegotiationneeded=async()=>{if(this.isCurrentAttempt(t,void 0,n)&&e&&n.signalingState==="stable"){console.log("[WebRTCTransport] Creating offer (initiator)");try{let i=await n.createOffer();if(await n.setLocalDescription(i),!this.isCurrentAttempt(t,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(r){console.warn("[WebRTCTransport] Offer signaling failed (non-fatal)",{error:r,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.setState("failed");}}},n.onconnectionstatechange=()=>{if(!this.isCurrentAttempt(t,void 0,n))return;let i=n.connectionState;if(console.log(`[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"&&(console.log("[WebRTCTransport] pc.connectionState=disconnected, deferring to ICE grace period"),this.startIceDisconnectedGrace(t,n,e,"pc-disconnected"));},n.oniceconnectionstatechange=()=>{if(!this.isCurrentAttempt(t,void 0,n))return;let i=n.iceConnectionState;if(console.log(`[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,"ice-disconnected"):(i==="connected"||i==="completed")&&(this.iceDisconnectedGraceTimer&&console.log("[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)&&console.log(`[WebRTCTransport] ICE gathering state: ${n.iceGatheringState}`,{iceConnectionState:n.iceConnectionState,signalingState:n.signalingState,hasLocalDesc:!!n.localDescription,hasRemoteDesc:!!n.remoteDescription});});}handleSignalingMessage(e){if(!this.pc||e.transport!=="webrtc")return;let t=this.normalizeNegotiationId(e?.negotiationId);if(t&&this.negotiationId&&t!==this.negotiationId){console.info("[WebRTCTransport] Ignoring stale signaling message for a different negotiation",{signalType:e?.type??null,signalNegotiationId:t,activeNegotiationId:this.negotiationId});return}if(e.type==="candidate"){let n=e.candidate;console.log("[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),console.log(`[WebRTCTransport] Buffered remote candidate \u2014 ${this.pendingCandidates.length} pending`));}else if(e.type==="sdp"){let n=e.sdp,i=n.type==="offer",r=n.type==="answer";if(r&&this.pc.signalingState!=="have-local-offer"){console.info("[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}console.log(`[WebRTCTransport] Received SDP ${n.type} \u2014 applying remote description`),r&&(this.sdpAnswerReceived=true),this.pc.setRemoteDescription(n).then(async()=>{if(r&&(console.log("[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&&(console.log(`[WebRTCTransport] Flushing ${this.pendingCandidates.length} buffered candidate(s)`),this.pendingCandidates.forEach(o=>this.pc?.addIceCandidate(o)),this.pendingCandidates=[]),i){console.log("[WebRTCTransport] Creating answer (responder)");let o=await this.pc.createAnswer();if(await this.pc.setLocalDescription(o),console.log("[WebRTCTransport] Answer sent"),this.internalSignalSender)try{await this.internalSignalSender({transport:"webrtc",type:"sdp",sdp:o,negotiationId:t??this.negotiationId??void 0});}catch(s){throw console.warn("[WebRTCTransport] Failed sending SDP answer signal",{error:s,signalingState:this.pc?.signalingState,hasLocalDescription:!!this.pc?.localDescription,hasRemoteDescription:!!this.pc?.remoteDescription}),s}else console.warn("[WebRTCTransport] No signal sender \u2014 answer not transmitted");}}).catch(o=>{console.error(`[WebRTCTransport] setRemoteDescription (${n.type}) failed`,o),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 ${Q.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"));},Q.ICE_CONNECT_TIMEOUT_MS);}clearConnectTimeout(){this.connectTimeoutId&&(clearTimeout(this.connectTimeoutId),this.connectTimeoutId=null);}startIceDisconnectedGrace(e,t,n,i){if(!this.iceDisconnectedGraceTimer){if(this.iceRestartAttempted)console.log("[WebRTCTransport] ice-disconnected grace (restart already attempted)",{reason:i});else if(this.iceRestartAttempted=true,n){try{console.log("[WebRTCTransport] ice-restart-attempted",{reason:i,isInitiator:n}),t.restartIce();}catch(r){console.warn("[WebRTCTransport] restartIce threw",r);}this.sendIceRestartOffer(e,t);}else console.log("[WebRTCTransport] ice-restart deferred to initiator",{reason:i});this.iceDisconnectedGraceTimer=setTimeout(()=>{if(this.iceDisconnectedGraceTimer=null,this.activeAttemptId!==e||this.pc!==t)return;let r=t.iceConnectionState,o=t.connectionState,s=this.dc?.readyState??"missing";if(r==="connected"||r==="completed"||o==="connected"||s==="open"){console.log("[WebRTCTransport] ice-grace expired \u2014 recovered",{ice:r,conn:o,dcReadyState:s});return}if(this.disconnectedGraceExtensions<1){this.disconnectedGraceExtensions+=1,console.warn("[WebRTCTransport] ice-grace expired \u2014 extending once before fail",{ice:r,conn:o,dcReadyState:s,extension:this.disconnectedGraceExtensions}),this.startIceDisconnectedGrace(e,t,n,`${i}:extended`);return}console.warn("[WebRTCTransport] ice-grace expired \u2014 marking failed",{ice:r,conn:o}),this.setState("failed");},Q.ICE_DISCONNECTED_GRACE_MS);}}async sendIceRestartOffer(e,t){try{let n=await t.createOffer({iceRestart:!0});if(!this.isCurrentAttempt(e,void 0,t)||(await t.setLocalDescription(n),!this.isCurrentAttempt(e,void 0,t)))return;this.internalSignalSender?(await this.internalSignalSender({transport:"webrtc",type:"sdp",sdp:n,negotiationId:this.negotiationId??void 0}),console.log("[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){let t=this.dc?.readyState??"missing";if(t!=="open"){console.log("[WebRTCTransport] Deferring connected state until DataChannel is open",{reason:e,dcReadyState:t,iceConnectionState:this.pc?.iceConnectionState,connectionState:this.pc?.connectionState});return}this.clearIceDisconnectedGrace(`connected:${e}`),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.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}};Q.ICE_CONNECT_TIMEOUT_MS=et,Q.ICE_DISCONNECTED_GRACE_MS=2e4;var Pe=Q;var z=class{static createTransport(e){if(this.assertProtocolAvailable(e),e==="webrtc")return new Pe;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"),webrtc:this.getProtocolCapability("webrtc"),moq:this.getProtocolCapability("moq")}}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}`)}}};z.capabilityMap={iroh:{protocol:"iroh",maturity:"stable",available:true},"iroh-quic":{protocol:"iroh-quic",maturity:"stable",available:false,reason:"iroh-quic is a path label, not a standalone transport."},"iroh-relay":{protocol:"iroh-relay",maturity:"stable",available:false,reason:"iroh-relay is a path label, not a standalone transport."},webrtc:{protocol:"webrtc",maturity:"stable",available:true},moq:{protocol:"moq",maturity:"experimental",available:true,reason:"Client-level session lifecycle with evolving media/data semantics."}};function ke(){return BigInt(Date.now())}function tt(l,e){let t=new ArrayBuffer(17),n=new DataView(t);return n.setUint8(0,3),n.setBigUint64(1,l,false),n.setBigInt64(9,e,false),new Uint8Array(t)}function At(l,e){let t=new ArrayBuffer(25),n=new DataView(t);return n.setUint8(0,4),n.setBigUint64(1,l.seq,false),n.setBigInt64(9,l.senderUnixMs,false),n.setBigInt64(17,e,false),new Uint8Array(t)}function Mt(l){if(l.byteLength<17||l[0]!==3)return null;let e=new DataView(l.buffer,l.byteOffset,l.byteLength);return {seq:e.getBigUint64(1,false),senderUnixMs:e.getBigInt64(9,false)}}function Nt(l){if(l.byteLength<25||l[0]!==4)return null;let e=new DataView(l.buffer,l.byteOffset,l.byteLength);return {seq:e.getBigUint64(1,false),senderUnixMs:e.getBigInt64(9,false),recvUnixMs:e.getBigInt64(17,false)}}function nt(l,e){let t=import.meta.env??{};if(!(String(t.VITE_E2E??"").toLowerCase()==="true"))return e;let i=l==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS:l==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS:l==="VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS"?t.VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS:void 0,r=Number(i);return Number.isFinite(r)&&r>0?r:e}var le={tickIntervalMs:nt("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_TICK_MS",5e3),suspectAfterMs:nt("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_SUSPECT_MS",1e4),staleAfterMs:nt("VITE_OPENRTC_E2E_WEBRTC_HEARTBEAT_STALE_MS",3e4)},Ae=class{constructor(e,t,n=le){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.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();}handleIncoming(e){if(!e||e.byteLength===0)return false;let t=e[0];if(t===3){let n=Mt(e);if(n){console.debug("[TransportHeartbeat] ping received from peer, sending pong",{seq:n.seq.toString()});let i=At(n,ke());this.sendFn(i).catch(r=>console.warn("[TransportHeartbeat] pong send failed",r));}else console.warn("[TransportHeartbeat] ping decode failed",{byteLength:e.byteLength});return true}if(t===4){let n=Nt(e);if(n){let i=this.pendingPings.has(n.seq);console.debug("[TransportHeartbeat] pong received",{seq:n.seq.toString(),wasPending:i,pendingCount:this.pendingPings.size}),i&&(this.pendingPings.delete(n.seq),this.lastPongAtMs=Date.now(),this.evaluateHealth());let r=this.probeWaiters.get(n.seq);r&&(this.probeWaiters.delete(n.seq),r(true));}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[r,o]of this.pendingPings)o<=t&&this.pendingPings.delete(r);this.seq++;let n=this.seq,i=tt(n,ke());try{await this.sendFn(i),this.firstPingSentAtMs===null&&(this.firstPingSentAtMs=e),this.pendingPings.set(n,e),console.debug("[TransportHeartbeat] ping sent",{seq:n.toString(),pendingCount:this.pendingPings.size,lastPongAtMs:this.lastPongAtMs,silenceSinceLastPongMs:this.lastPongAtMs?e-this.lastPongAtMs:null});}catch(r){console.warn("[TransportHeartbeat] ping send failed",{seq:n.toString(),error:r});}this.evaluateHealth();}evaluateHealth(){let e=this.computeHealth();if(e!==this.currentHealth){console.debug("[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=tt(t,ke());try{await this.sendFn(n);}catch{return false}let i=Date.now();return this.pendingPings.set(t,i),this.firstPingSentAtMs===null&&(this.firstPingSentAtMs=i),await new Promise(r=>{let o=setTimeout(()=>{this.probeWaiters.delete(t)&&r(false);},e);this.probeWaiters.set(t,s=>{clearTimeout(o),r(s);});})}};var N=class N{constructor(e,t,n,i,r,o={}){this.listeners=[];this.pendingMessages=[];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.nativeSignalSender=null;this.webrtcTransport=null;this.upgradeState="none";this.upgradeRequested=false;this.upgradeAttemptActive=false;this.upgradeRetryCount=0;this.upgradeRetryTimer=null;this.upgradeAttemptTimeoutTimer=null;this.lastReportedTransportStatus=null;this.upgradeTerminalFailure=false;this.pendingSignals=[];this.activeNegotiationId=null;this.webrtcHeartbeat=null;this.webRtcHeartbeatProbeInFlight=false;this.webRtcHeartbeatConsecutiveProbeFailures=0;this.irohHealthListeners=[];this.webrtcHealthListeners=[];this.lastWebRtcHeartbeatOkAt=null;this.lastWebRtcDataChannelOpenAt=null;this.lastForegroundAt=null;this.webRtcDisconnectedGraceTimer=null;this.preferredWebRtcRole=null;this._peerMoQReady=false;this._remoteSupportsWebRTC=false;this.mediaListeners=[];this.trackListeners=[];this.id=e,this.localNodeId=t,this.remoteNodeId=n,this.deviceId=n,this.writer=i,this.reader=r,this.options=o,this.readLoop();}get isClosed(){return this._isClosed}requestWebRTCUpgrade(e="peer-capable"){if(!this.options.rtcConfig)return;let t=this.nativeSignalSender?this.getDeterministicWebRtcRole():"initiator";this.upgradeState==="upgrading"&&this.preferredWebRtcRole==="responder"||(this.preferredWebRtcRole=t),this.beginWebRtcRecovery(e,{forceRenegotiate:false,replaceExisting:false,resetRetryBudget:true,skipIfAlreadyUpgrading:true});}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,r=typeof t?.iceConnectionState=="string"?t.iceConnectionState:null;if(this.upgradeState!=="upgraded"||n!=="open"||i==="failed"||i==="disconnected"||r==="failed"||r==="disconnected"){this.requestTransportRecovery("app-foreground",{forceRenegotiate:true,replaceExisting:!!e||this.upgradeState==="failed"||this.upgradeState==="upgraded"});return}let s=this.webrtcHeartbeat,a=this.lastWebRtcHeartbeatOkAt===null?null:Date.now()-this.lastWebRtcHeartbeatOkAt;!(a!==null&&a>=le.suspectAfterMs)||!s||s.probe(N.FOREGROUND_PROBE_TIMEOUT_MS).then(u=>{u||this._isClosed||this.webrtcTransport===e&&this.requestTransportRecovery("app-foreground-probe-failed",{forceRenegotiate:true,replaceExisting:true});});}beginWebRtcRecovery(e,t){if(!(!this.options.rtcConfig||this._isClosed)){if(t.skipIfAlreadyUpgrading&&(this.upgradeState==="upgrading"||this.upgradeState==="upgraded")){b$1("[Connection] WebRTC recovery request ignored: attempt already active",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,currentState:this.upgradeState});return}b$1("[Connection] beginWebRtcRecovery called",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,replaceExisting:t.replaceExisting,forceRenegotiate:t.forceRenegotiate,resetRetryBudget:t.resetRetryBudget,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.clearUpgradeAttemptTimeoutTimer(),t.resetRetryBudget&&(this.upgradeRetryCount=0),t.replaceExisting&&(this.stopWebRtcHeartbeat(),this.pendingSignals=[],this.teardownWebRTCTransport()),this.attemptUpgrade({forceRenegotiate:t.forceRenegotiate,replaceExisting:t.replaceExisting});}}getUpgradeState(){return this.upgradeState}updateRTCConfig(e){this.options.rtcConfig=e;}onUpgradeStateChange(e){this.upgradeStateListeners.push(e);}async getTransportDiagnostics(){let e=this.transportType,t=this.resolveParallelTransport(e),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 r=await i.getStats(),o=null;r.forEach(I=>{if(o||I?.type!=="transport")return;let _=I?.selectedCandidatePairId;!_||typeof r.get!="function"||(o=r.get(_)??null);}),o||r.forEach(I=>{if(!o&&I?.type==="candidate-pair"){if(I?.selected===!0){o=I;return}I?.nominated===!0&&I?.state==="succeeded"&&(o=I);}});let s=o?.localCandidateId&&typeof r.get=="function"?r.get(o.localCandidateId):null,a=o?.remoteCandidateId&&typeof r.get=="function"?r.get(o.remoteCandidateId):null,d=typeof s?.candidateType=="string"?s.candidateType:null,u=typeof a?.candidateType=="string"?a.candidateType:null,p=typeof s?.protocol=="string"?s.protocol:null,h=typeof a?.protocol=="string"?a.protocol:null,g=!!(d||u),f=g?d==="relay"||u==="relay":null,v=g?`${d??"unknown"}<->${u??"unknown"}`:null;return {...n,usesRelay:f,relaySource:f==null?null:f?"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:u,localProtocol:p,remoteProtocol:h,candidateTypeSummary:v}}}catch{return {...n,relaySource:"webrtc-stats-unavailable"}}}get transportType(){return this.upgradeState==="upgraded"?"webrtc":this.peerMoQReady?"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){return this.sendTyped(0,e)}async sendMedia(e,t){let n=e==="video"?1:2;return this.sendTyped(n,t)}async sendOnTransport(e,t){return this.sendTypedOnTransport(e,0,t)}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=[];this.webrtcTransport&&this.upgradeState==="upgraded"&&e.push("webrtc");let t=this.options.transportContext;return t&&t.isMoQReady()&&this.peerMoQReady&&e.push("moq"),this.writer&&e.push("iroh"),e}onWebRTCBinaryMessage(e){this.webrtcBinaryHandlers.push(e);}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))}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 r=this.writeMutex,o;this.writeMutex=new Promise(s=>{o=s;});try{return await r,this.writer?(await this.writer.write(t),!0):!1}catch(s){if(this.preserveWebRtcConnectionAfterBaseTransportLoss(`Iroh Send Error: ${s}`))return false;throw console.error("[Connection] Iroh Send error:",s),this.close(`Send Error: ${s}`),s}finally{o();}}async sendUsingTransport(e,t,n,i,r){let o=this.options.transportContext;return e==="webrtc"?!this.webrtcTransport||this.upgradeState!=="upgraded"||t!==0?false:(await this.webrtcTransport.send(i),true):e==="moq"?o&&o.isMoQReady()&&this.peerMoQReady?(await o.sendMoQ(r),true):false:e==="iroh"||e==="iroh-relay"||e==="iroh-quic"?this.sendOverIroh(t,r,"explicit transport send"):false}async sendTypedOnTransport(e,t,n){let i=this.encodePayload(n),r=this.buildFrame(t,i);if(!await this.sendUsingTransport(e,t,n,i,r))throw new Error(`[Connection] Requested transport unavailable: ${e}`)}async sendTyped(e,t){let i=this.options.transportContext?.priorities||["webrtc","moq","iroh"],r=this.encodePayload(t),o=this.buildFrame(e,r);for(let s of i)try{if(await this.sendUsingTransport(s,e,t,r,o))return}catch(a){console.warn(`[Connection] ${s} Send Failed:`,a);}}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.clearUpgradeAttemptTimeoutTimer(),this.clearWebRtcDisconnectedGraceTimer(),this.teardownWebRTCTransport(),this.setUpgradeState("none"),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){if(!this.webrtcTransport||this.upgradeState!=="upgraded"&&!(this.upgradeState==="upgrading"&&this.nativeSignalSender))return false;b$1("[Connection] Base transport closed while WebRTC is usable or recoverable; preserving connection",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,activeTransport:this.transportType,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 r=this.receiveBuffer.slice(4,4+i);if(r.length>0){let o=r[0],s=r.slice(1);N.isUntypedDataFrame(r)?this.processDataPayload(r):o===3?this.sendIrohHeartbeatPong(s):o===4?this.irohHealthListeners.forEach(a=>a("healthy")):o===1?this.emitMedia("video",s):o===2?this.emitMedia("audio",s):this.processDataPayload(s);}this.receiveBuffer=this.receiveBuffer.slice(4+i);}}static isUntypedDataFrame(e){let t=e[0];return t===123||t===91?true:e.length>=4&&e[0]===68&&e[1]===86&&e[2]===67&&e[3]===72}processDataPayload(e){try{let t=N.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=N.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 r=t.charCodeAt(i);if(r<32&&r!==9&&r!==10&&r!==13)return !1}let n=N.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>N.MAX_PENDING_MESSAGES&&this.pendingMessages.splice(0,this.pendingMessages.length-N.MAX_PENDING_MESSAGES),this.listeners.length!==0&&this.listeners.forEach(t=>t(e));}receiveMessage(e){this.emitMessage(e);}receiveDataPayload(e){this.processDataPayload(e);}addTrack(e){let t=this.webrtcTransport?.getNativeTransport?.();return t&&typeof t.addTrack=="function"?t.addTrack(e):null}addTransceiver(e,t){let n=this.webrtcTransport?.getNativeTransport?.();return n&&typeof n.addTransceiver=="function"?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,r=typeof n?.iceConnectionState=="string"?n.iceConnectionState:null;return t==="closed"||t==="closing"?false:t==="open"?true:i==="connected"||i==="connecting"||r==="connected"||r==="completed"||r==="checking"}handleDisconnectedTransportStateWithGrace(e){let t=e.getDataChannelReadyState?.()??null;if(t==="closed"||t==="closing"){b$1("[Connection] WebRTC disconnected with closed DataChannel; failing upgraded transport immediately",{connectionId:this.id,remoteNodeId:this.remoteNodeId,dcReadyState:t}),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("transport-state-disconnected-dc-closed");return}this.webRtcDisconnectedGraceTimer||(b$1("[Connection] WebRTC transport reported disconnected; applying grace window before fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId}),this.webRtcDisconnectedGraceTimer=setTimeout(()=>{if(this.webRtcDisconnectedGraceTimer=null,!(this._isClosed||this.webrtcTransport!==e)){if(this.transportStillLikelyAlive(e)){b$1("[Connection] WebRTC disconnected grace expired but transport appears alive; suppressing fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId});return}this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("transport-state-disconnected-grace-expired");}},N.WEBRTC_DISCONNECTED_GRACE_MS));}async attemptUpgrade(e){if(this._isClosed||!this.upgradeRequested||!this.options.rtcConfig)return;let t=typeof e=="object"&&e!==null?e:{preferredNegotiationId:e??null},n=t.preferredNegotiationId,i=!!t.forceRenegotiate;if(!!!t.replaceExisting&&(this.upgradeAttemptActive||this.upgradeState==="upgraded"))return;this.upgradeAttemptActive=true,this.teardownWebRTCTransport();let o=this.normalizeNegotiationId(n)??this.createNegotiationId();this.activeNegotiationId=o,this.setUpgradeState("upgrading"),this.startUpgradeAttemptTimeout(o),(i||this.upgradeRetryCount>0)&&this.sendInternalSignal({transport:"webrtc",type:"renegotiate",negotiationId:o}).catch(()=>{});try{this.webrtcTransport=z.createTransport("webrtc");}catch(u){this.upgradeAttemptActive=false,b$1("[Connection] WebRTC upgrade unavailable",u),this.handleUpgradeFailure("transport-create-error");return}let s=this.webrtcTransport;typeof s.setSignalSender=="function"&&s.setSignalSender(u=>this.sendInternalSignal(u)),s.onMessage(u=>{if(u instanceof Uint8Array&&u.byteLength>0){if(this.webrtcHeartbeat?.handleIncoming(u))return;if(u[0]===2){for(let p of this.webrtcBinaryHandlers)if(p(u))return}}this.processDataPayload(u);}),s.onStateChange(u=>{if(!(this._isClosed||this.webrtcTransport!==s)){if(c$2(`[Connection] WebRTC transport state changed: ${u}`),u==="connected"){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.clearUpgradeRetryTimer(),this.lastWebRtcDataChannelOpenAt=Date.now(),this.setUpgradeState("upgraded"),this.startWebRtcHeartbeat(s);return}if(u==="failed"||u==="disconnected"){if(this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,u==="disconnected"&&this.upgradeState==="upgraded"){this.handleDisconnectedTransportStateWithGrace(s);return}this.clearWebRtcDisconnectedGraceTimer(),s.isTerminalFailure?.()&&(this.upgradeTerminalFailure=true),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure(`transport-state-${u}`);}}});try{await s.init(this.localNodeId,this.deviceId,{rtcConfig:this.options.rtcConfig,negotiationId:o,forceRole:this.preferredWebRtcRole??void 0});}catch(u){this.upgradeAttemptActive=false,this.clearUpgradeAttemptTimeoutTimer(),b$1("[Connection] WebRTC init failed",u),this.handleUpgradeFailure("init-error");return}if(this.webrtcTransport!==s){this.upgradeAttemptActive=false;return}let a=s.getNegotiationId?.();if(a&&(this.activeNegotiationId=this.normalizeNegotiationId(a)??o),this.pendingSignals.length>0){let u=this.pendingSignals.splice(0);for(let p of u)s.handleSignalingMessage?.(p);}let d=s.getNativeTransport?.();d&&d.ontrack!==void 0&&(d.ontrack=u=>{c$2(`[Connection] Peer track received: ${u.track.kind}`),this.trackListeners.forEach(p=>p(u));});}setUpgradeState(e){this.upgradeState!==e&&(this.upgradeState=e,this.reportTransportStatusIfChanged(),this.upgradeStateListeners.forEach(t=>{try{t(e);}catch(n){b$1("[Connection] Upgrade state listener failed",n);}}));}handleUpgradeFailure(e){if(this._isClosed||!this.upgradeRequested)return;this.clearUpgradeAttemptTimeoutTimer();let t=this.upgradeTerminalFailure,n=!t&&this.shouldRetryUpgrade();if(this.upgradeAttemptActive=false,this.setUpgradeState("failed"),console.warn(`[Connection] WebRTC upgrade failed: ${e}`,{connectionId:this.id,remoteNodeId:this.remoteNodeId,retryCount:this.upgradeRetryCount,maxRetries:N.MAX_UPGRADE_RETRIES,terminal:t,willRetry:n}),t&&console.warn("[Connection] WebRTC upgrade is terminal \u2014 not retrying. Both peers may be on the same page (same-context loopback)."),b$1(`[Connection] WebRTC upgrade fallback: ${e}`),n){this.scheduleUpgradeRetry();return}this.clearUpgradeRetryTimer(),this.teardownWebRTCTransport();}shouldRetryUpgrade(){return !(this._isClosed||!this.upgradeRequested||this.upgradeTerminalFailure||!this.options.rtcConfig||!this.hasRecoverableBasePath()||this.upgradeRetryCount>=N.MAX_UPGRADE_RETRIES)}scheduleUpgradeRetry(){this.clearUpgradeRetryTimer(),this.upgradeRetryCount+=1;let e=this.upgradeRetryCount;this.upgradeRetryTimer=setTimeout(()=>{this.upgradeRetryTimer=null,!(this._isClosed||!this.upgradeRequested||this.upgradeAttemptActive)&&(c$2(`[Connection] Retrying WebRTC upgrade ${e}/${N.MAX_UPGRADE_RETRIES}`),this.attemptUpgrade());},N.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,b$1("[Connection] WebRTC upgrade attempt timed out",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:e}),this.handleUpgradeFailure("upgrade-attempt-timeout"));},N.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS);}clearUpgradeAttemptTimeoutTimer(){this.upgradeAttemptTimeoutTimer&&(clearTimeout(this.upgradeAttemptTimeoutTimer),this.upgradeAttemptTimeoutTimer=null);}teardownWebRTCTransport(){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer();let e=this.webrtcTransport;if(e){this.webrtcTransport=null,this.stopWebRtcHeartbeat();try{e.close();}catch(t){b$1("[Connection] WebRTC transport close failed",t);}this.reportTransportStatusIfChanged();}}startWebRtcHeartbeat(e){this.stopWebRtcHeartbeat();let t=Date.now();console.debug("[Connection] WebRTC heartbeat starting",{connectionId:this.id,startedAt:t,config:le});let n=new Ae(async i=>{console.debug("[Connection] WebRTC heartbeat send",{connectionId:this.id,byteLength:i.byteLength,typeId:i[0]}),await e.send(i);},i=>{let r=Date.now()-t;if(console.debug("[Connection] WebRTC heartbeat health callback",{connectionId:this.id,health:i,elapsedSinceStartMs:r}),i==="healthy"&&(this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0),this.webrtcHealthListeners.forEach(o=>o(i)),i==="stale"){if(this.webRtcHeartbeatProbeInFlight)return;this.webRtcHeartbeatProbeInFlight=true,c$2("[Connection] WebRTC heartbeat stale \u2014 probing transport before fallback"),n.probe(4e3).then(o=>{if(o){this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0,c$2("[Connection] WebRTC heartbeat probe succeeded \u2014 keeping upgraded transport");return}if(this.webRtcHeartbeatConsecutiveProbeFailures+=1,this.transportStillLikelyAlive(e)){this.lastWebRtcHeartbeatOkAt=Date.now(),c$2("[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){c$2("[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(),c$2("[Connection] WebRTC heartbeat probe failed but no base recovery path exists \u2014 keeping transport",{connectionId:this.id,remoteNodeId:this.remoteNodeId});return}c$2("[Connection] WebRTC heartbeat probe failed consecutively \u2014 triggering upgrade fallback"),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("heartbeat-stale-probe-failed");}).finally(()=>{this.webRtcHeartbeatProbeInFlight=false;});}},le);this.webrtcHeartbeat=n,n.start();}stopWebRtcHeartbeat(){this.webRtcHeartbeatProbeInFlight=false,this.webRtcHeartbeatConsecutiveProbeFailures=0,this.webrtcHeartbeat&&(this.webrtcHeartbeat.stop(),this.webrtcHeartbeat=null);}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),r=BigInt(Date.now()),o=new ArrayBuffer(29),s=new DataView(o);s.setUint32(0,25,false),s.setUint8(4,4),s.setBigUint64(5,n,false),s.setBigInt64(13,i,false),s.setBigInt64(21,r,false);let a=this.writeMutex,d;this.writeMutex=new Promise(u=>{d=u;});try{await a,this.writer&&await this.writer.write(new Uint8Array(o));}catch{}finally{d();}}onWebRtcHeartbeatHealth(e){this.webrtcHealthListeners.push(e);}onIrohHeartbeatHealth(e){this.irohHealthListeners.push(e);}reportTransportStatusIfChanged(){if(this._isClosed)return;let e=this.transportType,t=this.resolveParallelTransport(e),n=`${e}:${t??""}`;this.lastReportedTransportStatus!==n&&(this.lastReportedTransportStatus=n,this.options.onTransportStatusChange?.({activeTransport:e,parallelTransport:t}));}resolveParallelTransport(e){if(this._isClosed)return null;let t=e==="iroh"||e==="iroh-relay"||e==="iroh-quic";return !t&&this.writer||!t&&e==="webrtc"&&this.hasRecoverableBasePath()?"iroh-relay":t&&this.isWebRtcDataChannelOpen()?"webrtc":null}setNativeSignalSender(e){this.nativeSignalSender=e;}async sendInternalSignal(e){let t=e&&(e.transport==="webrtc"||!e.transport)?{...e,transport:"webrtc",negotiationId:this.normalizeNegotiationId(e.negotiationId)??this.activeNegotiationId??void 0}:e,n={type:"#pluto-signal",content:t};if(this.nativeSignalSender)try{await this.nativeSignalSender(n),c$2("[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 iroh transport",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null,error:i});}try{if((t?.type==="sdp"||t?.type==="candidate"||t?.type==="renegotiate")&&console.info("[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)),r=new Uint8Array(1+i.byteLength);r[0]=0,r.set(i,1);let o=new ArrayBuffer(4+r.byteLength),s=new DataView(o),a=new Uint8Array(o);s.setUint32(0,r.byteLength,!1),a.set(r,4),await this.sendRawIrohFrame(a),c$2("[Connection] Sent internal signal over native-main iroh frame",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});return}await this.sendOnTransport("iroh",n),c$2("[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,r=n?.sdp&&typeof n.sdp=="object"&&typeof n.sdp.type=="string"?n.sdp.type:null,o=i==="sdp"&&r==="offer",s=this.normalizeNegotiationId(n?.negotiationId);if((i==="sdp"||i==="candidate"||i==="renegotiate")&&console.info("[Connection][WebRTC][signal][recv]",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:s??null,signalType:i,sdpType:r,hasSdp:!!n?.sdp?.sdp,hasCandidate:!!n?.candidate,upgradeState:this.upgradeState}),i==="renegotiate"){if(this.isWebRtcDataChannelOpen()){console.info("[Connection] Ignoring WebRTC renegotiate request because transport is already upgraded",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}if(this.upgradeState==="upgrading"&&this.webrtcTransport){console.info("[Connection] Ignoring WebRTC renegotiate request while an upgrade is already in flight",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}}let a=!!s&&!!this.activeNegotiationId&&s!==this.activeNegotiationId,d=i==="sdp"&&o||i==="renegotiate"&&this.upgradeState!=="upgrading"&&this.upgradeState!=="upgraded";if(a&&!d){console.info("[Connection] Ignoring stale WebRTC signal from a previous negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:i,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}let u=!!this.activeNegotiationId?.startsWith("native-"),p=o&&!!s?.startsWith(`conn-${this.id}-`);if(a&&d&&this.upgradeState==="upgrading"&&this.preferredWebRtcRole==="responder"&&u&&p){console.info("[Connection] Ignoring reflected WebRTC offer during active native negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}a&&d&&(console.info("[Connection] Switching to a fresh inbound WebRTC negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,priorNegotiationId:this.activeNegotiationId,nextNegotiationId:s,priorState:this.upgradeState,signalType:i}),this.clearUpgradeRetryTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,this.pendingSignals=[],this.stopWebRtcHeartbeat(),this.teardownWebRTCTransport()),s&&(!this.activeNegotiationId||a)&&(this.activeNegotiationId=s);let h=!this.webrtcTransport||this.upgradeState==="failed"||a&&this.upgradeState!=="upgrading";if(d&&h&&this.options.rtcConfig&&!this._isClosed){console.info("[Connection] Auto-requesting WebRTC upgrade from incoming signal",{connectionId:this.id,remoteNodeId:this.remoteNodeId,currentState:this.upgradeState,signalType:i,sdpType:r,signalNegotiationId:s,preferredRole:o?"responder":this.preferredWebRtcRole}),o&&(this.preferredWebRtcRole="responder"),this.upgradeRequested=true,this.upgradeTerminalFailure=false,this.pendingSignals=[n],this.attemptUpgrade(s);return}n.transport||(n.transport="webrtc"),this.webrtcTransport?.handleSignalingMessage?this.webrtcTransport.handleSignalingMessage(n):(!s||!this.activeNegotiationId||s===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}};N.textDecoder=new TextDecoder("utf-8",{fatal:true}),N.textEncoder=new TextEncoder,N.UPGRADE_RETRY_DELAY_MS=1e3,N.MAX_UPGRADE_RETRIES=5,N.WEBRTC_DISCONNECTED_GRACE_MS=4e3,N.MAX_PENDING_MESSAGES=256,N.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS=et+3e3,N.FOREGROUND_PROBE_TIMEOUT_MS=2e3;var te=N;var de=class{constructor(e$1,t){this.appTag=e(e$1),this.backend=t;}get tag(){return this.appTag}async waitForAuth(){return this.backend.waitForAuth()}get currentUser(){return this.backend.currentUser}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 e$1().signInWithPluto();}async signOut(){await this.backend.signOut();}async stopAuthScopedActivity(){typeof this.backend.stopAuthScopedActivity=="function"&&await this.backend.stopAuthScopedActivity();}async getTurnCredentials(){return this.backend.getTurnCredentials()}async updatePresence(e,t,n=true,i=300*1e3,r){await this.backend.updatePresence(e,t,n,i,r);}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(),r=false;return (async()=>{try{for(;!r;){let{done:s,value:a}=await i.read();if(s)break;if(a)for(let d of a)"session"in d&&d.session&&t(d.session);}}catch(s){r||console.error("[Signaling] Session stream error:",s);}})(),()=>{r=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,r){this.backend.startPresenceLoop(e,t,n,i,r);}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 an=6e5,cn=250,ln=20,Me=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,r=>{let o=Date.now(),s=r.docs.map(a=>this.toRoomMember(a)).filter(a=>!!a).filter(a=>a.nodeId!==t).filter(a=>!this.isExpired(a,o)).sort((a,d)=>a.joinedAt!==d.joinedAt?a.joinedAt-d.joinedAt:a.nodeId.localeCompare(d.nodeId));n(s);})}watchMembersWithRtdb(e,t,n,i){let r=this.rtdbPresence,o=this.getAppTag(),s=[],a={},d=()=>{let h=Date.now(),g=s.filter(f=>f.nodeId!==t).filter(f=>!this.isExpired(f,h)).filter(f=>{let v=a[f.nodeId];return !(v&&!v.online)}).sort((f,v)=>f.joinedAt!==v.joinedAt?f.joinedAt-v.joinedAt:f.nodeId.localeCompare(v.nodeId));i(g);},u=this.watchMembersSnapshot(n,h=>{s=h.docs.map(g=>this.toRoomMember(g)).filter(g=>!!g),d();}),p=r.onRoomPresenceChange(o,e,h=>{a=h,d();});return ()=>{u(),p();}}watchMembersSnapshot(e,t){let n=false,i=0,r=null,o=null,s=()=>{n||(o=onSnapshot(e,a=>{i=0,t(a);},a=>{if(o=null,this.isTransientPermissionError(a)&&i<ln){i+=1,r=setTimeout(s,cn);return}console.warn("[BrowserFirestoreRooms] room watch failed:",a);}));};return s(),()=>{n=true,r&&(clearTimeout(r),r=null),o?.(),o=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+an<=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}}};var ue=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 Me({app:e$1().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);}usesDirectRoomBackend(){return this.client.usesDirectRoomBackend()}get roomBackendTag(){return this.client.getRoomBackendTag()}get appTag(){return this.signaling.tag}async invokeRoomCallable(e,t){let{getFunctions:n,httpsCallable:i}=await import('firebase/functions'),r=n(e$1().getApp());return (await i(r,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")}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");let t=await this.client.getTicket(),n=await this.client.getNodeId(),i=this.signaling.currentUser?.id??n??"anonymous";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="",u=false,p=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",h=p?1:3;for(let g=0;g<h;g+=1){if(p)d=p;else {let f=new Uint8Array(6);crypto.getRandomValues(f),d=Array.from(f,v=>v.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}try{await this.invokeRoomCallable("createClientRoom",{appTag:this.appTag,roomId:d,nodeId:n,ticket:t}),u=!0;break}catch(f){if(this.isAlreadyExistsError(f)){if(p)throw f;continue}throw f}}if(!u)throw new Error(p?`Failed to create requested room "${p}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(d,n),d}let r="",o=false,s=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",a=s?1:3;for(let d=0;d<a;d++){if(s)r=s;else {let p=new Uint8Array(6);crypto.getRandomValues(p),r=Array.from(p,h=>h.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}let u=this.client.appLimits.maxMembersPerRoom>0?this.client.appLimits.maxMembersPerRoom:void 0;if(o=await this.client.wasmClient.create_room(r,i,t,n,this.roomBackendTag,u),o){console.log(`Room created: ${r}`);break}else {if(s)throw new Error(`Room "${r}" already exists.`);console.log(`Collision for roomId ${r}, retrying...`);}}if(!o)throw new Error(s?`Failed to create requested room "${s}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(r,n),r}async joinRoom(e,t={}){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");if(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(),r=this.signaling.currentUser?.id??i??"anonymous",o=e.toUpperCase(),s=e==="demo"?"demo":e;console.log("[RoomManager] joinRoom request",{roomId:e,normalizedId:o,targetRoomId:s,tag:this.roomBackendTag,userId:r,myNodeId:i,hasTicket:!!n,ticketLength:n?.length||0});try{this.usesDirectRoomBackend()?await this.client.wasmClient.join_room(s,r,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(d){throw b$1("[RoomManager] joinRoom failed",d),d}let a=[];if(t.bootstrapPeers!==false){let u=(await this.getMembersInternal(s,i)).map(async h=>{let g=false,f=Date.now();if(h.expiresAt)h.expiresAt<f&&(g=true);else {let v=h.lastSeenAt||h.joinedAt||0;f-v>300*1e3&&(g=true);}if(g)return null;if(h.ticket)try{console.log(`Bootstrapping: Connecting to peer ${h.nodeId}...`);let v=await this.client.connect(h.ticket,5e3);return v.send({type:"chat",text:`Use ${r} joined the room.`}),v}catch(v){return console.warn(`Failed to connect to peer ${h.nodeId}:`,v),null}return null});(await Promise.allSettled(u)).forEach(h=>{h.status==="fulfilled"&&h.value&&a.push(h.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=e==="demo"?"demo":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=e==="demo"?"demo":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 r=e==="demo"?"demo":e,o=await this.client.getNodeId();if(n)return;i=this.getBrowserRooms().watchMembers(r,o,t),n&&(i(),i=null);}catch(r){n||console.warn("[RoomManager] watchRoom listener failed:",r);}})(),()=>{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){console.warn("[RoomManager] RTDB room member register failed:",i);}this.heartbeatStops.set(e,()=>{this.markRtdbRoomMemberOffline(e,t);});}else this.startLegacyHeartbeat(e,t);}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);}}startLegacyHeartbeat(e,t){let n=setInterval(()=>{this.client.wasmClient&&this.client.wasmClient.heartbeat_tick(e,t,this.roomBackendTag).catch(console.error);},3e5);this.heartbeatStops.set(e,()=>clearInterval(n));}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();}};var F=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)}},O=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=BigInt(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}},Ne=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 Ee=0,dn=1;function rt(l,e){let t=new TextEncoder().encode(e);l.writeVarInt(1),l.writeVarInt(t.length),l.writeBytes(t);}function ot(l){let e=Number(l.readVarInt()),t=[];for(let n=0;n<e;n++){let i=Number(l.readVarInt()),r=l.readBytes(i);t.push(new TextDecoder().decode(r));}return t.join("/")}var pe=class{static serialize(e){let t=new O;switch(e.type){case 64:{let r=e;t.writeVarInt(r.supportedVersions.length);for(let a of r.supportedVersions)t.writeVarInt(a);let o=new O,s=0;r.role!==void 0&&(s++,o.writeVarInt(Ee),o.writeVarInt(1),o.writeVarInt(r.role)),t.writeVarInt(s),t.writeBytes(o.toUint8Array());break}case 65:{let r=e;t.writeVarInt(r.selectedVersion);let o=new O,s=0;r.role!==void 0&&(s++,o.writeVarInt(Ee),o.writeVarInt(1),o.writeVarInt(r.role)),t.writeVarInt(s),t.writeBytes(o.toUint8Array());break}case 3:{let r=e;t.writeVarInt(r.subscribeId),t.writeVarInt(r.trackAlias),rt(t,r.trackNamespace);let o=new TextEncoder().encode(r.trackName);t.writeVarInt(o.length),t.writeBytes(o),t.writeUint8(r.subscriberPriority??128),t.writeUint8(r.groupOrder??1),r.startGroup!==void 0&&r.startObject!==void 0&&r.endGroup!==void 0&&r.endObject!==void 0?(t.writeVarInt(4),t.writeVarInt(r.startGroup),t.writeVarInt(r.startObject),t.writeVarInt(r.endGroup),t.writeVarInt(r.endObject)):r.startGroup!==void 0&&r.startObject!==void 0?(t.writeVarInt(3),t.writeVarInt(r.startGroup),t.writeVarInt(r.startObject)):t.writeVarInt(1),t.writeVarInt(0);break}case 4:{let r=e;t.writeVarInt(r.subscribeId),t.writeVarInt(r.expires),t.writeUint8(1),t.writeUint8(0),t.writeVarInt(0);break}case 6:{rt(t,e.trackNamespace),t.writeVarInt(0);break}case 7:{rt(t,e.trackNamespace);break}}let n=t.toUint8Array(),i=new O;return i.writeVarInt(e.type),i.writeVarInt(n.length),i.writeBytes(n),i.toUint8Array()}static deserialize(e){if(!e.peekVarInt())return null;try{e.checkpoint();let n=Number(e.readVarInt()),i=Number(e.readVarInt());if(console.log(`[MoQ] Deserializing msg type=0x${n.toString(16)}, length=${i}`),!e.has(i))return e.rewind(),null;let r;switch(n){case 65:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=0;for(let d=0;d<s;d++){let u=Number(e.readVarInt()),p=Number(e.readVarInt()),h=e.readBytes(p);if(u===Ee){let g=new F;g.append(h),a=Number(g.readVarInt());}}r={type:n,selectedVersion:o,role:a};break}case 3:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=ot(e),d=Number(e.readVarInt()),u=e.readBytes(d),p=new TextDecoder().decode(u);e.readUint8(),e.readUint8();let h=Number(e.readVarInt()),g,f,v,I;h===3?(g=Number(e.readVarInt()),f=Number(e.readVarInt())):h===4&&(g=Number(e.readVarInt()),f=Number(e.readVarInt()),v=Number(e.readVarInt()),I=Number(e.readVarInt()));let _=Number(e.readVarInt());for(let M=0;M<_;M++){let k=Number(e.readVarInt()),w=Number(e.readVarInt());e.readBytes(w);}r={type:n,subscribeId:o,trackAlias:s,trackNamespace:a,trackName:p,startGroup:g,startObject:f};break}case 4:{let o=Number(e.readVarInt()),s=Number(e.readVarInt());e.readUint8(),e.readUint8()===1&&(e.readVarInt(),e.readVarInt());let d=Number(e.readVarInt());for(let u=0;u<d;u++){let p=Number(e.readVarInt()),h=Number(e.readVarInt());e.readBytes(h);}r={type:n,subscribeId:o,expires:s};break}case 7:{let o=ot(e);r={type:n,trackNamespace:o};break}case 8:{let o=ot(e),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d);console.warn(`[MoQ] ANNOUNCE_ERROR: ns=${o} code=${s} reason=${u}`),r={type:n,trackNamespace:o,code:s,reason:u};break}case 21:{let o=Number(e.readVarInt());console.log(`[MoQ] MAX_SUBSCRIBE_ID: ${o}`),r={type:n,subscribeId:o};break}case 5:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d),p=Number(e.readVarInt());console.warn(`[MoQ] SUBSCRIBE_ERROR: id=${o} code=${s} reason=${u} alias=${p}`),r={type:n,subscribeId:o,code:s,reason:u};break}case 16:{let o=Number(e.readVarInt());e.readBytes(o),console.warn("[MoQ] GOAWAY received"),r={type:n};break}case 64:{let o=Number(e.readVarInt()),s=[];for(let p=0;p<o;p++)s.push(Number(e.readVarInt()));let a=Number(e.readVarInt()),d=0,u;for(let p=0;p<a;p++){let h=Number(e.readVarInt()),g=Number(e.readVarInt()),f=e.readBytes(g);if(h===Ee){let v=new F;v.append(f),d=Number(v.readVarInt());}else h===dn&&(u=new TextDecoder().decode(f));}r={type:n,supportedVersions:s,role:d,path:u};break}case 10:{let o=Number(e.readVarInt());console.log(`[MoQ] UNSUBSCRIBE for id=${o}`),r={type:n,subscribeId:o};break}case 11:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d),p,h;e.readUint8()===1&&(p=Number(e.readVarInt()),h=Number(e.readVarInt())),console.log(`[MoQ] SUBSCRIBE_DONE for id=${o} code=${s} reason=${u}`),r={type:n,subscribeId:o,code:s,reason:u,finalGroup:p,finalObject:h};break}default:{console.warn(`[MoQ] Unknown MsgType: 0x${n.toString(16)}, skipping ${i} bytes`),e.readBytes(i),r={type:n};break}}return e.commit(),r}catch(n){if(n.message==="EOF")return e.rewind(),null;throw n}}};var De=class{constructor(e){this.tracks=new Map;this.activePublishers=new Map;this.pendingAnnounces=new Map;this.session=e;}async announce(e){console.log(`[MoQ] Announcing namespace: ${e}`);let t={type:6,trackNamespace:e,params:{}};return new Promise(async(n,i)=>{this.pendingAnnounces.set(e,{resolve:n,reject:i});let r=setTimeout(()=>{this.pendingAnnounces.has(e)&&(this.pendingAnnounces.delete(e),i(new Error("Announce timed out")));},5e3);try{await this.session.sendControlMessage(t);}catch(o){clearTimeout(r),this.pendingAnnounces.delete(e),i(o);}})}onAnnounceResult(e,t){let n=this.pendingAnnounces.get(e);n&&(this.pendingAnnounces.delete(e),t?n.reject(new Error(`Announce failed: code=${t.code} reason=${t.reason}`)):n.resolve());}onSubscribe(e){let t=`${e.trackNamespace}/${e.trackName}`;console.log(`[MoQ] Publisher received SUBSCRIBE for ${t} -> subId=${e.subscribeId} alias=${e.trackAlias}`),this.tracks.set(t,{subscribeId:e.subscribeId,trackAlias:e.trackAlias});}onUnsubscribe(e){for(let[t,n]of this.tracks.entries())if(n.subscribeId===e){console.log(`[MoQ] Publisher received UNSUBSCRIBE for ${t} (subId=${e})`),this.tracks.delete(t);break}}async createTrack(e,t){let n=`${e}/${t}`;if(this.activePublishers.has(n))return this.activePublishers.get(n);let i=null,r=0,o=0,s=new Ne,a=()=>{if(i){let h=i;i=null,h.close().catch(()=>{});}},d=()=>{console.log(`[MoQ] Stopping publisher for ${n}`),a(),this.activePublishers.delete(n);},u=async()=>{a(),r++,o=0;let h=this.tracks.get(n);if(h===void 0)return;let{subscribeId:g,trackAlias:f}=h,I=(await this.session.transport.createUnidirectionalStream()).getWriter();r<=2&&console.log(`[MoQ] Opening Group ${r} for ${n} (subId=${g} alias=${f})`);let _=new O;_.writeVarInt(4),_.writeVarInt(g),_.writeVarInt(f),_.writeVarInt(r),_.writeVarInt(0),_.writeUint8(0),await I.write(_.toUint8Array()),i=I;},p={close:d,push:async(h,g)=>{await s.dispatch(async()=>{if(!this.tracks.has(n))return;if(g.isKey)await u();else if(!i)return;if(!i)return;let f=new O;if(f.writeVarInt(o++),f.writeVarInt(h.length),f.writeBytes(h),i)try{await i.write(f.toUint8Array());}catch(v){(v.message||"").includes("STOP_SENDING")||v.name==="WebTransportError"?(console.warn(`[MoQ] Group stream closed by remote (STOP_SENDING) for ${n}.`),i=null):console.error(`[MoQ] Writer error for ${n}:`,v);}});}};return this.activePublishers.set(n,p),p}};var Le=class{constructor(e,t){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;}async subscribe(e,t){let n=this.nextAlias++,i=this.nextSubscribeId++;this.aliasMap.set(n,{namespace:e,name:t}),console.log(`[MoQ] Subscribing to ${e}/${t} with Alias ${n} ID ${i}`);let r={type:3,subscribeId:i,trackAlias:n,trackNamespace:e,trackName:t};this.pendingSubscriptions.set(i,{namespace:e,name:t,trackAlias:n}),this.activeSubscriptions.set(i,n),await this.session.sendControlMessage(r);}onSubscribeOk(e){this.pendingSubscriptions.delete(e);}async onSubscribeError(e,t){let n=this.pendingSubscriptions.get(e);if(this.pendingSubscriptions.delete(e),!!n&&t===404){console.log(`[MoQ] Will retry subscription to ${n.namespace}/${n.name} in 2s...`),await new Promise(o=>setTimeout(o,2e3));let i=this.nextSubscribeId++,r={type:3,subscribeId:i,trackAlias:n.trackAlias,trackNamespace:n.namespace,trackName:n.name};this.pendingSubscriptions.set(i,n),console.log(`[MoQ] Retrying subscription to ${n.namespace}/${n.name} with ID ${i}`),await this.session.sendControlMessage(r);}}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",r=n?n.name:"unknown";for(;;){let o=t.groups.get(t.nextDeliverGroupId);if(o){for(;o.frames.length>0;){let s=o.frames.shift();this.onObject(i,r,s.payload,{groupId:s.groupId,objectId:s.objectId});}if(o.done){t.groups.delete(t.nextDeliverGroupId),t.nextDeliverGroupId++;continue}}else {let s=null;for(let a of t.groups.keys())a>t.nextDeliverGroupId&&(s===null||a<s)&&(s=a);if(s!==null&&s>t.nextDeliverGroupId+1){console.warn(`[MoQ] Skipping missing group ${t.nextDeliverGroupId}, jumping to ${s}`),t.nextDeliverGroupId=s;continue}}await new Promise(s=>{t.notifyResolve=s;});}}async handleIncomingUniStream(e){let t=e.getReader(),n=new F,i=-1,r=-1,o=null;try{for(;;){let{done:a,value:d}=await t.read();if(a)return;d&&n.append(d);try{n.checkpoint();let u=Number(n.readVarInt()),p=Number(n.readVarInt());i=Number(n.readVarInt()),r=Number(n.readVarInt()),n.readVarInt(),n.readUint8(),n.commit();break}catch(u){if(u.message==="EOF"){n.rewind();continue}throw u}}let s=this.deliveryState.get(i);if(s||(s={groups:new Map,nextDeliverGroupId:r,notifyResolve:null,loopRunning:!1},this.deliveryState.set(i,s)),r<s.nextDeliverGroupId){t.cancel().catch(()=>{});return}for(o={frames:[],done:!1},s.groups.set(r,o),s.loopRunning||(s.loopRunning=!0,this.runDeliveryLoop(i));;){if(!n.has(1)){let{done:a,value:d}=await t.read();if(a)break;d&&n.append(d);}try{n.checkpoint();let a=Number(n.readVarInt()),d=Number(n.readVarInt()),u=n.readBytes(d);n.commit(),o.frames.push({payload:u,groupId:r,objectId:a}),this.wakeDelivery(i);}catch(a){if(a.message==="EOF"){n.rewind();let{done:d,value:u}=await t.read();if(d)break;u&&n.append(u);continue}throw a}}}catch(s){console.error("Subscriber Stream Error",s);}finally{o&&(o.done=true,this.wakeDelivery(i));}}};var xe=class{constructor(e,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 F;this.transport=e,this.role=n,this.setupPromise=new Promise(i=>{this.setupResolve=i;}),this.publisher=new De(this),this.subscriber=new Le(this,t||((i,r,o,s)=>console.log(`[MoQ] Object: ${i}/${r}`,s)));}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=pe.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="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&&(console.log(`[MoQ] Control Stream RX: ${n.byteLength} bytes`),this.streamBuffer.append(n),this.processBuffer());}}catch(t){e=t,this.closed||console.error("Control stream error",t);}finally{this.emitClose(e);}console.log("[MoQ] Read Loop Exited");}processBuffer(){for(;;){let e;try{e=pe.deserialize(this.streamBuffer);}catch(t){console.error("[MoQ] Deserialization Error:",t);break}if(!e)break;this.handleControlMessage(e);}}handleControlMessage(e){switch(e.type){case 65:console.log(`[MoQ] Handshake Complete. Server selected version: 0x${e.selectedVersion.toString(16)}`),this.setupComplete=true,this.setupResolve&&(this.setupResolve(),this.setupResolve=null);break;case 21:this.maxSubscribeId=e.subscribeId,console.log(`[MoQ] Max Subscribe ID updated: ${this.maxSubscribeId}`);break;case 3:this.publisher.onSubscribe(e);let t={type:4,subscribeId:e.subscribeId,expires:0};this.sendControlMessage(t).catch(console.error);break;case 4:console.log(`[MoQ] SUBSCRIBE_OK for id=${e.subscribeId}`),this.subscriber.onSubscribeOk(e.subscribeId);break;case 5:console.error(`[MoQ] SUBSCRIBE_ERROR for id=${e.subscribeId} code=${e.code}`),this.subscriber.onSubscribeError(e.subscribeId,e.code).catch(console.error);break;case 7:console.log(`[MoQ] ANNOUNCE_OK for ns=${e.trackNamespace}`),this.publisher.onAnnounceResult(e.trackNamespace);break;case 8:console.error(`[MoQ] ANNOUNCE_ERROR for ns=${e.trackNamespace} code=${e.code}`),this.publisher.onAnnounceResult(e.trackNamespace,{code:e.code,reason:e.reasonPhrase||"Unknown"});break;case 10:this.publisher.onUnsubscribe(e.subscribeId);break;case 11:this.subscriber.onSubscribeDone(e.subscribeId,e.code,e.reason);break;case 16:console.warn("[MoQ] GOAWAY received");break;default:console.log(`[MoQ] Received Control Message type=0x${e.type.toString(16)}`);}}};function Y(l){if(!l)return null;let e=l.trim();return e?e.toLowerCase():null}function st(l){return l.deviceId||l.deviceIdHint||l.peerId||null}function Ue(l){return [...l].sort()}function ne(l,e){return l?l.peerId===e.peerId&&(l.deviceId??null)===(e.deviceId??null)&&(l.deviceIdHint??null)===(e.deviceIdHint??null)&&(l.nodeId??null)===(e.nodeId??null)&&(l.connectionId??null)===(e.connectionId??null)&&(l.ticket??null)===(e.ticket??null)&&!!l.online==!!e.online&&(l.deviceName??null)===(e.deviceName??null)&&(l.platformType??null)===(e.platformType??null)&&l.status===e.status&&l.health===e.health&&(l.transportState??null)===(e.transportState??null)&&(l.protocolState??null)===(e.protocolState??null)&&!!l.routable==!!e.routable&&(l.activeTransportStableId??null)===(e.activeTransportStableId??null)&&(l.transportGeneration??null)===(e.transportGeneration??null)&&(l.activeTransport??null)===(e.activeTransport??null)&&(l.parallelTransport??null)===(e.parallelTransport??null)&&(l.promotionEligible??true)===(e.promotionEligible??true)&&(l.error??null)===(e.error??null)&&JSON.stringify(Ue(l.connectionIds))===JSON.stringify(Ue(e.connectionIds))&&JSON.stringify(Ue(l.scopes))===JSON.stringify(Ue(e.scopes)):false}function Dt(l){return l==="closed"||l==="disconnected"||l==="failed"}function un(l){return Dt(l.status)?l.status:l.routable===true||l.protocolState==="routable"?"connected":l.status}var Be=class{constructor(){this.peers=new Map;this.aliases=new Map;this.watchers=new Set;}resolveCanonicalPeerId(e){let t=[e.deviceId,e.deviceIdHint,e.nodeId,e.peerId,e.connectionId];for(let n of t){let i=Y(n);if(!i)continue;let r=this.aliases.get(i);if(r)return r}return st(e)}setAlias(e,t){let n=Y(e);n&&this.aliases.set(n,t);}snapshot(e){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:un(e),health:e.health,transportState:e.transportState,protocolState:e.protocolState,routable:e.routable,activeTransportStableId:e.activeTransportStableId,transportGeneration:e.transportGeneration,activeTransport:e.activeTransport,parallelTransport:e.parallelTransport,promotionEligible:e.promotionEligible,scopes:Array.from(e.scopes.values()),lastSeenAt:e.lastSeenAt,error:e.error}}emit(){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,r]of this.aliases.entries())r===e&&this.aliases.set(i,t);return n}upsert(e){let t=this.resolveCanonicalPeerId(e)??st(e);if(!t)throw new Error("Peer projection upsert requires a device-keyed identifier.");let n=st(e)??t,i=this.peers.get(t),r=!!i;i||(i={peerId:t,connectionIds:new Set,status:e.status??"disconnected",health:e.health??"unknown",scopes:new Set},this.peers.set(t,i));let o=r?this.snapshot(i):void 0;if(n!==i.peerId){let u=e.deviceId||i.deviceId||e.deviceIdHint||i.deviceIdHint||e.nodeId||i.nodeId||i.peerId;u&&u!==i.peerId&&(i=this.rekeyPeer(i.peerId,u));}e.deviceId&&(i.deviceId=e.deviceId),e.deviceIdHint!==void 0&&(i.deviceIdHint=e.deviceIdHint),e.nodeId&&(i.nodeId=e.nodeId),e.connectionId&&(i.connectionId=e.connectionId,i.connectionIds.add(e.connectionId)),e.ticket!==void 0&&(i.ticket=e.ticket),e.online!==void 0&&(i.online=e.online),e.deviceName!==void 0&&(i.deviceName=e.deviceName),e.platformType!==void 0&&(i.platformType=e.platformType);let s=r&&Dt(i.status)&&typeof i.error=="string"&&i.error.toLowerCase().includes("manual disconnect"),a=e.status==="connected"||e.status==="connecting"||e.routable===true||e.protocolState==="routable"||e.transportState==="connected"||e.activeTransport!==void 0||e.parallelTransport!==void 0;if(s&&a&&!e.clearError){let u=this.snapshot(i);return ne(o,u)||this.emit(),u}if(e.status&&(i.status=e.status),e.health&&(i.health=e.health),e.transportState!==void 0&&(i.transportState=e.transportState),e.protocolState!==void 0&&(i.protocolState=e.protocolState),e.routable!==void 0&&(i.routable=e.routable),e.activeTransportStableId!==void 0&&(i.activeTransportStableId=e.activeTransportStableId),e.transportGeneration!==void 0&&(i.transportGeneration=e.transportGeneration),e.activeTransport!==void 0&&(i.activeTransport=e.activeTransport),e.parallelTransport!==void 0&&(i.parallelTransport=e.parallelTransport),e.promotionEligible!==void 0&&(i.promotionEligible=e.promotionEligible),e.clearError?i.error=void 0:e.error!==void 0&&(i.error=e.error),e.lastSeenAt!==void 0&&(i.lastSeenAt=e.lastSeenAt),e.scopes)for(let u of e.scopes)i.scopes.add(u);(i.status==="closed"||i.status==="failed"||i.status==="disconnected")&&(i.routable=false,i.activeTransportStableId=null,i.activeTransport=void 0,i.parallelTransport=null,(!i.transportState||i.transportState==="connected")&&(i.transportState="closed"),(!i.protocolState||i.protocolState==="routable")&&(i.protocolState="closed")),this.setAlias(i.peerId,i.peerId),this.setAlias(i.deviceId,i.peerId),this.setAlias(i.deviceIdHint,i.peerId),this.setAlias(i.nodeId,i.peerId),this.setAlias(i.connectionId,i.peerId);for(let u of i.connectionIds)this.setAlias(u,i.peerId);let d=this.snapshot(i);return ne(o,d)||this.emit(),d}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.watchers.add(e),e(this.list()),()=>{this.watchers.delete(e);}}get(e){let t=Y(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 r=this.snapshot(n);return ne(i,r)||this.emit(),r}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 r=this.snapshot(n);return ne(i,r)||this.emit(),r}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=Y(e);if(i){let o=Array.from(t.connectionIds).find(s=>Y(s)===i);o&&t.connectionIds.delete(o);}t.connectionId&&Y(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 r=this.snapshot(t);return ne(n,r)||this.emit(),r}updateHealth(e,t,n){let i=this.resolveRecord(e);if(!i)return;let r=this.snapshot(i);i.health=t,n&&(i.status=n),i.lastSeenAt=Date.now();let o=this.snapshot(i);return ne(r,o)||this.emit(),o}resolveRecord(e){let t=Y(e),n=t?this.aliases.get(t):void 0;return n&&this.peers.get(n)||this.peers.get(e)}};var Oe=class{constructor(e,t){this.peerLifecycle=e;this.deps=t;}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.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.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}};function J(){if(typeof navigator>"u")return false;let l=navigator.userAgent||"",e=navigator.userAgentData?.platform||navigator.platform||"";return /iPhone|iPad|iPod|Android|Mobile|CriOS|FxiOS/i.test(`${l} ${e}`)}function We(){return typeof window>"u"?false:new URLSearchParams(window.location.search).has("ticket")}function Lt(l){return l?l.routing==="stream-envelope"&&l.readiness==="transport-only":false}function at(l){let e=l.signalingMode??"hosted",t=J(),n=We(),i=e==="ticket-only",r=t&&n;return {flow:i?"ticket-only":"default",signalingMode:e,mobileBrowser:t,ticketQueryPresent:n,diagnosticsMode:r,skipIncomingBiProbe:r,skipIncomingChannelEnvelopeInspection:r,readerCloseStrategy:r?"release-lock":"cancel"}}var pn="trustedDevice",xt="plutonium:e2ee:identity:v1";function ie(l){let e=atob(l),t=new Uint8Array(e.length);for(let n=0;n<e.length;n+=1)t[n]=e.charCodeAt(n);return t}function Fe(l){let e="";for(let t=0;t<l.length;t+=1)e+=String.fromCharCode(l[t]);return btoa(e)}async function Ut(l){let e=await crypto.subtle.digest("SHA-256",l),t=new Uint8Array(e);return Array.from(t).map(n=>n.toString(16).padStart(2,"0")).join("")}function Bt(l=32){let e=crypto.getRandomValues(new Uint8Array(l));return Fe(e)}function Ot(l,e){let t=He.sign.detached(ie(l),e);return Fe(t)}function Wt(l,e,t){try{return He.sign.detached.verify(ie(l),ie(e),ie(t))}catch{return false}}function Ft(l){if(!l||!l.trim())return null;try{let e=JSON.parse(l),t=e&&typeof e=="object"&&!Array.isArray(e)?e[pn]:null;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t,i=typeof n.version=="number"?n.version:null,r=typeof n.identityPublicKey=="string"?n.identityPublicKey:null,o=typeof n.identityFingerprint=="string"?n.identityFingerprint:null;return !i||!r||!o?null:{version:i,identityPublicKey:r,identityFingerprint:o}}catch{return null}}async function hn(){if(typeof localStorage>"u")return null;let l=localStorage.getItem(xt);if(!l)return null;try{let e=JSON.parse(l);if(typeof e.publicKey!="string"||typeof e.secretKey!="string")return null;let t=ie(e.publicKey),n=ie(e.secretKey),i=await Ut(t);return {publicKey:t,secretKey:n,fingerprint:i}}catch{return null}}async function ct(){let l=await hn();if(l)return l;if(typeof localStorage>"u")return null;try{let e=He.sign.keyPair(),t={publicKey:Fe(e.publicKey),secretKey:Fe(e.secretKey)};localStorage.setItem(xt,JSON.stringify(t));let n=await Ut(e.publicKey);return {publicKey:e.publicKey,secretKey:e.secretKey,fingerprint:n}}catch{return null}}var fe=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,Ht.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Ht.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_bistream_free(e,0);}get endpoint_id(){let e,t;try{let n=c.bistream_endpoint_id(this.__wbg_ptr);return e=n[0],t=n[1],E(n[0],n[1])}finally{c.__wbindgen_free(e,t,1);}}get recv(){return c.bistream_recv(this.__wbg_ptr)}get send(){return c.bistream_send(this.__wbg_ptr)}};Symbol.dispose&&(fe.prototype[Symbol.dispose]=fe.prototype.free);var me=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,Gt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Gt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_intounderlyingsink_free(e,0);}abort(e){let t=this.__destroy_into_raw();return c.intounderlyingsink_abort(t,e)}close(){let e=this.__destroy_into_raw();return c.intounderlyingsink_close(e)}write(e){return c.intounderlyingsink_write(this.__wbg_ptr,e)}};Symbol.dispose&&(me.prototype[Symbol.dispose]=me.prototype.free);var be=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,qt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,qt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_intounderlyingsource_free(e,0);}cancel(){let e=this.__destroy_into_raw();c.intounderlyingsource_cancel(e);}pull(e){return c.intounderlyingsource_pull(this.__wbg_ptr,e)}};Symbol.dispose&&(be.prototype[Symbol.dispose]=be.prototype.free);var oe=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,lt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,lt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_wasmclient_free(e,0);}add_peer_scope(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_add_peer_scope(this.__wbg_ptr,n,i,r,o)}bind_connection_device_id(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_bind_connection_device_id(this.__wbg_ptr,n,i,r,o)}clear_session_tokens(){c.wasmclient_clear_session_tokens(this.__wbg_ptr);}connect(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_connect(this.__wbg_ptr,t,n)}connect_device(e,t){var n=P(e)?0:b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;let r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_connect_device(this.__wbg_ptr,n,i,r,o)}connection_state(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_connection_state(this.__wbg_ptr,t,n)}connection_states(){return c.wasmclient_connection_states(this.__wbg_ptr)}create_room(e,t,n,i,r,o){let s=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m,d=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m,p=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m,g=b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),f=m,v=b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),I=m;return c.wasmclient_create_room(this.__wbg_ptr,s,a,d,u,p,h,g,f,v,I,P(o)?Number.MAX_SAFE_INTEGER:o>>>0)}create_session(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_create_session(this.__wbg_ptr,t,n)}delete_device(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_delete_device(this.__wbg_ptr,n,i,r,o)}devices_with_status(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_devices_with_status(this.__wbg_ptr,t,n)}disconnect(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_disconnect(this.__wbg_ptr,t,n)}disconnect_device(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;var r=P(t)?0:b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_disconnect_device(this.__wbg_ptr,n,i,r,o)}endpoint_id_from_ticket(e){let t,n;try{let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=c.wasmclient_endpoint_id_from_ticket(this.__wbg_ptr,o,s);var i=a[0],r=a[1];if(a[3])throw i=0,r=0,$(a[2]);return t=i,n=r,E(i,r)}finally{c.__wbindgen_free(t,n,1);}}endpoint_ticket(){return c.wasmclient_endpoint_ticket(this.__wbg_ptr)}endpoint_ticket_with_token(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_endpoint_ticket_with_token(this.__wbg_ptr,n,i,t)}force_reconnect_snapshot(){c.wasmclient_force_reconnect_snapshot(this.__wbg_ptr);}get_members(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_get_members(this.__wbg_ptr,i,r,o,s,a,d)}heartbeat_tick(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_heartbeat_tick(this.__wbg_ptr,i,r,o,s,a,d)}incoming_streams(){return c.wasmclient_incoming_streams(this.__wbg_ptr)}init_iroh(e){var t=P(e)?0:$t(e,c.__wbindgen_malloc),n=m;return c.wasmclient_init_iroh(this.__wbg_ptr,t,n)}iroh_path_kind(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_iroh_path_kind(this.__wbg_ptr,t,n)}iroh_secret_key(){return c.wasmclient_iroh_secret_key(this.__wbg_ptr)}is_auto_connect_excluded(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_is_auto_connect_excluded(this.__wbg_ptr,t,n)!==0}is_connected(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_is_connected(this.__wbg_ptr,t,n)}join_room(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m,u=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m,h=b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m,f=b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),v=m;return c.wasmclient_join_room(this.__wbg_ptr,o,s,a,d,u,p,h,g,f,v)}leave_room(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_leave_room(this.__wbg_ptr,i,r,o,s,a,d)}list_managed_connections(){return c.wasmclient_list_managed_connections(this.__wbg_ptr)}constructor(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=c.wasmclient_new(n,i,r,o);if(s[2])throw $(s[1]);return this.__wbg_ptr=s[0],lt.register(this,this.__wbg_ptr,this),this}static newWithAppTag(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=c.wasmclient_newWithAppTag(n,i,r,o);if(s[2])throw $(s[1]);return l.__wrap(s[0])}node_addr(){return c.wasmclient_node_addr(this.__wbg_ptr)}open_bi(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_open_bi(this.__wbg_ptr,t,n)}open_peer_bi(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_bi(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_peer_bi_transport_only(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_bi_transport_only(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_peer_uni(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_uni(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_uni(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_open_uni(this.__wbg_ptr,t,n)}peer_scopes(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_scopes(this.__wbg_ptr,t,n)}peer_session(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_session(this.__wbg_ptr,t,n)}peer_sessions(){return c.wasmclient_peer_sessions(this.__wbg_ptr)}peer_snapshot(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_snapshot(this.__wbg_ptr,t,n)}peer_snapshots(){return c.wasmclient_peer_snapshots(this.__wbg_ptr)}present_session_token_to_host(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_present_session_token_to_host(this.__wbg_ptr,n,i,r,o)}register_session_token(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;c.wasmclient_register_session_token(this.__wbg_ptr,i,r,o,s,n);}release_peer_scope(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;var r=P(t)?0:b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_release_peer_scope(this.__wbg_ptr,n,i,r,o)}report_managed_connection_settled(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;var o=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;return c.wasmclient_report_managed_connection_settled(this.__wbg_ptr,i,r,t,o,s)}report_transport_status(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;var a=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_report_transport_status(this.__wbg_ptr,i,r,o,s,a,d)}resolve_peer_connection_records(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_resolve_peer_connection_records(this.__wbg_ptr,t,n)}revoke_session_token(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;c.wasmclient_revoke_session_token(this.__wbg_ptr,t,n);}revoke_tokens_by_scope(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_revoke_tokens_by_scope(this.__wbg_ptr,t,n)}runtime_policy(){let e=c.wasmclient_runtime_policy(this.__wbg_ptr);if(e[2])throw $(e[1]);return $(e[0])}same_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_same_peer(this.__wbg_ptr,n,i,r,o)}search_devices(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_search_devices(this.__wbg_ptr,t,n)}send_message(e,t,n,i){let r=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m;var d=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m,p=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m;return c.wasmclient_send_message(this.__wbg_ptr,r,o,s,a,d,u,p,h)}send_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=$t(t,c.__wbindgen_malloc),o=m;return c.wasmclient_send_peer(this.__wbg_ptr,n,i,r,o)}set_auth_token(e){var t=P(e)?0:b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;c.wasmclient_set_auth_token(this.__wbg_ptr,t,n);}set_auto_connect_excluded(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_set_auto_connect_excluded(this.__wbg_ptr,n,i,t)}set_offline(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_set_offline(this.__wbg_ptr,t,n)}start_auto_connect(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;c.wasmclient_start_auto_connect(this.__wbg_ptr,n,i,r,o);}start_presence_loop(e,t,n,i){let r=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m,d=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m;var p=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m;c.wasmclient_start_presence_loop(this.__wbg_ptr,r,o,s,a,d,u,p,h);}stop_auth_scoped_activity(){c.wasmclient_stop_auth_scoped_activity(this.__wbg_ptr);}stop_auto_connect(){c.wasmclient_stop_auto_connect(this.__wbg_ptr);}stop_presence_loop(){c.wasmclient_stop_presence_loop(this.__wbg_ptr);}update_device(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;var u=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m,h=P(r)?0:b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m;return c.wasmclient_update_device(this.__wbg_ptr,o,s,a,d,u,p,P(i)?0:H(i),h,g)}update_presence(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m,u=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m;var h=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m;return c.wasmclient_update_presence(this.__wbg_ptr,o,s,a,d,u,p,h,g,!P(r),P(r)?BigInt(0):r)}update_session(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_update_session(this.__wbg_ptr,n,i,r,o)}validate_session_token(e){let t,n;try{let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=c.wasmclient_validate_session_token(this.__wbg_ptr,o,s);var i=a[0],r=a[1];if(a[3])throw i=0,r=0,$(a[2]);return t=i,n=r,E(i,r)}finally{c.__wbindgen_free(t,n,1);}}validate_session_token_for_connection(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_validate_session_token_for_connection(this.__wbg_ptr,n,i,r,o)}wait_for_settled_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_wait_for_settled_peer(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}};Symbol.dispose&&(oe.prototype[Symbol.dispose]=oe.prototype.free);function jt(){c.start();}function gn(){return {__proto__:null,"./openrtc_bg.js":{__proto__:null,__wbg_Error_3639a60ed15f87e7:function(e,t){return Error(E(e,t))},__wbg_String_8564e559799eccda:function(e,t){let n=String(t),i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg___wbindgen_boolean_get_c3dd5c39f1b5a12b:function(e){let t=e,n=typeof t=="boolean"?t:void 0;return P(n)?16777215:n?1:0},__wbg___wbindgen_debug_string_07cb72cfcc952e2b:function(e,t){let n=ut(t),i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg___wbindgen_in_2617fa76397620d3:function(e,t){return e in t},__wbg___wbindgen_is_function_2f0fd7ceb86e64c5:function(e){return typeof e=="function"},__wbg___wbindgen_is_null_066086be3abe9bb3:function(e){return e===null},__wbg___wbindgen_is_object_5b22ff2418063a9c:function(e){let t=e;return typeof t=="object"&&t!==null},__wbg___wbindgen_is_string_eddc07a3efad52e6:function(e){return typeof e=="string"},__wbg___wbindgen_is_undefined_244a92c34d3b6ec0:function(e){return e===void 0},__wbg___wbindgen_jsval_eq_403eaa3610500a25:function(e,t){return e===t},__wbg___wbindgen_jsval_loose_eq_1978f1e77b4bce62:function(e,t){return e==t},__wbg___wbindgen_number_get_dd6d69a6079f26f1:function(e,t){let n=t,i=typeof n=="number"?n:void 0;D().setFloat64(e+8,P(i)?0:i,true),D().setInt32(e+0,!P(i),true);},__wbg___wbindgen_string_get_965592073e5d848c:function(e,t){let n=t,i=typeof n=="string"?n:void 0;var r=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;D().setInt32(e+4,o,true),D().setInt32(e+0,r,true);},__wbg___wbindgen_throw_9c75d47bf9e7731e:function(e,t){throw new Error(E(e,t))},__wbg__wbg_cb_unref_158e43e869788cdc:function(e){e._wbg_cb_unref();},__wbg_abort_43913e33ecb83d0d:function(e,t){e.abort(t);},__wbg_abort_87eb7f23cf4b73d1:function(e){e.abort();},__wbg_addEventListener_8b7ec0528991cf78:function(){return R(function(e,t,n,i){e.addEventListener(E(t,n),i);},arguments)},__wbg_append_8df396311184f750:function(){return R(function(e,t,n,i,r){e.append(E(t,n),E(i,r));},arguments)},__wbg_arrayBuffer_87e3ac06d961f7a0:function(){return R(function(e){return e.arrayBuffer()},arguments)},__wbg_bistream_new:function(e){return fe.__wrap(e)},__wbg_body_6929614c20dfa7b0:function(e){let t=e.body;return P(t)?0:H(t)},__wbg_buffer_9ee17426fe5a5d65:function(e){return e.buffer},__wbg_byobRequest_178b64c09a0bee03:function(e){let t=e.byobRequest;return P(t)?0:H(t)},__wbg_byteLength_1f57c71e64ee0180:function(e){return e.byteLength},__wbg_byteOffset_648d0af273024f3d:function(e){return e.byteOffset},__wbg_call_a41d6421b30a32c5:function(){return R(function(e,t,n){return e.call(t,n)},arguments)},__wbg_call_add9e5a76382e668:function(){return R(function(e,t){return e.call(t)},arguments)},__wbg_cancel_f97a3ee5a8b30eef:function(e){return e.cancel()},__wbg_catch_f939343cb181958c:function(e,t){return e.catch(t)},__wbg_clearTimeout_113b1cde814ec762:function(e){return clearTimeout(e)},__wbg_clearTimeout_1ccca1faf41fc6f8:function(e){return clearTimeout(e)},__wbg_clearTimeout_47a40e3be01ed7a3:function(){return R(function(e,t){e.clearTimeout(t);},arguments)},__wbg_clearTimeout_6b8d9a38b9263d65:function(e){return clearTimeout(e)},__wbg_close_63e009c5a75f5597:function(){return R(function(e){e.close();},arguments)},__wbg_close_931d0c62e2aab92c:function(){return R(function(e){e.close();},arguments)},__wbg_close_de471367367aa5cb:function(){return R(function(e){e.close();},arguments)},__wbg_code_be6f339819ebb2c4:function(e){return e.code},__wbg_code_f1d2ddc1fbbb5aad:function(e){return e.code},__wbg_createDataChannel_e92347b9e9a8f5fa:function(e,t,n){return e.createDataChannel(E(t,n))},__wbg_crypto_38df2bab126b63dc:function(e){return e.crypto},__wbg_data_4a14fad4c5f216c4:function(e){return e.data},__wbg_debug_37240d2c1d0ce2bb:function(e){console.debug(e);},__wbg_dispatchEvent_62b7eaa3eef4c3e8:function(){return R(function(e,t){return e.dispatchEvent(t)},arguments)},__wbg_done_b1afd6201ac045e0:function(e){return e.done},__wbg_enqueue_6c7cd543c0f3828e:function(){return R(function(e,t){e.enqueue(t);},arguments)},__wbg_entries_83f42485034accab:function(e){return e.entries()},__wbg_error_48655ee7e4756f8b:function(e){console.error(e);},__wbg_error_a6fa202b58aa1cd3:function(e,t){let n,i;try{n=e,i=t,console.error(E(e,t));}finally{c.__wbindgen_free(n,i,1);}},__wbg_fetch_1a030943aa8e0c38:function(e,t){return e.fetch(t)},__wbg_fetch_9dad4fe911207b37:function(e){return fetch(e)},__wbg_fetch_c6486a0142348bc8:function(e){return fetch(e)},__wbg_fetch_f36631298df17a02:function(e,t){return e.fetch(t)},__wbg_getRandomValues_76dfc69825c9c552:function(){return R(function(e,t){globalThis.crypto.getRandomValues(X(e,t));},arguments)},__wbg_getRandomValues_c44a50d8cfdaebeb:function(){return R(function(e,t){e.getRandomValues(t);},arguments)},__wbg_getReader_9facd4f899beac89:function(){return R(function(e){return e.getReader()},arguments)},__wbg_getReader_fe5bfa2b1fd51521:function(e){return e.getReader()},__wbg_get_41476db20fef99a8:function(){return R(function(e,t){return Reflect.get(e,t)},arguments)},__wbg_get_652f640b3b0b6e3e:function(e,t){return e[t>>>0]},__wbg_get_6aaf7ff105162d98:function(){return R(function(e,t,n,i){let r=t.get(E(n,i));var o=P(r)?0:b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;D().setInt32(e+4,s,true),D().setInt32(e+0,o,true);},arguments)},__wbg_get_9cfea9b7bbf12a15:function(){return R(function(e,t){return Reflect.get(e,t)},arguments)},__wbg_get_done_2088079830fb242e:function(e){let t=e.done;return P(t)?16777215:t?1:0},__wbg_get_value_52f4b39f58a812ed:function(e){return e.value},__wbg_get_with_ref_key_6412cf3094599694:function(e,t){return e[t]},__wbg_has_3a6f31f647e0ba22:function(){return R(function(e,t){return Reflect.has(e,t)},arguments)},__wbg_headers_de17f740bce997ae:function(e){return e.headers},__wbg_info_092aeeab8cd06a0b:function(e){console.info(e);},__wbg_instanceof_ArrayBuffer_eab9f28fbec23477:function(e){let t;try{t=e instanceof ArrayBuffer;}catch{t=false;}return t},__wbg_instanceof_Blob_03470b25075ee8f1:function(e){let t;try{t=e instanceof Blob;}catch{t=false;}return t},__wbg_instanceof_ReadableStreamDefaultReader_8203766c0e55064a:function(e){let t;try{t=e instanceof ReadableStreamDefaultReader;}catch{t=false;}return t},__wbg_instanceof_Response_370b83aa6c17e88a:function(e){let t;try{t=e instanceof Response;}catch{t=false;}return t},__wbg_instanceof_Uint8Array_57d77acd50e4c44d:function(e){let t;try{t=e instanceof Uint8Array;}catch{t=false;}return t},__wbg_instanceof_Window_4153c1818a1c0c0b:function(e){let t;try{t=e instanceof Window;}catch{t=false;}return t},__wbg_isArray_c6c6ef8308995bcf:function(e){return Array.isArray(e)},__wbg_iterator_9d68985a1d096fc2:function(){return Symbol.iterator},__wbg_length_ba3c032602efe310:function(e){return e.length},__wbg_log_72d22df918dcc232:function(e){console.log(e);},__wbg_message_609b498da776cb30:function(e,t){let n=t.message,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_msCrypto_bd5a034af96bcba6:function(e){return e.msCrypto},__wbg_new_0_e486ec9936f7edbf:function(){return new Date},__wbg_new_18865c63fa645c6f:function(){return R(function(){return new Headers},arguments)},__wbg_new_227d7c05414eb861:function(){return new Error},__wbg_new_2fad8ca02fd00684:function(){return new Object},__wbg_new_3baa8d9866155c79:function(){return new Array},__wbg_new_46ae4e4ff2a07a64:function(){return new Map},__wbg_new_51ff470dc2f61e27:function(){return R(function(){return new AbortController},arguments)},__wbg_new_71b820e9c1f9ee88:function(){return R(function(e,t){return new WebSocket(E(e,t))},arguments)},__wbg_new_8454eee672b2ba6e:function(e){return new Uint8Array(e)},__wbg_new_c9ea13ea803a692e:function(e,t){return new Error(E(e,t))},__wbg_new_from_slice_5a173c243af2e823:function(e,t){return new Uint8Array(X(e,t))},__wbg_new_typed_1137602701dc87d4:function(e,t){try{var n={a:e,b:t},i=(o,s)=>{let a=n.a;n.a=0;try{return Cn(a,n.b,o,s)}finally{n.a=a;}};return new Promise(i)}finally{n.a=0;}},__wbg_new_with_byte_offset_and_length_643e5e9e2fb6b1ad:function(e,t,n){return new Uint8Array(e,t>>>0,n>>>0)},__wbg_new_with_configuration_3b46f8f863c57190:function(){return R(function(e){return new RTCPeerConnection(e)},arguments)},__wbg_new_with_event_init_dict_e01f6dc8f5a4058b:function(){return R(function(e,t,n){return new CustomEvent(E(e,t),n)},arguments)},__wbg_new_with_into_underlying_sink_2596343f9b6c8e58:function(e){return new WritableStream(me.__wrap(e))},__wbg_new_with_into_underlying_source_fd904252f385f59c:function(e,t){return new ReadableStream(be.__wrap(e),t)},__wbg_new_with_length_9011f5da794bf5d9:function(e){return new Uint8Array(e>>>0)},__wbg_new_with_str_and_init_da311e12114f4d1e:function(){return R(function(e,t,n){return new Request(E(e,t),n)},arguments)},__wbg_new_with_str_sequence_d90cb07368a00c61:function(){return R(function(e,t,n){return new WebSocket(E(e,t),n)},arguments)},__wbg_next_261c3c48c6e309a5:function(e){return e.next},__wbg_next_aacee310bcfe6461:function(){return R(function(e){return e.next()},arguments)},__wbg_node_84ea875411254db1:function(e){return e.node},__wbg_now_4f457f10f864aec5:function(){return Date.now()},__wbg_now_e7c6795a7f81e10f:function(e){return e.now()},__wbg_ok_b6a9978bb5f66f33:function(e){return e.ok},__wbg_parse_6a6cc87f3d5b738c:function(e,t){return Date.parse(E(e,t))},__wbg_performance_3fcf6e32a7e1ed0a:function(e){return e.performance},__wbg_process_44c7a14e11e9f69e:function(e){return e.process},__wbg_protocol_db28bce84eb5b12a:function(e,t){let n=t.protocol,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_prototypesetcall_fd4050e806e1d519:function(e,t,n){Uint8Array.prototype.set.call(X(e,t),n);},__wbg_push_60a5366c0bb22a7d:function(e,t){return e.push(t)},__wbg_queueMicrotask_40ac6ffc2848ba77:function(e){queueMicrotask(e);},__wbg_queueMicrotask_74d092439f6494c1:function(e){return e.queueMicrotask},__wbg_randomFillSync_6c25eac9869eb53c:function(){return R(function(e,t){e.randomFillSync(t);},arguments)},__wbg_read_ac2e4325f1799cbe:function(e){return e.read()},__wbg_readyState_be3cc9403da6c6ae:function(e){return e.readyState},__wbg_reason_fe958bcb63725f3b:function(e,t){let n=t.reason,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_releaseLock_9e0ebc0b5270a358:function(e){e.releaseLock();},__wbg_removeEventListener_83bbb9ee36238073:function(){return R(function(e,t,n,i){e.removeEventListener(E(t,n),i);},arguments)},__wbg_require_b4edbdcf3e2a1ef0:function(){return R(function(){return module.require},arguments)},__wbg_resolve_9feb5d906ca62419:function(e){return Promise.resolve(e)},__wbg_respond_e7e53102735b2ae2:function(){return R(function(e,t){e.respond(t>>>0);},arguments)},__wbg_send_0edb796d05cd3239:function(){return R(function(e,t,n){e.send(E(t,n));},arguments)},__wbg_send_c422d0aa0cb71d09:function(){return R(function(e,t,n){e.send(X(t,n));},arguments)},__wbg_setTimeout_30be5552e4410378:function(e,t){return setTimeout(e,t)},__wbg_setTimeout_6613a51400c1bf9f:function(){return R(function(e,t,n){return e.setTimeout(t,n)},arguments)},__wbg_setTimeout_ef24d2fc3ad97385:function(){return R(function(e,t){return setTimeout(e,t)},arguments)},__wbg_setTimeout_f757f00851f76c42:function(e,t){return setTimeout(e,t)},__wbg_set_5337f8ac82364a3f:function(){return R(function(e,t,n){return Reflect.set(e,t,n)},arguments)},__wbg_set_6be42768c690e380:function(e,t,n){e[t]=n;},__wbg_set_82f7a370f604db70:function(e,t,n){return e.set(t,n)},__wbg_set_959f043b9152efeb:function(){return R(function(e,t,n,i,r){e.set(E(t,n),E(i,r));},arguments)},__wbg_set_b0d9dc239ecdb765:function(e,t,n){e.set(X(t,n));},__wbg_set_binaryType_8564bdba0fbec720:function(e,t){e.binaryType=Tn[t];},__wbg_set_body_aaff4f5f9991f342:function(e,t){e.body=t;},__wbg_set_cache_d1f2b7b4dfa39317:function(e,t){e.cache=Pn[t];},__wbg_set_credentials_f31e4d30b974ce14:function(e,t){e.credentials=kn[t];},__wbg_set_detail_ff73098900fc0958:function(e,t){e.detail=t;},__wbg_set_f614f6a0608d1d1d:function(e,t,n){e[t>>>0]=n;},__wbg_set_handle_event_ce9002ca160b1275:function(e,t){e.handleEvent=t;},__wbg_set_headers_ae96049ea40e9eef:function(e,t){e.headers=t;},__wbg_set_high_water_mark_84684938153a659a:function(e,t){e.highWaterMark=t;},__wbg_set_method_0eea8a5597775fa1:function(e,t,n){e.method=E(t,n);},__wbg_set_mode_9fe47bff60a1580d:function(e,t){e.mode=An[t];},__wbg_set_onclose_f756840519cd20b5:function(e,t){e.onclose=t;},__wbg_set_onerror_02f33de339f1fa31:function(e,t){e.onerror=t;},__wbg_set_onmessage_d2ff0c1d20584625:function(e,t){e.onmessage=t;},__wbg_set_onopen_1da8a4f65e6180d2:function(e,t){e.onopen=t;},__wbg_set_signal_8c5cf4c3b27bd8a8:function(e,t){e.signal=t;},__wbg_signal_4643ce883b92b553:function(e){return e.signal},__wbg_stack_3b0d974bbf31e44f:function(e,t){let n=t.stack,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_static_accessor_GLOBAL_THIS_1c7f1bd6c6941fdb:function(){let e=typeof globalThis>"u"?null:globalThis;return P(e)?0:H(e)},__wbg_static_accessor_GLOBAL_e039bc914f83e74e:function(){let e=typeof global>"u"?null:global;return P(e)?0:H(e)},__wbg_static_accessor_SELF_8bf8c48c28420ad5:function(){let e=typeof self>"u"?null:self;return P(e)?0:H(e)},__wbg_static_accessor_WINDOW_6aeee9b51652ee0f:function(){let e=typeof window>"u"?null:window;return P(e)?0:H(e)},__wbg_status_157e67ab07d01f8a:function(e){return e.status},__wbg_stringify_7fd5cae8859a6f10:function(){return R(function(e){return JSON.stringify(e)},arguments)},__wbg_subarray_fbe3cef290e1fa43:function(e,t,n){return e.subarray(t>>>0,n>>>0)},__wbg_text_de416916b5c06490:function(){return R(function(e){return e.text()},arguments)},__wbg_then_20a157d939b514f5:function(e,t){return e.then(t)},__wbg_then_5ef9b762bc91555c:function(e,t,n){return e.then(t,n)},__wbg_toISOString_72dcc3eb1fd97de6:function(e){return e.toISOString()},__wbg_url_68fd9a221360e0db:function(e,t){let n=t.url,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_url_a0e994e7d0317efc:function(e,t){let n=t.url,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_value_f852716acdeb3e82:function(e){return e.value},__wbg_versions_276b2795b1c6a219:function(e){return e.versions},__wbg_view_16bd97d49793e1a9:function(e){let t=e.view;return P(t)?0:H(t)},__wbg_warn_1f9b94806da61fbb:function(e){console.warn(e);},__wbg_wasClean_92b4133f985dfae0:function(e){return e.wasClean},__wbindgen_cast_0000000000000001:function(e,t){return V(e,t,_n)},__wbindgen_cast_0000000000000002:function(e,t){return V(e,t,Sn)},__wbindgen_cast_0000000000000003:function(e,t){return V(e,t,wn)},__wbindgen_cast_0000000000000004:function(e,t){return V(e,t,In)},__wbindgen_cast_0000000000000005:function(e,t){return V(e,t,fn)},__wbindgen_cast_0000000000000006:function(e,t){return V(e,t,mn)},__wbindgen_cast_0000000000000007:function(e,t){return V(e,t,bn)},__wbindgen_cast_0000000000000008:function(e,t){return Nn(e,t,vn)},__wbindgen_cast_0000000000000009:function(e,t){return V(e,t,yn)},__wbindgen_cast_000000000000000a:function(e){return e},__wbindgen_cast_000000000000000b:function(e){return e},__wbindgen_cast_000000000000000c:function(e,t){return X(e,t)},__wbindgen_cast_000000000000000d:function(e,t){return E(e,t)},__wbindgen_cast_000000000000000e:function(e){return BigInt.asUintN(64,e)},__wbindgen_cast_000000000000000f:function(e,t){var n=X(e,t).slice();return c.__wbindgen_free(e,t*1,1),n},__wbindgen_init_externref_table:function(){let e=c.__wbindgen_externrefs,t=e.grow(4);e.set(0,void 0),e.set(t+0,void 0),e.set(t+1,null),e.set(t+2,true),e.set(t+3,false);}}}}function fn(l,e){c.wasm_bindgen__convert__closures_____invoke__h509d1e5f9a719179(l,e);}function mn(l,e){c.wasm_bindgen__convert__closures_____invoke__h1ecdc95d38c8111b(l,e);}function bn(l,e){c.wasm_bindgen__convert__closures_____invoke__h47f09f7820fbff6c(l,e);}function vn(l,e){c.wasm_bindgen__convert__closures_____invoke__ha910581f00459fa9(l,e);}function yn(l,e){c.wasm_bindgen__convert__closures_____invoke__h1893948438c6db09(l,e);}function _n(l,e,t){c.wasm_bindgen__convert__closures_____invoke__h4dc49b34d4d77b81(l,e,t);}function wn(l,e,t){c.wasm_bindgen__convert__closures_____invoke__hf679ef60a72d1948(l,e,t);}function In(l,e,t){c.wasm_bindgen__convert__closures_____invoke__h4b742547b50caebd(l,e,t);}function Sn(l,e,t){let n=c.wasm_bindgen__convert__closures_____invoke__hd47f17ba87c541ec(l,e,t);if(n[1])throw $(n[0])}function Cn(l,e,t,n){c.wasm_bindgen__convert__closures_____invoke__h776304867400b4e4(l,e,t,n);}var Tn=["blob","arraybuffer"],Pn=["default","no-store","reload","no-cache","force-cache","only-if-cached"],kn=["omit","same-origin","include"],An=["same-origin","no-cors","cors","navigate"],Ht=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_bistream_free(l,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(l=>c.__wbg_intounderlyingbytesource_free(l,1));var Gt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_intounderlyingsink_free(l,1)),qt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_intounderlyingsource_free(l,1)),lt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_wasmclient_free(l,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(l=>c.__wbg_wasmconnection_free(l,1));function H(l){let e=c.__externref_table_alloc();return c.__wbindgen_externrefs.set(e,l),e}var $e=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbindgen_destroy_closure(l.a,l.b));function ut(l){let e=typeof l;if(e=="number"||e=="boolean"||l==null)return `${l}`;if(e=="string")return `"${l}"`;if(e=="symbol"){let i=l.description;return i==null?"Symbol":`Symbol(${i})`}if(e=="function"){let i=l.name;return typeof i=="string"&&i.length>0?`Function(${i})`:"Function"}if(Array.isArray(l)){let i=l.length,r="[";i>0&&(r+=ut(l[0]));for(let o=1;o<i;o++)r+=", "+ut(l[o]);return r+="]",r}let t=/\[object ([^\]]+)\]/.exec(toString.call(l)),n;if(t&&t.length>1)n=t[1];else return toString.call(l);if(n=="Object")try{return "Object("+JSON.stringify(l)+")"}catch{return "Object"}return l instanceof Error?`${l.name}: ${l.message}
2
+ `).slice(1,4).join(" | ")}),this.upgradeRequested=true,this.upgradeAttemptActive=false,this.upgradeTerminalFailure=false,this.clearUpgradeRetryTimer(),this.clearUpgradeAttemptTimeoutTimer(),t.resetRetryBudget&&(this.upgradeRetryCount=0),t.replaceExisting&&(this.stopWebRtcHeartbeat(),this.pendingSignals=[],this.teardownWebRTCTransport()),this.attemptUpgrade({forceRenegotiate:t.forceRenegotiate,replaceExisting:t.replaceExisting});}}getUpgradeState(){return this.upgradeState}updateRTCConfig(e){this.options.rtcConfig=e;}onUpgradeStateChange(e){this.upgradeStateListeners.push(e);}async getTransportDiagnostics(){let e=this.transportType,t=this.resolveParallelTransport(e),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 r=await i.getStats(),o=null;r.forEach(I=>{if(o||I?.type!=="transport")return;let _=I?.selectedCandidatePairId;!_||typeof r.get!="function"||(o=r.get(_)??null);}),o||r.forEach(I=>{if(!o&&I?.type==="candidate-pair"){if(I?.selected===!0){o=I;return}I?.nominated===!0&&I?.state==="succeeded"&&(o=I);}});let s=o?.localCandidateId&&typeof r.get=="function"?r.get(o.localCandidateId):null,a=o?.remoteCandidateId&&typeof r.get=="function"?r.get(o.remoteCandidateId):null,d=typeof s?.candidateType=="string"?s.candidateType:null,u=typeof a?.candidateType=="string"?a.candidateType:null,p=typeof s?.protocol=="string"?s.protocol:null,h=typeof a?.protocol=="string"?a.protocol:null,g=!!(d||u),f=g?d==="relay"||u==="relay":null,v=g?`${d??"unknown"}<->${u??"unknown"}`:null;return {...n,usesRelay:f,relaySource:f==null?null:f?"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:u,localProtocol:p,remoteProtocol:h,candidateTypeSummary:v}}}catch{return {...n,relaySource:"webrtc-stats-unavailable"}}}get transportType(){return this.upgradeState==="upgraded"?"webrtc":this.peerMoQReady?"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){return this.sendTyped(0,e)}async sendMedia(e,t){let n=e==="video"?1:2;return this.sendTyped(n,t)}async sendOnTransport(e,t){return this.sendTypedOnTransport(e,0,t)}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=[];this.webrtcTransport&&this.upgradeState==="upgraded"&&e.push("webrtc");let t=this.options.transportContext;return t&&t.isMoQReady()&&this.peerMoQReady&&e.push("moq"),this.writer&&e.push("iroh"),e}onWebRTCBinaryMessage(e){this.webrtcBinaryHandlers.push(e);}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))}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 r=this.writeMutex,o;this.writeMutex=new Promise(s=>{o=s;});try{return await r,this.writer?(await this.writer.write(t),!0):!1}catch(s){if(this.preserveWebRtcConnectionAfterBaseTransportLoss(`Iroh Send Error: ${s}`))return false;throw console.error("[Connection] Iroh Send error:",s),this.close(`Send Error: ${s}`),s}finally{o();}}async sendUsingTransport(e,t,n,i,r){let o=this.options.transportContext;return e==="webrtc"?!this.webrtcTransport||this.upgradeState!=="upgraded"||t!==0?false:(await this.webrtcTransport.send(i),true):e==="moq"?o&&o.isMoQReady()&&this.peerMoQReady?(await o.sendMoQ(r),true):false:e==="iroh"||e==="iroh-relay"||e==="iroh-quic"?this.sendOverIroh(t,r,"explicit transport send"):false}async sendTypedOnTransport(e,t,n){let i=this.encodePayload(n),r=this.buildFrame(t,i);if(!await this.sendUsingTransport(e,t,n,i,r))throw new Error(`[Connection] Requested transport unavailable: ${e}`)}async sendTyped(e,t){let i=this.options.transportContext?.priorities||["webrtc","moq","iroh"],r=this.encodePayload(t),o=this.buildFrame(e,r);for(let s of i)try{if(await this.sendUsingTransport(s,e,t,r,o))return}catch(a){console.warn(`[Connection] ${s} Send Failed:`,a);}}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.clearUpgradeAttemptTimeoutTimer(),this.clearWebRtcDisconnectedGraceTimer(),this.teardownWebRTCTransport(),this.setUpgradeState("none"),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){if(!this.webrtcTransport||this.upgradeState!=="upgraded"&&!(this.upgradeState==="upgrading"&&this.nativeSignalSender))return false;b$1("[Connection] Base transport closed while WebRTC is usable or recoverable; preserving connection",{connectionId:this.id,remoteNodeId:this.remoteNodeId,reason:e,activeTransport:this.transportType,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 r=this.receiveBuffer.slice(4,4+i);if(r.length>0){let o=r[0],s=r.slice(1);N.isUntypedDataFrame(r)?this.processDataPayload(r):o===3?this.sendIrohHeartbeatPong(s):o===4?this.irohHealthListeners.forEach(a=>a("healthy")):o===1?this.emitMedia("video",s):o===2?this.emitMedia("audio",s):this.processDataPayload(s);}this.receiveBuffer=this.receiveBuffer.slice(4+i);}}static isUntypedDataFrame(e){let t=e[0];return t===123||t===91?true:e.length>=4&&e[0]===68&&e[1]===86&&e[2]===67&&e[3]===72}processDataPayload(e){try{let t=N.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=N.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 r=t.charCodeAt(i);if(r<32&&r!==9&&r!==10&&r!==13)return !1}let n=N.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>N.MAX_PENDING_MESSAGES&&this.pendingMessages.splice(0,this.pendingMessages.length-N.MAX_PENDING_MESSAGES),this.listeners.length!==0&&this.listeners.forEach(t=>t(e));}receiveMessage(e){this.emitMessage(e);}receiveDataPayload(e){this.processDataPayload(e);}addTrack(e){let t=this.webrtcTransport?.getNativeTransport?.();return t&&typeof t.addTrack=="function"?t.addTrack(e):null}addTransceiver(e,t){let n=this.webrtcTransport?.getNativeTransport?.();return n&&typeof n.addTransceiver=="function"?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,r=typeof n?.iceConnectionState=="string"?n.iceConnectionState:null;return t==="closed"||t==="closing"?false:t==="open"?true:i==="connected"||i==="connecting"||r==="connected"||r==="completed"||r==="checking"}handleDisconnectedTransportStateWithGrace(e){let t=e.getDataChannelReadyState?.()??null;if(t==="closed"||t==="closing"){b$1("[Connection] WebRTC disconnected with closed DataChannel; failing upgraded transport immediately",{connectionId:this.id,remoteNodeId:this.remoteNodeId,dcReadyState:t}),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("transport-state-disconnected-dc-closed");return}this.webRtcDisconnectedGraceTimer||(b$1("[Connection] WebRTC transport reported disconnected; applying grace window before fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId}),this.webRtcDisconnectedGraceTimer=setTimeout(()=>{if(this.webRtcDisconnectedGraceTimer=null,!(this._isClosed||this.webrtcTransport!==e)){if(this.transportStillLikelyAlive(e)){b$1("[Connection] WebRTC disconnected grace expired but transport appears alive; suppressing fallback",{connectionId:this.id,remoteNodeId:this.remoteNodeId});return}this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("transport-state-disconnected-grace-expired");}},N.WEBRTC_DISCONNECTED_GRACE_MS));}async attemptUpgrade(e){if(this._isClosed||!this.upgradeRequested||!this.options.rtcConfig)return;let t=typeof e=="object"&&e!==null?e:{preferredNegotiationId:e??null},n=t.preferredNegotiationId,i=!!t.forceRenegotiate;if(!!!t.replaceExisting&&(this.upgradeAttemptActive||this.upgradeState==="upgraded"))return;this.upgradeAttemptActive=true,this.teardownWebRTCTransport();let o=this.normalizeNegotiationId(n)??this.createNegotiationId();this.activeNegotiationId=o,this.setUpgradeState("upgrading"),this.startUpgradeAttemptTimeout(o),(i||this.upgradeRetryCount>0)&&this.sendInternalSignal({transport:"webrtc",type:"renegotiate",negotiationId:o}).catch(()=>{});try{this.webrtcTransport=z.createTransport("webrtc");}catch(u){this.upgradeAttemptActive=false,b$1("[Connection] WebRTC upgrade unavailable",u),this.handleUpgradeFailure("transport-create-error");return}let s=this.webrtcTransport;typeof s.setSignalSender=="function"&&s.setSignalSender(u=>this.sendInternalSignal(u)),s.onMessage(u=>{if(u instanceof Uint8Array&&u.byteLength>0){if(this.webrtcHeartbeat?.handleIncoming(u))return;if(u[0]===2){for(let p of this.webrtcBinaryHandlers)if(p(u))return}}this.processDataPayload(u);}),s.onStateChange(u=>{if(!(this._isClosed||this.webrtcTransport!==s)){if(c$2(`[Connection] WebRTC transport state changed: ${u}`),u==="connected"){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.clearUpgradeRetryTimer(),this.lastWebRtcDataChannelOpenAt=Date.now(),this.setUpgradeState("upgraded"),this.startWebRtcHeartbeat(s);return}if(u==="failed"||u==="disconnected"){if(this.clearUpgradeAttemptTimeoutTimer(),this.upgradeAttemptActive=false,u==="disconnected"&&this.upgradeState==="upgraded"){this.handleDisconnectedTransportStateWithGrace(s);return}this.clearWebRtcDisconnectedGraceTimer(),s.isTerminalFailure?.()&&(this.upgradeTerminalFailure=true),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure(`transport-state-${u}`);}}});try{await s.init(this.localNodeId,this.deviceId,{rtcConfig:this.options.rtcConfig,negotiationId:o,forceRole:this.preferredWebRtcRole??void 0});}catch(u){this.upgradeAttemptActive=false,this.clearUpgradeAttemptTimeoutTimer(),b$1("[Connection] WebRTC init failed",u),this.handleUpgradeFailure("init-error");return}if(this.webrtcTransport!==s){this.upgradeAttemptActive=false;return}let a=s.getNegotiationId?.();if(a&&(this.activeNegotiationId=this.normalizeNegotiationId(a)??o),this.pendingSignals.length>0){let u=this.pendingSignals.splice(0);for(let p of u)s.handleSignalingMessage?.(p);}let d=s.getNativeTransport?.();d&&d.ontrack!==void 0&&(d.ontrack=u=>{c$2(`[Connection] Peer track received: ${u.track.kind}`),this.trackListeners.forEach(p=>p(u));});}setUpgradeState(e){this.upgradeState!==e&&(this.upgradeState=e,this.reportTransportStatusIfChanged(),this.upgradeStateListeners.forEach(t=>{try{t(e);}catch(n){b$1("[Connection] Upgrade state listener failed",n);}}));}handleUpgradeFailure(e){if(this._isClosed||!this.upgradeRequested)return;this.clearUpgradeAttemptTimeoutTimer();let t=this.upgradeTerminalFailure,n=!t&&this.shouldRetryUpgrade();if(this.upgradeAttemptActive=false,this.setUpgradeState("failed"),console.warn(`[Connection] WebRTC upgrade failed: ${e}`,{connectionId:this.id,remoteNodeId:this.remoteNodeId,retryCount:this.upgradeRetryCount,maxRetries:N.MAX_UPGRADE_RETRIES,terminal:t,willRetry:n}),t&&console.warn("[Connection] WebRTC upgrade is terminal \u2014 not retrying. Both peers may be on the same page (same-context loopback)."),b$1(`[Connection] WebRTC upgrade fallback: ${e}`),n){this.scheduleUpgradeRetry();return}this.clearUpgradeRetryTimer(),this.teardownWebRTCTransport();}shouldRetryUpgrade(){return !(this._isClosed||!this.upgradeRequested||this.upgradeTerminalFailure||!this.options.rtcConfig||!this.hasRecoverableBasePath()||this.upgradeRetryCount>=N.MAX_UPGRADE_RETRIES)}scheduleUpgradeRetry(){this.clearUpgradeRetryTimer(),this.upgradeRetryCount+=1;let e=this.upgradeRetryCount;this.upgradeRetryTimer=setTimeout(()=>{this.upgradeRetryTimer=null,!(this._isClosed||!this.upgradeRequested||this.upgradeAttemptActive)&&(c$2(`[Connection] Retrying WebRTC upgrade ${e}/${N.MAX_UPGRADE_RETRIES}`),this.attemptUpgrade());},N.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,b$1("[Connection] WebRTC upgrade attempt timed out",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:e}),this.handleUpgradeFailure("upgrade-attempt-timeout"));},N.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS);}clearUpgradeAttemptTimeoutTimer(){this.upgradeAttemptTimeoutTimer&&(clearTimeout(this.upgradeAttemptTimeoutTimer),this.upgradeAttemptTimeoutTimer=null);}teardownWebRTCTransport(){this.clearWebRtcDisconnectedGraceTimer(),this.clearUpgradeAttemptTimeoutTimer();let e=this.webrtcTransport;if(e){this.webrtcTransport=null,this.stopWebRtcHeartbeat();try{e.close();}catch(t){b$1("[Connection] WebRTC transport close failed",t);}this.reportTransportStatusIfChanged();}}startWebRtcHeartbeat(e){this.stopWebRtcHeartbeat();let t=Date.now();console.debug("[Connection] WebRTC heartbeat starting",{connectionId:this.id,startedAt:t,config:le});let n=new Ae(async i=>{console.debug("[Connection] WebRTC heartbeat send",{connectionId:this.id,byteLength:i.byteLength,typeId:i[0]}),await e.send(i);},i=>{let r=Date.now()-t;if(console.debug("[Connection] WebRTC heartbeat health callback",{connectionId:this.id,health:i,elapsedSinceStartMs:r}),i==="healthy"&&(this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0),this.webrtcHealthListeners.forEach(o=>o(i)),i==="stale"){if(this.webRtcHeartbeatProbeInFlight)return;this.webRtcHeartbeatProbeInFlight=true,c$2("[Connection] WebRTC heartbeat stale \u2014 probing transport before fallback"),n.probe(4e3).then(o=>{if(o){this.lastWebRtcHeartbeatOkAt=Date.now(),this.webRtcHeartbeatConsecutiveProbeFailures=0,c$2("[Connection] WebRTC heartbeat probe succeeded \u2014 keeping upgraded transport");return}if(this.webRtcHeartbeatConsecutiveProbeFailures+=1,this.transportStillLikelyAlive(e)){this.lastWebRtcHeartbeatOkAt=Date.now(),c$2("[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){c$2("[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(),c$2("[Connection] WebRTC heartbeat probe failed but no base recovery path exists \u2014 keeping transport",{connectionId:this.id,remoteNodeId:this.remoteNodeId});return}c$2("[Connection] WebRTC heartbeat probe failed consecutively \u2014 triggering upgrade fallback"),this.stopWebRtcHeartbeat(),this.handleUpgradeFailure("heartbeat-stale-probe-failed");}).finally(()=>{this.webRtcHeartbeatProbeInFlight=false;});}},le);this.webrtcHeartbeat=n,n.start();}stopWebRtcHeartbeat(){this.webRtcHeartbeatProbeInFlight=false,this.webRtcHeartbeatConsecutiveProbeFailures=0,this.webrtcHeartbeat&&(this.webrtcHeartbeat.stop(),this.webrtcHeartbeat=null);}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),r=BigInt(Date.now()),o=new ArrayBuffer(29),s=new DataView(o);s.setUint32(0,25,false),s.setUint8(4,4),s.setBigUint64(5,n,false),s.setBigInt64(13,i,false),s.setBigInt64(21,r,false);let a=this.writeMutex,d;this.writeMutex=new Promise(u=>{d=u;});try{await a,this.writer&&await this.writer.write(new Uint8Array(o));}catch{}finally{d();}}onWebRtcHeartbeatHealth(e){this.webrtcHealthListeners.push(e);}onIrohHeartbeatHealth(e){this.irohHealthListeners.push(e);}reportTransportStatusIfChanged(){if(this._isClosed)return;let e=this.transportType,t=this.resolveParallelTransport(e),n=`${e}:${t??""}`;this.lastReportedTransportStatus!==n&&(this.lastReportedTransportStatus=n,this.options.onTransportStatusChange?.({activeTransport:e,parallelTransport:t}));}resolveParallelTransport(e){if(this._isClosed)return null;let t=e==="iroh"||e==="iroh-relay"||e==="iroh-quic";return !t&&this.writer||!t&&e==="webrtc"&&this.hasRecoverableBasePath()?"iroh-relay":t&&this.isWebRtcDataChannelOpen()?"webrtc":null}setNativeSignalSender(e){this.nativeSignalSender=e;}async sendInternalSignal(e){let t=e&&(e.transport==="webrtc"||!e.transport)?{...e,transport:"webrtc",negotiationId:this.normalizeNegotiationId(e.negotiationId)??this.activeNegotiationId??void 0}:e,n={type:"#pluto-signal",content:t};if(this.nativeSignalSender)try{await this.nativeSignalSender(n),c$2("[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 iroh transport",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null,error:i});}try{if((t?.type==="sdp"||t?.type==="candidate"||t?.type==="renegotiate")&&console.info("[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)),r=new Uint8Array(1+i.byteLength);r[0]=0,r.set(i,1);let o=new ArrayBuffer(4+r.byteLength),s=new DataView(o),a=new Uint8Array(o);s.setUint32(0,r.byteLength,!1),a.set(r,4),await this.sendRawIrohFrame(a),c$2("[Connection] Sent internal signal over native-main iroh frame",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:t?.type??null});return}await this.sendOnTransport("iroh",n),c$2("[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,r=n?.sdp&&typeof n.sdp=="object"&&typeof n.sdp.type=="string"?n.sdp.type:null,o=i==="sdp"&&r==="offer",s=this.normalizeNegotiationId(n?.negotiationId);if((i==="sdp"||i==="candidate"||i==="renegotiate")&&console.info("[Connection][WebRTC][signal][recv]",{connectionId:this.id,remoteNodeId:this.remoteNodeId,negotiationId:s??null,signalType:i,sdpType:r,hasSdp:!!n?.sdp?.sdp,hasCandidate:!!n?.candidate,upgradeState:this.upgradeState}),i==="renegotiate"){if(this.isWebRtcDataChannelOpen()){console.info("[Connection] Ignoring WebRTC renegotiate request because transport is already upgraded",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}if(this.upgradeState==="upgrading"&&this.webrtcTransport){console.info("[Connection] Ignoring WebRTC renegotiate request while an upgrade is already in flight",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}}let a=!!s&&!!this.activeNegotiationId&&s!==this.activeNegotiationId,d=i==="sdp"&&o||i==="renegotiate"&&this.upgradeState!=="upgrading"&&this.upgradeState!=="upgraded";if(a&&!d){console.info("[Connection] Ignoring stale WebRTC signal from a previous negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalType:i,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}let u=!!this.activeNegotiationId?.startsWith("native-"),p=o&&!!s?.startsWith(`conn-${this.id}-`);if(a&&d&&this.upgradeState==="upgrading"&&this.preferredWebRtcRole==="responder"&&u&&p){console.info("[Connection] Ignoring reflected WebRTC offer during active native negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,signalNegotiationId:s,activeNegotiationId:this.activeNegotiationId});return}a&&d&&(console.info("[Connection] Switching to a fresh inbound WebRTC negotiation",{connectionId:this.id,remoteNodeId:this.remoteNodeId,priorNegotiationId:this.activeNegotiationId,nextNegotiationId:s,priorState:this.upgradeState,signalType:i}),this.clearUpgradeRetryTimer(),this.upgradeAttemptActive=false,this.upgradeRetryCount=0,this.upgradeTerminalFailure=false,this.pendingSignals=[],this.stopWebRtcHeartbeat(),this.teardownWebRTCTransport()),s&&(!this.activeNegotiationId||a)&&(this.activeNegotiationId=s);let h=!this.webrtcTransport||this.upgradeState==="failed"||a&&this.upgradeState!=="upgrading";if(d&&h&&this.options.rtcConfig&&!this._isClosed){console.info("[Connection] Auto-requesting WebRTC upgrade from incoming signal",{connectionId:this.id,remoteNodeId:this.remoteNodeId,currentState:this.upgradeState,signalType:i,sdpType:r,signalNegotiationId:s,preferredRole:o?"responder":this.preferredWebRtcRole}),o&&(this.preferredWebRtcRole="responder"),this.upgradeRequested=true,this.upgradeTerminalFailure=false,this.pendingSignals=[n],this.attemptUpgrade(s);return}n.transport||(n.transport="webrtc"),this.webrtcTransport?.handleSignalingMessage?this.webrtcTransport.handleSignalingMessage(n):(!s||!this.activeNegotiationId||s===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}};N.textDecoder=new TextDecoder("utf-8",{fatal:true}),N.textEncoder=new TextEncoder,N.UPGRADE_RETRY_DELAY_MS=1e3,N.MAX_UPGRADE_RETRIES=5,N.WEBRTC_DISCONNECTED_GRACE_MS=4e3,N.MAX_PENDING_MESSAGES=256,N.WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS=et+3e3,N.FOREGROUND_PROBE_TIMEOUT_MS=2e3;var te=N;var de=class{constructor(e$1,t){this.appTag=e(e$1),this.backend=t;}get tag(){return this.appTag}async waitForAuth(){return this.backend.waitForAuth()}get currentUser(){return this.backend.currentUser}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 e$1().signInWithPluto();}async signOut(){await this.backend.signOut();}async stopAuthScopedActivity(){typeof this.backend.stopAuthScopedActivity=="function"&&await this.backend.stopAuthScopedActivity();}async getTurnCredentials(){return this.backend.getTurnCredentials()}async updatePresence(e,t,n=true,i=300*1e3,r){await this.backend.updatePresence(e,t,n,i,r);}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(),r=false;return (async()=>{try{for(;!r;){let{done:s,value:a}=await i.read();if(s)break;if(a)for(let d of a)"session"in d&&d.session&&t(d.session);}}catch(s){r||console.error("[Signaling] Session stream error:",s);}})(),()=>{r=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,r){this.backend.startPresenceLoop(e,t,n,i,r);}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 an=6e5,cn=250,ln=20,Me=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,r=>{let o=Date.now(),s=r.docs.map(a=>this.toRoomMember(a)).filter(a=>!!a).filter(a=>a.nodeId!==t).filter(a=>!this.isExpired(a,o)).sort((a,d)=>a.joinedAt!==d.joinedAt?a.joinedAt-d.joinedAt:a.nodeId.localeCompare(d.nodeId));n(s);})}watchMembersWithRtdb(e,t,n,i){let r=this.rtdbPresence,o=this.getAppTag(),s=[],a={},d=()=>{let h=Date.now(),g=s.filter(f=>f.nodeId!==t).filter(f=>!this.isExpired(f,h)).filter(f=>{let v=a[f.nodeId];return !(v&&!v.online)}).sort((f,v)=>f.joinedAt!==v.joinedAt?f.joinedAt-v.joinedAt:f.nodeId.localeCompare(v.nodeId));i(g);},u=this.watchMembersSnapshot(n,h=>{s=h.docs.map(g=>this.toRoomMember(g)).filter(g=>!!g),d();}),p=r.onRoomPresenceChange(o,e,h=>{a=h,d();});return ()=>{u(),p();}}watchMembersSnapshot(e,t){let n=false,i=0,r=null,o=null,s=()=>{n||(o=onSnapshot(e,a=>{i=0,t(a);},a=>{if(o=null,this.isTransientPermissionError(a)&&i<ln){i+=1,r=setTimeout(s,cn);return}console.warn("[BrowserFirestoreRooms] room watch failed:",a);}));};return s(),()=>{n=true,r&&(clearTimeout(r),r=null),o?.(),o=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+an<=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}}};var ue=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 Me({app:e$1().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);}usesDirectRoomBackend(){return this.client.usesDirectRoomBackend()}get roomBackendTag(){return this.client.getRoomBackendTag()}get appTag(){return this.signaling.tag}async invokeRoomCallable(e,t){let{getFunctions:n,httpsCallable:i}=await import('firebase/functions'),r=n(e$1().getApp());return (await i(r,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")}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");let t=await this.client.getTicket(),n=await this.client.getNodeId(),i=this.signaling.currentUser?.id??n??"anonymous";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="",u=false,p=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",h=p?1:3;for(let g=0;g<h;g+=1){if(p)d=p;else {let f=new Uint8Array(6);crypto.getRandomValues(f),d=Array.from(f,v=>v.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}try{await this.invokeRoomCallable("createClientRoom",{appTag:this.appTag,roomId:d,nodeId:n,ticket:t}),u=!0;break}catch(f){if(this.isAlreadyExistsError(f)){if(p)throw f;continue}throw f}}if(!u)throw new Error(p?`Failed to create requested room "${p}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(d,n),d}let r="",o=false,s=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",a=s?1:3;for(let d=0;d<a;d++){if(s)r=s;else {let p=new Uint8Array(6);crypto.getRandomValues(p),r=Array.from(p,h=>h.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}await this.client.refreshHostedAppSettings();let u=this.client.appLimits.maxMembersPerRoom>=0?this.client.appLimits.maxMembersPerRoom:50;if(o=await this.client.wasmClient.create_room(r,i,t,n,this.roomBackendTag,u),o){console.log(`Room created: ${r}`);break}else {if(s)throw new Error(`Room "${r}" already exists.`);console.log(`Collision for roomId ${r}, retrying...`);}}if(!o)throw new Error(s?`Failed to create requested room "${s}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.registerRtdbRoomMember(r,n),r}async joinRoom(e,t={}){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");if(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(),r=this.signaling.currentUser?.id??i??"anonymous",o=e.toUpperCase(),s=e==="demo"?"demo":e;console.log("[RoomManager] joinRoom request",{roomId:e,normalizedId:o,targetRoomId:s,tag:this.roomBackendTag,userId:r,myNodeId:i,hasTicket:!!n,ticketLength:n?.length||0});try{this.usesDirectRoomBackend()?await this.client.wasmClient.join_room(s,r,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(d){throw b$1("[RoomManager] joinRoom failed",d),d}let a=[];if(t.bootstrapPeers!==false){let u=(await this.getMembersInternal(s,i)).map(async h=>{let g=false,f=Date.now();if(h.expiresAt)h.expiresAt<f&&(g=true);else {let v=h.lastSeenAt||h.joinedAt||0;f-v>300*1e3&&(g=true);}if(g)return null;if(h.ticket)try{console.log(`Bootstrapping: Connecting to peer ${h.nodeId}...`);let v=await this.client.connect(h.ticket,5e3);return v.send({type:"chat",text:`Use ${r} joined the room.`}),v}catch(v){return console.warn(`Failed to connect to peer ${h.nodeId}:`,v),null}return null});(await Promise.allSettled(u)).forEach(h=>{h.status==="fulfilled"&&h.value&&a.push(h.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=e==="demo"?"demo":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=e==="demo"?"demo":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 r=e==="demo"?"demo":e,o=await this.client.getNodeId();if(n)return;i=this.getBrowserRooms().watchMembers(r,o,t),n&&(i(),i=null);}catch(r){n||console.warn("[RoomManager] watchRoom listener failed:",r);}})(),()=>{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){console.warn("[RoomManager] RTDB room member register failed:",i);}this.heartbeatStops.set(e,()=>{this.markRtdbRoomMemberOffline(e,t);});}else this.startLegacyHeartbeat(e,t);}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);}}startLegacyHeartbeat(e,t){let n=setInterval(()=>{this.client.wasmClient&&this.client.wasmClient.heartbeat_tick(e,t,this.roomBackendTag).catch(console.error);},3e5);this.heartbeatStops.set(e,()=>clearInterval(n));}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();}};var F=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)}},O=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=BigInt(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}},Ne=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 Ee=0,dn=1;function rt(l,e){let t=new TextEncoder().encode(e);l.writeVarInt(1),l.writeVarInt(t.length),l.writeBytes(t);}function ot(l){let e=Number(l.readVarInt()),t=[];for(let n=0;n<e;n++){let i=Number(l.readVarInt()),r=l.readBytes(i);t.push(new TextDecoder().decode(r));}return t.join("/")}var pe=class{static serialize(e){let t=new O;switch(e.type){case 64:{let r=e;t.writeVarInt(r.supportedVersions.length);for(let a of r.supportedVersions)t.writeVarInt(a);let o=new O,s=0;r.role!==void 0&&(s++,o.writeVarInt(Ee),o.writeVarInt(1),o.writeVarInt(r.role)),t.writeVarInt(s),t.writeBytes(o.toUint8Array());break}case 65:{let r=e;t.writeVarInt(r.selectedVersion);let o=new O,s=0;r.role!==void 0&&(s++,o.writeVarInt(Ee),o.writeVarInt(1),o.writeVarInt(r.role)),t.writeVarInt(s),t.writeBytes(o.toUint8Array());break}case 3:{let r=e;t.writeVarInt(r.subscribeId),t.writeVarInt(r.trackAlias),rt(t,r.trackNamespace);let o=new TextEncoder().encode(r.trackName);t.writeVarInt(o.length),t.writeBytes(o),t.writeUint8(r.subscriberPriority??128),t.writeUint8(r.groupOrder??1),r.startGroup!==void 0&&r.startObject!==void 0&&r.endGroup!==void 0&&r.endObject!==void 0?(t.writeVarInt(4),t.writeVarInt(r.startGroup),t.writeVarInt(r.startObject),t.writeVarInt(r.endGroup),t.writeVarInt(r.endObject)):r.startGroup!==void 0&&r.startObject!==void 0?(t.writeVarInt(3),t.writeVarInt(r.startGroup),t.writeVarInt(r.startObject)):t.writeVarInt(1),t.writeVarInt(0);break}case 4:{let r=e;t.writeVarInt(r.subscribeId),t.writeVarInt(r.expires),t.writeUint8(1),t.writeUint8(0),t.writeVarInt(0);break}case 6:{rt(t,e.trackNamespace),t.writeVarInt(0);break}case 7:{rt(t,e.trackNamespace);break}}let n=t.toUint8Array(),i=new O;return i.writeVarInt(e.type),i.writeVarInt(n.length),i.writeBytes(n),i.toUint8Array()}static deserialize(e){if(!e.peekVarInt())return null;try{e.checkpoint();let n=Number(e.readVarInt()),i=Number(e.readVarInt());if(console.log(`[MoQ] Deserializing msg type=0x${n.toString(16)}, length=${i}`),!e.has(i))return e.rewind(),null;let r;switch(n){case 65:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=0;for(let d=0;d<s;d++){let u=Number(e.readVarInt()),p=Number(e.readVarInt()),h=e.readBytes(p);if(u===Ee){let g=new F;g.append(h),a=Number(g.readVarInt());}}r={type:n,selectedVersion:o,role:a};break}case 3:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=ot(e),d=Number(e.readVarInt()),u=e.readBytes(d),p=new TextDecoder().decode(u);e.readUint8(),e.readUint8();let h=Number(e.readVarInt()),g,f,v,I;h===3?(g=Number(e.readVarInt()),f=Number(e.readVarInt())):h===4&&(g=Number(e.readVarInt()),f=Number(e.readVarInt()),v=Number(e.readVarInt()),I=Number(e.readVarInt()));let _=Number(e.readVarInt());for(let M=0;M<_;M++){let k=Number(e.readVarInt()),w=Number(e.readVarInt());e.readBytes(w);}r={type:n,subscribeId:o,trackAlias:s,trackNamespace:a,trackName:p,startGroup:g,startObject:f};break}case 4:{let o=Number(e.readVarInt()),s=Number(e.readVarInt());e.readUint8(),e.readUint8()===1&&(e.readVarInt(),e.readVarInt());let d=Number(e.readVarInt());for(let u=0;u<d;u++){let p=Number(e.readVarInt()),h=Number(e.readVarInt());e.readBytes(h);}r={type:n,subscribeId:o,expires:s};break}case 7:{let o=ot(e);r={type:n,trackNamespace:o};break}case 8:{let o=ot(e),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d);console.warn(`[MoQ] ANNOUNCE_ERROR: ns=${o} code=${s} reason=${u}`),r={type:n,trackNamespace:o,code:s,reason:u};break}case 21:{let o=Number(e.readVarInt());console.log(`[MoQ] MAX_SUBSCRIBE_ID: ${o}`),r={type:n,subscribeId:o};break}case 5:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d),p=Number(e.readVarInt());console.warn(`[MoQ] SUBSCRIBE_ERROR: id=${o} code=${s} reason=${u} alias=${p}`),r={type:n,subscribeId:o,code:s,reason:u};break}case 16:{let o=Number(e.readVarInt());e.readBytes(o),console.warn("[MoQ] GOAWAY received"),r={type:n};break}case 64:{let o=Number(e.readVarInt()),s=[];for(let p=0;p<o;p++)s.push(Number(e.readVarInt()));let a=Number(e.readVarInt()),d=0,u;for(let p=0;p<a;p++){let h=Number(e.readVarInt()),g=Number(e.readVarInt()),f=e.readBytes(g);if(h===Ee){let v=new F;v.append(f),d=Number(v.readVarInt());}else h===dn&&(u=new TextDecoder().decode(f));}r={type:n,supportedVersions:s,role:d,path:u};break}case 10:{let o=Number(e.readVarInt());console.log(`[MoQ] UNSUBSCRIBE for id=${o}`),r={type:n,subscribeId:o};break}case 11:{let o=Number(e.readVarInt()),s=Number(e.readVarInt()),a=Number(e.readVarInt()),d=e.readBytes(a),u=new TextDecoder().decode(d),p,h;e.readUint8()===1&&(p=Number(e.readVarInt()),h=Number(e.readVarInt())),console.log(`[MoQ] SUBSCRIBE_DONE for id=${o} code=${s} reason=${u}`),r={type:n,subscribeId:o,code:s,reason:u,finalGroup:p,finalObject:h};break}default:{console.warn(`[MoQ] Unknown MsgType: 0x${n.toString(16)}, skipping ${i} bytes`),e.readBytes(i),r={type:n};break}}return e.commit(),r}catch(n){if(n.message==="EOF")return e.rewind(),null;throw n}}};var De=class{constructor(e){this.tracks=new Map;this.activePublishers=new Map;this.pendingAnnounces=new Map;this.session=e;}async announce(e){console.log(`[MoQ] Announcing namespace: ${e}`);let t={type:6,trackNamespace:e,params:{}};return new Promise(async(n,i)=>{this.pendingAnnounces.set(e,{resolve:n,reject:i});let r=setTimeout(()=>{this.pendingAnnounces.has(e)&&(this.pendingAnnounces.delete(e),i(new Error("Announce timed out")));},5e3);try{await this.session.sendControlMessage(t);}catch(o){clearTimeout(r),this.pendingAnnounces.delete(e),i(o);}})}onAnnounceResult(e,t){let n=this.pendingAnnounces.get(e);n&&(this.pendingAnnounces.delete(e),t?n.reject(new Error(`Announce failed: code=${t.code} reason=${t.reason}`)):n.resolve());}onSubscribe(e){let t=`${e.trackNamespace}/${e.trackName}`;console.log(`[MoQ] Publisher received SUBSCRIBE for ${t} -> subId=${e.subscribeId} alias=${e.trackAlias}`),this.tracks.set(t,{subscribeId:e.subscribeId,trackAlias:e.trackAlias});}onUnsubscribe(e){for(let[t,n]of this.tracks.entries())if(n.subscribeId===e){console.log(`[MoQ] Publisher received UNSUBSCRIBE for ${t} (subId=${e})`),this.tracks.delete(t);break}}async createTrack(e,t){let n=`${e}/${t}`;if(this.activePublishers.has(n))return this.activePublishers.get(n);let i=null,r=0,o=0,s=new Ne,a=()=>{if(i){let h=i;i=null,h.close().catch(()=>{});}},d=()=>{console.log(`[MoQ] Stopping publisher for ${n}`),a(),this.activePublishers.delete(n);},u=async()=>{a(),r++,o=0;let h=this.tracks.get(n);if(h===void 0)return;let{subscribeId:g,trackAlias:f}=h,I=(await this.session.transport.createUnidirectionalStream()).getWriter();r<=2&&console.log(`[MoQ] Opening Group ${r} for ${n} (subId=${g} alias=${f})`);let _=new O;_.writeVarInt(4),_.writeVarInt(g),_.writeVarInt(f),_.writeVarInt(r),_.writeVarInt(0),_.writeUint8(0),await I.write(_.toUint8Array()),i=I;},p={close:d,push:async(h,g)=>{await s.dispatch(async()=>{if(!this.tracks.has(n))return;if(g.isKey)await u();else if(!i)return;if(!i)return;let f=new O;if(f.writeVarInt(o++),f.writeVarInt(h.length),f.writeBytes(h),i)try{await i.write(f.toUint8Array());}catch(v){(v.message||"").includes("STOP_SENDING")||v.name==="WebTransportError"?(console.warn(`[MoQ] Group stream closed by remote (STOP_SENDING) for ${n}.`),i=null):console.error(`[MoQ] Writer error for ${n}:`,v);}});}};return this.activePublishers.set(n,p),p}};var Le=class{constructor(e,t){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;}async subscribe(e,t){let n=this.nextAlias++,i=this.nextSubscribeId++;this.aliasMap.set(n,{namespace:e,name:t}),console.log(`[MoQ] Subscribing to ${e}/${t} with Alias ${n} ID ${i}`);let r={type:3,subscribeId:i,trackAlias:n,trackNamespace:e,trackName:t};this.pendingSubscriptions.set(i,{namespace:e,name:t,trackAlias:n}),this.activeSubscriptions.set(i,n),await this.session.sendControlMessage(r);}onSubscribeOk(e){this.pendingSubscriptions.delete(e);}async onSubscribeError(e,t){let n=this.pendingSubscriptions.get(e);if(this.pendingSubscriptions.delete(e),!!n&&t===404){console.log(`[MoQ] Will retry subscription to ${n.namespace}/${n.name} in 2s...`),await new Promise(o=>setTimeout(o,2e3));let i=this.nextSubscribeId++,r={type:3,subscribeId:i,trackAlias:n.trackAlias,trackNamespace:n.namespace,trackName:n.name};this.pendingSubscriptions.set(i,n),console.log(`[MoQ] Retrying subscription to ${n.namespace}/${n.name} with ID ${i}`),await this.session.sendControlMessage(r);}}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",r=n?n.name:"unknown";for(;;){let o=t.groups.get(t.nextDeliverGroupId);if(o){for(;o.frames.length>0;){let s=o.frames.shift();this.onObject(i,r,s.payload,{groupId:s.groupId,objectId:s.objectId});}if(o.done){t.groups.delete(t.nextDeliverGroupId),t.nextDeliverGroupId++;continue}}else {let s=null;for(let a of t.groups.keys())a>t.nextDeliverGroupId&&(s===null||a<s)&&(s=a);if(s!==null&&s>t.nextDeliverGroupId+1){console.warn(`[MoQ] Skipping missing group ${t.nextDeliverGroupId}, jumping to ${s}`),t.nextDeliverGroupId=s;continue}}await new Promise(s=>{t.notifyResolve=s;});}}async handleIncomingUniStream(e){let t=e.getReader(),n=new F,i=-1,r=-1,o=null;try{for(;;){let{done:a,value:d}=await t.read();if(a)return;d&&n.append(d);try{n.checkpoint();let u=Number(n.readVarInt()),p=Number(n.readVarInt());i=Number(n.readVarInt()),r=Number(n.readVarInt()),n.readVarInt(),n.readUint8(),n.commit();break}catch(u){if(u.message==="EOF"){n.rewind();continue}throw u}}let s=this.deliveryState.get(i);if(s||(s={groups:new Map,nextDeliverGroupId:r,notifyResolve:null,loopRunning:!1},this.deliveryState.set(i,s)),r<s.nextDeliverGroupId){t.cancel().catch(()=>{});return}for(o={frames:[],done:!1},s.groups.set(r,o),s.loopRunning||(s.loopRunning=!0,this.runDeliveryLoop(i));;){if(!n.has(1)){let{done:a,value:d}=await t.read();if(a)break;d&&n.append(d);}try{n.checkpoint();let a=Number(n.readVarInt()),d=Number(n.readVarInt()),u=n.readBytes(d);n.commit(),o.frames.push({payload:u,groupId:r,objectId:a}),this.wakeDelivery(i);}catch(a){if(a.message==="EOF"){n.rewind();let{done:d,value:u}=await t.read();if(d)break;u&&n.append(u);continue}throw a}}}catch(s){console.error("Subscriber Stream Error",s);}finally{o&&(o.done=true,this.wakeDelivery(i));}}};var xe=class{constructor(e,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 F;this.transport=e,this.role=n,this.setupPromise=new Promise(i=>{this.setupResolve=i;}),this.publisher=new De(this),this.subscriber=new Le(this,t||((i,r,o,s)=>console.log(`[MoQ] Object: ${i}/${r}`,s)));}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=pe.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="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&&(console.log(`[MoQ] Control Stream RX: ${n.byteLength} bytes`),this.streamBuffer.append(n),this.processBuffer());}}catch(t){e=t,this.closed||console.error("Control stream error",t);}finally{this.emitClose(e);}console.log("[MoQ] Read Loop Exited");}processBuffer(){for(;;){let e;try{e=pe.deserialize(this.streamBuffer);}catch(t){console.error("[MoQ] Deserialization Error:",t);break}if(!e)break;this.handleControlMessage(e);}}handleControlMessage(e){switch(e.type){case 65:console.log(`[MoQ] Handshake Complete. Server selected version: 0x${e.selectedVersion.toString(16)}`),this.setupComplete=true,this.setupResolve&&(this.setupResolve(),this.setupResolve=null);break;case 21:this.maxSubscribeId=e.subscribeId,console.log(`[MoQ] Max Subscribe ID updated: ${this.maxSubscribeId}`);break;case 3:this.publisher.onSubscribe(e);let t={type:4,subscribeId:e.subscribeId,expires:0};this.sendControlMessage(t).catch(console.error);break;case 4:console.log(`[MoQ] SUBSCRIBE_OK for id=${e.subscribeId}`),this.subscriber.onSubscribeOk(e.subscribeId);break;case 5:console.error(`[MoQ] SUBSCRIBE_ERROR for id=${e.subscribeId} code=${e.code}`),this.subscriber.onSubscribeError(e.subscribeId,e.code).catch(console.error);break;case 7:console.log(`[MoQ] ANNOUNCE_OK for ns=${e.trackNamespace}`),this.publisher.onAnnounceResult(e.trackNamespace);break;case 8:console.error(`[MoQ] ANNOUNCE_ERROR for ns=${e.trackNamespace} code=${e.code}`),this.publisher.onAnnounceResult(e.trackNamespace,{code:e.code,reason:e.reasonPhrase||"Unknown"});break;case 10:this.publisher.onUnsubscribe(e.subscribeId);break;case 11:this.subscriber.onSubscribeDone(e.subscribeId,e.code,e.reason);break;case 16:console.warn("[MoQ] GOAWAY received");break;default:console.log(`[MoQ] Received Control Message type=0x${e.type.toString(16)}`);}}};function Y(l){if(!l)return null;let e=l.trim();return e?e.toLowerCase():null}function st(l){return l.deviceId||l.deviceIdHint||l.peerId||null}function Ue(l){return [...l].sort()}function ne(l,e){return l?l.peerId===e.peerId&&(l.deviceId??null)===(e.deviceId??null)&&(l.deviceIdHint??null)===(e.deviceIdHint??null)&&(l.nodeId??null)===(e.nodeId??null)&&(l.connectionId??null)===(e.connectionId??null)&&(l.ticket??null)===(e.ticket??null)&&!!l.online==!!e.online&&(l.deviceName??null)===(e.deviceName??null)&&(l.platformType??null)===(e.platformType??null)&&l.status===e.status&&l.health===e.health&&(l.transportState??null)===(e.transportState??null)&&(l.protocolState??null)===(e.protocolState??null)&&!!l.routable==!!e.routable&&(l.activeTransportStableId??null)===(e.activeTransportStableId??null)&&(l.transportGeneration??null)===(e.transportGeneration??null)&&(l.activeTransport??null)===(e.activeTransport??null)&&(l.parallelTransport??null)===(e.parallelTransport??null)&&(l.promotionEligible??true)===(e.promotionEligible??true)&&(l.error??null)===(e.error??null)&&JSON.stringify(Ue(l.connectionIds))===JSON.stringify(Ue(e.connectionIds))&&JSON.stringify(Ue(l.scopes))===JSON.stringify(Ue(e.scopes)):false}function Dt(l){return l==="closed"||l==="disconnected"||l==="failed"}function un(l){return Dt(l.status)?l.status:l.routable===true||l.protocolState==="routable"?"connected":l.status}var Be=class{constructor(){this.peers=new Map;this.aliases=new Map;this.watchers=new Set;}resolveCanonicalPeerId(e){let t=[e.deviceId,e.deviceIdHint,e.nodeId,e.peerId,e.connectionId];for(let n of t){let i=Y(n);if(!i)continue;let r=this.aliases.get(i);if(r)return r}return st(e)}setAlias(e,t){let n=Y(e);n&&this.aliases.set(n,t);}snapshot(e){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:un(e),health:e.health,transportState:e.transportState,protocolState:e.protocolState,routable:e.routable,activeTransportStableId:e.activeTransportStableId,transportGeneration:e.transportGeneration,activeTransport:e.activeTransport,parallelTransport:e.parallelTransport,promotionEligible:e.promotionEligible,scopes:Array.from(e.scopes.values()),lastSeenAt:e.lastSeenAt,error:e.error}}emit(){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,r]of this.aliases.entries())r===e&&this.aliases.set(i,t);return n}upsert(e){let t=this.resolveCanonicalPeerId(e)??st(e);if(!t)throw new Error("Peer projection upsert requires a device-keyed identifier.");let n=st(e)??t,i=this.peers.get(t),r=!!i;i||(i={peerId:t,connectionIds:new Set,status:e.status??"disconnected",health:e.health??"unknown",scopes:new Set},this.peers.set(t,i));let o=r?this.snapshot(i):void 0;if(n!==i.peerId){let u=e.deviceId||i.deviceId||e.deviceIdHint||i.deviceIdHint||e.nodeId||i.nodeId||i.peerId;u&&u!==i.peerId&&(i=this.rekeyPeer(i.peerId,u));}e.deviceId&&(i.deviceId=e.deviceId),e.deviceIdHint!==void 0&&(i.deviceIdHint=e.deviceIdHint),e.nodeId&&(i.nodeId=e.nodeId),e.connectionId&&(i.connectionId=e.connectionId,i.connectionIds.add(e.connectionId)),e.ticket!==void 0&&(i.ticket=e.ticket),e.online!==void 0&&(i.online=e.online),e.deviceName!==void 0&&(i.deviceName=e.deviceName),e.platformType!==void 0&&(i.platformType=e.platformType);let s=r&&Dt(i.status)&&typeof i.error=="string"&&i.error.toLowerCase().includes("manual disconnect"),a=e.status==="connected"||e.status==="connecting"||e.routable===true||e.protocolState==="routable"||e.transportState==="connected"||e.activeTransport!==void 0||e.parallelTransport!==void 0;if(s&&a&&!e.clearError){let u=this.snapshot(i);return ne(o,u)||this.emit(),u}if(e.status&&(i.status=e.status),e.health&&(i.health=e.health),e.transportState!==void 0&&(i.transportState=e.transportState),e.protocolState!==void 0&&(i.protocolState=e.protocolState),e.routable!==void 0&&(i.routable=e.routable),e.activeTransportStableId!==void 0&&(i.activeTransportStableId=e.activeTransportStableId),e.transportGeneration!==void 0&&(i.transportGeneration=e.transportGeneration),e.activeTransport!==void 0&&(i.activeTransport=e.activeTransport),e.parallelTransport!==void 0&&(i.parallelTransport=e.parallelTransport),e.promotionEligible!==void 0&&(i.promotionEligible=e.promotionEligible),e.clearError?i.error=void 0:e.error!==void 0&&(i.error=e.error),e.lastSeenAt!==void 0&&(i.lastSeenAt=e.lastSeenAt),e.scopes)for(let u of e.scopes)i.scopes.add(u);(i.status==="closed"||i.status==="failed"||i.status==="disconnected")&&(i.routable=false,i.activeTransportStableId=null,i.activeTransport=void 0,i.parallelTransport=null,(!i.transportState||i.transportState==="connected")&&(i.transportState="closed"),(!i.protocolState||i.protocolState==="routable")&&(i.protocolState="closed")),this.setAlias(i.peerId,i.peerId),this.setAlias(i.deviceId,i.peerId),this.setAlias(i.deviceIdHint,i.peerId),this.setAlias(i.nodeId,i.peerId),this.setAlias(i.connectionId,i.peerId);for(let u of i.connectionIds)this.setAlias(u,i.peerId);let d=this.snapshot(i);return ne(o,d)||this.emit(),d}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.watchers.add(e),e(this.list()),()=>{this.watchers.delete(e);}}get(e){let t=Y(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 r=this.snapshot(n);return ne(i,r)||this.emit(),r}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 r=this.snapshot(n);return ne(i,r)||this.emit(),r}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=Y(e);if(i){let o=Array.from(t.connectionIds).find(s=>Y(s)===i);o&&t.connectionIds.delete(o);}t.connectionId&&Y(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 r=this.snapshot(t);return ne(n,r)||this.emit(),r}updateHealth(e,t,n){let i=this.resolveRecord(e);if(!i)return;let r=this.snapshot(i);i.health=t,n&&(i.status=n),i.lastSeenAt=Date.now();let o=this.snapshot(i);return ne(r,o)||this.emit(),o}resolveRecord(e){let t=Y(e),n=t?this.aliases.get(t):void 0;return n&&this.peers.get(n)||this.peers.get(e)}};var Oe=class{constructor(e,t){this.peerLifecycle=e;this.deps=t;}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.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.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}};function J(){if(typeof navigator>"u")return false;let l=navigator.userAgent||"",e=navigator.userAgentData?.platform||navigator.platform||"";return /iPhone|iPad|iPod|Android|Mobile|CriOS|FxiOS/i.test(`${l} ${e}`)}function We(){return typeof window>"u"?false:new URLSearchParams(window.location.search).has("ticket")}function Lt(l){return l?l.routing==="stream-envelope"&&l.readiness==="transport-only":false}function at(l){let e=l.signalingMode??"hosted",t=J(),n=We(),i=e==="ticket-only",r=t&&n;return {flow:i?"ticket-only":"default",signalingMode:e,mobileBrowser:t,ticketQueryPresent:n,diagnosticsMode:r,skipIncomingBiProbe:r,skipIncomingChannelEnvelopeInspection:r,readerCloseStrategy:r?"release-lock":"cancel"}}var pn="trustedDevice",xt="plutonium:e2ee:identity:v1";function ie(l){let e=atob(l),t=new Uint8Array(e.length);for(let n=0;n<e.length;n+=1)t[n]=e.charCodeAt(n);return t}function Fe(l){let e="";for(let t=0;t<l.length;t+=1)e+=String.fromCharCode(l[t]);return btoa(e)}async function Ut(l){let e=await crypto.subtle.digest("SHA-256",l),t=new Uint8Array(e);return Array.from(t).map(n=>n.toString(16).padStart(2,"0")).join("")}function Bt(l=32){let e=crypto.getRandomValues(new Uint8Array(l));return Fe(e)}function Ot(l,e){let t=He.sign.detached(ie(l),e);return Fe(t)}function Wt(l,e,t){try{return He.sign.detached.verify(ie(l),ie(e),ie(t))}catch{return false}}function Ft(l){if(!l||!l.trim())return null;try{let e=JSON.parse(l),t=e&&typeof e=="object"&&!Array.isArray(e)?e[pn]:null;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t,i=typeof n.version=="number"?n.version:null,r=typeof n.identityPublicKey=="string"?n.identityPublicKey:null,o=typeof n.identityFingerprint=="string"?n.identityFingerprint:null;return !i||!r||!o?null:{version:i,identityPublicKey:r,identityFingerprint:o}}catch{return null}}async function hn(){if(typeof localStorage>"u")return null;let l=localStorage.getItem(xt);if(!l)return null;try{let e=JSON.parse(l);if(typeof e.publicKey!="string"||typeof e.secretKey!="string")return null;let t=ie(e.publicKey),n=ie(e.secretKey),i=await Ut(t);return {publicKey:t,secretKey:n,fingerprint:i}}catch{return null}}async function ct(){let l=await hn();if(l)return l;if(typeof localStorage>"u")return null;try{let e=He.sign.keyPair(),t={publicKey:Fe(e.publicKey),secretKey:Fe(e.secretKey)};localStorage.setItem(xt,JSON.stringify(t));let n=await Ut(e.publicKey);return {publicKey:e.publicKey,secretKey:e.secretKey,fingerprint:n}}catch{return null}}var fe=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,Ht.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Ht.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_bistream_free(e,0);}get endpoint_id(){let e,t;try{let n=c.bistream_endpoint_id(this.__wbg_ptr);return e=n[0],t=n[1],E(n[0],n[1])}finally{c.__wbindgen_free(e,t,1);}}get recv(){return c.bistream_recv(this.__wbg_ptr)}get send(){return c.bistream_send(this.__wbg_ptr)}};Symbol.dispose&&(fe.prototype[Symbol.dispose]=fe.prototype.free);var me=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,Gt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,Gt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_intounderlyingsink_free(e,0);}abort(e){let t=this.__destroy_into_raw();return c.intounderlyingsink_abort(t,e)}close(){let e=this.__destroy_into_raw();return c.intounderlyingsink_close(e)}write(e){return c.intounderlyingsink_write(this.__wbg_ptr,e)}};Symbol.dispose&&(me.prototype[Symbol.dispose]=me.prototype.free);var be=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,qt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,qt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_intounderlyingsource_free(e,0);}cancel(){let e=this.__destroy_into_raw();c.intounderlyingsource_cancel(e);}pull(e){return c.intounderlyingsource_pull(this.__wbg_ptr,e)}};Symbol.dispose&&(be.prototype[Symbol.dispose]=be.prototype.free);var oe=class l{static __wrap(e){let t=Object.create(l.prototype);return t.__wbg_ptr=e,lt.register(t,t.__wbg_ptr,t),t}__destroy_into_raw(){let e=this.__wbg_ptr;return this.__wbg_ptr=0,lt.unregister(this),e}free(){let e=this.__destroy_into_raw();c.__wbg_wasmclient_free(e,0);}add_peer_scope(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_add_peer_scope(this.__wbg_ptr,n,i,r,o)}bind_connection_device_id(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_bind_connection_device_id(this.__wbg_ptr,n,i,r,o)}clear_session_tokens(){c.wasmclient_clear_session_tokens(this.__wbg_ptr);}connect(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_connect(this.__wbg_ptr,t,n)}connect_device(e,t){var n=P(e)?0:b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;let r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_connect_device(this.__wbg_ptr,n,i,r,o)}connection_state(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_connection_state(this.__wbg_ptr,t,n)}connection_states(){return c.wasmclient_connection_states(this.__wbg_ptr)}create_room(e,t,n,i,r,o){let s=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m,d=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m,p=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m,g=b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),f=m,v=b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),I=m;return c.wasmclient_create_room(this.__wbg_ptr,s,a,d,u,p,h,g,f,v,I,P(o)?Number.MAX_SAFE_INTEGER:o>>>0)}create_session(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_create_session(this.__wbg_ptr,t,n)}delete_device(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_delete_device(this.__wbg_ptr,n,i,r,o)}devices_with_status(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_devices_with_status(this.__wbg_ptr,t,n)}disconnect(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_disconnect(this.__wbg_ptr,t,n)}disconnect_device(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;var r=P(t)?0:b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_disconnect_device(this.__wbg_ptr,n,i,r,o)}endpoint_id_from_ticket(e){let t,n;try{let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=c.wasmclient_endpoint_id_from_ticket(this.__wbg_ptr,o,s);var i=a[0],r=a[1];if(a[3])throw i=0,r=0,$(a[2]);return t=i,n=r,E(i,r)}finally{c.__wbindgen_free(t,n,1);}}endpoint_ticket(){return c.wasmclient_endpoint_ticket(this.__wbg_ptr)}endpoint_ticket_with_token(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_endpoint_ticket_with_token(this.__wbg_ptr,n,i,t)}force_reconnect_snapshot(){c.wasmclient_force_reconnect_snapshot(this.__wbg_ptr);}get_members(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_get_members(this.__wbg_ptr,i,r,o,s,a,d)}heartbeat_tick(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_heartbeat_tick(this.__wbg_ptr,i,r,o,s,a,d)}incoming_streams(){return c.wasmclient_incoming_streams(this.__wbg_ptr)}init_iroh(e){var t=P(e)?0:$t(e,c.__wbindgen_malloc),n=m;return c.wasmclient_init_iroh(this.__wbg_ptr,t,n)}iroh_path_kind(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_iroh_path_kind(this.__wbg_ptr,t,n)}iroh_secret_key(){return c.wasmclient_iroh_secret_key(this.__wbg_ptr)}is_auto_connect_excluded(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_is_auto_connect_excluded(this.__wbg_ptr,t,n)!==0}is_connected(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_is_connected(this.__wbg_ptr,t,n)}join_room(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m,u=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m,h=b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m,f=b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),v=m;return c.wasmclient_join_room(this.__wbg_ptr,o,s,a,d,u,p,h,g,f,v)}leave_room(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_leave_room(this.__wbg_ptr,i,r,o,s,a,d)}list_managed_connections(){return c.wasmclient_list_managed_connections(this.__wbg_ptr)}constructor(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=c.wasmclient_new(n,i,r,o);if(s[2])throw $(s[1]);return this.__wbg_ptr=s[0],lt.register(this,this.__wbg_ptr,this),this}static newWithAppTag(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=c.wasmclient_newWithAppTag(n,i,r,o);if(s[2])throw $(s[1]);return l.__wrap(s[0])}node_addr(){return c.wasmclient_node_addr(this.__wbg_ptr)}open_bi(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_open_bi(this.__wbg_ptr,t,n)}open_peer_bi(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_bi(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_peer_bi_transport_only(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_bi_transport_only(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_peer_uni(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_open_peer_uni(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}open_uni(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_open_uni(this.__wbg_ptr,t,n)}peer_scopes(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_scopes(this.__wbg_ptr,t,n)}peer_session(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_session(this.__wbg_ptr,t,n)}peer_sessions(){return c.wasmclient_peer_sessions(this.__wbg_ptr)}peer_snapshot(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_peer_snapshot(this.__wbg_ptr,t,n)}peer_snapshots(){return c.wasmclient_peer_snapshots(this.__wbg_ptr)}present_session_token_to_host(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_present_session_token_to_host(this.__wbg_ptr,n,i,r,o)}register_session_token(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;c.wasmclient_register_session_token(this.__wbg_ptr,i,r,o,s,n);}release_peer_scope(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;var r=P(t)?0:b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_release_peer_scope(this.__wbg_ptr,n,i,r,o)}report_managed_connection_settled(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;var o=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;return c.wasmclient_report_managed_connection_settled(this.__wbg_ptr,i,r,t,o,s)}report_transport_status(e,t,n){let i=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m,o=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;var a=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;return c.wasmclient_report_transport_status(this.__wbg_ptr,i,r,o,s,a,d)}resolve_peer_connection_records(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_resolve_peer_connection_records(this.__wbg_ptr,t,n)}revoke_session_token(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;c.wasmclient_revoke_session_token(this.__wbg_ptr,t,n);}revoke_tokens_by_scope(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_revoke_tokens_by_scope(this.__wbg_ptr,t,n)}runtime_policy(){let e=c.wasmclient_runtime_policy(this.__wbg_ptr);if(e[2])throw $(e[1]);return $(e[0])}same_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_same_peer(this.__wbg_ptr,n,i,r,o)}search_devices(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_search_devices(this.__wbg_ptr,t,n)}send_message(e,t,n,i){let r=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m;var d=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m,p=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m;return c.wasmclient_send_message(this.__wbg_ptr,r,o,s,a,d,u,p,h)}send_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=$t(t,c.__wbindgen_malloc),o=m;return c.wasmclient_send_peer(this.__wbg_ptr,n,i,r,o)}set_auth_token(e){var t=P(e)?0:b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;c.wasmclient_set_auth_token(this.__wbg_ptr,t,n);}set_auto_connect_excluded(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_set_auto_connect_excluded(this.__wbg_ptr,n,i,t)}set_offline(e){let t=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),n=m;return c.wasmclient_set_offline(this.__wbg_ptr,t,n)}start_auto_connect(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;c.wasmclient_start_auto_connect(this.__wbg_ptr,n,i,r,o);}start_presence_loop(e,t,n,i){let r=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m,s=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),a=m,d=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),u=m;var p=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),h=m;c.wasmclient_start_presence_loop(this.__wbg_ptr,r,o,s,a,d,u,p,h);}stop_auth_scoped_activity(){c.wasmclient_stop_auth_scoped_activity(this.__wbg_ptr);}stop_auto_connect(){c.wasmclient_stop_auto_connect(this.__wbg_ptr);}stop_presence_loop(){c.wasmclient_stop_presence_loop(this.__wbg_ptr);}update_device(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m;var u=P(n)?0:b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m,h=P(r)?0:b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m;return c.wasmclient_update_device(this.__wbg_ptr,o,s,a,d,u,p,P(i)?0:H(i),h,g)}update_presence(e,t,n,i,r){let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),d=m,u=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),p=m;var h=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),g=m;return c.wasmclient_update_presence(this.__wbg_ptr,o,s,a,d,u,p,h,g,!P(r),P(r)?BigInt(0):r)}update_session(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_update_session(this.__wbg_ptr,n,i,r,o)}validate_session_token(e){let t,n;try{let o=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m,a=c.wasmclient_validate_session_token(this.__wbg_ptr,o,s);var i=a[0],r=a[1];if(a[3])throw i=0,r=0,$(a[2]);return t=i,n=r,E(i,r)}finally{c.__wbindgen_free(t,n,1);}}validate_session_token_for_connection(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m,r=b(t,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;return c.wasmclient_validate_session_token_for_connection(this.__wbg_ptr,n,i,r,o)}wait_for_settled_peer(e,t){let n=b(e,c.__wbindgen_malloc,c.__wbindgen_realloc),i=m;return c.wasmclient_wait_for_settled_peer(this.__wbg_ptr,n,i,P(t)?Number.MAX_SAFE_INTEGER:t>>>0)}};Symbol.dispose&&(oe.prototype[Symbol.dispose]=oe.prototype.free);function jt(){c.start();}function gn(){return {__proto__:null,"./openrtc_bg.js":{__proto__:null,__wbg_Error_3639a60ed15f87e7:function(e,t){return Error(E(e,t))},__wbg_String_8564e559799eccda:function(e,t){let n=String(t),i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg___wbindgen_boolean_get_c3dd5c39f1b5a12b:function(e){let t=e,n=typeof t=="boolean"?t:void 0;return P(n)?16777215:n?1:0},__wbg___wbindgen_debug_string_07cb72cfcc952e2b:function(e,t){let n=ut(t),i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg___wbindgen_in_2617fa76397620d3:function(e,t){return e in t},__wbg___wbindgen_is_function_2f0fd7ceb86e64c5:function(e){return typeof e=="function"},__wbg___wbindgen_is_null_066086be3abe9bb3:function(e){return e===null},__wbg___wbindgen_is_object_5b22ff2418063a9c:function(e){let t=e;return typeof t=="object"&&t!==null},__wbg___wbindgen_is_string_eddc07a3efad52e6:function(e){return typeof e=="string"},__wbg___wbindgen_is_undefined_244a92c34d3b6ec0:function(e){return e===void 0},__wbg___wbindgen_jsval_eq_403eaa3610500a25:function(e,t){return e===t},__wbg___wbindgen_jsval_loose_eq_1978f1e77b4bce62:function(e,t){return e==t},__wbg___wbindgen_number_get_dd6d69a6079f26f1:function(e,t){let n=t,i=typeof n=="number"?n:void 0;D().setFloat64(e+8,P(i)?0:i,true),D().setInt32(e+0,!P(i),true);},__wbg___wbindgen_string_get_965592073e5d848c:function(e,t){let n=t,i=typeof n=="string"?n:void 0;var r=P(i)?0:b(i,c.__wbindgen_malloc,c.__wbindgen_realloc),o=m;D().setInt32(e+4,o,true),D().setInt32(e+0,r,true);},__wbg___wbindgen_throw_9c75d47bf9e7731e:function(e,t){throw new Error(E(e,t))},__wbg__wbg_cb_unref_158e43e869788cdc:function(e){e._wbg_cb_unref();},__wbg_abort_43913e33ecb83d0d:function(e,t){e.abort(t);},__wbg_abort_87eb7f23cf4b73d1:function(e){e.abort();},__wbg_addEventListener_8b7ec0528991cf78:function(){return R(function(e,t,n,i){e.addEventListener(E(t,n),i);},arguments)},__wbg_append_8df396311184f750:function(){return R(function(e,t,n,i,r){e.append(E(t,n),E(i,r));},arguments)},__wbg_arrayBuffer_87e3ac06d961f7a0:function(){return R(function(e){return e.arrayBuffer()},arguments)},__wbg_bistream_new:function(e){return fe.__wrap(e)},__wbg_body_6929614c20dfa7b0:function(e){let t=e.body;return P(t)?0:H(t)},__wbg_buffer_9ee17426fe5a5d65:function(e){return e.buffer},__wbg_byobRequest_178b64c09a0bee03:function(e){let t=e.byobRequest;return P(t)?0:H(t)},__wbg_byteLength_1f57c71e64ee0180:function(e){return e.byteLength},__wbg_byteOffset_648d0af273024f3d:function(e){return e.byteOffset},__wbg_call_a41d6421b30a32c5:function(){return R(function(e,t,n){return e.call(t,n)},arguments)},__wbg_call_add9e5a76382e668:function(){return R(function(e,t){return e.call(t)},arguments)},__wbg_cancel_f97a3ee5a8b30eef:function(e){return e.cancel()},__wbg_catch_f939343cb181958c:function(e,t){return e.catch(t)},__wbg_clearTimeout_113b1cde814ec762:function(e){return clearTimeout(e)},__wbg_clearTimeout_1ccca1faf41fc6f8:function(e){return clearTimeout(e)},__wbg_clearTimeout_47a40e3be01ed7a3:function(){return R(function(e,t){e.clearTimeout(t);},arguments)},__wbg_clearTimeout_6b8d9a38b9263d65:function(e){return clearTimeout(e)},__wbg_close_63e009c5a75f5597:function(){return R(function(e){e.close();},arguments)},__wbg_close_931d0c62e2aab92c:function(){return R(function(e){e.close();},arguments)},__wbg_close_de471367367aa5cb:function(){return R(function(e){e.close();},arguments)},__wbg_code_be6f339819ebb2c4:function(e){return e.code},__wbg_code_f1d2ddc1fbbb5aad:function(e){return e.code},__wbg_createDataChannel_e92347b9e9a8f5fa:function(e,t,n){return e.createDataChannel(E(t,n))},__wbg_crypto_38df2bab126b63dc:function(e){return e.crypto},__wbg_data_4a14fad4c5f216c4:function(e){return e.data},__wbg_debug_37240d2c1d0ce2bb:function(e){console.debug(e);},__wbg_dispatchEvent_62b7eaa3eef4c3e8:function(){return R(function(e,t){return e.dispatchEvent(t)},arguments)},__wbg_done_b1afd6201ac045e0:function(e){return e.done},__wbg_enqueue_6c7cd543c0f3828e:function(){return R(function(e,t){e.enqueue(t);},arguments)},__wbg_entries_83f42485034accab:function(e){return e.entries()},__wbg_error_48655ee7e4756f8b:function(e){console.error(e);},__wbg_error_a6fa202b58aa1cd3:function(e,t){let n,i;try{n=e,i=t,console.error(E(e,t));}finally{c.__wbindgen_free(n,i,1);}},__wbg_fetch_1a030943aa8e0c38:function(e,t){return e.fetch(t)},__wbg_fetch_9dad4fe911207b37:function(e){return fetch(e)},__wbg_fetch_c6486a0142348bc8:function(e){return fetch(e)},__wbg_fetch_f36631298df17a02:function(e,t){return e.fetch(t)},__wbg_getRandomValues_76dfc69825c9c552:function(){return R(function(e,t){globalThis.crypto.getRandomValues(X(e,t));},arguments)},__wbg_getRandomValues_c44a50d8cfdaebeb:function(){return R(function(e,t){e.getRandomValues(t);},arguments)},__wbg_getReader_9facd4f899beac89:function(){return R(function(e){return e.getReader()},arguments)},__wbg_getReader_fe5bfa2b1fd51521:function(e){return e.getReader()},__wbg_get_41476db20fef99a8:function(){return R(function(e,t){return Reflect.get(e,t)},arguments)},__wbg_get_652f640b3b0b6e3e:function(e,t){return e[t>>>0]},__wbg_get_6aaf7ff105162d98:function(){return R(function(e,t,n,i){let r=t.get(E(n,i));var o=P(r)?0:b(r,c.__wbindgen_malloc,c.__wbindgen_realloc),s=m;D().setInt32(e+4,s,true),D().setInt32(e+0,o,true);},arguments)},__wbg_get_9cfea9b7bbf12a15:function(){return R(function(e,t){return Reflect.get(e,t)},arguments)},__wbg_get_done_2088079830fb242e:function(e){let t=e.done;return P(t)?16777215:t?1:0},__wbg_get_value_52f4b39f58a812ed:function(e){return e.value},__wbg_get_with_ref_key_6412cf3094599694:function(e,t){return e[t]},__wbg_has_3a6f31f647e0ba22:function(){return R(function(e,t){return Reflect.has(e,t)},arguments)},__wbg_headers_de17f740bce997ae:function(e){return e.headers},__wbg_info_092aeeab8cd06a0b:function(e){console.info(e);},__wbg_instanceof_ArrayBuffer_eab9f28fbec23477:function(e){let t;try{t=e instanceof ArrayBuffer;}catch{t=false;}return t},__wbg_instanceof_Blob_03470b25075ee8f1:function(e){let t;try{t=e instanceof Blob;}catch{t=false;}return t},__wbg_instanceof_ReadableStreamDefaultReader_8203766c0e55064a:function(e){let t;try{t=e instanceof ReadableStreamDefaultReader;}catch{t=false;}return t},__wbg_instanceof_Response_370b83aa6c17e88a:function(e){let t;try{t=e instanceof Response;}catch{t=false;}return t},__wbg_instanceof_Uint8Array_57d77acd50e4c44d:function(e){let t;try{t=e instanceof Uint8Array;}catch{t=false;}return t},__wbg_instanceof_Window_4153c1818a1c0c0b:function(e){let t;try{t=e instanceof Window;}catch{t=false;}return t},__wbg_isArray_c6c6ef8308995bcf:function(e){return Array.isArray(e)},__wbg_iterator_9d68985a1d096fc2:function(){return Symbol.iterator},__wbg_length_ba3c032602efe310:function(e){return e.length},__wbg_log_72d22df918dcc232:function(e){console.log(e);},__wbg_message_609b498da776cb30:function(e,t){let n=t.message,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_msCrypto_bd5a034af96bcba6:function(e){return e.msCrypto},__wbg_new_0_e486ec9936f7edbf:function(){return new Date},__wbg_new_18865c63fa645c6f:function(){return R(function(){return new Headers},arguments)},__wbg_new_227d7c05414eb861:function(){return new Error},__wbg_new_2fad8ca02fd00684:function(){return new Object},__wbg_new_3baa8d9866155c79:function(){return new Array},__wbg_new_46ae4e4ff2a07a64:function(){return new Map},__wbg_new_51ff470dc2f61e27:function(){return R(function(){return new AbortController},arguments)},__wbg_new_71b820e9c1f9ee88:function(){return R(function(e,t){return new WebSocket(E(e,t))},arguments)},__wbg_new_8454eee672b2ba6e:function(e){return new Uint8Array(e)},__wbg_new_c9ea13ea803a692e:function(e,t){return new Error(E(e,t))},__wbg_new_from_slice_5a173c243af2e823:function(e,t){return new Uint8Array(X(e,t))},__wbg_new_typed_1137602701dc87d4:function(e,t){try{var n={a:e,b:t},i=(o,s)=>{let a=n.a;n.a=0;try{return Cn(a,n.b,o,s)}finally{n.a=a;}};return new Promise(i)}finally{n.a=0;}},__wbg_new_with_byte_offset_and_length_643e5e9e2fb6b1ad:function(e,t,n){return new Uint8Array(e,t>>>0,n>>>0)},__wbg_new_with_configuration_3b46f8f863c57190:function(){return R(function(e){return new RTCPeerConnection(e)},arguments)},__wbg_new_with_event_init_dict_e01f6dc8f5a4058b:function(){return R(function(e,t,n){return new CustomEvent(E(e,t),n)},arguments)},__wbg_new_with_into_underlying_sink_2596343f9b6c8e58:function(e){return new WritableStream(me.__wrap(e))},__wbg_new_with_into_underlying_source_fd904252f385f59c:function(e,t){return new ReadableStream(be.__wrap(e),t)},__wbg_new_with_length_9011f5da794bf5d9:function(e){return new Uint8Array(e>>>0)},__wbg_new_with_str_and_init_da311e12114f4d1e:function(){return R(function(e,t,n){return new Request(E(e,t),n)},arguments)},__wbg_new_with_str_sequence_d90cb07368a00c61:function(){return R(function(e,t,n){return new WebSocket(E(e,t),n)},arguments)},__wbg_next_261c3c48c6e309a5:function(e){return e.next},__wbg_next_aacee310bcfe6461:function(){return R(function(e){return e.next()},arguments)},__wbg_node_84ea875411254db1:function(e){return e.node},__wbg_now_4f457f10f864aec5:function(){return Date.now()},__wbg_now_e7c6795a7f81e10f:function(e){return e.now()},__wbg_ok_b6a9978bb5f66f33:function(e){return e.ok},__wbg_parse_6a6cc87f3d5b738c:function(e,t){return Date.parse(E(e,t))},__wbg_performance_3fcf6e32a7e1ed0a:function(e){return e.performance},__wbg_process_44c7a14e11e9f69e:function(e){return e.process},__wbg_protocol_db28bce84eb5b12a:function(e,t){let n=t.protocol,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_prototypesetcall_fd4050e806e1d519:function(e,t,n){Uint8Array.prototype.set.call(X(e,t),n);},__wbg_push_60a5366c0bb22a7d:function(e,t){return e.push(t)},__wbg_queueMicrotask_40ac6ffc2848ba77:function(e){queueMicrotask(e);},__wbg_queueMicrotask_74d092439f6494c1:function(e){return e.queueMicrotask},__wbg_randomFillSync_6c25eac9869eb53c:function(){return R(function(e,t){e.randomFillSync(t);},arguments)},__wbg_read_ac2e4325f1799cbe:function(e){return e.read()},__wbg_readyState_be3cc9403da6c6ae:function(e){return e.readyState},__wbg_reason_fe958bcb63725f3b:function(e,t){let n=t.reason,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_releaseLock_9e0ebc0b5270a358:function(e){e.releaseLock();},__wbg_removeEventListener_83bbb9ee36238073:function(){return R(function(e,t,n,i){e.removeEventListener(E(t,n),i);},arguments)},__wbg_require_b4edbdcf3e2a1ef0:function(){return R(function(){return module.require},arguments)},__wbg_resolve_9feb5d906ca62419:function(e){return Promise.resolve(e)},__wbg_respond_e7e53102735b2ae2:function(){return R(function(e,t){e.respond(t>>>0);},arguments)},__wbg_send_0edb796d05cd3239:function(){return R(function(e,t,n){e.send(E(t,n));},arguments)},__wbg_send_c422d0aa0cb71d09:function(){return R(function(e,t,n){e.send(X(t,n));},arguments)},__wbg_setTimeout_30be5552e4410378:function(e,t){return setTimeout(e,t)},__wbg_setTimeout_6613a51400c1bf9f:function(){return R(function(e,t,n){return e.setTimeout(t,n)},arguments)},__wbg_setTimeout_ef24d2fc3ad97385:function(){return R(function(e,t){return setTimeout(e,t)},arguments)},__wbg_setTimeout_f757f00851f76c42:function(e,t){return setTimeout(e,t)},__wbg_set_5337f8ac82364a3f:function(){return R(function(e,t,n){return Reflect.set(e,t,n)},arguments)},__wbg_set_6be42768c690e380:function(e,t,n){e[t]=n;},__wbg_set_82f7a370f604db70:function(e,t,n){return e.set(t,n)},__wbg_set_959f043b9152efeb:function(){return R(function(e,t,n,i,r){e.set(E(t,n),E(i,r));},arguments)},__wbg_set_b0d9dc239ecdb765:function(e,t,n){e.set(X(t,n));},__wbg_set_binaryType_8564bdba0fbec720:function(e,t){e.binaryType=Tn[t];},__wbg_set_body_aaff4f5f9991f342:function(e,t){e.body=t;},__wbg_set_cache_d1f2b7b4dfa39317:function(e,t){e.cache=Pn[t];},__wbg_set_credentials_f31e4d30b974ce14:function(e,t){e.credentials=kn[t];},__wbg_set_detail_ff73098900fc0958:function(e,t){e.detail=t;},__wbg_set_f614f6a0608d1d1d:function(e,t,n){e[t>>>0]=n;},__wbg_set_handle_event_ce9002ca160b1275:function(e,t){e.handleEvent=t;},__wbg_set_headers_ae96049ea40e9eef:function(e,t){e.headers=t;},__wbg_set_high_water_mark_84684938153a659a:function(e,t){e.highWaterMark=t;},__wbg_set_method_0eea8a5597775fa1:function(e,t,n){e.method=E(t,n);},__wbg_set_mode_9fe47bff60a1580d:function(e,t){e.mode=An[t];},__wbg_set_onclose_f756840519cd20b5:function(e,t){e.onclose=t;},__wbg_set_onerror_02f33de339f1fa31:function(e,t){e.onerror=t;},__wbg_set_onmessage_d2ff0c1d20584625:function(e,t){e.onmessage=t;},__wbg_set_onopen_1da8a4f65e6180d2:function(e,t){e.onopen=t;},__wbg_set_signal_8c5cf4c3b27bd8a8:function(e,t){e.signal=t;},__wbg_signal_4643ce883b92b553:function(e){return e.signal},__wbg_stack_3b0d974bbf31e44f:function(e,t){let n=t.stack,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_static_accessor_GLOBAL_THIS_1c7f1bd6c6941fdb:function(){let e=typeof globalThis>"u"?null:globalThis;return P(e)?0:H(e)},__wbg_static_accessor_GLOBAL_e039bc914f83e74e:function(){let e=typeof global>"u"?null:global;return P(e)?0:H(e)},__wbg_static_accessor_SELF_8bf8c48c28420ad5:function(){let e=typeof self>"u"?null:self;return P(e)?0:H(e)},__wbg_static_accessor_WINDOW_6aeee9b51652ee0f:function(){let e=typeof window>"u"?null:window;return P(e)?0:H(e)},__wbg_status_157e67ab07d01f8a:function(e){return e.status},__wbg_stringify_7fd5cae8859a6f10:function(){return R(function(e){return JSON.stringify(e)},arguments)},__wbg_subarray_fbe3cef290e1fa43:function(e,t,n){return e.subarray(t>>>0,n>>>0)},__wbg_text_de416916b5c06490:function(){return R(function(e){return e.text()},arguments)},__wbg_then_20a157d939b514f5:function(e,t){return e.then(t)},__wbg_then_5ef9b762bc91555c:function(e,t,n){return e.then(t,n)},__wbg_toISOString_72dcc3eb1fd97de6:function(e){return e.toISOString()},__wbg_url_68fd9a221360e0db:function(e,t){let n=t.url,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_url_a0e994e7d0317efc:function(e,t){let n=t.url,i=b(n,c.__wbindgen_malloc,c.__wbindgen_realloc),r=m;D().setInt32(e+4,r,true),D().setInt32(e+0,i,true);},__wbg_value_f852716acdeb3e82:function(e){return e.value},__wbg_versions_276b2795b1c6a219:function(e){return e.versions},__wbg_view_16bd97d49793e1a9:function(e){let t=e.view;return P(t)?0:H(t)},__wbg_warn_1f9b94806da61fbb:function(e){console.warn(e);},__wbg_wasClean_92b4133f985dfae0:function(e){return e.wasClean},__wbindgen_cast_0000000000000001:function(e,t){return V(e,t,_n)},__wbindgen_cast_0000000000000002:function(e,t){return V(e,t,Sn)},__wbindgen_cast_0000000000000003:function(e,t){return V(e,t,wn)},__wbindgen_cast_0000000000000004:function(e,t){return V(e,t,In)},__wbindgen_cast_0000000000000005:function(e,t){return V(e,t,fn)},__wbindgen_cast_0000000000000006:function(e,t){return V(e,t,mn)},__wbindgen_cast_0000000000000007:function(e,t){return V(e,t,bn)},__wbindgen_cast_0000000000000008:function(e,t){return Nn(e,t,vn)},__wbindgen_cast_0000000000000009:function(e,t){return V(e,t,yn)},__wbindgen_cast_000000000000000a:function(e){return e},__wbindgen_cast_000000000000000b:function(e){return e},__wbindgen_cast_000000000000000c:function(e,t){return X(e,t)},__wbindgen_cast_000000000000000d:function(e,t){return E(e,t)},__wbindgen_cast_000000000000000e:function(e){return BigInt.asUintN(64,e)},__wbindgen_cast_000000000000000f:function(e,t){var n=X(e,t).slice();return c.__wbindgen_free(e,t*1,1),n},__wbindgen_init_externref_table:function(){let e=c.__wbindgen_externrefs,t=e.grow(4);e.set(0,void 0),e.set(t+0,void 0),e.set(t+1,null),e.set(t+2,true),e.set(t+3,false);}}}}function fn(l,e){c.wasm_bindgen__convert__closures_____invoke__h509d1e5f9a719179(l,e);}function mn(l,e){c.wasm_bindgen__convert__closures_____invoke__h1ecdc95d38c8111b(l,e);}function bn(l,e){c.wasm_bindgen__convert__closures_____invoke__h47f09f7820fbff6c(l,e);}function vn(l,e){c.wasm_bindgen__convert__closures_____invoke__ha910581f00459fa9(l,e);}function yn(l,e){c.wasm_bindgen__convert__closures_____invoke__h1893948438c6db09(l,e);}function _n(l,e,t){c.wasm_bindgen__convert__closures_____invoke__h4dc49b34d4d77b81(l,e,t);}function wn(l,e,t){c.wasm_bindgen__convert__closures_____invoke__hf679ef60a72d1948(l,e,t);}function In(l,e,t){c.wasm_bindgen__convert__closures_____invoke__h4b742547b50caebd(l,e,t);}function Sn(l,e,t){let n=c.wasm_bindgen__convert__closures_____invoke__hd47f17ba87c541ec(l,e,t);if(n[1])throw $(n[0])}function Cn(l,e,t,n){c.wasm_bindgen__convert__closures_____invoke__h776304867400b4e4(l,e,t,n);}var Tn=["blob","arraybuffer"],Pn=["default","no-store","reload","no-cache","force-cache","only-if-cached"],kn=["omit","same-origin","include"],An=["same-origin","no-cors","cors","navigate"],Ht=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_bistream_free(l,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(l=>c.__wbg_intounderlyingbytesource_free(l,1));var Gt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_intounderlyingsink_free(l,1)),qt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_intounderlyingsource_free(l,1)),lt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbg_wasmclient_free(l,1));typeof FinalizationRegistry>"u"?{}:new FinalizationRegistry(l=>c.__wbg_wasmconnection_free(l,1));function H(l){let e=c.__externref_table_alloc();return c.__wbindgen_externrefs.set(e,l),e}var $e=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(l=>c.__wbindgen_destroy_closure(l.a,l.b));function ut(l){let e=typeof l;if(e=="number"||e=="boolean"||l==null)return `${l}`;if(e=="string")return `"${l}"`;if(e=="symbol"){let i=l.description;return i==null?"Symbol":`Symbol(${i})`}if(e=="function"){let i=l.name;return typeof i=="string"&&i.length>0?`Function(${i})`:"Function"}if(Array.isArray(l)){let i=l.length,r="[";i>0&&(r+=ut(l[0]));for(let o=1;o<i;o++)r+=", "+ut(l[o]);return r+="]",r}let t=/\[object ([^\]]+)\]/.exec(toString.call(l)),n;if(t&&t.length>1)n=t[1];else return toString.call(l);if(n=="Object")try{return "Object("+JSON.stringify(l)+")"}catch{return "Object"}return l instanceof Error?`${l.name}: ${l.message}
3
3
  ${l.stack}`:n}function X(l,e){return l=l>>>0,re().subarray(l/1,l/1+e)}var Z=null;function D(){return (Z===null||Z.buffer.detached===true||Z.buffer.detached===void 0&&Z.buffer!==c.memory.buffer)&&(Z=new DataView(c.memory.buffer)),Z}function E(l,e){return Dn(l>>>0,e)}var he=null;function re(){return (he===null||he.byteLength===0)&&(he=new Uint8Array(c.memory.buffer)),he}function R(l,e){try{return l.apply(this,e)}catch(t){let n=H(t);c.__wbindgen_exn_store(n);}}function P(l){return l==null}function Nn(l,e,t){let n={a:l,b:e,cnt:1},i=(...r)=>{n.cnt++;try{return t(n.a,n.b,...r)}finally{i._wbg_cb_unref();}};return i._wbg_cb_unref=()=>{--n.cnt===0&&(c.__wbindgen_destroy_closure(n.a,n.b),n.a=0,$e.unregister(n));},$e.register(i,n,n),i}function V(l,e,t){let n={a:l,b:e,cnt:1},i=(...r)=>{n.cnt++;let o=n.a;n.a=0;try{return t(o,n.b,...r)}finally{n.a=o,i._wbg_cb_unref();}};return i._wbg_cb_unref=()=>{--n.cnt===0&&(c.__wbindgen_destroy_closure(n.a,n.b),n.a=0,$e.unregister(n));},$e.register(i,n,n),i}function $t(l,e){let t=e(l.length*1,1)>>>0;return re().set(l,t/1),m=l.length,t}function b(l,e,t){if(t===void 0){let s=ge.encode(l),a=e(s.length,1)>>>0;return re().subarray(a,a+s.length).set(s),m=s.length,a}let n=l.length,i=e(n,1)>>>0,r=re(),o=0;for(;o<n;o++){let s=l.charCodeAt(o);if(s>127)break;r[i+o]=s;}if(o!==n){o!==0&&(l=l.slice(o)),i=t(i,n,n=o+l.length*3,1)>>>0;let s=re().subarray(i+o,i+n),a=ge.encodeInto(l,s);o+=a.written,i=t(i,n,o,1)>>>0;}return m=o,i}function $(l){let e=c.__wbindgen_externrefs.get(l);return c.__externref_table_dealloc(l),e}var Ge=new TextDecoder("utf-8",{ignoreBOM:true,fatal:true});Ge.decode();var En=2146435072,dt=0;function Dn(l,e){return dt+=e,dt>=En&&(Ge=new TextDecoder("utf-8",{ignoreBOM:true,fatal:true}),Ge.decode(),dt=e),Ge.decode(re().subarray(l,l+e))}var ge=new TextEncoder;"encodeInto"in ge||(ge.encodeInto=function(l,e){let t=ge.encode(l);return e.set(t),{read:l.length,written:t.length}});var m=0,c;function Un(l,e){return c=l.exports,Z=null,he=null,c.__wbindgen_start(),c}async function Bn(l,e){if(typeof Response=="function"&&l instanceof Response){if(typeof WebAssembly.instantiateStreaming=="function")try{return await WebAssembly.instantiateStreaming(l,e)}catch(i){if(l.ok&&t(l.type)&&l.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 l.arrayBuffer();return await WebAssembly.instantiate(n,e)}else {let n=await WebAssembly.instantiate(l,e);return n instanceof WebAssembly.Instance?{instance:n,module:l}:n}function t(n){switch(n){case "basic":case "cors":case "default":return true}return false}}async function Kt(l){if(c!==void 0)return c;l!==void 0&&(Object.getPrototypeOf(l)===Object.prototype?{module_or_path:l}=l:console.warn("using deprecated parameters for the initialization function; pass a single object instead")),l===void 0&&(l=new URL("openrtc_bg.wasm",import.meta.url));let e=gn();(typeof l=="string"||typeof Request=="function"&&l instanceof Request||typeof URL=="function"&&l instanceof URL)&&(l=fetch(l));let{instance:t,module:n}=await Bn(await l,e);return Un(t)}var Qt={devicesPerUser:2,maxRooms:10,maxMembersPerRoom:5,maxPersonalDevices:50},On="https://relay.cloudflare.mediaoverquic.com:443/moq",pt=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun.cloudflare.com:3478"}],je={iceServers:pt},Ke={relayUrl:On};function Wn(l){return (Array.isArray(l.urls)?l.urls:[l.urls]).some(t=>typeof t=="string"&&(t.startsWith("turn:")||t.startsWith("turns:")))}function Fn(l){let t=(Array.isArray(l.urls)?l.urls:[l.urls]).filter(n=>typeof n=="string"&&!n.startsWith("stun:"));return t.length===0?null:{...l,urls:Array.isArray(l.urls)?t:t[0]}}function ht(l){if(l)return l.map(e=>Fn(e)).filter(e=>e!==null)}function Qe(l){let e=l.lastIndexOf(".");return {irohTicket:e>=0?l.slice(0,e):l,tokenSuffix:e>=0?l.slice(e+1):null}}function gt(l){try{let e=l.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4;return JSON.parse(atob(e+"=".repeat(t)))}catch{return null}}function ye(l){try{let e=l?.type;return typeof e=="string"?e:"unknown"}catch{return "unknown"}}function ae(l){try{let e=l?.endpointId;if(typeof e=="string"&&e.trim().length>0)return e}catch{}try{let e=l?.endpoint_id;if(typeof e=="string"&&e.trim().length>0)return e}catch{}return "unknown"}function Hn(l){try{let e=l?.protocolHint;if(e==="control"||e==="explicit"||e==="native-main"||e==="unknown")return e}catch{}return null}function Gn(l){try{if(!l||!("channel"in l))return {present:!1,channel:null};let e=l.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}}}function ve(l,e){return Promise.race([l,new Promise((t,n)=>{setTimeout(()=>n(new Error(`timeout after ${e}ms`)),e);})])}async function zt(l,e,t){for(let n=0;n<e;n+=1){if(await l().catch(()=>false))return true;n<e-1&&await new Promise(r=>setTimeout(r,t));}return false}var se=class se{constructor(e){this.wasmClient=e;this.clients=new Set;this.listenLoopTask=null;}addClient(e){this.clients.has(e)||(this.clients.add(e),this.ensureListening());}removeClient(e){this.clients.delete(e);}ensureListening(){this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null,this.clients.size>0&&this.ensureListening();}));}nextRetryDelayMs(e){let t=se.RETRY_MIN_DELAY_MS*Math.pow(2,Math.max(0,e-1));return Math.min(se.RETRY_MAX_DELAY_MS,t)}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=typeof t.shouldInspectIncomingChannelEnvelope=="function"?!!t.shouldInspectIncomingChannelEnvelope():Array.from(this.clients).some(a=>!!a.hasAnyIncomingChannelListeners()),i=await t.normalizeIncomingStreamEvent(e,{inspectChannelEnvelope:n}),r=i.channel?.channelId?.trim();if(r){for(let a of this.getChannelTargetClients(r))if(!!a.dispatchIncomingChannelListeners(i))return}let o=this.getPrimaryClient();!o||o.dispatchIncomingGenericListeners(i)||await o.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,J()&&We()&&console.info("[Client][INCOMING][MOBILE] shared-hub reader acquired",{sharedHubClients:this.clients.size});this.clients.size>0;){let{done:r,value:o}=await i.read();if(r)throw new Error("incoming stream reader closed unexpectedly");if(!o)continue;let s=ye(o);s!=="uni"&&console.debug("[Client][INCOMING] Received stream from WASM node",{type:s,endpointId:ae(o),sharedHubClients:this.clients.size});let a=performance.now();try{await this.dispatchIncoming(o);let d=performance.now()-a;d>50&&console.warn(`[PERFORMANCE] handleIncomingStream loop took abnormally long: ${Math.round(d)}ms`,{endpointId:ae(o),type:s});}catch(d){let u=o,p=ye(u),h=ae(u);console.error("[Client][INCOMING] Failed to handle incoming stream via shared hub",{remoteNodeId:h,type:p,error:d});}}}catch(n){if(this.clients.size===0)return;e+=1;let i=this.nextRetryDelayMs(e);console.warn("[Client][INCOMING] Shared listen loop restarting after stream failure",{attempt:e,delayMs:i,mobile:J(),error:n}),await new Promise(r=>setTimeout(r,i));}finally{if(t)try{t.releaseLock(),J()&&We()&&console.info("[Client][INCOMING][MOBILE] shared-hub reader released",{sharedHubClients:this.clients.size});}catch{}}}}};se.RETRY_MIN_DELAY_MS=250,se.RETRY_MAX_DELAY_MS=2e3;var ft=se,y=class y{constructor(e$1){this.wasmLoaded=false;this.wasmClient=null;this.initPromise=null;this.node=null;this.connections=new Map;this.connectionListeners=[];this.disconnectionListeners=[];this.messageListeners=[];this.roomRequestListeners=[];this.streamListeners=[];this.channelStreamListeners=new Map;this.registeredChannels=new Map;this.announcedConnections=new Set;this.peerLifecycle=new Be;this.knownDevicesById=new Map;this.knownDeviceIdsByNodeId=new Map;this.connectionTrustStates=new Map;this.connectionChannelIds=new Map;this.pendingSessionTokenTrustApprovals=new Map;this.sessionTokenRejectionCooldowns=new Map;this.trustFailureCooldowns=new Map;this.sessionTokenApprovedNodes=new Set;this.sessionTokenApprovedConnectionIds=new Set;this.inboundNativeMainWriters=new Map;this.inboundNativeMainWriteMutex=new Map;this.inboundNativeMainWriterMeta=new Map;this.inboundNativeMainBypassUntilMs=new Map;this.inboundNativeMainWriterSeq=0;this.managedPresenceGrant=null;this.pendingTokenByNodeId=new Map;this.pendingNativeMainConnections=new Map;this.webrtcIncomingExplicitTransfers=new Map;this.localNodeId="";this.listening=false;this.listenLoopTask=null;this.appLimits={...Qt};this.pendingConnection=null;this.incomingTraceSequence=0;this.browserBackgrounded=false;this.authSyncUnsubscribe=null;this.backendConnectionStateUnsubscribe=null;this.authRefreshInterval=null;this.deviceId=null;this.lastWasmAuthSyncUserId=null;this.lastWasmAuthSyncToken=null;this.loggedNativeDiscoveryWasmSkip=false;this.presenceInterval=null;this.hostedAppSettingsLoaded=false;this._moqSession=null;this._moqState="none";this.moqReadyListeners=[];this.moqFailedListeners=[];this.moqObjectListeners=[];this.moqReconnectTimer=null;this.moqReconnectAttempts=0;this.moqPeerSubscriptions=new Set;this.roomCreationMode="client-open";let t=e(e$1),n=f(e$1);this.options={strictMode:false,disableIrohFallback:false,transportPriority:["webrtc","moq","iroh"],...e$1,authMode:n},this.runtimeSafetyProfile=at(this.options),this.effectiveRoomBackendTag=t,this.roomCreationMode=(this.options.discoveryMode??"personal")==="personal"?"client-open":"client-auth",this.options.transports&&(this.options.transports.webrtc===true?this.options.transports.webrtc={...je}:this.options.transports.webrtc===false&&(this.options.transports.webrtc=void 0),this.options.transports.moq===true?this.options.transports.moq={...Ke}:this.options.transports.moq===false&&(this.options.transports.moq=void 0),this.options.transports.iroh===true?this.options.transports.iroh={}:this.options.transports.iroh===false&&(this.options.transports.iroh=void 0));let i=this.options.transports?.iroh,r=this.options.nodeIdPersistence??(typeof i=="object"?i.persistenceMode:void 0)??"persistent",o={apiKey:this.options.apiKey,allowAnonymousHostedDefaults:this.options.allowAnonymousHostedDefaults,authMode:this.options.authMode,projectId:this.options.projectId,storagePrefix:this.options.storagePrefix,nodeIdPersistence:r},a=new Proxy({},{get(d,u){}});this.signaling=new de(o,a),this.rooms=new ue(this,this.signaling),this.registerChannel({id:y.DEFAULT_PEER_CHANNEL_ID,kind:"system",ownership:"shared",peerModel:"device-first",routing:"session-default",readiness:"settled-peer",promotionPolicy:"eligible",signalingPolicy:"hosted",description:"Default trusted device/runtime traffic"}),this.registerChannel({id:y.SHARE_FILE_CHANNEL_ID,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"}),this.registerChannel({id:y.SHARE_CONTROL_CHANNEL_ID,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"}),this.installAppLifecycleListeners(),this.peerLifecycleClient=new Oe(this.peerLifecycle,{getWasmClient:()=>this.wasmClient,scheduleRefreshPeerSnapshot:async()=>{await this.refreshPeerSnapshot();},resolvePromotionEligibility:d=>this.resolvePromotionEligibility(d)});}sleep(e){return new Promise(t=>setTimeout(t,e))}installAppLifecycleListeners(){if(typeof document>"u"||typeof window>"u")return;let e=()=>{let n=document.visibilityState==="hidden";this.handleAppBackgroundState(n,"visibilitychange");},t=()=>{this.handleAppBackgroundState(false,"pageshow");};e(),document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",t);}async handleAppBackgroundState(e,t){let n=this.browserBackgrounded!==e;this.browserBackgrounded=e;let i=this.wasmClient;if(i&&typeof i.set_app_backgrounded=="function")try{await i.set_app_backgrounded(e);}catch(r){console.warn("[Client][APP] Failed to propagate background state to wasm runtime",{backgrounded:e,source:t,error:r});}!e&&n&&this.reconcileConnectionsAfterForeground(t);}reconcileConnectionsAfterForeground(e){for(let t of this.connections.values()){if(t.isClosed)continue;let n=t.getUpgradeState();if(console.info("[Client][APP] Foreground recovery reconcile",{source:e,connectionId:t.id,remoteNodeId:t.remoteNodeId,upgradeState:n}),t.remoteSupportsWebRTC&&n==="none"){t.requestWebRTCUpgrade(`app-foreground:${e}`);continue}n!=="upgrading"&&t.handleAppForeground();}}get apiKey(){return this.options.apiKey}get discoveryMode(){return this.options.discoveryMode??"personal"}usesTicketOnlySignalingMode(){return (this.options?.signalingMode??"hosted")==="ticket-only"}usesDirectRoomBackend(){return this.effectiveRoomBackendTag.startsWith("space::")||(this.options.discoveryMode===void 0||this.options.discoveryMode==="personal")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0}getRoomBackendTag(){return this.effectiveRoomBackendTag}async refreshHostedAppSettings(e=false){if(!this.usesTicketOnlySignalingMode()&&!(this.hostedAppSettingsLoaded&&!e))try{let{getFunctions:t,httpsCallable:n}=await import('firebase/functions'),i=t(e$1().getApp()),s=(await n(i,"validateApiKey")({apiKey:this.apiKey})).data;s.warning&&console.warn("[pluto-rtc]",s.warning),this.appLimits=s.limits,s.discoveryMode&&(this.options.discoveryMode=s.discoveryMode),this.roomCreationMode=s.roomCreationMode??((this.options.discoveryMode??"personal")==="personal"?"client-open":"client-auth"),this.hostedAppSettingsLoaded=!0;}catch(t){console.warn("[pluto-rtc] Could not fetch hosted app settings, using local defaults.",t);}}setSignalingBackend(e){this.backendConnectionStateUnsubscribe?.(),this.backendConnectionStateUnsubscribe=null,this.signaling=new de(this.options,e),this.rooms=new ue(this,this.signaling),typeof e.setCoreClient=="function"&&e.setCoreClient(this),e.checkForSSOToken(),a$1("[Client] subscribing to backend connection state changes",{backendType:e?.constructor?.name??"unknown",hasGetConnectionStates:typeof e.getConnectionStates=="function",hasOnConnectionStateChange:typeof e.onConnectionStateChange=="function"});let t=this.signaling.onConnectionStateChange(n=>{this.applyBackendConnectionState(n);});typeof t=="function"?(this.backendConnectionStateUnsubscribe=t,a$1("[Client] backend connection state subscription established synchronously")):t&&typeof t.then=="function"&&t.then(n=>{this.backendConnectionStateUnsubscribe=n,a$1("[Client] backend connection state subscription established asynchronously");}).catch(n=>{console.warn("[Client] Failed to subscribe to backend connection state changes:",n);});}get currentUser(){return this.signaling.currentUser}onAuthChange(e){return this.signaling.onAuthChange(e)}async signInAnonymously(){return this.signaling.signInAnonymously()}async signInWithPluto(){return this.signaling.signInWithPluto()}async signOut(){return this.listening=false,await this.signaling.stopAuthScopedActivity(),this.signaling.signOut()}getSignalingTelemetry(){return {transport:"runtime-bridge",wasmLoaded:this.wasmLoaded}}getProtocolCapabilities(){return z.getProtocolCapabilities()}async getRuntimeStatus(){let e="unknown";return typeof window<"u"&&(e=window.__TAURI__?"tauri":"browser"),{runtime:e,wasmLoaded:this.wasmLoaded,localNodeId:this.localNodeId||void 0,userId:this.signaling.currentUser?.id}}async ensureWasmRuntimeForP2P(){if(!(this.wasmClient&&this.localNodeId)&&(await this.init(),!this.wasmClient||!this.localNodeId))throw new Error("Node not initialized")}usesNativeIpcRuntimeWithoutWasmFallback(){let t=this.signaling.getRuntimeCapabilities?.();return !!t?.signaling?.nativeIpc&&t?.transport?.wasm===false&&t?.fallback?.wasm===false}nativeWasmInitForbiddenError(e){let n=this.signaling.getRuntimeCapabilities?.(),i=`[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(i,{capabilities:n}),new Error(i)}async ensureSignalingReadyForDiscovery(e){if(this.usesTicketOnlySignalingMode())return;let t=this.usesNativeIpcRuntimeWithoutWasmFallback();!this.wasmLoaded&&t?this.loggedNativeDiscoveryWasmSkip||(this.loggedNativeDiscoveryWasmSkip=true,console.info(`[Client][NATIVE-GUARD] Discovery ${e} is using native IPC readiness; skipped WASM init.`)):this.wasmLoaded||await this.init();try{await this.ensureAuthenticated("discovery");}catch(n){console.warn(`[Client][AUTH] ensureAuthenticated failed for ${e}:`,n);}try{this.wasmClient&&await this.syncAuthTokenToWasm("auth-change");}catch(n){console.warn(`[Client][WASM-AUTH] Token sync failed for ${e}:`,n);}}requiresManagedTransportTrust(){return !this.usesTicketOnlySignalingMode()&&this.discoveryMode!=="personal"&&!!this.currentUser?.id}getRegisteredChannel(e){let t=typeof e=="string"?e.trim():"";return t?this.registeredChannels.get(t)??null:null}isChannelPromotionEligible(e){let t=this.getRegisteredChannel(e);return t?t.promotionPolicy!=="never":true}isTransportOnlyChannel(e){return Lt(this.getRegisteredChannel(e))}getConnectionChannelId(e){let t=typeof e=="string"?e.trim():"";return t?this.connectionChannelIds.get(t)??null:null}isTransportOnlyConnectionId(e){return this.isTransportOnlyChannel(this.getConnectionChannelId(e))}resolvePromotionEligibility(e){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.connections.values()){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}assignConnectionChannel(e,t){let n=typeof t=="string"?t.trim():"";if(!n)return;this.connectionChannelIds.set(e.id,n);let i=this.connectionTrustStates.get(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.knownDeviceIdsByNodeId.get(e.remoteNodeId)||null)),this.hasRustPeerLifecycleProjection())this.refreshPeerSnapshot().catch(()=>{});else {let r=this.connections.get(e.id);r&&this.applyConnectionTrustProjection(r);}}rememberKnownDevice(e){e?.deviceId&&(this.knownDevicesById.set(e.deviceId,e),typeof e.nodeId=="string"&&e.nodeId.trim()&&this.knownDeviceIdsByNodeId.set(e.nodeId.trim(),e.deviceId));}getKnownDevice(e,t){let n=typeof e=="string"?e.trim():"";if(n){let r=this.knownDevicesById.get(n);if(r)return r}let i=typeof t=="string"?t.trim():"";if(i){let r=this.knownDeviceIdsByNodeId.get(i);if(r)return this.knownDevicesById.get(r)??null}return null}async refreshKnownDeviceCache(){if(!this.requiresManagedTransportTrust())return;(await this.searchDevices().catch(()=>[])).forEach(t=>this.rememberKnownDevice(t));}initializeConnectionTrust(e,t){let n=this.connectionTrustStates.get(e.id);if(n)return t&&!n.expectedDeviceId&&(n.expectedDeviceId=t),n;let i=this.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId,deviceId:t??void 0}),o=!this.consumePendingSessionTokenTrustApproval(e.id)&&i&&this.requiresManagedTransportTrust(),s={required:o,verified:!o,failed:false,expectedDeviceId:t||this.knownDeviceIdsByNodeId.get(e.remoteNodeId)||null,verifiedDeviceId:o?null:t||this.knownDeviceIdsByNodeId.get(e.remoteNodeId)||null,issuedChallenge:o?Bt():null};return this.connectionTrustStates.set(e.id,s),s}consumePendingSessionTokenTrustApproval(e){let t=this.pendingSessionTokenTrustApprovals.get(e);return t?(this.pendingSessionTokenTrustApprovals.delete(e),Date.now()-t<=y.SESSION_TOKEN_TRUST_APPROVAL_TTL_MS):false}applySessionTokenTrustApproval(e,t,n="session-token"){if(!e||e.isClosed)return;this.pendingSessionTokenTrustApprovals.set(e.id,Date.now()),this.sessionTokenRejectionCooldowns.delete(e.remoteNodeId),this.trustFailureCooldowns.delete(e.remoteNodeId),this.sessionTokenApprovedNodes.add(e.remoteNodeId),this.sessionTokenApprovedConnectionIds.add(e.id);let i=this.knownDeviceIdsByNodeId.get(e.remoteNodeId)??null,r=this.initializeConnectionTrust(e,i);r.required=false,r.verified=true,r.failed=false,r.failureReason=void 0,r.issuedChallenge=null,r.verifiedDeviceId=r.verifiedDeviceId??r.expectedDeviceId??i??null,this.applyConnectionTrustProjection(e);let o=r.verifiedDeviceId??r.expectedDeviceId??i??null;o&&this.bindConnectionDeviceIdInRust(e,o),console.info("[Client][AUTH] session-token approval applied to connection trust",{connectionId:e.id,remoteNodeId:e.remoteNodeId,scope:t??null,source:n}),this.isWebRTCTransportEnabled()&&e.remoteSupportsWebRTC&&e.requestWebRTCUpgrade("session-token-trust-applied");}getConnectionTrustState(e){let t=this.connectionTrustStates instanceof Map?this.connectionTrustStates:null;if(!t)return null;let n=typeof e.connectionId=="string"?e.connectionId.trim():"";if(n)return t.get(n)??null;for(let[i,r]of t.entries())if(r.verifiedDeviceId&&(r.verifiedDeviceId===e.deviceId||r.verifiedDeviceId===e.deviceIdHint)||r.expectedDeviceId&&(r.expectedDeviceId===e.deviceId||r.expectedDeviceId===e.deviceIdHint))return t.get(i)??null;return null}getConnectionTrustProjection(e){let t=this.getConnectionTrustState(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}applyConnectionTrustProjection(e){if(this.hasRustPeerLifecycleProjection())return;let t=this.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.getConnectionTrustProjection({connectionId:e.id,nodeId:e.remoteNodeId});if(!n){this.syncConnectionPeerLifecycle(e);return}this.peerLifecycle.upsert({peerId:n.deviceId??void 0,deviceId:n.deviceId??void 0,deviceIdHint:n.deviceId??void 0,nodeId:e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:n.health,transportState:this.getConnectionTransportProjectionState(e),activeTransport:e.transportType,protocolState:n.protocolState,routable:n.routable,promotionEligible:t,error:n.error,lastSeenAt:Date.now()});}getConnectionTransportProjectionState(e){if(e.isClosed)return "closed";let t=e.getUpgradeState();return t==="upgraded"?"webrtc":t==="upgrading"?"webrtc-upgrading":t==="failed"?"iroh-fallback":"connected"}async buildLocalTransportTrustPayload(e){let t=await ct().catch(()=>null),n=await this.getLocalDeviceId().catch(()=>null)||this.deviceId||this.options.localDeviceId||null;if(!t||!n)return null;let i=this.initializeConnectionTrust(e);return {version:1,deviceId:n,identityFingerprint:t.fingerprint,challenge:i.issuedChallenge??void 0}}async sendTransportHandshake(e,t,n){let i={webrtc:this.isWebRTCTransportEnabled(),moq:this.moqState==="ready"},r=t==="hello"?this.pendingTokenByNodeId.get(e.remoteNodeId)??void 0:void 0;console.info("[Client][HANDSHAKE] sending",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId,channelId:this.getConnectionChannelId(e.id)??null,capabilities:i,hasSessionToken:!!r,hasChallengeToSign:!!n});let o={type:"handshake",action:t,capabilities:i,moq:i.moq,channelId:this.getConnectionChannelId(e.id)??void 0,...r?{sessionToken:r}:{}},s=await this.buildLocalTransportTrustPayload(e);if(console.info("[Client][HANDSHAKE] local trust payload status",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId,hasTransportTrustPayload:!!s,hasChallengeInPayload:!!s?.challenge}),!s){if(this.requiresManagedTransportTrust()){let d=this.initializeConnectionTrust(e);d.failed=true,d.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});}typeof e.sendRawIrohFrame=="function"?await e.sendRawIrohFrame(this.buildFramedMessage(this.buildNativeMainPayload(o))):await e.send(o);return}if(n){let d=await ct().catch(()=>null);if(!d)throw new Error("Local trusted identity unavailable for handshake proof");s.signedChallenge=Ot(n,d.secretKey);}let a={...o,transportTrust:s};typeof e.sendRawIrohFrame=="function"?await e.sendRawIrohFrame(this.buildFramedMessage(this.buildNativeMainPayload(a))):await e.send(a),console.info("[Client][HANDSHAKE] sent OK",{action:t,connectionId:e.id,remoteNodeId:e.remoteNodeId});}async broadcastTransportCapabilityUpdate(e){if(this.isWebRTCTransportEnabled()){let r=this.getRTCConfig();this.connections.forEach(o=>{o.updateRTCConfig(r);});}let t=Array.from(this.connections.values()).filter(r=>!r.isClosed).map(async r=>{await this.sendTransportHandshake(r,"capability-update"),this.isWebRTCTransportEnabled()&&r.remoteSupportsWebRTC&&r.requestWebRTCUpgrade("capability-update");}),i=(await Promise.allSettled(t)).filter(r=>r.status==="rejected");i.length>0&&b$1("[Client] Some transport capability updates failed",{reason:e,failures:i.length});}async verifyRemoteTransportTrust(e,t){let n=this.initializeConnectionTrust(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 r=this.getKnownDevice(i,e.remoteNodeId);if(r||(await this.refreshKnownDeviceCache(),r=this.getKnownDevice(i,e.remoteNodeId)),!r)return {verified:false,reason:`unknown-trusted-device:${i}`};let o=Ft(r.metadata);if(!o)return {verified:false,reason:`missing-trusted-device-metadata:${i}`};if(t.identityFingerprint&&o.identityFingerprint!==t.identityFingerprint)return {verified:false,reason:`trusted-device-fingerprint-mismatch:${i}`};let s=n.issuedChallenge;return !s||!t.signedChallenge?{verified:false,reason:"missing-signed-transport-challenge"}:Wt(s,t.signedChallenge,o.identityPublicKey)?{verified:true,deviceId:i}:{verified:false,reason:`invalid-transport-proof:${i}`}}async enforceConnectionTrustFailure(e,t){let n=this.initializeConnectionTrust(e);n.failed=true,n.verified=false,n.failureReason=t,this.applyConnectionTrustProjection(e),console.warn("[Client][TRUST] Disconnecting unverified connection",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t}),this.trustFailureCooldowns.set(e.remoteNodeId,Date.now()),await Promise.allSettled([e.disconnect(),this.disconnectNode(e.remoteNodeId).catch(()=>{})]);}markConnectionTrustVerified(e,t){this.trustFailureCooldowns.delete(e.remoteNodeId);let n=this.initializeConnectionTrust(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.applyConnectionTrustProjection(e);let i=n.verifiedDeviceId??n.expectedDeviceId??t??null;i&&(this.bindConnectionDeviceIdInRust(e,i),this.retireSupersededConnections(e,i,"trusted-device-replacement"));}bindConnectionDeviceIdInRust(e,t){let n=t.trim();if(!n)return;let i=this.wasmClient,r=!!i&&typeof i.bind_connection_device_id=="function";console.info("[Client][BIND] bindConnectionDeviceIdInRust entered",{connectionId:e.id,remoteNodeId:e.remoteNodeId,deviceId:n,hasWasmClient:!!i,hasMethod:r}),r&&i.bind_connection_device_id(e.id,n).then(()=>{console.info("[Client][BIND] bind_connection_device_id resolved",{connectionId:e.id,deviceId:n});}).catch(o=>{console.warn("[Client][TRUST] Failed to bind deviceId on Rust connection record",{connectionId:e.id,remoteNodeId:e.remoteNodeId,deviceId:n,error:o});});}retireSupersededConnections(e,t,n){let i=t.trim();if(i)for(let r of this.connections.values()){if(r.id===e.id||r.isClosed)continue;let o=this.connectionTrustStates.get(r.id);(o?.verifiedDeviceId??o?.expectedDeviceId??null)===i&&(console.info("[Client][CONNECTION] Retiring superseded connection for logical device",{keptConnectionId:e.id,retiredConnectionId:r.id,logicalDeviceId:i,reason:n}),r.disconnect().catch(()=>{}));}}async searchDevices(){await this.ensureSignalingReadyForDiscovery("search");let e=await this.signaling.searchDevices();return e.forEach(t=>{this.rememberKnownDevice(t),this.peerLifecycle.upsertDevice(t);}),e}async updateDevice(e,t){await this.ensureSignalingReadyForDiscovery("search"),await this.signaling.updateDevice(e,t);}async deleteDevice(e){await this.ensureSignalingReadyForDiscovery("search"),await this.signaling.deleteDevice(e);}async cleanupStaleDevices(){await this.ensureSignalingReadyForDiscovery("search"),await this.signaling.cleanupStaleDevices();}onDevicesChange(e){let t=true,n=null;return (async()=>{await this.ensureSignalingReadyForDiscovery("watch"),t&&(n=this.signaling.onDevicesChange(i=>{i.forEach(r=>{this.rememberKnownDevice(r),this.peerLifecycle.upsertDevice(r);}),e(i);}));})().catch(i=>{console.warn("[Client] Failed to initialize onDevicesChange listener:",i),t&&e([]);}),()=>{t=false,n&&(n(),n=null);}}async subscribeSessions(e,t){return await this.ensureSignalingReadyForDiscovery("sessions"),this.signaling.subscribeSessions(e,t)}async startScanningLoop(e){e.autoConnect??false;let n=new Set,i=false,r=null,o=null,s=e.localDeviceId;try{let a=await this.signaling.getLocalDeviceId();a&&(s=a);}catch{}return r=this.onDevicesChange(a=>{i||e.onDevices?.(a);}),e.onIncomingSession&&(o=await this.subscribeSessions(s,async a=>{if(i)return;let d=a.sessionId||a.connectionId;if(!(!d||n.has(d))&&a.targetDeviceId===s&&a.initiatorDeviceId!==s&&!(a.state==="connected"||a.state==="closed"||a.state==="failed")){n.add(d);try{if(e.onIncomingSession){await e.onIncomingSession(a);return}(this.getPeerState(a.initiatorDeviceId)?.status==="connected"||e.isConnected?.(a.initiatorDeviceId))&&(this.peerLifecycle.hasScopes(a.initiatorDeviceId)||(e.hasProtectedConnectionIntent?.(a.initiatorDeviceId)??!1)||await this.forceDisconnectPeer(a.initiatorDeviceId).catch(async()=>{await e.cleanupStaleConnection?.(a.initiatorDeviceId);})),a.initiatorNodeId&&await e.allowIncomingNodeId?.(a.initiatorNodeId);let p=await e.acceptIncomingSession?.(d,a.initiatorDeviceId);if(!p?.success)throw new Error(p?.error||"Failed to accept incoming signaling session");await e.onIncomingSessionAccepted?.(a);}catch(u){throw n.delete(d),u}}})),{stop:()=>{i=true,r&&(r(),r=null),o&&(o(),o=null);}}}async connectDeviceWithRetry(e,t,n){if(!n.localDeviceId)return {success:false,skipped:"missing-local-device-id",attempts:0,error:"Missing local device ID"};let i=n.maxRetries??3,r=n.initialBackoffMs??2e3,o=await t.getConnectionState?.(e.deviceId);if(o==="connecting")return {success:true,skipped:"already-connecting",attempts:0};o==="connected"&&t.forceDisconnect&&(await t.forceDisconnect(e.deviceId),await t.refreshState?.());let s=async()=>{if(typeof e.nodeId=="string"&&e.nodeId.trim().length>0||typeof e.ticket=="string"&&e.ticket.trim().length>0){await t.directConnect(e),await t.onConnected?.(e);return}let p=await t.signalConnect({localDeviceId:n.localDeviceId,targetDeviceId:e.deviceId,targetUserId:n.targetUserId,device:e});if(!p.success)throw new Error(p.error||"Signaling failed")},a=0,d;for(;a<=i;)try{return await s(),{success:!0,attempts:a}}catch(u){if(d=u,a===i)break;let p=r*Math.pow(2,a);t.onRetry?.(e,a+1,p),await new Promise(h=>setTimeout(h,p)),a+=1;}return {success:false,attempts:i+1,error:d instanceof Error?d.message:"Connection failed"}}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,r=e.retryPollAttempts??8,o=e.retryPollIntervalMs??300,s=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"};let a=e.isNativeReady;if(!await zt(a,n,i)){await e.retryNativeInit?.();let[u,p]=await Promise.all([e.waitForNativeInitEvent?.(s)??Promise.resolve(false),zt(a,r,o)]);if(!(u||p))return {ready:false,mode:"native"}}return t&&await this.init(),{ready:true,mode:"native"}}updateTransportConfig(e){e&&(this.options.transports={...this.options.transports||{},...e});}async getTurnCredentialsForTransportConfig(){return typeof this.options.turnCredentialsProvider=="function"?await this.options.turnCredentialsProvider()??null:await this.signaling.getTurnCredentials()??null}async init(){if(this.initPromise)return this.initPromise;if(!(this.wasmLoaded&&this.wasmClient&&this.localNodeId)){if(this.usesNativeIpcRuntimeWithoutWasmFallback())throw this.nativeWasmInitForbiddenError("Client.init()");return this.initPromise=(async()=>{try{c$2("[Client][INIT] Loading WASM module..."),await Kt(),jt(),this.wasmLoaded=!0,c$2("[Client][INIT] WASM module loaded");let e$1=g(this.options),t=typeof this.options.apiKey=="string"?this.options.apiKey.trim():"",n=typeof this.options.spaceKey=="string"?this.options.spaceKey.trim():"",i=(this.options.discoveryMode===void 0||this.options.discoveryMode==="personal")&&!!t&&!!n,r=e(this.options);if(i){let g=await d(t,n);r=`space::${g}`,c$2(`[Client][INIT] Personal Mode \u2014 WASM rooms routed to spaces/${g.slice(0,8)}\u2026`);}this.effectiveRoomBackendTag=r,this.wasmClient=new oe(e$1,r),c$2("PlutoRTC WASM Core Initialized"),this.signaling.setWasmClient(this.wasmClient),this.usesTicketOnlySignalingMode()||(await this.ensureAuthenticated("init"),await this.syncAuthTokenToWasm("init"),this.installAuthTokenSync());let o=`iroh_secret_key_${h(this.options)}`,s,a=this.options.nodeIdPersistence??(typeof this.options.transports?.iroh=="object"?this.options.transports.iroh.persistenceMode:void 0)??"persistent";if(this.options.secretKey){let g=this.options.secretKey.match(/.{1,2}/g);g&&(s=new Uint8Array(g.map(f=>parseInt(f,16))));}else if(a==="persistent"){let g=typeof localStorage<"u"?localStorage.getItem(o):null;if(g){let f=g.match(/.{1,2}/g);f&&(s=new Uint8Array(f.map(v=>parseInt(v,16))));}}this.deviceId=await this.signaling.getLocalDeviceId().catch(()=>null);let d$1=Date.now();c$2(`[Client][INIT][IROH] start persistence=${a} hasSecretKey=${!!s} secretKeyLen=${s?.length||0} hasStoredDeviceId=${!!this.deviceId}`);let u=setInterval(()=>{let g=Date.now()-d$1;console.warn(`[Client][INIT][IROH] pending elapsedMs=${g} hasWasmClient=${!!this.wasmClient}`);},5e3);try{this.localNodeId=await ve(this.wasmClient.init_iroh(s),2e4);}catch(g){let f=Date.now()-d$1;throw new Error(`[Client] init_iroh stalled or failed: ${g?.message||g}; elapsed_ms=${f}; persistence=${a}; has_secret_key=${!!s}`)}finally{clearInterval(u);}if(c$2(`[Client][INIT][IROH] complete elapsedMs=${Date.now()-d$1} nodeId=${this.localNodeId}`),!this.localNodeId)throw new Error("[Client] init_iroh returned empty node id");if(this.deviceId||(this.deviceId=await this.signaling.getLocalDeviceId().catch(()=>null)),this.node={initialized:!0,localNodeId:this.localNodeId},this.localNodeId&&a==="persistent"&&!this.options.secretKey&&typeof localStorage<"u"){let g=s??(typeof this.wasmClient?.iroh_secret_key=="function"?await this.wasmClient.iroh_secret_key().catch(()=>{}):void 0);if(g&&g.length>0){let f=Array.from(g).map(v=>Number(v).toString(16).padStart(2,"0")).join("");localStorage.setItem(o,f),c$2(`[Client][INIT][IROH] persisted secret key bytes=${g.length} nodeId=${this.localNodeId}`);}else console.warn(`[Client][INIT][IROH] unable to persist secret key for nodeId=${this.localNodeId}`);}this.options.transports?.moq&&this.initMoQ();let p=this.options.transports?.webrtc||je;if(p?.useTurn||p?.privacyMode||this.options.strictMode)try{let g=await this.getTurnCredentialsForTransportConfig();if(g&&g.iceServers){let f=Array.isArray(g.iceServers)?g.iceServers:[g.iceServers];p?.privacyMode||this.options.strictMode?(f=ht(f)??[],c$2(`[Client] Strict / Privacy Mode: Filtered STUN servers. Remaining=${f.length}`)):c$2(`[Client] Automatically fetched ${f.length} TURN servers.`),this.options.transports||(this.options.transports={}),this.options.transports.webrtc||(this.options.transports.webrtc={});let v=this.options.transports.webrtc||je;v.iceServers||(v.iceServers=[]),(this.options.strictMode||v.privacyMode)&&(v.iceServers=ht(v.iceServers)??[]),v.iceServers.push(...f);}}catch(g){console.warn("[Client] Failed to auto-fetch TURN credentials:",g);}if(!this.options.strictMode&&!p?.privacyMode){let g=this.options.transports?.webrtc;g&&(!g.iceServers||Array.isArray(g.iceServers)&&g.iceServers.length===0)&&(c$2("[Client] No ICE servers provided. Using default public STUN servers."),g.iceServers=[...pt]);}this.isWebRTCTransportEnabled()&&this.broadcastTransportCapabilityUpdate("webrtc-ready").catch(g=>{b$1("[Client] Late WebRTC capability update failed",g);});}catch(e){throw console.error("Failed to initialize PlutoRTC:",e),this.initPromise=null,e}})(),this.initPromise}}async ensureAuthenticated(e){if(this.usesTicketOnlySignalingMode())return;let t=this.options.authMode??"anonymous",n=e!=="discovery";if(!((this.options.discoveryMode===void 0||this.options.discoveryMode==="personal")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0)){try{await ve(this.signaling.waitForAuth(),5e3);}catch(r){n&&console.warn(`[Client][AUTH] waitForAuth timed out (${e})`,r);}if(this.signaling.currentUser){n&&c$2(`[Client][AUTH] Authenticated (${e}) as ${this.signaling.currentUser.id}`);return}if(t==="external"||t==="required")throw new Error(`[Client][AUTH] ${t} auth mode requires host-provided auth before ${e}`);n&&c$2(`[Client][AUTH] No user (${e}); attempting anonymous sign-in...`),await ve(this.signaling.signInAnonymously(),8e3);try{await ve(this.signaling.waitForAuth(),5e3);}catch{}if(!this.signaling.currentUser)throw new Error("[Client][AUTH] Anonymous sign-in did not produce an authenticated user");n&&c$2(`[Client][AUTH] Anonymous sign-in success (${e})`);}}installAuthTokenSync(){this.authSyncUnsubscribe||(this.authSyncUnsubscribe=this.signaling.onAuthChange(()=>{this.syncAuthTokenToWasm("auth-change").catch(e=>{console.warn("[Client][WASM-AUTH] Failed syncing auth token on auth change:",e);});}),this.authRefreshInterval||(this.authRefreshInterval=setInterval(()=>{this.syncAuthTokenToWasm("periodic-refresh",true).catch(e=>{console.warn("[Client][WASM-AUTH] Periodic auth refresh sync failed:",e);});},600*1e3)));}async syncAuthTokenToWasm(e,t=false){if(!this.wasmClient||typeof this.wasmClient.set_auth_token!="function"){console.warn("[Client][WASM-AUTH] WasmClient.set_auth_token is unavailable");return}let n=this.signaling.currentUser,i=n&&n.getToken?await n.getToken(t):null,r=!!i,o=i?.length||0,s=n?.id||null;this.lastWasmAuthSyncUserId===s&&this.lastWasmAuthSyncToken===i||(this.lastWasmAuthSyncUserId=s,this.lastWasmAuthSyncToken=i,c$2(`[Client][WASM-AUTH] Sync token (${e}) hasToken=${r} tokenLen=${o} uid=${s||"none"} forceRefresh=${t}`),this.wasmClient.set_auth_token(i));}get moqState(){return this._moqState}get moq(){return this._moqState!=="ready"||!this._moqSession?null:{session:this._moqSession,publisher:this._moqSession.publisher,subscriber:this._moqSession.subscriber}}onMoQReady(e){this.moqReadyListeners.push(e);}onMoQFailed(e){this.moqFailedListeners.push(e);}onMoQObject(e){this.moqObjectListeners.push(e);}clearMoQReconnectTimer(){this.moqReconnectTimer&&(clearTimeout(this.moqReconnectTimer),this.moqReconnectTimer=null);}closeMoQSession(e){let t=this._moqSession;if(this._moqSession=null,this.moqPeerSubscriptions.clear(),!!t)try{t.close();}catch(n){b$1("[Client] MoQ session close failed",{reason:e,error:n});}}handleMoQSessionClosed(e,t){this._moqSession===e&&(this._moqSession=null,this._moqState="failed",this.moqPeerSubscriptions.clear(),this.connections.forEach(n=>{n.peerMoQReady=false;}),this.moqFailedListeners.forEach(n=>n()),b$1("[Client] MoQ session closed; scheduling reconnect",{reason:t}),this.scheduleMoQReconnect(t));}scheduleMoQReconnect(e){if(!this.options.transports?.moq||this.moqReconnectTimer)return;let t=Math.min(y.MOQ_RECONNECT_INITIAL_DELAY_MS*Math.max(1,2**this.moqReconnectAttempts),y.MOQ_RECONNECT_MAX_DELAY_MS);this.moqReconnectAttempts+=1,this.moqReconnectTimer=setTimeout(()=>{this.moqReconnectTimer=null,!(!this.options.transports?.moq||this._moqState==="ready"||this._moqState==="connecting")&&(c$2(`[Client] Reconnecting MoQ relay after ${t}ms`,e),this.initMoQ());},t);}enableMoQForConnection(e){this.moqState!=="ready"||!this.moq||(e.peerMoQReady=true,this.subscribeMoQPeer(e));}subscribeMoQPeer(e){let t=this.moq;if(!t||!this.localNodeId||e.isClosed||this.moqPeerSubscriptions.has(e.id))return;this.moqPeerSubscriptions.add(e.id);let n=e.deviceId;Promise.allSettled([t.subscriber.subscribe(n,"data/broadcast"),t.subscriber.subscribe(n,`data / ${this.localNodeId} `)]).then(i=>{i.some(r=>r.status==="rejected")&&this.moqPeerSubscriptions.delete(e.id);});}resubscribeMoQPeers(){this.moqPeerSubscriptions.clear(),this.connections.forEach(e=>{!e.isClosed&&e.peerMoQReady&&this.subscribeMoQPeer(e);});}async initMoQ(){if(!this.options.transports?.moq||this._moqState==="ready"||this._moqState==="connecting")return;this.clearMoQReconnectTimer(),this.closeMoQSession("init"),this._moqState="connecting";let e=this.options.transports?.moq,n=(e&&typeof e=="object"?{...Ke,...e}:{...Ke}).relayUrl,i=null;try{let r=new WebTransport(n);if(await r.ready,i=new xe(r,(o,s,a,d)=>{if(this.moqObjectListeners.forEach(p=>p(o,s,a,d)),s.replace(/\s+/g,"").startsWith("data/")&&this.localNodeId){let p=this.getDeterministicConnectionId(o),h=this.connections.get(p);h&&h.injectData(a);}}),this._moqSession=i,i.onClose(o=>this.handleMoQSessionClosed(i,o)),await i.init(),await i.waitForSetup(),this._moqSession!==i)return;await i.publisher.announce(this.localNodeId),await this.createMoQDataTracks(),this._moqState="ready",this.moqReconnectAttempts=0,this.moqPeerSubscriptions.clear(),c$2(`[Client] MoQ Session Ready: Pub/Sub via ${n}`),this.moqReadyListeners.forEach(o=>o()),this.resubscribeMoQPeers(),this.broadcastTransportCapabilityUpdate("moq-ready").catch(o=>{b$1("[Client] Late MoQ capability update failed",o);});}catch(r){console.warn("[Client] MoQ init failed:",r),this._moqSession===i&&(this._moqSession=null),this._moqState="failed",this.moqFailedListeners.forEach(o=>o()),this.scheduleMoQReconnect(r);}}async connect(e,t=2e4,n,i){if(await this.ensureWasmRuntimeForP2P(),!e||!e.trim())throw new Error("connect requires a non-empty endpoint ticket");let r=async(S,L,j)=>await Promise.race([S,new Promise((_e,U)=>setTimeout(()=>U(new Error(`${j} timed out after ${L}ms`)),L))]),o=e.trim(),{irohTicket:s,tokenSuffix:a}=Qe(o),d;try{d=await this.wasmClient.endpoint_id_from_ticket(s);}catch(S){throw new Error(`connect requires a valid endpoint ticket: ${S?.message||S}`)}let u=null;if(a){let S=gt(a);typeof S?.t=="string"&&(u=S.t,this.pendingTokenByNodeId.set(d,S.t));}let p=this.getDeterministicConnectionId(d),h=this.getRegisteredChannel(i??null),g=this.shouldUseTransportOnlyChannelConnection(i);console.info("[Client][CONNECT] resolved ticket target",{nodeId:d,connectionId:p,channelId:i??null,registeredChannel:h?{id:h.id,readiness:h.readiness,promotionPolicy:h.promotionPolicy,signalingPolicy:h.signalingPolicy}:null,transportOnlyChannel:g,hasCompoundTicketToken:!!u});let f=this.connections.get(p);if(f)return n&&this.initializeConnectionTrust(f,n),f;try{c$2(`Initiating connection to ${d}...`),this.pendingConnection=await r(this.wasmClient.connect(s),Math.min(4e3,t),"wasmClient.connect"),this.pendingConnection&&typeof this.pendingConnection.getReader=="function"&&await this.awaitConnectEventReady(this.pendingConnection,d,Math.min(4e3,t));}catch(S){console.warn("Connect trigger failed:",S);}let v=null,I=0,_=500,M=Math.ceil(t/_);if(u&&this.wasmClient&&typeof this.wasmClient.present_session_token_to_host=="function"){if(typeof this.wasmClient.is_connected=="function"){let U=Date.now()+t;for(;Date.now()<U;){try{if(await this.wasmClient.is_connected(d))break}catch{}await new Promise(ee=>setTimeout(ee,_));}}let S=false,L=null,j=0,_e=null;for(;j<M;)try{this.shouldVerboseIncomingDiagnostics()&&console.info("[Client][AUTH][MOBILE] presenting session token",{nodeId:d,attempt:j+1,maxRetries:M}),_e=await r(this.wasmClient.present_session_token_to_host(d,u),Math.min(2500,t),"present_session_token_to_host"),console.info("[Client][AUTH] host approved session token",{nodeId:d,approvalScope:_e||null,nextStep:"open-main-stream-and-register-connection"}),S=!0;break}catch(U){L=U,j++,this.shouldVerboseIncomingDiagnostics()&&console.warn("[Client][AUTH][MOBILE] session token presentation retry",{nodeId:d,attempt:j,maxRetries:M,error:U?.message||String(U)});let ee=U?.message||String(U);if(typeof ee=="string"&&ee.includes("missing connection for session-token presentation"))try{this.pendingConnection=await this.wasmClient.connect(s),this.pendingConnection&&typeof this.pendingConnection.getReader=="function"&&await this.awaitConnectEventReady(this.pendingConnection,d,Math.min(4e3,t));}catch{}await new Promise(mt=>setTimeout(mt,_));}if(!S)throw new Error(`Failed to present session token to ${d} after ${t} ms: ${L?.message||L}`)}if(g){let S=this.createTransportOnlyChannelConnection(p,d);return this.assignConnectionChannel(S,i),this.initializeConnectionTrust(S,n),this.registerConnection(S),this.announceConnectionWhenStable(S),console.info("[Client][AUTH] using transport-only channel connection",{nodeId:d,connectionId:S.id,channelId:i??null,signalingMode:this.options.signalingMode??"hosted",hasCompoundTicketToken:!!u}),S}for(;I<M;)try{v=await r(this.wasmClient.open_bi(d),2500,"wasmClient.open_bi");break}catch{I++,await new Promise(L=>setTimeout(L,_));}if(!v)throw new Error(`Failed to establish connection to ${d} after ${t} ms`);(!this.usesTicketOnlySignalingMode()||u)&&await r(this.writeNativeMainLabelHeaderOnBiStream(v,d),4e3,"writeNativeMainLabelHeaderOnBiStream");let w=new te(p,this.localNodeId,d,v.send.getWriter(),v.recv.getReader(),{rtcConfig:this.getRTCConfig(),transportContext:this.createTransportContext(d),onTransportStatusChange:S=>{this.reportConnectionTransportStatus(p,S.activeTransport,S.parallelTransport);}});return this.assignConnectionChannel(w,i),this.initializeConnectionTrust(w,n),this.registerConnection(w),n&&this.bindConnectionDeviceIdInRust(w,n),u&&(this.sessionTokenApprovedNodes.add(d),this.sessionTokenApprovedConnectionIds.add(w.id),this.applySessionTokenTrustApproval(w,null,"dialer-compound-ticket"),console.info("[Client][AUTH] token-approved connection registered locally",{nodeId:d,connectionId:w.id,localNodeId:w.localNodeId,remoteNodeId:w.remoteNodeId})),this.announceConnectionWhenStable(w),console.info("[Client][HANDSHAKE] sending hello (dial path)",{connectionId:w.id,remoteNodeId:w.remoteNodeId}),this.sendTransportHandshake(w,"hello").catch(S=>{console.warn("[Client][TRUST] Failed to send outgoing handshake",{connectionId:w.id,remoteNodeId:w.remoteNodeId,error:S});}),w}async connectRaw(e,t=2e4){let n=await this.connect(e,t);return {connectionId:n.id,localNodeId:n.localNodeId,remoteNodeId:n.deviceId}}async startAutoConnect(e){await this.ensureSignalingReadyForDiscovery("watch");let t=this.currentUser?.id;if(!t)throw new Error("startAutoConnect requires an authenticated user");let n=e||await this.getLocalDeviceId()||this.deviceId;if(!n)throw new Error("startAutoConnect requires a local device identity");this.signaling.startAutoConnect(t,n);}async openBi(e){await this.ensureWasmRuntimeForP2P();let t=typeof this.wasmClient.open_peer_bi=="function"?await this.wasmClient.open_peer_bi(e,5e3):await this.wasmClient.open_bi(e);return {readable:t.recv,writable:t.send}}async openUni(e){return await this.ensureWasmRuntimeForP2P(),typeof this.wasmClient.open_peer_uni=="function"?await this.wasmClient.open_peer_uni(e,5e3):await this.wasmClient.open_uni(e)}getConnections(){return Array.from(this.connections.values())}getConnectionForPeer(e,t){for(let n of this.connections.values())if(e&&n.id===e||t&&n.remoteNodeId===t)return n;return null}watchPeerStates(e){return this.peerLifecycleClient.watchPeerStates(e)}getPeerState(e){return this.peerLifecycleClient.getPeerState(e)}listConnectedPeers(){return this.peerLifecycleClient.listConnectedPeers()}isPeerPromotionEligible(e){return this.peerLifecycleClient.isPeerPromotionEligible(e)}addPeerScope(e,t="persistent"){return this.peerLifecycleClient.addPeerScope(e,t)}releasePeerScope(e,t){return this.peerLifecycleClient.releasePeerScope(e,t)}getPeerScopes(e){return this.peerLifecycleClient.getPeerScopes(e)}isSamePeer(e,t){return this.peerLifecycleClient.isSamePeer(e,t)}async refreshPeerSnapshot(){let e=this.hasRustPeerLifecycleProjection(),t=false,n=o=>o.deviceId||o.deviceIdHint?true:[o.nodeId,o.connectionId].map(a=>typeof a=="string"?a.trim():"").filter(a=>a.length>0).some(a=>!!this.peerLifecycle.get(a));if(this.wasmClient&&typeof this.wasmClient.peer_sessions=="function"){let o=await this.wasmClient.peer_sessions();Array.isArray(o)&&o.forEach(s=>{let a=s.activeConnectionId||s.candidateConnectionIds?.[0];if(!n({deviceId:s.deviceId,deviceIdHint:s.deviceIdHint,nodeId:s.nodeId,connectionId:a})){a$1("[Client][PEER-SNAPSHOT] skipping rust session without identity",{status:s.status,health:s.health,settledReady:s.settledReady});return}let u=this.resolvePromotionEligibility({connectionId:a||void 0,deviceId:s.deviceId??void 0,deviceIdHint:s.deviceIdHint??void 0,nodeId:s.nodeId??void 0}),p=this.getConnectionTrustProjection({connectionId:a||void 0,deviceId:s.deviceId??void 0,deviceIdHint:s.deviceIdHint??void 0,nodeId:s.nodeId??void 0}),h=p?p.routable:!!s.settledReady;this.peerLifecycle.upsert({deviceId:p?.deviceId??s.deviceId??void 0,deviceIdHint:s.deviceIdHint,nodeId:s.nodeId,connectionId:a||void 0,status:h?"connected":this.mapRustPeerStatus(s.status),health:p?.health??this.mapRustPeerHealth(s.health),transportState:a?"connected":s.status==="connecting"?"connecting":"closed",protocolState:p?.protocolState??(h?"routable":a?"transport-only":s.status==="connecting"?"connecting":"closed"),routable:h,activeTransportStableId:s.activeTransportStableId??void 0,transportGeneration:s.transportGeneration,activeTransport:s.activeTransport,parallelTransport:s.parallelTransport??null,promotionEligible:u,scopes:s.scopes??[],error:p?.error??s.error??void 0,lastSeenAt:s.lastSeenAtMs}),t=true;});}else if(this.wasmClient&&typeof this.wasmClient.peer_snapshots=="function"){let o=await this.wasmClient.peer_snapshots();Array.isArray(o)&&o.forEach(s=>{let a=s.connectionIds?.[0];if(!n({deviceId:s.deviceId,deviceIdHint:s.deviceIdHint,nodeId:s.nodeId,connectionId:a})){a$1("[Client][PEER-SNAPSHOT] skipping rust snapshot without identity",{status:s.status,health:s.health});return}let u=this.resolvePromotionEligibility({connectionId:a,deviceId:s.deviceId??void 0,deviceIdHint:s.deviceIdHint??void 0,nodeId:s.nodeId??void 0});this.peerLifecycle.upsert({deviceId:s.deviceId,deviceIdHint:s.deviceIdHint,nodeId:s.nodeId,connectionId:a,status:s.status==="routable"?"connected":this.mapRustPeerStatus(s.status),health:this.mapRustPeerHealth(s.health),activeTransportStableId:s.activeTransportStableId??void 0,transportGeneration:s.activeTransportGeneration,activeTransport:s.activeTransport,parallelTransport:s.parallelTransport??null,promotionEligible:u,scopes:s.scopes??[],error:s.error??void 0,lastSeenAt:s.lastSeenAtMs}),t=true;});}(await this.searchDevices().catch(()=>[])).forEach(o=>{if(!n({deviceId:o.deviceId??null,nodeId:o.nodeId??null})){a$1("[Client][PEER-SNAPSHOT] skipping device projection without identity",{deviceName:o.deviceName??null,online:o.online??null});return}this.peerLifecycle.upsertDevice(o);}),e||this.connections.forEach(o=>{this.syncConnectionPeerLifecycle(o);});let r=await this.signaling.getConnectionStates().catch(()=>[]);return r.forEach(o=>{this.applyBackendConnectionState(o);}),e&&!t&&r.length===0?this.peerLifecycle.list():this.peerLifecycle.list()}async connectPeer(e){let t=e.scope??"persistent";if(!e.ticket)throw new Error("connectPeer requires a ticket.");console.info("[Client][connectPeer] starting",{scope:t,channelId:e.channelId??null,hasDeviceId:!!e.deviceId,ticketLength:e.ticket.length}),e.deviceId&&this.clearManualDisconnectProjection(e.deviceId);let n=await this.connect(e.ticket,2e4,e.deviceId,e.channelId),i=this.resolvePromotionEligibility({connectionId:n.id,nodeId:n.remoteNodeId,deviceId:e.deviceId??void 0}),r=e.deviceId||n.remoteNodeId||n.deviceId||n.id;return this.hasRustPeerLifecycleProjection()?this.refreshPeerSnapshot().catch(()=>{}):this.peerLifecycle.upsert({peerId:r,deviceId:e.deviceId,nodeId:n.deviceId,connectionId:n.id,ticket:e.ticket,status:"connected",health:"healthy",activeTransport:n.transportType,promotionEligible:i,scopes:[t],lastSeenAt:Date.now()}),this.addPeerScope(r,t),n}clearManualDisconnectProjection(e){let t=this.peerLifecycle.get(e);this.peerLifecycle.upsert({peerId:t?.peerId??e,deviceId:t?.deviceId??e,deviceIdHint:t?.deviceIdHint,nodeId:t?.nodeId,connectionId:t?.connectionId,status:"disconnected",health:"unknown",clearError:true,lastSeenAt:Date.now()});}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);await Promise.allSettled(Array.from(n).map(async i=>{let r=Array.from(this.connections.values()).filter(s=>{let a=s.id.trim().toLowerCase(),d=s.deviceId.trim().toLowerCase();return i===d||i===a||a.includes(i)});await Promise.allSettled(r.map(s=>s.disconnect()));let o=t?.nodeId||(r[0]?.deviceId??null);o&&i===o.trim().toLowerCase()&&await this.disconnectNode(o).catch(()=>{});})),this.hasRustPeerLifecycleProjection()?await this.refreshPeerSnapshot().catch(()=>{}):this.peerLifecycle.updateHealth(e,"stale","closed");}async getPeerHealth(e){let t=this.peerLifecycle.get(e);return t?t.health:"unknown"}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"}}async getTicket(){await this.ensureWasmRuntimeForP2P();let e=this.getRTCConfig(),t=this.options.transports?.iroh,n=typeof t=="object"&&t.relayOnly;return this.options.strictMode||e?.privacyMode||n?await this.wasmClient.endpoint_ticket():await this.wasmClient.endpoint_ticket()}async getNodeId(){return await this.ensureWasmRuntimeForP2P(),this.localNodeId}async getNodeIdFromTicket(e){let t=e.trim();if(!t)return null;let{irohTicket:n}=Qe(t);if(!this.wasmClient||typeof this.wasmClient.endpoint_id_from_ticket!="function")return null;try{return await this.wasmClient.endpoint_id_from_ticket(n)}catch{return null}}async getEndpointTicketWithToken(e,t=0){if(await this.ensureWasmRuntimeForP2P(),this.wasmClient&&typeof this.wasmClient.endpoint_ticket_with_token=="function")return await this.wasmClient.endpoint_ticket_with_token(e,t);if(e.trim()==="user-device")throw new Error("Managed user-device admission requires Rust/WASM endpoint_ticket_with_token support.");let n=await this.getTicket();return this.buildCompoundTicketWithToken(n,e,t)}buildCompoundTicketWithToken(e,t,n=0){let i=y.generateSessionToken();return this.wasmClient&&typeof this.wasmClient.register_session_token=="function"&&this.wasmClient.register_session_token(i,t,n),y.buildCompoundTicketWithPayload(e,i,t,n)}setManagedPresenceTicket(e){let t=e?.trim()||"";if(!t){this.managedPresenceGrant=null;return}let{irohTicket:n,tokenSuffix:i}=Qe(t),r=i?gt(i):null;if(!r?.t||!r?.s)throw new Error("Managed presence ticket must be a compound ticket with an embedded token payload");this.managedPresenceGrant={scope:r.s,token:r.t,maxConnections:typeof r.m=="number"?r.m:0,compoundTicket:t,irohTicket:n},this.wasmClient&&typeof this.wasmClient.register_session_token=="function"&&this.wasmClient.register_session_token(r.t,r.s,typeof r.m=="number"?r.m:0);}clearManagedPresenceTicket(){this.managedPresenceGrant=null;}registerSessionToken(e,t,n){this.wasmClient&&typeof this.wasmClient.register_session_token=="function"&&this.wasmClient.register_session_token(e,t,n);}revokeSessionToken(e){i("Client.revokeSessionToken",{tokenLength:e.length}),this.wasmClient&&typeof this.wasmClient.revoke_session_token=="function"&&this.wasmClient.revoke_session_token(e);}async revokeTokensByScope(e){if(i("Client.revokeTokensByScope",{grantScope:e}),await this.ensureWasmRuntimeForP2P(),!this.wasmClient||typeof this.wasmClient.revoke_tokens_by_scope!="function")return [];let t=await this.wasmClient.revoke_tokens_by_scope(e);if(!Array.isArray(t)||t.length===0)return [];let n=t.map(i=>this.connections.get(i)).filter(i=>!!i);return await Promise.allSettled(n.map(i=>i.disconnect())),t}static generateSessionToken(){let e=new Uint8Array(24);return crypto.getRandomValues(e),btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}static encodeSessionTokenPayload(e,t,n){return btoa(JSON.stringify({t:e,s:t,m:n})).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}static buildCompoundTicketWithPayload(e,t,n,i){return `${e}.${y.encodeSessionTokenPayload(t,n,i)}`}async clearSessionTokens(){i("Client.clearSessionTokens",{}),await this.ensureWasmRuntimeForP2P(),this.clearManagedPresenceTicket(),this.pendingTokenByNodeId.clear(),this.wasmClient&&typeof this.wasmClient.clear_session_tokens=="function"&&this.wasmClient.clear_session_tokens();}async resolvePresenceTicket(e){let t=e?.trim();if(t)return t;if(this.managedPresenceGrant)return this.refreshManagedPresenceTicketIfNeeded();let n=this.options.ticket?.trim();return n||this.getTicket()}async refreshManagedPresenceTicketIfNeeded(){let e=this.managedPresenceGrant;if(!e)return this.getTicket();let t=e.irohTicket;try{t=await this.getTicket();}catch{return e.compoundTicket}if(t===e.irohTicket)return e.compoundTicket;if(this.wasmClient&&typeof this.wasmClient.endpoint_ticket_with_token=="function"){let n=await this.wasmClient.endpoint_ticket_with_token(e.scope,e.maxConnections),{irohTicket:i,tokenSuffix:r}=Qe(n),o=r?gt(r):null;return e.irohTicket=i,e.compoundTicket=n,o?.t&&o?.s&&(e.token=o.t,e.scope=o.s,e.maxConnections=typeof o.m=="number"?o.m:0),console.info("[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=y.buildCompoundTicketWithPayload(t,e.token,e.scope,e.maxConnections),console.info("[Client][PRESENCE] rebuilt managed compound ticket after endpoint change",{grantScope:e.scope}),e.compoundTicket}async validateIncomingSessionToken(e,t){if(!this.wasmClient||typeof this.wasmClient.validate_session_token!="function")return {ok:true};try{let n="";return t&&typeof this.wasmClient.validate_session_token_for_connection=="function"?n=await this.wasmClient.validate_session_token_for_connection(e,t):n=this.wasmClient.validate_session_token(e),{ok:!0,scope:n||void 0}}catch(n){return {ok:false,reason:n?.message||`${n}`}}}async validateIncomingSessionTokenWithRetry(e,t,n){let i=await this.validateIncomingSessionToken(e,t);if(i.ok||!e||!(i.reason??"").toLowerCase().includes("unknown session token"))return i;for(let o=1;o<=y.SESSION_TOKEN_UNKNOWN_RETRY_ATTEMPTS;o+=1)if(await this.sleep(y.SESSION_TOKEN_UNKNOWN_RETRY_DELAY_MS*o),i=await this.validateIncomingSessionToken(e,t),i.ok)return console.info("[Client][SESSION-TOKEN] validation recovered after retry",{source:n?.source??"unknown",remoteNodeId:n?.remoteNodeId??null,connectionId:t??null,attempt:o}),i;return i}async startPresenceLoop(e){if(await this.ensureWasmRuntimeForP2P(),!this.localNodeId)throw new Error("startPresenceLoop requires an initialized node");let t=(this.options.discoveryMode===void 0||this.options.discoveryMode==="personal")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0,n=this.currentUser?.id??(t?this.localNodeId:null);if(!n)throw new Error("startPresenceLoop requires an authenticated user");let i=await this.resolvePresenceTicket(e?.ticket);if(!i||!i.trim())throw new Error("startPresenceLoop requires a valid endpoint ticket");this.signaling.startPresenceLoop(n,this.localNodeId,e?.deviceName||this.options.deviceName||"Unknown Device",i,e?.metadata);}async setOffline(){this.localNodeId&&await this.signaling.setOffline(this.localNodeId);}async isConnected(e){return await this.ensureWasmRuntimeForP2P(),!e||!e.trim()?false:this.wasmClient&&typeof this.wasmClient.is_connected=="function"?this.wasmClient.is_connected(e):this.signaling.isConnected(e)}async disconnectNode(e){if(!e||!e.trim())return;let t=Array.from(this.connections.values()).filter(n=>n.deviceId===e);await Promise.allSettled(t.map(n=>n.disconnect())),await this.disconnectNodeTransport(e);}async getLocalDeviceId(){return this.signaling.getLocalDeviceId()}async acceptNativeMessage(e,t,n){if(!t)return false;let i=this.getDeterministicConnectionId(t),r=this.connections.get(i);if(r)return this.handleMessage(r,n),false;if(n&&typeof n=="object"&&n.type==="handshake"&&(n.action==="hello"||!n.action)){let o=await this.validateIncomingSessionTokenWithRetry(n.sessionToken??"",e??void 0,{remoteNodeId:t,source:"accept-native-message"});if(!o.ok)return console.warn("[Client][SESSION-TOKEN] Rejecting native connection \u2014 invalid session token",{remoteNodeId:t,reason:o.reason,hasToken:!!n.sessionToken}),true}return false}async startListening(){if(this.listening)return;await this.ensureWasmRuntimeForP2P(),this.listening=true;let e=this.getSharedIncomingStreamHub();e?e.addClient(this):this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null;}));let t=this.signaling.currentUser?.id;if(t&&this.localNodeId){let n=await this.resolvePresenceTicket();this.signaling.startPresenceLoop(t,this.localNodeId,this.options.deviceName||"Unknown Device",n,"");}}stopListening(){this.listening=false,this.getSharedIncomingStreamHub()?.removeClient(this),this.localNodeId&&this.signaling.setOffline(this.localNodeId);}getSharedIncomingStreamHub(){if(!this.wasmClient||typeof this.wasmClient.incoming_streams!="function")return null;let e=this.wasmClient,t=y.incomingStreamHubs.get(e);return t||(t=new ft(this.wasmClient),y.incomingStreamHubs.set(e,t)),t}nextIncomingStreamRetryDelayMs(e){let t=y.INCOMING_STREAM_RETRY_MIN_DELAY_MS*Math.pow(2,Math.max(0,e-1));return Math.min(y.INCOMING_STREAM_RETRY_MAX_DELAY_MS,t)}getRuntimeSafetyProfile(){return this.runtimeSafetyProfile??at(this.options??{})}shouldVerboseIncomingDiagnostics(){return this.getRuntimeSafetyProfile().diagnosticsMode}shouldUseTransportOnlyChannelConnection(e){return this.isTransportOnlyChannel(e)}createTransportOnlyChannelConnection(e,t){let n=this,i=false,r=new Set,o=new Set,s=new Set;return {id:e,localNodeId:this.localNodeId,remoteNodeId:t,deviceId:t,get isClosed(){return i},get transportType(){return "iroh"},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(){i||(i=true,await n.disconnectNodeTransport(t).catch(()=>{}),s.forEach(a=>a()));},onMessage(a){typeof a=="function"&&r.add(a);},onMedia(a){typeof a=="function"&&o.add(a);},onDisconnect(a){typeof a=="function"&&s.add(a);}}}shouldInspectIncomingChannelEnvelope(){return !(!this.hasAnyIncomingChannelListeners()||this.getRuntimeSafetyProfile().skipIncomingChannelEnvelopeInspection)}createTransportContext(e){let t=this.getRuntimeSafetyProfile();return {priorities:this.options.transportPriority||["webrtc","moq","iroh"],disableIrohFallback:this.options.disableIrohFallback||false,isMoQReady:()=>this.moqState==="ready",sendMoQ:n=>this.sendMoQData(e,n),runtimeFlow:t.flow,readerCloseStrategy:t.readerCloseStrategy}}hasTransportOnlyConnectionForRemoteNode(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;for(let n of this.connections.values())if(n.remoteNodeId===t&&this.isTransportOnlyConnectionId(n.id))return true;return false}shouldSkipIncomingBiProbeForRemoteNode(e){return this.getRuntimeSafetyProfile().skipIncomingBiProbe?this.usesTicketOnlySignalingMode()?true:this.hasTransportOnlyConnectionForRemoteNode(e):false}async disconnectNodeTransport(e){if(!(!e||!e.trim())){if(this.wasmClient&&typeof this.wasmClient.disconnect=="function")try{await this.wasmClient.disconnect(e);}catch{}this.signaling.notifyDisconnectRequested(e);}}nextIncomingTraceId(e,t){Number.isFinite(this.incomingTraceSequence)||(this.incomingTraceSequence=0),this.incomingTraceSequence+=1;let n=t&&t.length>0?t.slice(0,8):"unknown";return `${e}-${n}-${this.incomingTraceSequence.toString(36)}`}logIncomingDiagnostic(e,t){this.shouldVerboseIncomingDiagnostics()&&console.info(`[Client][INCOMING][MOBILE] ${e}`,t);}async awaitConnectEventReady(e,t,n){let i=null;try{i=e.getReader();}catch(o){console.warn("[Client][CONNECT] connect event stream reader unavailable",{nodeId:t,error:o});return}let r=Date.now()+Math.max(1,n);try{for(;Date.now()<r;){let o=Math.max(1,r-Date.now()),{done:s,value:a}=await ve(i.read(),o).catch(()=>({done:!0,value:null}));if(s)return;let d=typeof a?.type=="string"?a.type:"unknown";if(d==="connected"){this.logIncomingDiagnostic("connect-events:connected",{nodeId:t});return}if(d==="closed"){this.logIncomingDiagnostic("connect-events:closed",{nodeId:t,error:typeof a?.error=="string"?a.error:null});return}}}catch(o){console.warn("[Client][CONNECT] connect event stream read failed",{nodeId:t,error:o});}finally{if(i)try{i.releaseLock();}catch{}}}safeReleaseReaderLock(e,t,n){try{e.releaseLock(),this.logIncomingDiagnostic("releaseLock:ok",{context:t,traceId:n||null});}catch(i){console.warn("[Client][INCOMING] releaseLock failed",{context:t,traceId:n||null,error:i});}}forceReconnectSnapshot(){this.signaling.forceReconnectSnapshot();}async updatePresenceInternal(){if(this.localNodeId){let e=await this.resolvePresenceTicket();await this.updatePresence(true,this.options.deviceTTL,void 0,e);}}async listenLoop(){let e=0;for(;this.listening;){if(!this.wasmClient||typeof this.wasmClient.incoming_streams!="function"){console.warn("[Client][INCOMING] incoming_streams is unavailable; stopping listen loop");return}let t=null;try{t=(await this.wasmClient.incoming_streams()).getReader();let i=t;for(e=0,this.shouldVerboseIncomingDiagnostics()&&console.info("[Client][INCOMING][MOBILE] direct listen reader acquired",{localNodeId:this.localNodeId||null});this.listening;){let{done:r,value:o}=await i.read();if(r)throw new Error("incoming stream reader closed unexpectedly");if(!o)continue;let s=ye(o);s!=="uni"&&console.debug("[Client][INCOMING] Received stream from WASM node",{type:s,endpointId:ae(o)});try{await this.handleIncomingStream(o);}catch(a){let d=o,u=ye(d),p=ae(d);console.error("[Client][INCOMING] Failed to handle incoming stream",{remoteNodeId:p,type:u,error:a});}}}catch(n){if(!this.listening)break;e+=1;let i=this.nextIncomingStreamRetryDelayMs(e);console.warn("[Client][INCOMING] Listen loop restarting after stream failure",{attempt:e,delayMs:i,mobile:J(),error:n}),await this.sleep(i);}finally{if(t)try{t.releaseLock(),this.shouldVerboseIncomingDiagnostics()&&console.info("[Client][INCOMING][MOBILE] direct listen reader released",{localNodeId:this.localNodeId||null});}catch{}}}}prependChunkToReadable(e,t,n="prependChunkToReadable",i){let r=false,o=a=>this.safeReleaseReaderLock(e,`${n}:${a}`,i),s=(a,d)=>this.logIncomingDiagnostic(a,d);return new ReadableStream({async pull(a){if(!r){r=true,a.enqueue(t);return}let d;try{d=await e.read();}catch(h){a.error(h),o("read-error"),s("prepend-chunk:read-error",{context:n,traceId:i||null,error:h?.message||String(h)});return}let{done:u,value:p}=d;if(u){a.close(),o("done");return}p&&a.enqueue(p);},async cancel(a){o("cancel");}})}async cancelUnhandledIncomingUniStream(e,t){if(!(!e||typeof e!="object")){if(this.shouldVerboseIncomingDiagnostics()){this.logIncomingDiagnostic("uni:drop-unhandled",{remoteNodeId:t||"unknown"});return}try{let n=e;if(typeof n.cancel=="function")return;if(typeof n.getReader=="function"){let i=n.getReader();try{await i.read().catch(()=>{});}finally{try{i.releaseLock();}catch{}}c$2("[Client][INCOMING] Released unhandled uni stream reader",{remoteNodeId:t});}}catch(n){console.warn("[Client][INCOMING] Failed to cancel unhandled uni stream",{remoteNodeId:t,error:n});}}}prependBytesToReader(e,t,n="prependBytesToReader",i){let r=t.byteLength===0,o=a=>this.safeReleaseReaderLock(e,`${n}:${a}`,i),s=(a,d)=>this.logIncomingDiagnostic(a,d);return new ReadableStream({async pull(a){if(!r){r=true,a.enqueue(t);return}let d;try{d=await e.read();}catch(h){a.error(h),o("read-error"),s("prepend-bytes:read-error",{context:n,traceId:i||null,error:h?.message||String(h)});return}let{done:u,value:p}=d;if(u){a.close(),o("done");return}p&&a.enqueue(p);},async cancel(a){o("cancel");}})}concatBytes(e){let t=e.reduce((r,o)=>r+o.byteLength,0),n=new Uint8Array(t),i=0;for(let r of e)n.set(r,i),i+=r.byteLength;return n}encodeChannelEnvelope(e,t){let n=e.trim();if(!n)throw new Error("Channel envelope requires a non-empty channel id.");let i=new TextEncoder,r=i.encode(n),o=t?i.encode(JSON.stringify(t)):new Uint8Array(0),s=new Uint8Array(y.CHANNEL_ENVELOPE_HEADER_BYTES+r.byteLength+o.byteLength),a=new DataView(s.buffer);return s[0]=y.CHANNEL_ENVELOPE_MAGIC,s[1]=y.CHANNEL_ENVELOPE_VERSION,a.setUint16(2,r.byteLength,false),a.setUint16(4,o.byteLength,false),s.set(r,y.CHANNEL_ENVELOPE_HEADER_BYTES),s.set(o,y.CHANNEL_ENVELOPE_HEADER_BYTES+r.byteLength),s}wrapChannelWritable(e,t,n){let i=this.encodeChannelEnvelope(t,n),r=e.getWriter(),o=false,s=async()=>{o||(o=true,await r.write(i));};return new WritableStream({write:async a=>{await s(),await r.write(a);},close:async()=>{await s();try{await r.close();}finally{r.releaseLock();}},abort:async a=>{try{await r.abort(a);}finally{r.releaseLock();}}})}async extractIncomingChannelEnvelope(e,t,n){if(!this.isBiStreamLike(e))return {stream:e,channel:null};let i;try{i=e.recv.getReader(),this.logIncomingDiagnostic("channel-envelope:reader-acquired",{traceId:n||null,remoteNodeId:t||"unknown"});}catch(w){return console.warn("[Client][CHANNEL] Incoming stream recv reader unavailable; skipping channel envelope inspection",{remoteNodeId:t,traceId:n||null,error:w}),{stream:e,channel:null}}let r=[],o=0;try{for(;o<y.CHANNEL_ENVELOPE_HEADER_BYTES;){let{done:w,value:S}=await i.read();if(w)break;if(!S||S.byteLength===0)continue;let L=new Uint8Array(S);r.push(L),o+=L.byteLength;}}catch(w){return console.warn("[Client][CHANNEL] Failed reading incoming channel envelope prefix",{remoteNodeId:t,traceId:n||null,error:w}),this.safeReleaseReaderLock(i,"extractIncomingChannelEnvelope:read-prefix-failed",n),{stream:e,channel:null}}let s=this.concatBytes(r);if(s.byteLength<y.CHANNEL_ENVELOPE_HEADER_BYTES||s[0]!==y.CHANNEL_ENVELOPE_MAGIC||s[1]!==y.CHANNEL_ENVELOPE_VERSION)return {stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,s,"extractIncomingChannelEnvelope:not-envelope",n)),channel:null};let a=new DataView(s.buffer,s.byteOffset,s.byteLength),d=a.getUint16(2,false),u=a.getUint16(4,false),p=y.CHANNEL_ENVELOPE_HEADER_BYTES+d+u,h=s;if(h.byteLength<p)try{for(;h.byteLength<p;){let{done:w,value:S}=await i.read();if(w)break;!S||S.byteLength===0||(h=this.concatBytes([h,new Uint8Array(S)]));}}catch(w){console.warn("[Client][CHANNEL] Failed extending incoming channel envelope read",{remoteNodeId:t,error:w});}if(h.byteLength<p||d===0)return {stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,h,"extractIncomingChannelEnvelope:truncated-envelope",n)),channel:null};let g=y.CHANNEL_ENVELOPE_HEADER_BYTES,f=g+d,v=f+u,I=new TextDecoder,_=I.decode(h.slice(g,f)).trim(),M=null;if(u>0)try{let w=JSON.parse(I.decode(h.slice(f,v)));w&&typeof w=="object"&&!Array.isArray(w)&&(M=w);}catch(w){console.warn("[Client][CHANNEL] Failed to parse incoming channel metadata",{remoteNodeId:t,channelId:_,error:w});}return _?{stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,h.slice(p),"extractIncomingChannelEnvelope:channel-envelope-consumed",n)),channel:{channelId:_,metadata:M}}:{stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,h,"extractIncomingChannelEnvelope:empty-channel-id",n)),channel:null}}isBiStreamLike(e){try{let t=e;return !!t&&!!t.send&&typeof t.send.getWriter=="function"&&!!t.recv&&typeof t.recv.getReader=="function"}catch{return false}}materializeIncomingBiStream(e,t){let n=e;if(!n)return null;try{let i=n.send,r=n.recv;if(!i||typeof i.getWriter!="function"||!r||typeof r.getReader!="function")return null;let o=typeof n.endpoint_id=="string"&&n.endpoint_id.trim().length>0?n.endpoint_id:t;return {send:i,recv:r,endpoint_id:o}}catch{return null}}rebuildBiIncomingStream(e,t){return {send:e.send,recv:t,endpoint_id:typeof e.endpoint_id=="string"?e.endpoint_id:""}}async classifyBiIncomingStream(e,t){if(!this.isBiStreamLike(e))return {stream:e,protocolHint:"unknown"};let n;try{n=e.recv.getReader();}catch{return {stream:e,protocolHint:"unknown"}}let i;try{i=await n.read();}catch{return this.safeReleaseReaderLock(n,"classifyBiIncomingStream:read-failed",t),{stream:e,protocolHint:"unknown"}}if(i.done||!i.value||i.value.byteLength===0)return this.safeReleaseReaderLock(n,"classifyBiIncomingStream:empty-first-read",t),console.debug("[Client][INCOMING] classifyBiIncomingStream: empty read",{traceId:t||null,done:i.done,hasValue:!!i.value,byteLength:i.value?.byteLength}),{stream:e,protocolHint:"unknown"};let r=new Uint8Array(i.value),o=r[0];console.debug("[Client][INCOMING] classifyBiIncomingStream: first byte",{traceId:t||null,firstByte:"0x"+o.toString(16),EXPLICIT_PROTOCOL_BYTE:"0x"+y.EXPLICIT_PROTOCOL_BYTE.toString(16),isExplicit:o===y.EXPLICIT_PROTOCOL_BYTE,chunkLength:r.length});let s=this.rebuildBiIncomingStream(e,this.prependChunkToReadable(n,r,"classifyBiIncomingStream:first-chunk",t));return o===y.EXPLICIT_PROTOCOL_BYTE?{stream:s,protocolHint:"explicit"}:{stream:s,protocolHint:"control"}}async detectNativeMainStream(e,t,n){if(!this.isBiStreamLike(e))return {handled:false,stream:e,protocolHint:"unknown"};let i;try{i=e.recv.getReader();}catch(_){return console.warn("[Client][NATIVE-MAIN] Incoming stream recv reader unavailable",{remoteNodeId:t,traceId:n||null,error:_}),{handled:false,stream:e,protocolHint:"control"}}let r=[],o=0,s=5,a=false;try{for(;o<s;){let{done:_,value:M}=await i.read();if(_){a=!0;break}!M||M.byteLength===0||(r.push(new Uint8Array(M)),o+=M.byteLength);}}catch(_){return console.warn("[Client][NATIVE-MAIN] Failed reading incoming prefix",{remoteNodeId:t,traceId:n||null,error:_}),this.safeReleaseReaderLock(i,"detectNativeMainStream:read-prefix-failed",n),{handled:false,stream:e,protocolHint:"control"}}let d=this.concatBytes(r);if(d.byteLength<s||d[0]!==y.NATIVE_MAIN_PROTOCOL_BYTE)return {handled:false,stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,d,"detectNativeMainStream:not-native-main",n)),protocolHint:d[0]===y.EXPLICIT_PROTOCOL_BYTE?"explicit":"control"};let u=new DataView(d.buffer,d.byteOffset,d.byteLength).getUint32(1,false);if(u===0||u>y.NATIVE_MAIN_MAX_LABEL_BYTES)return {handled:false,stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,d,"detectNativeMainStream:invalid-label-length",n)),protocolHint:"control"};let p=5+u,h=d;if(h.byteLength<p&&!a){let _=[h],M=h.byteLength;try{for(;M<p;){let{done:k,value:w}=await i.read();if(k){a=!0;break}if(!w||w.byteLength===0)continue;let S=new Uint8Array(w);_.push(S),M+=S.byteLength;}}catch(k){console.warn("[Client][NATIVE-MAIN] Failed extending prefix read",{remoteNodeId:t,error:k});}h=this.concatBytes(_);}if(h.byteLength<p)return {handled:false,stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,h,"detectNativeMainStream:truncated-label",n)),protocolHint:"control"};let g=h.slice(5,p),f=new TextDecoder().decode(g);if(f!==y.NATIVE_MAIN_LABEL)return {handled:false,stream:this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,h,"detectNativeMainStream:label-mismatch",n)),protocolHint:"control"};let v=h.slice(p),I=this.rebuildBiIncomingStream(e,this.prependBytesToReader(i,v,"detectNativeMainStream:label-consumed",n));return b$1("[Client][NATIVE-MAIN] Detected desktop native main stream",{remoteNodeId:t,traceId:n||null,label:f}),{handled:true,stream:I,protocolHint:"native-main"}}async resolveLocalHandshakePayload(){let e=await this.getLocalDeviceId().catch(()=>null)||this.deviceId||this.options.localDeviceId;if(!e)throw new Error("Local device id unavailable for native handshake response");let t=typeof window<"u"&&typeof window.__TAURI__<"u",n=t?J()?"mobile":"desktop":"web",i=t?{canHost:true,canSync:true,readOnly:false}:{canHost:false,canSync:true,readOnly:false},r=n==="mobile"?"Mobile Device":n==="desktop"?"Desktop Device":"Browser Device";return {deviceId:e,deviceName:this.options.deviceName||r,platformType:n,capabilities:i,protocolVersion:y.NATIVE_MAIN_PROTOCOL_VERSION,timestamp:Date.now()}}getDeterministicConnectionId(e){return this.localNodeId?this.localNodeId<=e?`${this.localNodeId}-${e}`:`${e}-${this.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=r=>{if(!r)return false;let o=String(r.status??"").toLowerCase(),s=String(r.error??"").toLowerCase();return (o==="closed"||o==="disconnected"||o==="failed")&&s.includes("manual disconnect")};for(let r of [e,n]){let o=this.peerLifecycle?.get?.(r);if(i(o))return o}return this.peerLifecycle?.list?.().find(r=>{if(!i(r))return false;let o=String(r.nodeId??"").trim().toLowerCase(),s=String(r.connectionId??"").trim().toLowerCase(),a=Array.isArray(r.connectionIds)?r.connectionIds.map(d=>String(d??"").trim().toLowerCase()):[];return o===t||s===n||s.endsWith(`-${t}`)||a.includes(n)||a.some(d=>d.endsWith(`-${t}`))})??null}hasKnownConnectionForRemoteNode(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;if(this.connections?.has(this.getDeterministicConnectionId(t)))return true;for(let n of this.connections?.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 r=this.peerLifecycle?.get?.(t);i=Array.isArray(r?.scopes)&&r.scopes.includes("magic-link");}catch{i=false;}return {protocolHint:this.hasAnyIncomingChannelListeners()||(this.streamListeners?.length??0)>0||i?"explicit":"control",hasExistingConnection:n,hasMagicLinkScope:i}}hasRustPeerLifecycleProjection(){return this.signaling&&typeof this.signaling.supportsRustPeerLifecycleProjection=="function"&&this.signaling.supportsRustPeerLifecycleProjection()?true:!!(this.wasmClient&&(typeof this.wasmClient.peer_sessions=="function"||typeof this.wasmClient.peer_snapshots=="function"))}shouldProjectNativeMainLifecycle(){return !this.hasRustPeerLifecycleProjection()}emitNativeMainConnectionState(e,t,n){if(!this.shouldProjectNativeMainLifecycle())return;let i=this.getNativeMainConnectionId(e),r=this.peerLifecycle&&typeof this.peerLifecycle.get=="function"?this.peerLifecycle.get(i):void 0,o={connectionId:i,deviceId:n,remoteNodeId:e,state:t,transportState:t==="connected"?"connected":"closed",protocolState:t==="connected"?"routable":"closed",routable:t==="connected",updatedAt:Date.now()},s=r&&r.status===o.state&&r.deviceId===o.deviceId&&r.nodeId===o.remoteNodeId&&r.transportState===o.transportState&&r.protocolState===o.protocolState&&r.routable===o.routable;!o.deviceId&&!r||(this.peerLifecycle.upsert({deviceId:o.deviceId,nodeId:o.remoteNodeId,connectionId:o.connectionId,status:o.state==="connected"?"connected":"closed",health:o.state==="connected"?"healthy":"stale",transportState:o.transportState,protocolState:o.protocolState,routable:o.routable,lastSeenAt:o.updatedAt}),!(s||typeof window>"u")&&window.dispatchEvent(new CustomEvent(y.CONNECTION_STATE_CHANGED_EVENT,{detail:{connectionId:o.connectionId,deviceId:o.deviceId??null,remoteNodeId:o.remoteNodeId,state:o.state,transportState:o.transportState,protocolState:o.protocolState,routable:o.routable,updatedAt:o.updatedAt}})));}applyBackendConnectionState(e){if(!e?.connectionId)return;let t=this.getConnectionTrustProjection({connectionId:e.connectionId,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.remoteNodeId??void 0}),n=this.peerLifecycle&&typeof this.peerLifecycle.get=="function"?this.peerLifecycle.get.bind(this.peerLifecycle):null,i=n?.(e.connectionId)??(e.remoteNodeId?n?.(e.remoteNodeId):void 0),r=e.deviceId??t?.deviceId??i?.deviceId??void 0,o=e.deviceIdHint??i?.deviceIdHint??void 0;if(!r&&!o&&!i)return;a$1("[Client] applyBackendConnectionState",{connectionId:e.connectionId,deviceId:r??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:i?.peerId??null});let s=e.state==="closed"||e.state==="failed"||e.state==="disconnected",a=s?false:t?t.routable:e.routable,d=s?e.protocolState??"closed":t?.protocolState??e.protocolState,u=s?e.error??e.lastDisconnectReason??t?.error:t?.error??e.error,p=s?"stale":t?.health??(e.routable||e.readinessState==="routable"||e.transportState==="connected"?"healthy":e.state==="failed"||e.state==="closed"?"stale":"unknown");this.peerLifecycle.upsert({peerId:i?.peerId??void 0,deviceId:r,deviceIdHint:o,nodeId:e.remoteNodeId??i?.nodeId??void 0,connectionId:e.connectionId,status:e.state==="connected"?"connected":e.state==="connecting"||e.state==="new"?"connecting":e.state==="failed"?"failed":e.state==="closed"?"closed":"disconnected",health:p,transportState:e.transportState,protocolState:d,routable:a,activeTransportStableId:e.activeTransportStableId??void 0,transportGeneration:e.transportGeneration,activeTransport:e.activeTransport,parallelTransport:e.parallelTransport??null,error:u,lastSeenAt:e.updatedAt??Date.now()});}encodeNativeMainFrame(e){let t=new TextEncoder().encode(JSON.stringify(e)),n=new TextEncoder().encode(y.NATIVE_MAIN_LABEL),i=new Uint8Array(5+n.byteLength+4+t.byteLength),r=new DataView(i.buffer),o=0;return i[o]=y.NATIVE_MAIN_PROTOCOL_BYTE,o+=1,r.setUint32(o,n.byteLength,false),o+=4,i.set(n,o),o+=n.byteLength,r.setUint32(o,t.byteLength,false),o+=4,i.set(t,o),i}dispatchNativeMainMessage(e,t){typeof window>"u"||typeof window.dispatchEvent!="function"||window.dispatchEvent(new CustomEvent(y.NATIVE_MAIN_MESSAGE_EVENT,{detail:{remoteNodeId:e,message:t}}));}async writeNativeMainMessage(e,t){await e.write(this.encodeNativeMainFrame(t));}async handleNativeHandshakeRequest(e,t,n){let i=await this.resolveLocalHandshakePayload(),r=n.payload&&typeof n.payload.deviceId=="string"?n.payload.deviceId:void 0,o={channel:"handshake",action:"response",requestId:n.requestId,payload:{accepted:true,...i},timestamp:Date.now()};await this.writeNativeMainMessage(e,o),this.emitNativeMainConnectionState(t,"connected",r),b$1("[Client][NATIVE-MAIN] Responded to desktop handshake",{remoteNodeId:t,requestId:n.requestId??null,localDeviceId:i.deviceId});}async handleNativeSessionTokenRequest(e,t,n){let r=this.sessionTokenRejectionCooldowns.get(t),o=this.getNativeMainConnectionId(t);if(r!==void 0&&Date.now()-r<5e3){let u={channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:"session-token-rejection-cooldown",connectionId:o},timestamp:Date.now()};await this.writeNativeMainMessage(e,u),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=await this.validateIncomingSessionTokenWithRetry(s,o,{remoteNodeId:t,source:"native-main-session-token"}),d=a.ok?{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:true,scope:a.scope??null,connectionId:o},timestamp:Date.now()}:{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:a.reason??"session-token-rejected",connectionId:o},timestamp:Date.now()};if(await this.writeNativeMainMessage(e,d),a.ok){let u=this.connections.get(o);u&&!u.isClosed?(this.applySessionTokenTrustApproval(u,a.scope??null,"native-main-session-token"),u.requestTransportRecovery("managed-token-approved",{forceRenegotiate:true,replaceExisting:true})):(this.pendingSessionTokenTrustApprovals.set(o,Date.now()),this.sessionTokenApprovedNodes.add(t),this.sessionTokenApprovedConnectionIds.add(o)),this.sessionTokenRejectionCooldowns.delete(t),this.trustFailureCooldowns.delete(t),console.info("[Client][AUTH] host approved managed session token",{remoteNodeId:t,connectionId:o,scope:a.scope??null}),(!u||u.isClosed)&&this.ensureIncomingConnectionForRemoteNode(t).then(p=>{p?console.info("[Client][AUTH] post-approval kickstart opened control connection",{remoteNodeId:t,connectionId:p.id}):console.warn("[Client][AUTH] post-approval kickstart failed to open control connection",{remoteNodeId:t,connectionId:o});}).catch(p=>{console.warn("[Client][AUTH] post-approval kickstart error",{remoteNodeId:t,connectionId:o,error:p});});return}console.warn("[Client][AUTH] host rejected managed session token",{remoteNodeId:t,connectionId:o,reason:a.reason??"session-token-rejected",hasToken:s.length>0}),this.sessionTokenRejectionCooldowns.set(t,Date.now()),this.wasmClient&&typeof this.wasmClient.disconnect=="function"&&this.wasmClient.disconnect(t).catch(()=>{});}isNativeSignalEnvelope(e){if(!e||typeof e!="object")return false;let t=e;return t.type==="#pluto-signal"&&typeof t.content=="object"&&t.content!==null}buildNativeMainPayload(e){let t=JSON.stringify(e),n=new TextEncoder().encode(t),i=new Uint8Array(1+n.byteLength);return i[0]=0,i.set(n,1),i}buildFramedMessage(e){let t=new ArrayBuffer(4+e.byteLength);new DataView(t).setUint32(0,e.byteLength,false);let i=new Uint8Array(t);return i.set(e,4),i}buildNativeMainLabelHeader(){let e=new TextEncoder().encode("main"),t=new ArrayBuffer(5+e.byteLength),n=new Uint8Array(t);return n[0]=0,new DataView(t).setUint32(1,e.byteLength,false),n.set(e,5),n}async writeNativeMainLabelHeaderOnBiStream(e,t){let n=e.send.getWriter();try{await n.write(this.buildNativeMainLabelHeader());}catch(i){throw console.warn("[Client][NATIVE-MAIN] Label header write failed",{remoteNodeId:t,error:i}),i}finally{try{n.releaseLock();}catch{}}}registerInboundNativeMainWriter(e,t){let n=this.inboundNativeMainWriters instanceof Map?this.inboundNativeMainWriters:null;if(!n||!e||!t)return;let i=this.inboundNativeMainWriterMeta instanceof Map?this.inboundNativeMainWriterMeta:null,r=n.get(e);this.inboundNativeMainWriterSeq+=1;let o=this.inboundNativeMainWriterSeq;n.set(e,t),this.inboundNativeMainBypassUntilMs instanceof Map&&this.inboundNativeMainBypassUntilMs.delete(e),i?.set(e,{id:o,registeredAtMs:Date.now()}),console.info("[Client][NATIVE-MAIN] Inbound control writer registered",{remoteNodeId:e,writerId:o,replacedExistingWriter:!!r&&r!==t}),console.info("[SIGNAL-STREAM][TS] writer-registered",{remoteNodeId:e,writerId:o,replacedExistingWriter:!!r&&r!==t});}clearInboundNativeMainWriter(e,t,n="stream-finalize"){let i=this.inboundNativeMainWriters instanceof Map?this.inboundNativeMainWriters:null,r=this.inboundNativeMainWriteMutex instanceof Map?this.inboundNativeMainWriteMutex:null,o=this.inboundNativeMainWriterMeta instanceof Map?this.inboundNativeMainWriterMeta:null;if(!i||!r)return;let s=i.get(e),a=o?.get(e);s===t?(i.delete(e),o?.delete(e),this.inboundNativeMainBypassUntilMs.set(e,Date.now()+y.INBOUND_WRITER_RETRY_COOLDOWN_MS),console.info("[Client][NATIVE-MAIN] Inbound control writer cleared",{remoteNodeId:e,writerId:a?.id??null,ageMs:a?Date.now()-a.registeredAtMs:null,reason:n}),console.info("[SIGNAL-STREAM][TS] writer-cleared",{remoteNodeId:e,writerId:a?.id??null,ageMs:a?Date.now()-a.registeredAtMs:null,reason:n})):console.info("[Client][NATIVE-MAIN] Inbound control writer clear skipped (mismatch)",{remoteNodeId:e,activeWriterId:a?.id??null,reason:n}),r.delete(e);}async sendNativeSignalViaInboundControlStream(e,t,n={}){let i=this.inboundNativeMainWriters instanceof Map?this.inboundNativeMainWriters:null,r=this.inboundNativeMainWriteMutex instanceof Map?this.inboundNativeMainWriteMutex:null,o=this.inboundNativeMainWriterMeta instanceof Map?this.inboundNativeMainWriterMeta:null;if(!i||!r)return {sent:false,reason:"writer-or-mutex-map-unavailable",writerId:null,writerAgeMs:null,error:null};let s=o?.get(e),a=this.inboundNativeMainBypassUntilMs instanceof Map?this.inboundNativeMainBypassUntilMs:null,d=a?.get(e)??0;if(!n.ignoreCooldown&&d>Date.now())return {sent:false,reason:"inbound-writer-cooldown",writerId:s?.id??null,writerAgeMs:s?Date.now()-s.registeredAtMs:null,error:null};let u=i.get(e),p=s?.id??null,h=s?Date.now()-s.registeredAtMs:null;if(!u)return a?.set(e,Date.now()+y.INBOUND_WRITER_RETRY_COOLDOWN_MS),{sent:false,reason:"no-inbound-writer",writerId:p,writerAgeMs:h,error:null};let g=this.buildFramedMessage(this.buildNativeMainPayload(t)),f=r.get(e)??Promise.resolve(),v,I=new Promise(_=>{v=_;});r.set(e,I);try{return await f.catch(()=>{}),await u.write(g),{sent:!0,reason:"sent",writerId:p,writerAgeMs:h,error:null}}catch(_){return a?.set(e,Date.now()+y.INBOUND_WRITER_RETRY_COOLDOWN_MS),console.warn("[Client][NATIVE-MAIN] Inbound control-stream signal send failed",{remoteNodeId:e,signalType:t?.content?.type??null,writerId:p,writerAgeMs:h,error:_}),{sent:false,reason:"inbound-writer-write-failed",writerId:p,writerAgeMs:h,error:_?.message??String(_)}}finally{v(),r.get(e)===I&&r.delete(e);}}async sendNativeSignalViaDedicatedStream(e,t,n){let i=await e.open_bi(t),r=i.send.getWriter();try{await r.write(this.buildNativeMainLabelHeader()),await r.write(this.buildFramedMessage(this.buildNativeMainPayload(n)));}finally{try{r.releaseLock();}catch{}}this.handleNativeMainStream(i,t).catch(o=>{console.warn("[Client][NATIVE-MAIN] Dedicated signal stream handler exited with error",{remoteNodeId:t,error:o});});}async sendNativeSignalEnvelope(e,t,n,i){let r=n?.content?.transport??null,o=n?.content?.type??null,a=r==="webrtc"&&(o==="sdp"||o==="candidate"||o==="renegotiate")&&e.getUpgradeState()==="upgrading",d=this.sessionTokenApprovedNodes instanceof Set?this.sessionTokenApprovedNodes:null,u=this.sessionTokenApprovedConnectionIds instanceof Set?this.sessionTokenApprovedConnectionIds:null,p=!!d&&!!u&&d.has(t)&&u.has(e.id),h=p||a,g=!!d&&d.has(t),f=!!u&&u.has(e.id),v=await this.sendNativeSignalViaInboundControlStream(t,n,{ignoreCooldown:a});if(v.sent){b$1("[Client][NATIVE-MAIN] Sent native signal over inbound control stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs}),console.info("[Client][NATIVE-MAIN] Signal route=inbound-control",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs}),console.info("[SIGNAL-STREAM][TS] reply-on-persistent-writer",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs});return}if(console.info("[Client][NATIVE-MAIN] Signal route=inbound-control-unavailable",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,reason:v.reason,writerId:v.writerId,writerAgeMs:v.writerAgeMs,inboundError:v.error,hasApprovedNode:g,hasApprovedConnectionId:f,hasApprovedDedicatedStream:p,preferDedicatedSignalPath:a,canUseDedicatedStream:h}),h)try{await this.sendNativeSignalViaDedicatedStream(i,t,n),b$1("[Client][NATIVE-MAIN] Sent native signal over dedicated stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),console.info("[Client][NATIVE-MAIN] Signal route=dedicated-open_bi",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:v.reason});return}catch(I){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:I});}try{await e.sendRawIrohFrame(this.buildFramedMessage(this.buildNativeMainPayload(n))),b$1("[Client][NATIVE-MAIN] Sent native signal over control stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),console.info("[Client][NATIVE-MAIN] Signal route=cached-control-writer",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:v.reason});return}catch(I){if(console.warn("[Client][NATIVE-MAIN] Control-stream signal send failed",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null,error:I}),!h)throw I}await this.sendNativeSignalViaDedicatedStream(i,t,n),b$1("[Client][NATIVE-MAIN] Sent native signal over dedicated stream",{connectionId:e.id,remoteNodeId:t,signalType:n?.content?.type??null}),console.info("[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:v.reason});}async ensureIncomingConnectionForRemoteNode(e){let t=this.getDeterministicConnectionId(e),n=this.connections.get(t);if(n&&!n.isClosed){if(console.info("[Client][NATIVE-MAIN] Reusing existing control connection",{connectionId:n.id,remoteNodeId:e,upgradeState:typeof n.getUpgradeState=="function"?n.getUpgradeState():null}),this.wasmClient&&typeof this.wasmClient.open_bi=="function"){let s=this.wasmClient;n.setNativeSignalSender(async a=>{await this.sendNativeSignalEnvelope(n,e,a,s);});}return n}let i=this.pendingNativeMainConnections.get(t);if(i)return i;let r=this.trustFailureCooldowns.get(e);if(r!==void 0&&Date.now()-r<y.TRUST_FAILURE_COOLDOWN_MS&&!this.sessionTokenApprovedNodes.has(e))return console.debug("[Client][TRUST] Skipping connection rebuild for node in trust-failure cooldown",{remoteNodeId:e,cooldownRemainingMs:y.TRUST_FAILURE_COOLDOWN_MS-(Date.now()-r)}),null;let o=(async()=>{if(!this.wasmClient||typeof this.wasmClient.open_bi!="function")return null;let s;try{s=await this.wasmClient.open_bi(e);}catch(u){return console.warn("[Client][NATIVE-MAIN] Failed to open control stream for native signal routing",{remoteNodeId:e,connectionId:t,error:u}),null}try{await this.writeNativeMainLabelHeaderOnBiStream(s,e);}catch(u){return console.warn("[Client][NATIVE-MAIN] Failed to write label header on control stream",{remoteNodeId:e,connectionId:t,error:u}),null}let a=new te(t,this.localNodeId,e,s.send.getWriter(),s.recv.getReader(),{rtcConfig:this.getRTCConfig(),transportContext:this.createTransportContext(e),onTransportStatusChange:u=>{this.reportConnectionTransportStatus(t,u.activeTransport,u.parallelTransport);}}),d=this.wasmClient;return a.setNativeSignalSender(async u=>{await this.sendNativeSignalEnvelope(a,e,u,d);}),this.initializeConnectionTrust(a,this.knownDeviceIdsByNodeId.get(e)??null),this.markConnectionTrustVerified(a,this.knownDeviceIdsByNodeId.get(e)??null),this.registerConnection(a),this.announceConnectionWhenStable(a),console.info("[Client][HANDSHAKE] sending hello (native signal routing path)",{connectionId:a.id,remoteNodeId:a.remoteNodeId}),this.sendTransportHandshake(a,"hello").catch(u=>{console.warn("[Client][TRUST] Failed to send outgoing handshake for native signal routing",{connectionId:a.id,remoteNodeId:a.remoteNodeId,error:u});}),console.info("[Client][NATIVE-MAIN] Created control connection for native signal routing",{connectionId:a.id,remoteNodeId:e,channelId:this.getConnectionChannelId(a.id)??null,rtcEnabled:this.isWebRTCTransportEnabled()}),a})();this.pendingNativeMainConnections.set(t,o);try{return await o}finally{this.pendingNativeMainConnections.delete(t);}}async handleNativeMainStream(e,t){if(!this.isBiStreamLike(e))return;let n,i;try{n=e.recv.getReader(),i=e.send.getWriter(),this.registerInboundNativeMainWriter(t,i);}catch(a){console.warn("[Client][NATIVE-MAIN] Unable to acquire stream handles",{remoteNodeId:t,error:a});return}let r=[],o=new Uint8Array(0),s="stream-active";try{for(;;){let a=this.tryExtractNativeMainPayload(o);for(;!a.ready;){let{done:f,value:v}=await n.read();if(f){s=a.phase==="frame-start"?"remote-closed-before-frame-length":"remote-closed-mid-frame",this.shouldProjectNativeMainLifecycle()?this.emitNativeMainConnectionState(t,"closed"):this.refreshPeerSnapshot().catch(()=>{}),a.phase==="frame-start"?b$1("[Client][NATIVE-MAIN] Remote closed native main stream",{remoteNodeId:t}):console.warn("[Client][NATIVE-MAIN] Native main stream ended mid-frame",{remoteNodeId:t,messageLen:a.expectedFrameLength,bufferedBytes:o.byteLength});return}v&&v.byteLength>0&&(r.length=0,o=this.concatBytes([o,new Uint8Array(v)]));try{a=this.tryExtractNativeMainPayload(o);}catch(I){s="invalid-native-main-frame",console.warn("[Client][NATIVE-MAIN] Invalid native main frame",{remoteNodeId:t,error:I});return}}if(a.expectedFrameLength===0){o=o.slice(a.consumedBytes),r.length=0,o.byteLength>0&&r.push(o);continue}let d=a.payloadBytes;o=o.slice(a.consumedBytes),r.length=0,o.byteLength>0&&r.push(o);let u=d.byteLength>1&&d[0]===0?d.slice(1):d,p;try{p=JSON.parse(new TextDecoder().decode(u));}catch(f){let v=await this.ensureIncomingConnectionForRemoteNode(t);v?v.receiveDataPayload(u):console.warn("[Client][NATIVE-MAIN] Dropping binary app payload: no control connection",{remoteNodeId:t,error:f});continue}let h=this.findManualDisconnectProjectionForNativeNode(t);if(this.isHandshakeMessage(p)){if(h){b$1("[Client][NATIVE-MAIN] Dropping TS handshake for manually disconnected peer",{remoteNodeId:t,peerId:h.peerId,action:p.action??"hello"});continue}let f=await this.ensureIncomingConnectionForRemoteNode(t);if(!f){console.warn("[Client][NATIVE-MAIN] Dropping TS handshake: no control connection",{remoteNodeId:t,action:p.action??"hello"});continue}console.info("[Client][NATIVE-MAIN] Routed TS handshake to Connection",{remoteNodeId:t,connectionId:f.id,action:p.action??"hello"}),await this.handleMessage(f,p);continue}if(this.isNativeSignalEnvelope(p)){if(console.info("[Client][NATIVE-MAIN] Received #pluto-signal envelope",{remoteNodeId:t,signalType:p.content?.type??null,transport:p.content?.transport??null}),h){b$1("[Client][NATIVE-MAIN] Dropping native WebRTC signal for manually disconnected peer",{remoteNodeId:t,peerId:h.peerId,signalType:p.content?.type??null});continue}let f=await this.ensureIncomingConnectionForRemoteNode(t);if(!f){console.warn("[Client][NATIVE-MAIN] Dropping native WebRTC signal: no control connection",{remoteNodeId:t,signalType:p.content?.type??null});continue}f.receiveInternalSignal(p.content),b$1("[Client][NATIVE-MAIN] Routed #pluto-signal to Connection",{remoteNodeId:t,connectionId:f.id,signalType:p.content?.type??null});continue}let g=p;if(b$1("[Client][NATIVE-MAIN] Received native main message",{remoteNodeId:t,channel:g.channel,action:g.action,requestId:g.requestId??null}),g.channel==="handshake"&&g.action==="request"){await this.handleNativeHandshakeRequest(i,t,g);continue}if(g.channel==="session-token"&&g.action==="request"){await this.handleNativeSessionTokenRequest(i,t,g);continue}if(!g.channel&&!g.action&&!g.requestId){let f=await this.ensureIncomingConnectionForRemoteNode(t);if(!f){console.warn("[Client][NATIVE-MAIN] Dropping app payload: no control connection",{remoteNodeId:t});continue}f.receiveMessage(p);continue}this.dispatchNativeMainMessage(t,g);}}catch(a){s="handler-error",this.shouldProjectNativeMainLifecycle()?this.emitNativeMainConnectionState(t,"closed"):this.refreshPeerSnapshot().catch(()=>{}),console.error("[Client][NATIVE-MAIN] Native main stream handler failed",{remoteNodeId:t,error:a});}finally{this.clearInboundNativeMainWriter(t,i,s);try{i.releaseLock();}catch{}try{n.releaseLock();}catch{}}}tryExtractNativeMainPayload(e){if(e.byteLength===0)return {ready:false,phase:"frame-start",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};if(e[0]===y.NATIVE_MAIN_PROTOCOL_BYTE){if(e.byteLength<5)return {ready:false,phase:"frame-start",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};let i=new DataView(e.buffer,e.byteOffset,e.byteLength),r=i.getUint32(1,false);if(r>0&&r<=y.NATIVE_MAIN_MAX_LABEL_BYTES&&e.byteLength>=5+r&&new TextDecoder().decode(e.slice(5,5+r))===y.NATIVE_MAIN_LABEL){let s=5+r+4;if(e.byteLength<s)return {ready:false,phase:"frame-body",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};let a=i.getUint32(5+r,false);if(a>y.NATIVE_MAIN_MAX_FRAME_BYTES)throw new Error(`native-main frame too large: ${a}`);return e.byteLength<s+a?{ready:false,phase:"frame-body",expectedFrameLength:a,consumedBytes:0,payloadBytes:new Uint8Array}:{ready:true,phase:"frame-body",expectedFrameLength:a,consumedBytes:s+a,payloadBytes:e.slice(s,s+a)}}}if(e.byteLength<4)return {ready:false,phase:"frame-start",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};let n=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(0,false);if(n>y.NATIVE_MAIN_MAX_FRAME_BYTES)throw new Error(`legacy native-main frame too large: ${n}`);return e.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:e.slice(4,4+n)}}async isCoreConnectionHealthy(e){if(!e)return false;if(this.wasmClient&&typeof this.wasmClient.is_connected=="function")try{return !!await this.wasmClient.is_connected(e)}catch{}try{return await this.signaling.isConnected(e)}catch{return false}}async waitForStableConnection(e){let t=this.initializeConnectionTrust(e),n=false,i=false,r=null;if(this.wasmClient&&typeof this.wasmClient.wait_for_settled_peer=="function")try{let a=await this.wasmClient.wait_for_settled_peer(e.deviceId,y.CONNECTION_STABLE_TIMEOUT_MS),d=e.getUpgradeState;if(r=typeof d=="function"?d.call(e):null,a?.settledReady&&(!t.required||t.verified))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:a?.settledReady??null,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,upgradeState:r}),!1;if(!t.verified&&!this.usesTicketOnlySignalingMode())return console.warn("[Client][STABILITY] settled-peer gate rejected connection before poll loop",{connectionId:e.id,deviceId:e.deviceId,settledReady:a?.settledReady??null,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,upgradeState:r}),!1}catch{}let o=Date.now(),s=null;for(;Date.now()-o<y.CONNECTION_STABLE_TIMEOUT_MS;){if(e.isClosed||t.required&&t.failed)return false;let a=await this.isCoreConnectionHealthy(e.deviceId),d=e.getUpgradeState;r=typeof d=="function"?d.call(e):null;let u=r==="upgraded";if(n=a,i=u,a||u){if(s===null&&(s=Date.now()),Date.now()-s>=y.CONNECTION_STABLE_WINDOW_MS&&(!t.required||t.verified))return true}else s=null;await new Promise(h=>setTimeout(h,y.CONNECTION_STABLE_POLL_MS));}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,lastUpgradeState:r,availableTransports:e.getAvailableTransports?.()??null}),false}announceConnectionWhenStable(e){(async()=>{if(!await this.waitForStableConnection(e)){if(!e.isClosed){let i=this.connectionTrustStates.get(e.id);console.warn(`[Client] Suppressing unstable connection ${e.id}`,{deviceId:e.deviceId,upgradeState:e.getUpgradeState?.()??null,availableTransports:e.getAvailableTransports?.()??null,trustRequired:i?.required??null,trustVerified:i?.verified??null,trustFailed:i?.failed??null,trustFailureReason:i?.failureReason??null});}let n=this.connectionTrustStates.get(e.id);n?.required&&!e.isClosed&&await this.enforceConnectionTrustFailure(e,n.failureReason??"trusted-device-proof-timeout").catch(()=>{});return}this.announcedConnections.has(e.id)||(this.announcedConnections.add(e.id),this.connectionListeners.forEach(n=>n(e)));})();}async normalizeIncomingStreamEvent(e,t){let n="bi",i=e,r="",o=null,s=null,a={present:false,channel:null},d=false;try{d="type"in e;}catch{d=false;}if(d){n=ye(e);try{i=e.stream;}catch{i=null;}let h=ae(e);r=h==="unknown"?"":h,s=Hn(e),a=Gn(e);}else try{r=e.endpoint_id??"";}catch{r="";}let u=this.nextIncomingTraceId("incoming",r);this.logIncomingDiagnostic("normalize:start",{traceId:u,hasType:d,type:n,endpointId:r||"unknown",inspectChannelEnvelope:!!t?.inspectChannelEnvelope,authoritativeProtocolHint:s??null,authoritativeChannel:a.present}),n!=="uni"&&console.debug("[Client][INCOMING] handleIncomingStream called",{hasType:d,type:n,endpointId:r});let p="unknown";if(n==="bi"){let h=this.materializeIncomingBiStream(i,r);if(!h||!this.isBiStreamLike(h)){let g=false,f=false;try{g=!!i?.send;}catch{}try{f=!!i?.recv;}catch{}return console.error("[Client][INCOMING] Invalid bidirectional stream payload",{remoteNodeId:r,hasSend:g,hasRecv:f}),{type:"bi",stream:i,remoteNodeId:r,traceId:u,protocolHint:"unknown",channel:null,invalid:true}}if(i=h,a.present)o=a.channel;else if(t?.inspectChannelEnvelope){let g=await this.extractIncomingChannelEnvelope(i,r,u);i=g.stream,o=g.channel;}if(s!==null)p=s,this.logIncomingDiagnostic("bi:use-authoritative-metadata",{traceId:u,endpointId:r||"unknown",protocolHint:p,hasChannelEnvelope:!!o});else if(this.shouldSkipIncomingBiProbeForRemoteNode(r)){let g=this.inferTicketFlowBiProtocolHint(r);if(p=g.protocolHint,this.logIncomingDiagnostic("bi:skip-probe-ticket-flow",{traceId:u,endpointId:r||"unknown",inferredProtocolHint:p,hasExistingConnection:g.hasExistingConnection,hasMagicLinkScope:g.hasMagicLinkScope}),!o){let f=await this.detectNativeMainStream(i,r,u);i=f.stream,f.protocolHint==="native-main"&&(p="native-main");}}else {let g=await this.classifyBiIncomingStream(i,u);if(i=g.stream,p=g.protocolHint,p!=="explicit"){let f=await this.detectNativeMainStream(i,r,u);i=f.stream,f.protocolHint==="native-main"&&(p="native-main");}}}return this.logIncomingDiagnostic("normalize:done",{traceId:u,endpointId:r||"unknown",type:n,protocolHint:p,hasChannelEnvelope:!!o}),{type:n,stream:i,remoteNodeId:r,traceId:u,protocolHint:p,channel:o}}hasIncomingChannelListener(e){let t=e.trim();return t?(this.channelStreamListeners?.get(t)?.size??0)>0:false}hasAnyIncomingChannelListeners(){if(!this.channelStreamListeners)return false;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)if(i(e)===true)return true;return false}dispatchIncomingGenericListeners(e){for(let t of this.streamListeners??[])if(t(e)===true)return true;return false}shouldTreatIncomingStreamAsTransportOnly(e){return e.type!=="bi"?false:this.isTransportOnlyChannel(e.channel?.channelId)?true:e.protocolHint!=="explicit"?false:this.usesTicketOnlySignalingMode()?true:this.hasTransportOnlyConnectionForRemoteNode(e.remoteNodeId)}async handleUnhandledIncomingStreamEvent(e){let{type:t,stream:n,remoteNodeId:i,protocolHint:r,traceId:o}=e;if(!e.invalid){if(t==="uni"){await this.cancelUnhandledIncomingUniStream(n,i);return}if(t==="bi"&&r==="native-main"){b$1("[Client][INCOMING] Handling native desktop main stream",{remoteNodeId:i,traceId:o||null}),this.handleNativeMainStream(n,i).catch(s=>{console.error("[Client][NATIVE-MAIN] Background handler crashed",{remoteNodeId:i,traceId:o||null,error:s});});return}if(this.shouldTreatIncomingStreamAsTransportOnly(e)){this.logIncomingDiagnostic("bi:drop-unhandled-ticket-flow",{remoteNodeId:i||"unknown",traceId:o||null,protocolHint:r,channelId:e.channel?.channelId??null});return}if(t==="bi"&&r!=="explicit"){let s=i,a=this.getDeterministicConnectionId(s),d=this.connections.get(a);if(d&&!d.isClosed){let v=d.getUpgradeState(),I=await this.isCoreConnectionHealthy(s).catch(()=>false);if((v==="upgrading"||v==="upgraded")&&I){b$1("[Client][INCOMING] Routing auxiliary bi stream to native-main handler while connection is upgrading/upgraded",{connectionId:a,remoteNodeId:s,traceId:o||null,existingUpgradeState:v,protocolHint:r}),this.handleNativeMainStream(n,s).catch(M=>{console.error("[Client][NATIVE-MAIN] Auxiliary stream handler crashed",{remoteNodeId:s,traceId:o||null,error:M});});return}(v==="upgrading"||v==="upgraded")&&b$1("[Client][INCOMING] Replacing upgraded connection due to stale core transport",{connectionId:a,remoteNodeId:s,traceId:o||null,existingUpgradeState:v,coreTransportConnected:I}),b$1("[Client][INCOMING] Replacing existing connection main stream",{connectionId:a,remoteNodeId:s,traceId:o||null}),await d.disconnect().catch(()=>{}),this.connections.delete(a),this.announcedConnections.delete(a),this.connectionTrustStates.delete(a),this.connectionChannelIds.delete(a),this.moqPeerSubscriptions.delete(a);}let u=n;if(!this.isBiStreamLike(u)){console.error("[Client][INCOMING] Unable to construct connection from invalid bi stream",{remoteNodeId:s});return}let p,h;try{p=u.send.getWriter(),h=u.recv.getReader();}catch(v){console.error("[Client][INCOMING] Failed to acquire incoming stream reader/writer",{remoteNodeId:s,error:v});return}let g=new te(a,this.localNodeId,s,p,h,{rtcConfig:this.getRTCConfig(),transportContext:this.createTransportContext(s),onTransportStatusChange:v=>{this.reportConnectionTransportStatus(a,v.activeTransport,v.parallelTransport);}}),f=this.knownDeviceIdsByNodeId.get(s)??null;this.initializeConnectionTrust(g,f),this.registerConnection(g),f?this.bindConnectionDeviceIdInRust(g,f):this.searchDevices().then(()=>{let v=this.knownDeviceIdsByNodeId.get(s)??null;v?this.bindConnectionDeviceIdInRust(g,v):console.warn("[Client][BIND] Accept-side directory lookup found no deviceId for remote node",{connectionId:g.id,remoteNodeId:s});}).catch(v=>{console.warn("[Client][BIND] Accept-side searchDevices fallback failed",{connectionId:g.id,remoteNodeId:s,error:v});}),this.announceConnectionWhenStable(g),console.info("[Client][HANDSHAKE] sending hello (incoming connection path)",{connectionId:g.id,remoteNodeId:g.remoteNodeId}),this.sendTransportHandshake(g,"hello").catch(v=>{console.warn("[Client][TRUST] Failed to send incoming handshake",{connectionId:g.id,remoteNodeId:g.remoteNodeId,error:v});});}}}isHandshakeMessage(e){return !e||typeof e!="object"?false:e.type==="handshake"}async handleIncomingStream(e){let t=await this.normalizeIncomingStreamEvent(e,{inspectChannelEnvelope:this.shouldInspectIncomingChannelEnvelope()});this.dispatchIncomingChannelListeners(t)||this.dispatchIncomingGenericListeners(t)||await this.handleUnhandledIncomingStreamEvent(t);}maybeHandleWebRTCExplicitFileEnvelope(e,t){if(t.byteLength<25||t[0]!==y.EXPLICIT_PROTOCOL_BYTE)return false;let n=t.slice(1,17),i=Array.from(n).map(u=>u.toString(16).padStart(2,"0")).join(""),r=`${e.id}:${i}`,o=new DataView(t.buffer,t.byteOffset,t.byteLength),s=o.getUint32(17,false),a=o.getUint32(21,false);if(s===4294967295){if(t.byteLength<29)return true;let u=o.getUint32(25,false),p=29,h=p+u;return h>t.byteLength||(this.webrtcIncomingExplicitTransfers.set(r,{headerBytes:t.slice(p,h),chunks:new Map,total:0,received:0}),console.info("[Client][WebRTC][transfer] Incoming WebRTC explicit transfer header received",{connectionId:e.id,remoteNodeId:e.remoteNodeId,transferIdKey:i,headerBytes:u})),true}let d=this.webrtcIncomingExplicitTransfers.get(r);if(!d)return true;if(d.total===0)d.total=a;else if(d.total!==a)return this.webrtcIncomingExplicitTransfers.delete(r),true;if(d.chunks.has(s))return true;if(d.chunks.set(s,t.slice(25)),d.received+=1,d.total>0&&d.received>=d.total){let u=this.reassembleWebRTCExplicitPayload(d);this.webrtcIncomingExplicitTransfers.delete(r),u&&(console.info("[Client][WebRTC][transfer] Incoming WebRTC transfer assembled in browser",{connectionId:e.id,remoteNodeId:e.remoteNodeId,transferIdKey:i,chunks:d.total,payloadBytes:u.byteLength}),this.dispatchSyntheticExplicitIncomingStream(e,u));}return true}reassembleWebRTCExplicitPayload(e){let t=[],n=0;for(let o=0;o<e.total;o+=1){let s=e.chunks.get(o);if(!s)return null;t.push(s),n+=s.byteLength;}let i=new Uint8Array(5+e.headerBytes.byteLength+n);i[0]=y.EXPLICIT_PROTOCOL_BYTE,new DataView(i.buffer).setUint32(1,e.headerBytes.byteLength,false),i.set(e.headerBytes,5);let r=5+e.headerBytes.byteLength;for(let o of t)i.set(o,r),r+=o.byteLength;return i}dispatchSyntheticExplicitIncomingStream(e,t){console.info("[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(s){s.enqueue(t),s.close();}}),endpoint_id:e.remoteNodeId},i=this.connectionChannelIds.get(e.id)??null,r={type:"bi",stream:n,remoteNodeId:e.remoteNodeId,protocolHint:"explicit",traceId:`webrtc-explicit-${Date.now()}`,channel:i?{channelId:i}:null};if(this.dispatchIncomingChannelListeners(r))return;this.dispatchIncomingGenericListeners(r)||this.handleUnhandledIncomingStreamEvent(r).catch(s=>{b$1("[Client][INCOMING] Failed to process synthetic explicit stream",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:s});});}registerConnection(e){this.connections.set(e.id,e);let t=this.connectionTrustStates.get(e.id),n=t?.verifiedDeviceId??t?.expectedDeviceId??this.knownDeviceIdsByNodeId.get(e.remoteNodeId)??null;n?this.bindConnectionDeviceIdInRust(e,n):this.searchDevices().then(()=>{let i=this.knownDeviceIdsByNodeId.get(e.remoteNodeId)??null;i&&this.bindConnectionDeviceIdInRust(e,i);}).catch(()=>{}),t?.verified&&n&&this.retireSupersededConnections(e,n,"registered-trusted-replacement"),typeof e.onUpgradeStateChange=="function"&&e.onUpgradeStateChange(()=>{!this.connections.has(e.id)||e.isClosed||(this.hasRustPeerLifecycleProjection()?this.refreshPeerSnapshot().catch(()=>{}):this.applyConnectionTrustProjection(e));}),this.hasRustPeerLifecycleProjection()?this.refreshPeerSnapshot().catch(()=>{}):this.applyConnectionTrustProjection(e),typeof e.reportTransportStatusIfChanged=="function"&&e.reportTransportStatusIfChanged(),typeof e.onWebRTCBinaryMessage=="function"&&e.onWebRTCBinaryMessage(i=>this.maybeHandleWebRTCExplicitFileEnvelope(e,i)),e.onMessage(i=>{this.handleMessage(e,i);}),e.onDisconnect(()=>{this.connections.delete(e.id),this.connectionTrustStates.delete(e.id),this.connectionChannelIds.delete(e.id),this.pendingSessionTokenTrustApprovals.delete(e.id),this.sessionTokenApprovedConnectionIds.delete(e.id),this.moqPeerSubscriptions.delete(e.id),e.peerMoQReady=false,this.peerLifecycle.removeConnection(e.id),this.peerLifecycle.updateHealth(e.id,"stale","closed"),this.hasRustPeerLifecycleProjection()&&this.refreshPeerSnapshot().catch(()=>{}),this.announcedConnections.delete(e.id)&&this.disconnectionListeners.forEach(r=>r(e));});}async reportConnectionTransportStatus(e,t,n){let i=this.wasmClient;if(!(!i||typeof i.report_transport_status!="function"))try{await i.report_transport_status(e,t,n??null),this.hasRustPeerLifecycleProjection()&&await this.refreshPeerSnapshot();}catch(r){b$1("[Client] Failed to report active transport to Rust",{connectionId:e,activeTransport:t,parallelTransport:n??null,error:r});}}syncConnectionPeerLifecycle(e){let t=this.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.getConnectionTrustProjection({connectionId:e.id,nodeId:e.remoteNodeId});if(n){this.peerLifecycle.upsert({peerId:n.deviceId??void 0,deviceId:n.deviceId??void 0,deviceIdHint:n.deviceId??void 0,nodeId:e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:n.health,transportState:this.getConnectionTransportProjectionState(e),protocolState:n.protocolState,routable:n.routable,promotionEligible:t,error:n.error,lastSeenAt:Date.now()});return}let i=this.peerLifecycle.get(e.id)||this.peerLifecycle.list().find(a=>a.connectionIds.includes(e.id)||a.nodeId===e.deviceId),r=i?.peerId||i?.deviceId||i?.deviceIdHint,o=i?.deviceId,s=i?.deviceIdHint;!r&&!o&&!s||this.peerLifecycle.upsert({peerId:r,deviceId:o,deviceIdHint:s,nodeId:e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:e.isClosed?"stale":"healthy",activeTransport:e.transportType,promotionEligible:t,lastSeenAt:Date.now()});}getPeerCandidates(e){let t=this.peerLifecycle.get(e),n=new Set;return [e,t?.peerId,t?.deviceId,t?.nodeId,t?.connectionId,...t?.connectionIds??[]].forEach(r=>{if(!r)return;let o=r.trim().toLowerCase();o&&n.add(o);}),n}async updatePresence(e=true,t=3e5,n,i){if(!this.wasmClient)return;let r=this.currentUser?.id,o=(this.options.discoveryMode===void 0||this.options.discoveryMode==="personal")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0;if(!r&&!o)return;let s=this.localNodeId;if(!s)return;let a=await this.resolvePresenceTicket(i);if(!a||!a.trim())throw new Error("updatePresence requires a valid endpoint ticket");this.options.deviceName||"Browser Device";let u=n,p=await this.getLocalDeviceId()||this.deviceId;if(!p)throw new Error("updatePresence requires a stable local device ID");try{let h=n?JSON.parse(n):{};h.deviceId||(h.deviceId=p,u=JSON.stringify(h));}catch{u=JSON.stringify({deviceId:p,rawMetadata:n});}await this.signaling.updatePresence(s,a,e,t,u);}onConnection(e){return this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);}}onDisconnection(e){return this.disconnectionListeners.push(e),()=>{this.disconnectionListeners=this.disconnectionListeners.filter(t=>t!==e);}}onMessage(e){return this.messageListeners.push(e),()=>{this.messageListeners=this.messageListeners.filter(t=>t!==e);}}onIncomingStream(e){return this.streamListeners.push(e),()=>{this.streamListeners=this.streamListeners.filter(t=>t!==e);}}registerChannel(e){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){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 r=this.channelStreamListeners.get(n);r&&(r.delete(t),r.size===0&&this.channelStreamListeners.delete(n));}}onRoomJoinRequest(e){return this.roomRequestListeners.push(e),()=>{this.roomRequestListeners=this.roomRequestListeners.filter(t=>t!==e);}}async createMoQDataTracks(){if(!(!this._moqSession||this._moqState!=="ready"))try{await this._moqSession.publisher.createTrack(this.localNodeId,"data/broadcast"),c$2("[Client] MoQ Data Track created: data / broadcast");}catch(e){console.warn("Failed to create MoQ broadcast track",e);}}async sendMoQData(e,t){if(this._moqState!=="ready"||!this.moq)throw new Error("MoQ not ready");let n=e?`data / ${e} `:"data / broadcast",i=await this.moq.publisher.createTrack(this.localNodeId,n);if(!i)return;let r=Date.now();await i.push(t,{isKey:true,timestamp:r});}async handleMessage(e,t){if(t&&typeof t=="object"&&t.type==="handshake"){let n=t,i=n.action??"hello",r=n.capabilities?.webrtc===true,o=typeof n.capabilities?.moq=="boolean"?n.capabilities.moq:!!n.moq,s=this.isWebRTCTransportEnabled(),a=this.requiresManagedTransportTrust(),d=u=>{!r||!s||this.usesTicketOnlySignalingMode()&&this.localNodeId&&e.remoteNodeId&&this.localNodeId.localeCompare(e.remoteNodeId)>0||(console.info("[Client][HANDSHAKE] requesting WebRTC upgrade from handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:i,reason:u}),e.requestWebRTCUpgrade(u));};if(i==="hello"){let u=await this.validateIncomingSessionTokenWithRetry(n.sessionToken??"",e.id,{remoteNodeId:e.remoteNodeId,source:"handshake-hello"});if(!u.ok){console.warn("[Client][SESSION-TOKEN] Rejecting connection \u2014 invalid session token",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:u.reason,hasToken:!!n.sessionToken}),e.disconnect();return}n.sessionToken&&this.applySessionTokenTrustApproval(e,u.scope??null,"handshake-hello");}console.info("[Client][HANDSHAKE] received",{action:i,connectionId:e.id,remoteNodeId:e.remoteNodeId,channelId:n.channelId??this.getConnectionChannelId(e.id)??null,remoteSupportsWebRTC:r,remoteSupportsMoQ:o,localWebRTCEnabled:s,hasSessionToken:!!n.sessionToken,hasTransportTrust:!!n.transportTrust}),(i==="response"||i==="ack"||i==="capability-update")&&this.pendingTokenByNodeId.delete(e.remoteNodeId),r&&(e.remoteSupportsWebRTC=true),!a&&s&&r&&(i==="hello"||i==="capability-update"||i==="response"&&!n.transportTrust)&&d(`handshake:${i}`),o&&this.moqState==="ready"&&(c$2(`[Client] Peer ${e.deviceId.substring(0,6)} supports MoQ. Upgrading...`),this.enableMoQForConnection(e)),this.assignConnectionChannel(e,n.channelId??null),n.transportTrust||a?(async()=>{let u=i,p=n.transportTrust??null,h=this.initializeConnectionTrust(e);if(p?.deviceId&&!h.expectedDeviceId&&this.getKnownDevice(p.deviceId,e.remoteNodeId)&&(h.expectedDeviceId=p.deviceId),u==="hello"){let g=typeof p?.challenge=="string"?p.challenge:null;if(!g&&h.required)if(this.sessionTokenApprovedConnectionIds.has(e.id)||this.sessionTokenApprovedNodes.has(e.remoteNodeId)){h.required=false,h.verified=true,h.failed=false,h.failureReason=void 0,h.issuedChallenge=null,this.applyConnectionTrustProjection(e);let v=typeof p?.deviceId=="string"&&p.deviceId.trim()?p.deviceId.trim():h.expectedDeviceId??this.knownDeviceIdsByNodeId.get(e.remoteNodeId)??null;v&&this.bindConnectionDeviceIdInRust(e,v),console.info("[Client][TRUST] Skipping challenge enforcement for session-token-approved connection",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:u});}else h.failureReason="missing-transport-trust-challenge",this.applyConnectionTrustProjection(e),console.info("[Client][TRUST] Deferring missing hello challenge enforcement pending response/ack or session-token approval",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:u});await this.sendTransportHandshake(e,"response",g);}else if(u==="response"||u==="ack"){let g=await this.verifyRemoteTransportTrust(e,p);if(!g.verified){if(this.sessionTokenApprovedConnectionIds.has(e.id)||this.sessionTokenApprovedNodes.has(e.remoteNodeId)){this.applySessionTokenTrustApproval(e,null,"handshake-proof-bypass-after-session-token");return}h.required&&await this.enforceConnectionTrustFailure(e,g.reason??"remote-transport-proof-invalid");return}this.markConnectionTrustVerified(e,g.deviceId),u==="response"&&d(`handshake:${u}:trust-verified`),u==="response"&&typeof p?.challenge=="string"&&await this.sendTransportHandshake(e,"ack",p.challenge);}else if(u==="capability-update"){let g=this.sessionTokenApprovedConnectionIds.has(e.id)||this.sessionTokenApprovedNodes.has(e.remoteNodeId),f=this.connectionTrustStates.get(e.id);(g||f?.verified)&&d("capability-update:trust-reused");}})().catch(u=>{console.warn("[Client][TRUST] Handshake processing failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:u});}):(n.action==="hello"||!n.action)&&n.sessionToken&&this.sendTransportHandshake(e,"response").catch(u=>{console.warn("[Client][SESSION-TOKEN] Failed to send response handshake",{connectionId:e.id,error:u});});}this.messageListeners.forEach(n=>n(e,t));}isWebRTCTransportEnabled(){return !!this.options.transports?.webrtc}getRTCConfig(){let e=this.options.transports?.webrtc||void 0;if(e)return this.options.strictMode||e.privacyMode?{...e,iceServers:ht(e.iceServers),iceTransportPolicy:"relay"}:e.iceTransportPolicy==="relay"&&!(Array.isArray(e.iceServers)&&e.iceServers.some(n=>Wn(n)))?(b$1("[Client] Overriding relay-only ICE policy to all because no TURN servers are configured"),{...e,iceTransportPolicy:"all"}):e}};y.CHANNEL_ENVELOPE_MAGIC=127,y.CHANNEL_ENVELOPE_VERSION=1,y.CHANNEL_ENVELOPE_HEADER_BYTES=6,y.EXPLICIT_PROTOCOL_BYTE=2,y.NATIVE_MAIN_PROTOCOL_BYTE=0,y.NATIVE_MAIN_LABEL="main",y.NATIVE_MAIN_MAX_LABEL_BYTES=64,y.NATIVE_MAIN_MAX_FRAME_BYTES=4*1024*1024,y.NATIVE_MAIN_PROTOCOL_VERSION=1,y.CONNECTION_STATE_CHANGED_EVENT="connection-state-changed",y.NATIVE_MAIN_MESSAGE_EVENT="openrtc:native-main-message",y.INCOMING_STREAM_RETRY_MIN_DELAY_MS=250,y.INCOMING_STREAM_RETRY_MAX_DELAY_MS=2e3,y.DEFAULT_PEER_CHANNEL_ID="system/peer-default",y.SHARE_FILE_CHANNEL_ID="share/explicit-file",y.SHARE_CONTROL_CHANNEL_ID="share/explicit-control",y.incomingStreamHubs=new WeakMap,y.CONNECTION_STABLE_WINDOW_MS=600,y.CONNECTION_STABLE_TIMEOUT_MS=2e3,y.CONNECTION_STABLE_POLL_MS=120,y.SESSION_TOKEN_TRUST_APPROVAL_TTL_MS=15e3,y.SESSION_TOKEN_UNKNOWN_RETRY_ATTEMPTS=2,y.SESSION_TOKEN_UNKNOWN_RETRY_DELAY_MS=150,y.TRUST_FAILURE_COOLDOWN_MS=3e4,y.INBOUND_WRITER_RETRY_COOLDOWN_MS=250,y.MOQ_RECONNECT_INITIAL_DELAY_MS=1e3,y.MOQ_RECONNECT_MAX_DELAY_MS=1e4;var ze=y;var Ye=class{constructor(e){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,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=(r,o)=>{let s=this.normalizeLookupKey(r);!s||n.has(s)||n.set(s,o);};for(let r of e)for(let o of t(r))i(o,r);return n}normalizeLookupKey(e){return typeof e=="string"?e.trim().toLowerCase():""}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,o=>[o.peerId,o.deviceId,o.deviceIdHint,o.nodeId,o.activeConnectionId]),r=this.buildLookup(n,o=>[o.peerId,o.deviceId,o.deviceIdHint,o.nodeId,o.connectionId,...o.connectionIds??[]]);return e.map(o=>j({device:o,session:this.matchItem(i,o),peer:this.matchItem(r,o),isPromotionEligible:s=>this.client.isPeerPromotionEligible(s)}))}runtimeDeviceToStatusSnapshot(e){return j({device:e})}mergeWatchedDevicesIntoStatusSnapshots(e,t){if(!e)return t;let n=new Map(t.map(i=>[i.deviceId,i]));return e.map(i=>{let r=n.get(i.deviceId);if(!r)return this.runtimeDeviceToStatusSnapshot(i);let{connectionStatus:o,settledReady:s,readinessState:a,readinessReason:d,peerHealth:u,peerId:p,promotionEligible:h,connectionId:g,activeTransportStableId:f,transportGeneration:v,activeTransport:I,parallelTransport:_,...M}=r,{connectionStatus:k,settledReady:w,readinessState:S,readinessReason:L,peerHealth:j$1,peerId:_e,promotionEligible:U,connectionId:ee,activeTransportStableId:mt,transportGeneration:qn,activeTransport:Vn,parallelTransport:$n,...Jt}=i;return j({device:{...M,...Jt,online:r.online===true||i.online===true,platformType:r.platformType??i.platformType,deviceIdHint:r.deviceIdHint,scopes:r.scopes}})})}async listDevices(){return 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 u=this.peerApi.listConnectedPeers();return console.warn(`[RuntimeClient] refreshPeerSnapshot failed during listDevicesWithStatus(); using ${u.length} cached connected peers`,d),u})]),r=n.status==="fulfilled"?n.value:[],o=i.status==="fulfilled"?i.value:[],s=this.buildFinalDeviceStatusSnapshots(t,r,o);return (s.some(d=>d.activeTransport==="webrtc")||r.some(d=>d.activeTransport==="webrtc")||o.some(d=>d.activeTransport==="webrtc"))&&console.debug("[RuntimeClient] device status snapshot with transport labels",{devices:s.map(d=>({deviceId:d.deviceId,connectionStatus:d.connectionStatus,settledReady:!!d.settledReady,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null,connectionId:d.connectionId??null})),peerSessions:r.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:o.map(d=>({peerId:d.peerId,deviceId:d.deviceId??null,connectionId:d.connectionId??null,status:d.status,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null}))}),s}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){await this.client.deleteDevice(e);}watchDevices(e){return this.client.onDevicesChange(e)}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,r=[],o=null,s=[],a=null,d=false,u=false,p=k=>{let w=this.buildFinalDeviceStatusSnapshots(k,[],s),S=this.deviceStatusSnapshotKey(w);S!==i&&(i=S,e(w));},h=()=>{d=false,!(!n||!u)&&(u=false,f());},g=()=>{if(n){if(d){u=true;return}d=true,this.listDevicesWithStatus().then(k=>{n&&(r=k,p(this.mergeWatchedDevicesIntoStatusSnapshots(o,k)));}).catch(()=>{}).finally(()=>h());}},f=()=>{!n||a||(a=setTimeout(()=>{a=null,g();},this.deviceStatusRefreshDebounceMs));},v=this.watchDevices(k=>{Array.isArray(k)&&(o=k,p(this.mergeWatchedDevicesIntoStatusSnapshots(k,r))),f();}),I=this.peerApi.watchPeerStates(k=>{if(s=Array.isArray(k)?k:[],!r.length){f();return}p(this.mergeWatchedDevicesIntoStatusSnapshots(o,r));}),_=null;typeof t.onConnectionStateChange=="function"&&Promise.resolve(t.onConnectionStateChange(()=>f())).then(k=>{if(!n){k?.();return}_=typeof k=="function"?k:null;}).catch(k=>{console.warn("[RuntimeDeviceManager] native connection-state watcher unavailable",k);});let M=this.startManagedReconciliation(()=>f());return g(),()=>{n=false,a&&clearTimeout(a),M(),v(),I(),_?.();}}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 s=(await this.listDevicesWithStatus().catch(()=>this.listDevices().catch(()=>[]))).find(a=>a.deviceId===e.deviceId);s&&(n={...e,...s},i=typeof s.ticket=="string"?s.ticket.trim():"");}if(!i)return {success:false,error:`Cannot connect to ${e.deviceId}: missing endpoint ticket`,attempts:1};if(this.peerApi.getPeerState(e.deviceId)?.status==="connected")return {success:true,skipped:"already-connecting",attempts:0};try{return await this.connectToDevice({deviceId:n.deviceId,endpointTicket:i}),await this.peerApi.refreshPeerSnapshot().catch(()=>{}),await t.onConnected?.(n),{success:!0,attempts:1}}catch(o){return {success:false,error:o instanceof Error?o.message:`Cannot connect to ${e.deviceId}`,attempts:1}}}};var Je=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=(r,o)=>{let s=typeof r=="string"?r.trim():"";!s||n.has(s)||n.set(s,o);};for(let r of e)for(let o of t(r))i(o,r);return n}uniqueLookupIds(...e){let t=new Set,n=[];for(let i of e){let r=typeof i=="string"?i.trim():"";!r||t.has(r)||(t.add(r),n.push(r));}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 r=n.get(i);if(r)return r}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 r=this.matchSessionByLookupId(await t.listPeerSessions().catch(()=>[]),i);return this.uniqueLookupIds(...i,r?.peerId,r?.deviceId,r?.deviceIdHint,r?.nodeId,r?.activeConnectionId)}watchPeerStates(e){return this.client.watchPeerStates(e)}getPeerState(e){return this.client.getPeerState(e)}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 r=await t.getPeerSession(i);if(r)return r}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,r=this.uniqueLookupIds(i?.peerId,i?.deviceId,i?.deviceIdHint,i?.nodeId,e)[0]??e;return n.waitForSettledPeer(r,t)}async getPeerReadiness(e,t){let n=this.getPeerState(e)??null,i=typeof t=="number"?await this.waitForConnectedPeer(e,t).catch(()=>null):await this.getPeerSession(e).catch(()=>null),r=this.normalizeUiConnectionStatus(i?.status??n?.status??"disconnected"),o=n?.routable===false&&n?.protocolState==="unverified";return {requestedId:e,connected:r==="connected",settledReady:o?false:!!i?.settledReady,status:r,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:o?n?.protocolState:i?.readinessState??n?.protocolState,readinessReason:o?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)}listConnectedPeers(){return this.client.listConnectedPeers()}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)}async refreshPeerSnapshot(){return this.client.refreshPeerSnapshot()}};var A=class A{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.driveGrantActorRegistry=null;this.client=new ze(e),this.backend=t??null,t&&this.client.setSignalingBackend(t),this.peerManager=new Je(this.client,this.backend),this.connectionController=new Se(this.client,this.backend),this.deviceManager=new Ye({client:this.client,backend:this.backend,peerApi:{watchPeerStates:n=>this.peerManager.watchPeerStates(n),refreshPeerSnapshot:()=>this.peerManager.refreshPeerSnapshot(),listConnectedPeers:()=>this.peerManager.listConnectedPeers(),getPeerState:n=>this.peerManager.getPeerState(n)},connectToDevice:n=>this.connectionController.connectToDevice(n),startManagedReconciliation:n=>this.startManagedReconciliation(n),deviceStatusRefreshDebounceMs:A.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,"/"),r=(4-i.length%4)%4,o=JSON.parse(atob(i+"=".repeat(r)));return {hasTicket:!0,isCompound:!0,scope:typeof o?.s=="string"?o.s:null}}catch{return {hasTicket:true,isCompound:true,scope:null}}}async serializeManagedSessionOperation(e){let t=this.managedSessionTransition,n,i=new Promise(r=>{n=r;});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}sleep(e){return new Promise(t=>setTimeout(t,e))}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,r=(i?this.client.getConnections().find(s=>!s.isClosed&&s.id===i):void 0)??null,o=n?.nodeId?.trim()||r?.remoteNodeId?.trim()||t?.nodeId?.trim()||null;return {peer:t,session:n,connection:r,remoteNodeId:o}}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){let t=A.NATIVE_START_RETRY_MIN_DELAY_MS*Math.pow(2,Math.max(0,e-1));return Math.min(A.NATIVE_START_RETRY_MAX_DELAY_MS,t)}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){this.managedReconciliationTasks.add(e);let t=setInterval(()=>{this.hasManagedSession()&&e();},A.MANAGED_RECONCILIATION_INTERVAL_MS);return ()=>{clearInterval(t),this.managedReconciliationTasks.delete(e);}}notifyManagedReconciliation(){this.hasManagedSession()&&this.managedReconciliationTasks.forEach(e=>{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.notifyManagedReconciliation(),setTimeout(()=>this.notifyManagedReconciliation(),1500),setTimeout(()=>this.notifyManagedReconciliation(),5e3);}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,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<=A.NATIVE_START_RETRY_WINDOW_MS;){n+=1;try{await e.start(),n>1&&b$1(`[RuntimeClient] ${e.label} recovered after ${n} attempts`);return}catch(i){if(this.isUnsupportedRuntimeAdapterError(i,e.label))throw i;let r=this.nextNativeStartRetryDelayMs(n);console.warn(`[RuntimeClient] ${e.label} failed attempt=${n} retry_in_ms=${r}:`,i),await this.sleep(r);}}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}`)}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()}getRuntimePolicy(){return p}getRuntimeCapabilities(){let e=this.backend;return typeof e?.getRuntimeCapabilities=="function"?e.getRuntimeCapabilities():t(r)}async start(e){e?.clearSessionTokens!==false&&await this.client.clearSessionTokens().catch(()=>{}),await this.client.startListening();let t=this.backend;t?.onIncomingNativeMessage&&t.onIncomingNativeMessage((n,i,r)=>{(async()=>await this.client.acceptNativeMessage(n,i,r)&&t.disconnectDevice&&t.disconnectDevice(n).catch(()=>{}))();}).catch(()=>{});}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})),r=e?.platform??(i.runtime==="tauri"?"native":"web");return {deviceId:n,deviceName:e?.deviceName||t?.deviceName||"Unknown Device",platformType:t?.platformType||(r==="native"?"desktop":"web"),userId:e?.userId??this.identity?.id??i.userId??null,capabilities:t?.capabilities??{can_host:r==="native",can_sync:r==="native",read_only:r!=="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),r=this.backend,o=[];if(r?.revokeSessionTokensByScope)o=await r.revokeSessionTokensByScope(e).catch(()=>[]);else if(n)throw new Error("Native token revoke requires revokeSessionTokensByScope() on the IPC backend.");let s=Array.from(new Set([...i$1,...o]));return t?.rotateManagedScopeIfActive!==false&&e===A.MANAGED_USER_DEVICE_SCOPE&&this.managedSessionOptions&&this.managedSessionOptions.presence!==false&&await this.rotateManagedUserDeviceGrant(),s}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(A.MANAGED_FRIEND_SCOPE,e)}async revokeFriendTokens(){return this.revokeTokensByScope(A.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 r=this.serializeManagedSessionOperation(async()=>{if(this.managedSessionKey===n){if(e.platform==="native"&&t){let d=this.backend;if(d&&typeof d.startManagedSessionNative=="function")try{let u=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:u.localNodeId,presenceStarted:u.presenceStarted,autoConnectStarted:u.autoConnectStarted,localDeviceId:u.localDevice?.deviceId??null});}catch(u){console.warn("[RuntimeClient][managed-session][native-replay-failed]",{userId:t,message:u instanceof Error?u.message:String(u)});}}let a=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:t});return {mode:e.platform,device:a,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 o=null,s=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(()=>{}),o=await this.getTicketWithToken(A.MANAGED_USER_DEVICE_SCOPE,0),this.client.setManagedPresenceTicket(o),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.");let d=this.backend;if(!d||typeof d.startManagedSessionNative!="function")throw new Error("Native managed session startup requires a native backend-owned startManagedSessionNative() surface.");s=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:s.localNodeId,ticketScope:s.ticketScope??null,presenceStarted:s.presenceStarted,autoConnectStarted:s.autoConnectStarted,localDeviceId:s.localDevice?.deviceId??null});}this.fetchAndApplyAppLimits();let a=await this.getLocalDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:this.managedSessionUserId});return e.platform==="native"?(this.resolveManagedPresenceEnabled(e)&&!s?.presenceStarted&&console.warn("[RuntimeClient][managed-session][native-presence-missing]",{userId:this.managedSessionUserId,deviceId:a.deviceId}),this.resolveManagedAutoConnectEnabled(e)&&a.deviceId&&!s?.autoConnectStarted&&console.warn("[RuntimeClient][managed-session][native-auto-connect-missing]",{userId:this.managedSessionUserId,deviceId:a.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:a.deviceId,deviceName:a.deviceName,ticketScope:A.describeTicketForLogs(o).scope}),await this.startPresenceLoop({deviceName:a.deviceName,ticket:o,metadata:e.metadata}),console.info("[RuntimeClient][managed-session][presence-started]",{platform:e.platform,userId:this.managedSessionUserId,deviceId:a.deviceId})),e.platform!=="native"&&this.resolveManagedAutoConnectEnabled(e)&&a.deviceId&&(await this.startAutoConnect(a.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:a.deviceId})),await this.refreshPeerSnapshot().catch(()=>[]),this.notifyManagedReconciliation(),e.platform==="native"&&(setTimeout(()=>this.notifyManagedReconciliation(),1500),setTimeout(()=>this.notifyManagedReconciliation(),5e3)),{mode:e.platform,device:a,stop:async()=>this.stopManagedSession()}}catch(a){throw console.warn("[RuntimeClient][managed-session][start-failed-cleanup]",{platform:e.platform,requestedUserId:e.userId??null,runtimeUserId:this.identity?.id??null,effectiveUserId:this.managedSessionUserId,message:a instanceof Error?a.message:String(a)}),await this.stopManagedSessionInternal().catch(()=>{}),a}});this.managedSessionStartInFlight.set(n,r);try{return await r}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:A.MANAGED_USER_DEVICE_SCOPE}):(await this.revokeTokensByScopeInternal(A.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}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 r=this.backend;if(!r||typeof r.startManagedSessionNative!="function")throw new Error("Native managed ticket rotation requires a native backend-owned startManagedSessionNative() surface.");let o=this.managedSessionUserId??e.userId??this.identity?.id??null;if(!o)throw new Error("Native managed ticket rotation requires an authenticated user id.");await r.startManagedSessionNative({userId:o,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:A.MANAGED_USER_DEVICE_SCOPE,platform:e.platform,userId:o});return}let t=await this.getTicketWithToken(A.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:A.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.peerManager.watchPeerStates(e)}getPeerState(e){return this.peerManager.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.peerManager.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.peerManager.refreshPeerSnapshot()}async subscribeSessions(e,t){return this.client.subscribeSessions(e,t)}getAppLimits(){return this.client.appLimits}async createRoom(e){return this.client.rooms.createRoom(e)}async joinRoom(e,t){return 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)}getDriveGrantActor(e,t){let n=s=>{let a=t?.ticket,d=t?.channelId,u=t?.dial;return new Te({key:s,dial:async p=>{if(u){await u(p);return}await this.connectPeer({deviceId:p.peerNodeId,ticket:a,scope:p.scope,channelId:d});},close:async()=>{}})};this.driveGrantActorRegistry||(this.driveGrantActorRegistry=new Re(n));let i=kt(e.scope,e.peerNodeId),r=this.driveGrantActorRegistry.get(i),o=this.driveGrantActorRegistry.getOrSpawn(i,n);return (r===null||r!==null&&r!==o)&&x("[runtime-client][drive-grant-actor]",Ce(i.scope,{peerNodeId:i.peerNodeId}),"spawn"),o}getScopedConnectionActor(e,t){return this.getDriveGrantActor(e,t)}async shutdownScopedConnectionActors(){await this.shutdownDriveGrantActors();}async shutdownDriveGrantActors(){if(!this.driveGrantActorRegistry)return;let e=this.driveGrantActorRegistry.size();x("[runtime-client][drive-grant-actor]",{sessionKind:"drive-grant-guest"},"shutdown_all count={}",e),await this.driveGrantActorRegistry.shutdownAll();}async openPeerBi(e,t){let n=this.backend;if(n&&typeof n.openPeerBi=="function"){let i=await n.openPeerBi(e,t?.timeoutMs),r=await this.resolvePeerStreamTarget(e);return {connection:r.connection??this.compatPeerConnectionFromTarget(r,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 openPeerBiTransportOnly(e,t){let n=this.backend;if(n&&typeof n.openPeerBiTransportOnly=="function"){let i=await n.openPeerBiTransportOnly(e,t?.timeoutMs),r=await this.resolvePeerStreamTarget(e);return {connection:r.connection??this.compatPeerConnectionFromTarget(r,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),r=await this.resolvePeerStreamTarget(e);return {connection:r.connection??this.compatPeerConnectionFromTarget(r,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,connection:e.connection??n,remoteNodeId:e.remoteNodeId??n?.remoteNodeId};return t.sendExplicitFileData(i)}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),r=i||await this.getNodeId(),o=e?.ticket||await this.getEndpointTicket(),s=await this.getLocalDeviceProfile({deviceName:e?.deviceName,platform:"native",userId:n}),a=A.describeTicketForLogs(o);console.info("[RuntimeClient][native-presence][start]",{userId:n,localNodeId:r,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:s.deviceId,deviceName:e?.deviceName||s.deviceName,ticketScope:a.scope,isCompoundTicket:a.isCompound});try{await this.runNativeStartLoop({label:"startPresenceLoop",exhaustedMessage:`[RuntimeClient] startPresenceLoop exhausted retries user_id=${n} local_node_id=${r}`,start:()=>t.startPresenceLoopOnce(n,r,e?.deviceName||s.deviceName,o,e?.metadata)});}catch(u){if(!this.isUnsupportedRuntimeAdapterError(u,"startPresenceLoop"))throw u;await this.client.startPresenceLoop(e);return}console.info("[RuntimeClient][native-presence][started]",{userId:n,localNodeId:r,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:s.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){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(r){if(!this.isUnsupportedRuntimeAdapterError(r,"startAutoConnect"))throw r;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 u=this.connectionStateSnapshotKey(d);n.get(d.connectionId)!==u&&(n.set(d.connectionId,u),e(d));},r=()=>{t&&this.getConnectionStates().then(d=>{d.forEach(u=>i(u));}).catch(()=>{});},o=d=>()=>{t=false,s(),d?.();},s=this.startManagedReconciliation(()=>r()),a=this.client.signaling.onConnectionStateChange(d=>i(d));return r(),typeof a=="function"?o(a):Promise.resolve(a).then(d=>o(typeof d=="function"?d:null))}getConnections(){return this.client.getConnections()}onConnection(e){return this.client.onConnection(e)}onDisconnection(e){return this.client.onDisconnection(e)}onConnectionEvent(e){let t=this.client.onConnection(i=>{e({type:"connected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:i.transportType});}),n=this.client.onDisconnection(i=>{e({type:"disconnected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:i.transportType});});return ()=>{t(),n();}}forceReconnectSnapshot(){this.client.forceReconnectSnapshot();}async connect(){await this.initialize(),await this.start();}disconnect(){this.stop();}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 Ie(this,e)}};A.NATIVE_START_RETRY_WINDOW_MS=p.managedSession.nativeStartRetryWindowMs,A.NATIVE_START_RETRY_MIN_DELAY_MS=p.managedSession.nativeStartRetryMinDelayMs,A.NATIVE_START_RETRY_MAX_DELAY_MS=p.managedSession.nativeStartRetryMaxDelayMs,A.MANAGED_RECONCILIATION_INTERVAL_MS=p.managedSession.reconciliationIntervalMs,A.DEVICE_STATUS_REFRESH_DEBOUNCE_MS=p.managedSession.deviceStatusRefreshDebounceMs,A.MANAGED_USER_DEVICE_SCOPE="user-device",A.MANAGED_FRIEND_SCOPE="friend";var Xe=A;function Yt(l,e){let t=new Xe(l,e),n={runtime:t,async setAuthContext(i){if(typeof e.setAuthContext!="function")throw new Error("Selected runtime adapter does not support auth context injection.");await e.setAuthContext(i);},async syncPlutoAuth(i){let r=e$1(),o=r.getCurrentUser(),a=(typeof i?.userId=="string"?i.userId.trim():"")||o?.uid||null;if(!a){await n.setAuthContext(null);return}let d=await r.getIdToken({forceRefresh:i?.forceRefresh??false}).catch(()=>null),u=r.getCurrentUser()?.refreshToken??null,p=r.getCurrentUser()?.stsTokenManager?.expirationTime??null;await n.setAuthContext({userId:a,token:d,refreshToken:u,tokenProvider:async h=>r.getIdToken({forceRefresh:h??true}),expiresAtMs:p});},bindPlutoAuthHost(){let i=e$1();return n.syncPlutoAuth({userId:i.getCurrentUser()?.uid??null,forceRefresh:false}),i.onIdTokenChanged(r=>{n.syncPlutoAuth({userId:r?.uid??null,forceRefresh:false});})},signInWithPluto:()=>t.signInWithPluto(),signOut:()=>t.signOut(),stopManagedSession:()=>t.stopManagedSession(),startManagedSession:i=>t.startManagedSession(i),onAuthChange:i=>t.onIdentityChange(i),getManagedNodeId:i=>t.getManagedNodeId(i),getRuntimeStatus:()=>t.getRuntimeStatus(),listDevicesWithStatus:()=>t.listDevicesWithStatus(),watchDevicesWithStatus:i=>t.watchDevicesWithStatus(i),connectDevice:(i,r)=>t.connectDevice(i,r),setAutoConnectExcluded:(i,r)=>t.setAutoConnectExcluded(i,r)};return Object.defineProperty(n,"identity",{get:()=>t.identity,enumerable:true}),n}function Qr(l){let e=c$1(l);return Yt(e,new a(e))}function zr(l,e){let t=c$1(l);return Yt(t,new b$2({...t,bridge:e}))}
4
4
  export{Ie as a,Se as b,Zt as c,Ce as d,x as e,W as f,kt as g,Pt as h,Te as i,Re as j,Xe as k,Qr as l,zr as m};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import {l,m as m$1}from'./chunk-7VDM4CQ3.js';export{a as ScopedSession}from'./chunk-7VDM4CQ3.js';import'./chunk-D54VGRRH.js';import {a}from'./chunk-DIQYFAGL.js';export{p as OPENRTC_RUNTIME_POLICY,q as getRuntimePolicy}from'./chunk-PZ25OCVG.js';import'./chunk-4MH42GUI.js';function m(t){let n={...t};if("auth"in t&&!t.authMode){let o=t.auth;n.authMode=o==="none"?"anonymous":o;}if("identity"in t&&!t.nodeIdPersistence){let o=t.identity;n.nodeIdPersistence=o==="temporary"?"ephemeral":o;}return "namespace"in t&&!t.storagePrefix&&(n.storagePrefix=t.namespace),"privacy"in t&&t.strictMode===void 0&&(n.strictMode=!!t.privacy),n}function d(t){let n=t.runtime,o=Object.create(n),s=async e=>{if(typeof e!="string")return e;let r=(await n.listDevices()).find(h=>h.deviceId===e);if(!r)throw new Error(`OpenRTC device '${e}' is not currently discoverable.`);return r},c=async e=>({...e,localDeviceId:e?.localDeviceId??await n.getLocalDeviceId()??""}),g={list:()=>n.listDevices(),listWithStatus:()=>n.listDevicesWithStatus(),watch:e=>n.watchDevices(e),watchWithStatus:e=>n.watchDevicesWithStatus(e),connect:async(e,i)=>n.connectDevice(await s(e),await c(i)),connectWithRetry:async(e,i,r)=>n.connectDeviceWithRetry(await s(e),i,r),disconnect:e=>n.disconnectDevice(e),update:(e,i)=>n.updateDevice(e,i),delete:e=>n.deleteDevice(e),localId:()=>n.getLocalDeviceId(),localInfo:()=>n.getLocalDeviceInfo(),localProfile:e=>n.getLocalDeviceProfile(e),updateLocalName:e=>n.updateLocalDeviceName(e)},v={watch:e=>n.watchPeerStates(e),get:e=>n.getPeerState(e),listConnected:()=>n.listConnectedPeers(),connect:e=>n.connectPeer(e),disconnect:(e,i)=>n.disconnectPeer(e,i),forceDisconnect:e=>n.forceDisconnectPeer(e),session:e=>n.getPeerSession(e),sessions:()=>n.listPeerSessions(),waitConnected:(e,i)=>n.waitForConnectedPeer(e,i),readiness:(e,i)=>n.getPeerReadiness(e,i),health:e=>n.getPeerHealth(e),identity:e=>n.resolvePeerIdentity(e),addScope:(e,i)=>n.addPeerScope(e,i),releaseScope:(e,i)=>n.releasePeerScope(e,i),scopes:e=>n.getPeerScopes(e),refresh:()=>n.refreshPeerSnapshot()},C={register:e=>n.registerChannel(e),unregister:e=>n.unregisterChannel(e),list:()=>n.listChannels(),openBi:(e,i,r)=>n.openPeerBi(e,{...r,channelId:i}),openUni:(e,i,r)=>n.openPeerUni(e,{...r,channelId:i}),onIncoming:e=>n.onIncomingStream(e),onIncomingChannel:(e,i)=>n.onIncomingChannelStream(e,r=>{if(r.channel)return i(r)})},R={status:()=>n.getRuntimeStatus(),policy:()=>n.getRuntimePolicy(),capabilities:()=>n.getRuntimeCapabilities(),connectionStates:()=>n.getConnectionStates(),onConnectionStateChange:e=>n.onConnectionStateChange(e),connections:()=>n.getConnections(),onConnection:e=>n.onConnection(e),onDisconnection:e=>n.onDisconnection(e),onConnectionEvent:e=>n.onConnectionEvent(e),forceReconnectSnapshot:()=>n.forceReconnectSnapshot()},P={runtime:n,assembly:t,nodeId:()=>n.getNodeId(),nodeIdFromTicket:e=>n.getNodeIdFromTicket(e),endpointTicket:()=>n.getEndpointTicket(),connectRaw:e=>n.connectRaw(e),openBi:e=>n.openBi(e),openUni:e=>n.openUni(e),isConnected:e=>n.isConnected(e),disconnectNode:e=>n.disconnectNode(e),setAutoConnectExcluded:(e,i)=>n.setAutoConnectExcluded(e,i)};return Object.defineProperties(o,{devices:{get:()=>g,enumerable:true},peers:{get:()=>v,enumerable:true},channels:{get:()=>C,enumerable:true},diagnostics:{get:()=>R,enumerable:true},advanced:{get:()=>P,enumerable:true},setAuth:{value:e=>t.setAuthContext(e),enumerable:true,writable:true,configurable:true},setAuthContext:{value:e=>t.setAuthContext(e),enumerable:true,writable:true,configurable:true},syncPlutoAuth:{value:e=>t.syncPlutoAuth(e),enumerable:true,writable:true,configurable:true},bindPlutoAuthHost:{value:()=>t.bindPlutoAuthHost(),enumerable:true,writable:true,configurable:true},signIn:{value:()=>t.signInWithPluto(),enumerable:true,writable:true,configurable:true},signOut:{value:()=>t.signOut(),enumerable:true,writable:true,configurable:true},runtime:{get:()=>n,enumerable:false},_assembly:{get:()=>t,enumerable:false}}),o}function p(t){let n=m(t),o=l(n);return d(o)}p.native=function(t,n){let o=m(t),s=n??a(),c=m$1(o,s);return d(c)};export{p as OpenRTC};
1
+ import {l,m as m$1}from'./chunk-CQAKCS2S.js';export{a as ScopedSession}from'./chunk-CQAKCS2S.js';import'./chunk-D54VGRRH.js';import {a}from'./chunk-DIQYFAGL.js';export{p as OPENRTC_RUNTIME_POLICY,q as getRuntimePolicy}from'./chunk-PZ25OCVG.js';import'./chunk-4MH42GUI.js';function m(t){let n={...t};if("auth"in t&&!t.authMode){let o=t.auth;n.authMode=o==="none"?"anonymous":o;}if("identity"in t&&!t.nodeIdPersistence){let o=t.identity;n.nodeIdPersistence=o==="temporary"?"ephemeral":o;}return "namespace"in t&&!t.storagePrefix&&(n.storagePrefix=t.namespace),"privacy"in t&&t.strictMode===void 0&&(n.strictMode=!!t.privacy),n}function d(t){let n=t.runtime,o=Object.create(n),s=async e=>{if(typeof e!="string")return e;let r=(await n.listDevices()).find(h=>h.deviceId===e);if(!r)throw new Error(`OpenRTC device '${e}' is not currently discoverable.`);return r},c=async e=>({...e,localDeviceId:e?.localDeviceId??await n.getLocalDeviceId()??""}),g={list:()=>n.listDevices(),listWithStatus:()=>n.listDevicesWithStatus(),watch:e=>n.watchDevices(e),watchWithStatus:e=>n.watchDevicesWithStatus(e),connect:async(e,i)=>n.connectDevice(await s(e),await c(i)),connectWithRetry:async(e,i,r)=>n.connectDeviceWithRetry(await s(e),i,r),disconnect:e=>n.disconnectDevice(e),update:(e,i)=>n.updateDevice(e,i),delete:e=>n.deleteDevice(e),localId:()=>n.getLocalDeviceId(),localInfo:()=>n.getLocalDeviceInfo(),localProfile:e=>n.getLocalDeviceProfile(e),updateLocalName:e=>n.updateLocalDeviceName(e)},v={watch:e=>n.watchPeerStates(e),get:e=>n.getPeerState(e),listConnected:()=>n.listConnectedPeers(),connect:e=>n.connectPeer(e),disconnect:(e,i)=>n.disconnectPeer(e,i),forceDisconnect:e=>n.forceDisconnectPeer(e),session:e=>n.getPeerSession(e),sessions:()=>n.listPeerSessions(),waitConnected:(e,i)=>n.waitForConnectedPeer(e,i),readiness:(e,i)=>n.getPeerReadiness(e,i),health:e=>n.getPeerHealth(e),identity:e=>n.resolvePeerIdentity(e),addScope:(e,i)=>n.addPeerScope(e,i),releaseScope:(e,i)=>n.releasePeerScope(e,i),scopes:e=>n.getPeerScopes(e),refresh:()=>n.refreshPeerSnapshot()},C={register:e=>n.registerChannel(e),unregister:e=>n.unregisterChannel(e),list:()=>n.listChannels(),openBi:(e,i,r)=>n.openPeerBi(e,{...r,channelId:i}),openUni:(e,i,r)=>n.openPeerUni(e,{...r,channelId:i}),onIncoming:e=>n.onIncomingStream(e),onIncomingChannel:(e,i)=>n.onIncomingChannelStream(e,r=>{if(r.channel)return i(r)})},R={status:()=>n.getRuntimeStatus(),policy:()=>n.getRuntimePolicy(),capabilities:()=>n.getRuntimeCapabilities(),connectionStates:()=>n.getConnectionStates(),onConnectionStateChange:e=>n.onConnectionStateChange(e),connections:()=>n.getConnections(),onConnection:e=>n.onConnection(e),onDisconnection:e=>n.onDisconnection(e),onConnectionEvent:e=>n.onConnectionEvent(e),forceReconnectSnapshot:()=>n.forceReconnectSnapshot()},P={runtime:n,assembly:t,nodeId:()=>n.getNodeId(),nodeIdFromTicket:e=>n.getNodeIdFromTicket(e),endpointTicket:()=>n.getEndpointTicket(),connectRaw:e=>n.connectRaw(e),openBi:e=>n.openBi(e),openUni:e=>n.openUni(e),isConnected:e=>n.isConnected(e),disconnectNode:e=>n.disconnectNode(e),setAutoConnectExcluded:(e,i)=>n.setAutoConnectExcluded(e,i)};return Object.defineProperties(o,{devices:{get:()=>g,enumerable:true},peers:{get:()=>v,enumerable:true},channels:{get:()=>C,enumerable:true},diagnostics:{get:()=>R,enumerable:true},advanced:{get:()=>P,enumerable:true},setAuth:{value:e=>t.setAuthContext(e),enumerable:true,writable:true,configurable:true},setAuthContext:{value:e=>t.setAuthContext(e),enumerable:true,writable:true,configurable:true},syncPlutoAuth:{value:e=>t.syncPlutoAuth(e),enumerable:true,writable:true,configurable:true},bindPlutoAuthHost:{value:()=>t.bindPlutoAuthHost(),enumerable:true,writable:true,configurable:true},signIn:{value:()=>t.signInWithPluto(),enumerable:true,writable:true,configurable:true},signOut:{value:()=>t.signOut(),enumerable:true,writable:true,configurable:true},runtime:{get:()=>n,enumerable:false},_assembly:{get:()=>t,enumerable:false}}),o}function p(t){let n=m(t),o=l(n);return d(o)}p.native=function(t,n){let o=m(t),s=n??a(),c=m$1(o,s);return d(c)};export{p as OpenRTC};
Binary file
@@ -1 +1 @@
1
- export{f as DriveGrantActorError,i as DriveGrantActorHandle,j as DriveGrantActorRegistry,k as RuntimeClient,b as RuntimeConnectionController,f as ScopedConnectionActorError,i as ScopedConnectionActorHandle,j as ScopedConnectionActorRegistry,e as clog,d as correlationForDriveGrantScope,m as createIpcClient,l as createWasmClient,g as driveGrantConnectionKey,h as driveGrantConnectionKeyToString,c as renderCorrelationFields,g as scopedConnectionKey,h as scopedConnectionKeyToString}from'../chunk-7VDM4CQ3.js';export{a as WasmRuntimeAdapter}from'../chunk-D54VGRRH.js';export{b as TauriRuntimeAdapter,a as createTauriIpcBridge}from'../chunk-UVASANPG.js';export{b as IpcRuntimeAdapter}from'../chunk-DIQYFAGL.js';export{r as BROWSER_WASM_RUNTIME_CAPABILITIES,s as NATIVE_IPC_RUNTIME_CAPABILITIES,p as OPENRTC_RUNTIME_POLICY,t as cloneRuntimeCapabilities,q as getRuntimePolicy,i as logOpenRtcTeardownTrace}from'../chunk-PZ25OCVG.js';import'../chunk-4MH42GUI.js';
1
+ export{f as DriveGrantActorError,i as DriveGrantActorHandle,j as DriveGrantActorRegistry,k as RuntimeClient,b as RuntimeConnectionController,f as ScopedConnectionActorError,i as ScopedConnectionActorHandle,j as ScopedConnectionActorRegistry,e as clog,d as correlationForDriveGrantScope,m as createIpcClient,l as createWasmClient,g as driveGrantConnectionKey,h as driveGrantConnectionKeyToString,c as renderCorrelationFields,g as scopedConnectionKey,h as scopedConnectionKeyToString}from'../chunk-CQAKCS2S.js';export{a as WasmRuntimeAdapter}from'../chunk-D54VGRRH.js';export{b as TauriRuntimeAdapter,a as createTauriIpcBridge}from'../chunk-UVASANPG.js';export{b as IpcRuntimeAdapter}from'../chunk-DIQYFAGL.js';export{r as BROWSER_WASM_RUNTIME_CAPABILITIES,s as NATIVE_IPC_RUNTIME_CAPABILITIES,p as OPENRTC_RUNTIME_POLICY,t as cloneRuntimeCapabilities,q as getRuntimePolicy,i as logOpenRtcTeardownTrace}from'../chunk-PZ25OCVG.js';import'../chunk-4MH42GUI.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openrtc",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -62,6 +62,19 @@
62
62
  },
63
63
  "./package.json": "./package.json"
64
64
  },
65
+ "scripts": {
66
+ "build": "tsup",
67
+ "build:types": "tsc --noEmit",
68
+ "build:wasm": "cd ../../crates/openrtc && wasm-pack build --target web --out-dir ../../packages/openrtc/wasm && rm -rf ../../packages/openrtc/wasm/.gitignore",
69
+ "test": "pnpm run test:deterministic",
70
+ "test:deterministic": "OPENRTC_LIVE_TESTS=0 vitest run tests/unit tests/contract",
71
+ "test:emulator": "OPENRTC_EMULATOR_TESTS=1 OPENRTC_LIVE_TESTS=1 FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9100 VITE_USE_EMULATORS=true VITE_OPENRTC_FIRESTORE_EMULATOR_HOST=127.0.0.1:8082 VITE_OPENRTC_RTDB_EMULATOR_HOST=127.0.0.1:9001 vitest run tests/emulator",
72
+ "test:live": "pnpm run build:wasm && pnpm run build && OPENRTC_LIVE_TESTS=1 vitest run tests/live",
73
+ "test:live:emulator": "OPENRTC_LIVE_TESTS=1 FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9099 vitest run tests/live",
74
+ "test:watch": "vitest",
75
+ "coverage": "vitest run --coverage",
76
+ "prepublishOnly": "npm run build:wasm && npm run build"
77
+ },
65
78
  "dependencies": {
66
79
  "firebase": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0",
67
80
  "tweetnacl": "^1.0.3"
@@ -84,17 +97,5 @@
84
97
  },
85
98
  "bugs": {
86
99
  "url": "https://github.com/bluestarburst/Plutonium/issues"
87
- },
88
- "scripts": {
89
- "build": "tsup",
90
- "build:types": "tsc --noEmit",
91
- "build:wasm": "cd ../../crates/openrtc && wasm-pack build --target web --out-dir ../../packages/openrtc/wasm && rm -rf ../../packages/openrtc/wasm/.gitignore",
92
- "test": "pnpm run test:deterministic",
93
- "test:deterministic": "OPENRTC_LIVE_TESTS=0 vitest run tests/unit tests/contract",
94
- "test:emulator": "OPENRTC_EMULATOR_TESTS=1 OPENRTC_LIVE_TESTS=1 FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9100 VITE_USE_EMULATORS=true VITE_OPENRTC_FIRESTORE_EMULATOR_HOST=127.0.0.1:8082 VITE_OPENRTC_RTDB_EMULATOR_HOST=127.0.0.1:9001 vitest run tests/emulator",
95
- "test:live": "pnpm run build:wasm && pnpm run build && OPENRTC_LIVE_TESTS=1 vitest run tests/live",
96
- "test:live:emulator": "OPENRTC_LIVE_TESTS=1 FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9099 vitest run tests/live",
97
- "test:watch": "vitest",
98
- "coverage": "vitest run --coverage"
99
100
  }
100
- }
101
+ }
Binary file
package/wasm/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "openrtc",
3
3
  "type": "module",
4
4
  "description": "OpenRTC: a Rust-first P2P runtime for device discovery, signaling, and iroh/QUIC networking.",
5
- "version": "0.1.1",
5
+ "version": "0.1.2",
6
6
  "files": [
7
7
  "openrtc_bg.wasm",
8
8
  "openrtc.js",