openrtc 2.5.1 → 2.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +21 -1
  2. package/dist/{Connection-CTpuImO-.d.ts → Connection-CovQdc8E.d.ts} +30 -5
  3. package/dist/{DelegatingRuntimeAdapter-D67Ozqo3.d.ts → DelegatingRuntimeAdapter-3ykiNvyh.d.ts} +3 -2
  4. package/dist/{IpcRuntimeAdapter-Ddx0MtSI.d.ts → IpcRuntimeAdapter-BkM_1HyL.d.ts} +12 -2
  5. package/dist/NativeManagedBroadcastHost-WCQ6TPUU.js +1 -0
  6. package/dist/WasmBridge-LP7FHTHZ.js +1 -0
  7. package/dist/{assembly-DvfsYFCL.d.ts → assembly-C235UKSS.d.ts} +5 -3
  8. package/dist/{capabilities-CmzzxSvW.d.ts → capabilities-CdZpAKvE.d.ts} +1 -1
  9. package/dist/chunk-25CN4MLA.js +2 -0
  10. package/dist/chunk-42TNJH5S.js +1 -0
  11. package/dist/chunk-4CC6YIGG.js +1 -0
  12. package/dist/chunk-4J4F32QT.js +1 -0
  13. package/dist/chunk-CHT46RA7.js +2 -0
  14. package/dist/chunk-CNAW5BZ3.js +2 -0
  15. package/dist/chunk-P5GCLQHS.js +1 -0
  16. package/dist/chunk-VC7TGJFS.js +2 -0
  17. package/dist/{chunk-Z4KJHIV5.js → chunk-WMA4OMJL.js} +1 -1
  18. package/dist/{chunk-XTYALGJN.js → chunk-XMYBBLYK.js} +1 -1
  19. package/dist/coreClient.d.ts +3 -3
  20. package/dist/coreClient.js +1 -1
  21. package/dist/{dist-XO466BRG.js → dist-FIVA6EPA.js} +0 -18
  22. package/dist/index.d.ts +5 -5
  23. package/dist/index.js +1 -1
  24. package/dist/ipcFactory-2WMR4PH6.js +1 -0
  25. package/dist/native.d.ts +5 -5
  26. package/dist/native.js +1 -1
  27. package/dist/node.d.ts +9 -5
  28. package/dist/node.js +2 -2
  29. package/dist/openrtc-KERRTMSG.js +2 -0
  30. package/dist/openrtc_bg.wasm +0 -0
  31. package/dist/room-2MUFAJ4M.js +1 -0
  32. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  33. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  34. package/dist/runtime/device-status.d.ts +1 -1
  35. package/dist/runtime/factories.d.ts +6 -5
  36. package/dist/runtime/factories.js +1 -1
  37. package/dist/runtime/index.d.ts +9 -9
  38. package/dist/runtime/index.js +1 -1
  39. package/dist/server-browser.d.ts +4 -4
  40. package/dist/server.d.ts +4 -4
  41. package/dist/server.js +1 -1
  42. package/dist/service-node.d.ts +5 -4
  43. package/dist/service-node.js +1 -1
  44. package/dist/testing/native.d.ts +4 -4
  45. package/dist/testing/native.js +1 -1
  46. package/dist/testing.d.ts +6 -4
  47. package/dist/testing.js +1 -1
  48. package/dist/transport/index.d.ts +2 -2
  49. package/dist/{types-Cyc-mPjk.d.ts → types-C6SMXBzJ.d.ts} +1 -1
  50. package/native/darwin-arm64/openrtc-node-host +0 -0
  51. package/native/darwin-arm64/openrtc-node-host.manifest.json +20 -0
  52. package/native/darwin-x64/openrtc-node-host +0 -0
  53. package/native/darwin-x64/openrtc-node-host.manifest.json +20 -0
  54. package/native/linux-x64/openrtc-node-host +0 -0
  55. package/native/linux-x64/openrtc-node-host.manifest.json +20 -0
  56. package/native/openrtc-node-host-signing-public.pem +3 -0
  57. package/package.json +3 -2
  58. package/dist/WasmBridge-ZXBCXBBM.js +0 -1
  59. package/dist/chunk-2K47N3QP.js +0 -2
  60. package/dist/chunk-EIJNERKZ.js +0 -1
  61. package/dist/chunk-FEF3DPPB.js +0 -1
  62. package/dist/chunk-GHAJW6SZ.js +0 -2
  63. package/dist/chunk-GTHSRQ7Y.js +0 -2
  64. package/dist/chunk-VTYVIKTM.js +0 -1
  65. package/dist/chunk-Z54XUIKZ.js +0 -1
  66. package/dist/ipcFactory-PRAJ7JP7.js +0 -1
  67. package/dist/openrtc-VCS6V3AN.js +0 -2
  68. package/dist/room-ULZ2FGWV.js +0 -1
@@ -0,0 +1,2 @@
1
+ import {b as b$3,a as a$6}from'./chunk-BGWJHPBC.js';import {a as a$2}from'./chunk-4CC6YIGG.js';import {o,e,t,v,h,A,d as d$2,u,a as a$3,b,z,x,g as g$1,w as w$1,s,G,y,B,C,D,E,i,n as n$1,j,k,l as l$1,f,m as m$1}from'./chunk-25CN4MLA.js';import {g,m,n,o as o$1,c as c$4,e as e$2,d as d$3,b as b$1,f as f$1,i as i$1,h as h$1,j as j$1,k as k$2}from'./chunk-XMYBBLYK.js';import {c as c$7,k as k$1,d as d$6,a as a$5}from'./chunk-TYZS5LXQ.js';import {c,d as d$1,a,l,o as o$2,e as e$4,p,f as f$2,h as h$2,g as g$2,i as i$2,j as j$2}from'./chunk-OT7IPLZE.js';import {d}from'./chunk-OWKAJPOI.js';import {c as c$1,d as d$4,b as b$2}from'./chunk-72NEEJQG.js';import {c as c$6,d as d$5,a as a$4,b as b$4}from'./chunk-CNAW5BZ3.js';import {a as a$1}from'./chunk-DUY34MGT.js';import {c as c$2}from'./chunk-CCCYE3XN.js';import {c as c$3,e as e$1}from'./chunk-N6LGTNUI.js';import {c as c$5}from'./chunk-JPBW67B3.js';import {e as e$3}from'./chunk-2GX6GB6L.js';var at=class{constructor(e,t,n=()=>{}){this.client=e;this.backend=t;this.onLifecycleMutation=n;}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.excludeAutoConnect?.(e.deviceId,false)),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){try{await this.client.disconnectNode(e);}finally{this.onLifecycleMutation();}}async disconnectDevice(e){let t=this.backend,n=null;try{await t?.excludeAutoConnect?.(e,!0);}catch(i){n=i;}try{try{t&&typeof t.disconnectDevice=="function"&&await t.disconnectDevice(e);}finally{await this.client.forceDisconnectPeer(e);}}finally{this.onLifecycleMutation();}if(n)throw n}async excludeAutoConnect(e,t){let n=this.backend;n&&typeof n.excludeAutoConnect=="function"&&await n.excludeAutoConnect(e,t),t||this.clearManualDisconnectProjection(e);}async disconnectPeer(e,t){try{await this.client.disconnectPeer(e,t);}finally{this.onLifecycleMutation();}}async forceDisconnectPeer(e){try{await this.client.forceDisconnectPeer(e);}finally{this.onLifecycleMutation();}}clearManualDisconnectProjection(e){let t=this.client.clearManualDisconnectProjection;typeof t=="function"&&t.call(this.client,e);}};var Zi={classifyScope(r){return r.startsWith("drive-grant:")?{sessionKind:"drive-grant-guest",grantId:r.slice(12),scope:r}:r==="user-device"?{sessionKind:"app-user-device",scope:r}:{scope:r}}},Hr=[["sessionKind","session_kind"],["grantId","grant_id"],["scope","scope"],["peerNodeId","peer_node_id"],["connectionId","connection_id"],["transportEpoch","transport_epoch"],["channel","channel"],["tokenFp","token_fp"]];function Ur(r){let e=[];for(let[t,n]of Hr){let i=r[t];i==null||i===""||e.push(`${n}=${i}`);}return e.join(" ")}function Wr(r,e,t=Zi){let n=t.classifyScope(r);return {...{sessionKind:n.sessionKind,grantId:n.grantId,scope:n.scope??r},...e??{}}}function He(r,e){return Wr(r,e,Zi)}function $(r,e,t,...n){let i=Ur(e),o=jr(t,n);console.log(i&&o?`${r} ${i} ${o}`:i?`${r} ${i}`:o?`${r} ${o}`:r);}function jr(r,e){if(!r)return "";if(e.length===0)return r;if(/\{\}/.test(r)){let n=0;return r.replace(/\{\}/g,()=>{let i=n<e.length?e[n]:"";return n+=1,Xi(i)})}return [r,...e.map(Xi)].join(" ")}function Xi(r){if(r==null)return String(r);if(typeof r=="string")return r;if(typeof r=="number"||typeof r=="boolean")return String(r);try{return JSON.stringify(r)}catch{return String(r)}}var ce=class extends Error{constructor(e,t){super(t),this.kind=e,this.name="DriveGrantActorError";}};function dt(r,e){return {scope:r,peerNodeId:e}}function ct(r){return `${r.scope}@${r.peerNodeId}`}var Ue=class{constructor(e){this.state="idle";this.inFlight=null;this.key=e.key,this.dial=e.dial,this.close=e.close??(async()=>{});}isReady(){return this.state==="base-ready"||this.state==="protocol-ready"}isClosed(){return this.state==="closed"}getState(){return this.state}getPreferredTransport(){return this.state==="closed"||this.state==="idle"||this.state==="dialing"?"none":"base"}markProtocolReady(){this.state!=="closed"&&(this.state="protocol-ready",$("[drive-grant-actor][state]",this.correlation(),"state=protocol-ready"));}markDegraded(){this.state!=="closed"&&(this.state="degraded",$("[drive-grant-actor][state]",this.correlation(),"state=degraded"));}correlation(e){return He(this.key.scope,{peerNodeId:this.key.peerNodeId,...e??{}})}async ensureReady(){if(this.state==="closed")throw new ce("shutdown","drive-grant actor: already shut down");if(!this.isReady())return this.inFlight?this.inFlight:(this.state="dialing",$("[drive-grant-actor][dial]",this.correlation(),"begin"),this.inFlight=this.dial(this.key).then(()=>{this.state!=="closed"&&(this.state="base-ready",this.inFlight=null,$("[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 $("[drive-grant-actor][dial]",this.correlation(),"failed error={}",t),e instanceof ce?e:new ce("dial-failed",`drive-grant actor: dial failed: ${t}`)}),this.inFlight)}async openLogicalChannel(e){if(this.state==="closed")throw new ce("shutdown","drive-grant actor: already shut down");if(!this.isReady())throw new ce("not-ready","drive-grant actor: ensureReady() must resolve before openLogicalChannel");return $("[drive-grant-actor][channel]",this.correlation({channel:e}),"open"),{label:e}}async shutdown(){if(this.state!=="closed"){this.state="closed",this.inFlight=null,$("[drive-grant-actor][shutdown]",this.correlation(),"begin");try{await this.close(this.key);}catch{}$("[drive-grant-actor][shutdown]",this.correlation(),"complete");}}},We=class{constructor(e){this.actors=new Map;this.factory=e;}getOrSpawn(e,t){let n=ct(e),i=this.actors.get(n);if(i&&!i.isClosed())return i;let o=(t??this.factory)(e);return this.actors.set(n,o),o}get(e){return this.actors.get(ct(e))??null}async retireIfCurrent(e,t){let n=ct(e);return this.actors.get(n)!==t?false:(this.actors.delete(n),await t.shutdown(),true)}async shutdownAll(){let e=[...this.actors.values()];this.actors.clear(),await Promise.all(e.map(t=>t.shutdown()));}size(){return this.actors.size}};var qr=new TextEncoder,Gr=new TextDecoder;function Wn(r){let e=new Uint8Array(4+r.byteLength);return new DataView(e.buffer,e.byteOffset,e.byteLength).setUint32(0,r.byteLength,false),e.set(r,4),e}function Kr(r){let e=new Uint8Array(0);return t=>{for(e=jn(e,t);e.byteLength>=4;){let n=qn(e,0);if(e.byteLength<4+n)break;r(e.slice(4,4+n)),e=e.slice(4+n);}}}function zr(r){return qr.encode(JSON.stringify(r))}function Vr(r){return JSON.parse(Gr.decode(r))}function zs(r){return Wn(zr(r))}function Vs(r,e={}){return Kr(t=>{try{r(Vr(t),t);}catch(n){if(e.onInvalidJson){e.onInvalidJson(n,t);return}throw n}})}function jn(r,e){return c([r,e])}function qn(r,e){return (r[e]<<24|r[e+1]<<16|r[e+2]<<8|r[e+3])>>>0}var he=class{constructor(e,t){this.appTag=c$4(e),this.backend=t;}get tag(){return this.appTag}async waitForAuth(){return this.backend.waitForAuth()}get currentUser(){return this.backend.currentUser}usesCoordinationGateway(){return this.backend.usesCoordinationGateway?.()===true}async joinCoordinationRoom(e,t,n){if(!this.backend.joinCoordinationRoom)throw new Error("The active signaling provider does not support coordination rooms.");await this.backend.joinCoordinationRoom(e,t,n);}async leaveCoordinationRoom(e){this.backend.leaveCoordinationRoom&&await this.backend.leaveCoordinationRoom(e);}async getCoordinationRoomMembers(e){if(!this.backend.getCoordinationRoomMembers)throw new Error("The active signaling provider does not support coordination rooms.");return this.backend.getCoordinationRoomMembers(e)}watchCoordinationRoomMembers(e,t){if(!this.backend.watchCoordinationRoomMembers)throw new Error("The active signaling provider does not support coordination rooms.");return this.backend.watchCoordinationRoomMembers(e,t)}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 a$3().signInWithPluto();}async signOut(){await this.backend.signOut();}async stopAuthActivity(){typeof this.backend.stopAuthActivity=="function"&&await this.backend.stopAuthActivity();}setCoordinationHostAvailability(e){this.backend.setCoordinationHostAvailability?.(e);}capabilities(){return this.backend.capabilities?.()}async getTurnCredentials(){return this.backend.getTurnCredentials()}async updatePresence(e,t,n=true,i=300*1e3,o){await this.backend.updatePresence(e,t,n,i,o);}async setOffline(e){await this.backend.setOffline(e);}async cleanupStaleDevices(){await this.backend.cleanupStaleDevices();}async sendMessage(e,t,n,i){return this.backend.sendMessage(e,t,n,i)}async pollMessages(e){return this.backend.pollMessages(e)}async subscribeSessions(e,t){let i=(await this.backend.subscribeSessions(e)).getReader(),o=false;return (async()=>{try{for(;!o;){let{done:a,value:c}=await i.read();if(a)break;if(c)for(let d of c)"session"in d&&d.session&&await t(d.session);}}catch(a){o||console.error("[Signaling] Session stream error:",a);}})(),()=>{o=true,i.cancel();}}async getLocalDeviceId(){return typeof this.backend.getLocalDeviceId!="function"?null:this.backend.getLocalDeviceId()}async searchDevices(e){return this.backend.searchDevices(e)}async updateDevice(e,t){await this.backend.updateDevice(e,t);}async deleteDevice(e){await this.backend.deleteDevice(e);}onDevicesChange(e,t){return this.backend.onDevicesChange(e,t)}startAutoConnect(e,t){this.backend.startAutoConnect(e,t);}async submitDesiredPeerProjection(e,t){if(typeof this.backend.submitDesiredPeerProjection!="function")throw new Error("The active signaling provider does not support desired-peer projections.");await this.backend.submitDesiredPeerProjection(e,t);}notifyDisconnectRequested(e){typeof this.backend.notifyDisconnectRequested=="function"&&this.backend.notifyDisconnectRequested(e);}async startPresenceLoop(e,t,n,i,o){await this.backend.startPresenceLoop(e,t,n,i,o);}forceReconnect(){this.backend.forceReconnect();}async isConnected(e){return this.backend.isConnected(e)}async getConnectionStates(){return typeof this.backend.getConnectionStates=="function"?this.backend.getConnectionStates():[]}onStateChange(e){return typeof this.backend.onStateChange=="function"?this.backend.onStateChange(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);}};function we(r){let e=r?.split(".")[1];if(!e)return null;try{let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=(4-t.length%4)%4,i=atob(t+"=".repeat(n)),o=JSON.parse(i);return o&&typeof o=="object"&&!Array.isArray(o)?o:null}catch{return null}}function de(r,e){let t=r?.[e];return typeof t=="string"&&t.trim()?t.trim():null}function lt(r,e,t){let n=de(r,"namespaceId")===e||de(r,"appTag")===`space::${e}`,i=de(r,"developerAppTag");return n&&!!i&&(!t||i===t)}function eo(r){let e=de(r,"developerAppTag");if(e)return e;let t=de(r,"appTag");return t&&!t.startsWith("space::")?t:null}function to(r){return {get wasmClient(){return r.wasmClient},get roomCreationMode(){return r.roomCreationMode},get appLimits(){return r.appLimits},ensureAuthenticated:e=>r.ensureAuthenticated(e),getTicketWithToken:(e,t)=>r.getTicketWithToken(e,t),getNodeId:()=>r.getNodeId(),connect:(e,t)=>r.connect(e,t),refreshHostedAppSettings:e=>r.refreshHostedAppSettings(e),getRoomBackendTag:()=>r.getRoomBackendTag()}}var Te=class{constructor(e,t){this.client=e,this.signaling=t;}usesCoordinationGateway(){return this.signaling.usesCoordinationGateway?.()===true}requireCoordinationGateway(){if(!this.usesCoordinationGateway())throw new Error("[OpenRTC] Rooms require the managed coordination gateway; the direct Firebase room data plane has been removed.")}get roomBackendTag(){return this.client.getRoomBackendTag()}resolveRoomUserId(e){return a$3().getCurrentUser?.()?.uid??this.signaling.currentUser?.id??e??"anonymous"}async resolveControlPlaneAppTag(){let e=await a$3().getIdToken({forceRefresh:false}).catch(()=>null),t=eo(we(e));if(t)return t;let n=this.signaling.tag;if(!n.startsWith("space::"))return n;throw new Error("[OpenRTC] The scoped space identity is missing developer-app attribution. Mint a fresh space token before using room APIs.")}async invokeRoomCallable(e,t){let{httpsCallable:n}=await import('./dist-FIVA6EPA.js'),i=a$3().getFunctions();if(!t||typeof t!="object")throw new Error(`${e} requires an object request payload.`);if(typeof globalThis.crypto?.randomUUID!="function")throw new Error(`Secure request identity is unavailable for ${e}.`);let o={...t,idempotencyKey:`${e}:${globalThis.crypto.randomUUID()}`};return (await n(i,e)(o)).data}isAlreadyExistsError(e){if(!e||typeof e!="object")return false;let t="code"in e&&typeof e.code=="string"?e.code:"",n="message"in e&&typeof e.message=="string"?e.message:"";return t.includes("already-exists")||n.toLowerCase().includes("already exists")}normalizeRoomId(e){return e.trim().toUpperCase()}async getMembersInternal(e,t){this.requireCoordinationGateway();let n=await this.signaling.getCoordinationRoomMembers(e);return t?n.filter(i=>i.nodeId!==t):n}async createRoom(e){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");this.requireCoordinationGateway();let t=await this.client.getNodeId(),n=await this.resolveControlPlaneAppTag();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 i="",o=false,s="",a=typeof e=="string"&&e.trim().length>0?e.trim().toUpperCase():"",c=a?1:3;for(let d=0;d<c;d+=1){if(a)i=a;else {let p=new Uint8Array(6);crypto.getRandomValues(p),i=Array.from(p,u=>u.toString(36).padStart(2,"0")).join("").substring(0,6).toUpperCase();}let l=await this.client.getTicketWithToken(`room:${i}`,0);try{await this.invokeRoomCallable("createClientRoom",{appTag:n,roomId:i,nodeId:t,ticket:l}),o=!0,s=l;break}catch(p){if(this.isAlreadyExistsError(p)){if(a)throw p;continue}throw p}}if(!o)throw new Error(a?`Failed to create requested room "${a}".`:"Failed to create room after multiple attempts (ID collisions).");return await this.signaling.joinCoordinationRoom(i,t,s),i}async joinRoom(e$1,t={}){if(await this.client.ensureAuthenticated("room-op"),!this.client.wasmClient)throw new Error("WASM Client not loaded");if(this.requireCoordinationGateway(),typeof e$1!="string"||e$1.length===0||e$1.length>64)throw new Error("roomId must be a non-empty string of at most 64 characters");if(e$1!=="demo"&&!/^[a-zA-Z0-9_-]+$/.test(e$1))throw new Error("roomId must contain only alphanumeric characters, hyphens, or underscores");let n=await this.client.getNodeId(),i=this.resolveRoomUserId(n),o=await this.resolveControlPlaneAppTag(),s=this.normalizeRoomId(e$1),a=await this.client.getTicketWithToken(`room:${s}`,0);console.log("[RoomManager] joinRoom request",{roomId:e$1,normalizedId:s,targetRoomId:s,tag:this.roomBackendTag,userId:i,myNodeId:n,hasTicket:!!a,ticketLength:a?.length||0});try{await this.client.refreshHostedAppSettings(),await this.invokeRoomCallable("joinClientRoom",{appTag:o,roomId:s,nodeId:n,ticket:a}),await this.signaling.joinCoordinationRoom(s,n,a),console.log(`Joined room: ${s}`);}catch(d){throw e("[RoomManager] joinRoom failed",d),d}let c=[];if(t.bootstrapPeers!==false){let l=(await this.getMembersInternal(s,n)).map(async u=>{let h=false,f=Date.now();if(u.expiresAt)u.expiresAt<f&&(h=true);else {let m=u.lastSeenAt||u.joinedAt||0;f-m>300*1e3&&(h=true);}if(h)return null;if(u.ticket)try{console.log(`Bootstrapping: Connecting to peer ${u.nodeId}...`);let m=await this.client.connect(u.ticket,5e3);return m.send({type:"chat",text:`Use ${i} joined the room.`}).catch(v=>{e("[RoomManager] join notification send skipped",{roomId:s,peerNodeId:u.nodeId,error:v});}),m}catch(m){return console.warn(`Failed to connect to peer ${u.nodeId}:`,m),null}return null});(await Promise.allSettled(l)).forEach(u=>{u.status==="fulfilled"&&u.value&&c.push(u.value);});}return c}async leaveRoom(e){this.requireCoordinationGateway(),await this.client.ensureAuthenticated("room-op");let t=await this.client.getNodeId();if(!t)return;let n=this.normalizeRoomId(e),i=await this.resolveControlPlaneAppTag();console.log(`Leaving room ${n}...`),await this.signaling.leaveCoordinationRoom(n);try{await this.invokeRoomCallable("leaveClientRoom",{appTag:i,roomId:n,nodeId:t}),console.log(`Left room: ${n}`);}catch(o){throw console.warn("Leave room failed:",o),o}}async getRoomMembers(e){await this.client.ensureAuthenticated("room-op");let t=this.normalizeRoomId(e);return this.getMembersInternal(t)}watchRoom(e,t){let n=false,i=null;return (async()=>{try{if(await this.client.ensureAuthenticated("room-op"),n)return;this.requireCoordinationGateway();let o=this.normalizeRoomId(e);i=this.signaling.watchCoordinationRoomMembers(o,t),n&&(i(),i=null);}catch(o){n||console.warn("[RoomManager] watchRoom listener failed:",o);}})(),()=>{n=true,i?.(),i=null;}}stopHeartbeat(e){}};var $r=127,Yr=1,Gn=6;function Jr(r,e){let t=r.trim();if(!t)throw new Error("Channel envelope requires a non-empty channel id.");let n=new TextEncoder,i=n.encode(t),o=e?n.encode(JSON.stringify(e)):new Uint8Array(0),s=new Uint8Array(Gn+i.byteLength+o.byteLength),a=new DataView(s.buffer);return s[0]=$r,s[1]=Yr,a.setUint16(2,i.byteLength,false),a.setUint16(4,o.byteLength,false),s.set(i,Gn),s.set(o,Gn+i.byteLength),s}function no(r,e,t){let n=Jr(e,t),i=r.getWriter(),o=false,s=async()=>{o||(o=true,await i.write(n));},a=new WritableStream({write:async c=>{await s(),await i.write(c);},close:async()=>{await s();try{await i.close();}finally{i.releaseLock();}},abort:async c=>{try{await i.abort(c);}finally{i.releaseLock();}}});return c$5(r,a)}var io=[0,300,600,1e3,1500,2e3,2500,3e3,3500,3500,3500,3500,3500,3500,3500],oo=2e3,pt=0,ut="main",gt=64,ro=4*1024*1024,so=1,ao="openrtc:native-main-message",co=15e3,lo=16,po=3e4,uo=250,go=250,ho=2e3,mo=600,vo=2e3,fo=120;var Kn="system/peer-default",Qr="share/explicit-file",Xr="share/explicit-control",yo=[{id:Kn,kind:"system",ownership:"shared",peerModel:"device-first",routing:"session-default",readiness:"settled-peer",promotionPolicy:"eligible",signalingPolicy:"hosted",description:"Default trusted device/runtime traffic"},{id:Qr,kind:"share",ownership:"shared",peerModel:"anonymous-ticket",routing:"stream-envelope",readiness:"transport-only",promotionPolicy:"never",signalingPolicy:"ticket-only",description:"Explicit file transfer channel for share/ticket traffic"},{id:Xr,kind:"share",ownership:"shared",peerModel:"anonymous-ticket",routing:"stream-envelope",readiness:"transport-only",promotionPolicy:"never",signalingPolicy:"ticket-only",description:"Explicit control channel for share/ticket traffic"}];function Co(r){return {get registry(){return r.getRegistry()},get wasmClient(){return r.getWasmClient()},get node(){return r.getNode()},get discoveryMode(){return r.getDiscoveryMode()},get localNodeId(){return r.getLocalNodeId()},get deviceId(){return r.getDeviceId()},registerDisposer:e=>r.registerDisposer(e)}}var ht=class{constructor(e,t,n){this.ctx=e;this.options=t;this.deps=n;this.appliedAuthSessionToken=null;this.authSyncUnsubscribe=null;this.publicAuthChangeUnsubscribes=new Set;this.lastWasmAuthSyncUserId=null;this.lastWasmAuthSyncToken=null;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true;let e=this.authSyncUnsubscribe;if(this.authSyncUnsubscribe=null,e)try{e();}catch(t){console.warn("[Client][WASM-AUTH] auth-change unsubscribe failed",t);}for(let t of Array.from(this.publicAuthChangeUnsubscribes))try{t();}catch(n){console.warn("[Client][AUTH] public auth-change unsubscribe failed",n);}this.publicAuthChangeUnsubscribes.clear();}assertActive(){if(this.disposed)throw new Error("[Client][AUTH] Auth coordinator is disposed")}isSpaceWithSpaceKey(){let e=this.options.spaceKey??this.options.space;return (this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof e=="string"&&e.trim().length>0}async ensureAuthenticated(e){if(this.assertActive(),this.deps.usesTicketOnlySignalingMode())return;if(typeof this.options.coordinationGateway?.grantProvider=="function"){if(!this.deps.getCurrentUser())throw new Error("[OpenRTC] A v2 capability must install its provider-neutral identity before runtime activation.");return}let t=this.options.authMode??"anonymous",n=e!=="discovery";if(this.isSpaceWithSpaceKey()){let d=typeof this.options.apiKey=="string"?this.options.apiKey.trim():"",l=this.options.spaceKey??this.options.space,p=typeof l=="string"?l.trim():"",u=d&&p?await b$1(d,p).catch(()=>null):null;if(this.assertActive(),a$3().getCurrentUser()){let S=await a$3().getIdToken({forceRefresh:false}).catch(()=>null);this.assertActive();let C=we(S);if(u&&lt(C,u)){await b$3(this.deps.waitForAuth(),5e3),this.assertActive(),n&&f(`[Client][AUTH] Space scoped token already authenticated (${e})`);return}n&&f("[Client][AUTH] Existing Firebase user is not scoped to this space; minting scoped token",{reason:e,expectedNamespaceId:u?.slice(0,12)??null,actualNamespaceId:de(C,"namespaceId")?.slice(0,12)??null,actualDeveloperAppTag:de(C,"developerAppTag")});}let f$1=this.options.spaceTokenProvider;if(!f$1)throw new Error("[Client][AUTH] space discovery requires spaceTokenProvider (use spaceToken for static sites)");let m=await f$1(),v=typeof m?.customToken=="string"?m.customToken.trim():"";if(!v)throw new Error("[Client][AUTH] spaceTokenProvider returned no customToken");this.assertActive(),await a$3().signInWithCustomTokenValue(v),this.assertActive(),await b$3(this.deps.waitForAuth(),5e3),this.assertActive();let y=await a$3().getIdToken({forceRefresh:false}).catch(()=>null);this.assertActive(),this.setWasmAuthToken(y??v,y?"space-id-token":"space-token"),this.assertActive(),n&&f(`[Client][AUTH] Space scoped token authenticated (${e})`);return}let o=typeof this.options.sessionToken=="string"?this.options.sessionToken.trim():"";if(o&&this.appliedAuthSessionToken!==o){this.assertActive(),await a$3().signInWithCustomTokenValue(o),this.assertActive(),this.appliedAuthSessionToken=o,await b$3(this.deps.waitForAuth(),5e3),this.assertActive(),n&&f(`[Client][AUTH] Session token authenticated (${e})`);return}try{await b$3(this.deps.waitForAuth(),5e3);}catch(d){this.assertActive(),n&&console.warn(`[Client][AUTH] waitForAuth timed out (${e})`,d);}this.assertActive();let s=this.deps.getCurrentUser(),a=s?.id??s?.uid??null,c=this.options.discoveryMode==="user-scoped"&&typeof a=="string"&&a.startsWith("space_");if(s&&!c){n&&f(`[Client][AUTH] Authenticated (${e}) as ${a??"current-user"}`);return}if(c&&n&&f("[Client][AUTH] Ignoring space-scoped user for anonymous user-scoped discovery"),t==="external"||t==="required")throw new Error(`[Client][AUTH] ${t} auth mode requires host-provided auth before ${e}`);n&&f(`[Client][AUTH] No user (${e}); attempting anonymous sign-in...`),await b$3(this.deps.signInAnonymously(),8e3),this.assertActive();try{await b$3(this.deps.waitForAuth(),5e3);}catch{}if(this.assertActive(),!this.deps.getCurrentUser())throw new Error("[Client][AUTH] Anonymous sign-in did not produce an authenticated user");n&&f(`[Client][AUTH] Anonymous sign-in success (${e})`);}setWasmAuthToken(e,t){let n=this.ctx.wasmClient,i=typeof e=="string"&&e.trim().length>0?e:null,o=n?.setIdentityCredential??n?.set_auth_token;if(!n||typeof o!="function"){console.warn("[Client][WASM-IDENTITY] Wasm identity credential setter is unavailable");return}let s=i?"token":null;if(!(this.lastWasmAuthSyncUserId===s&&this.lastWasmAuthSyncToken===i)){if(this.lastWasmAuthSyncUserId=s,this.lastWasmAuthSyncToken=i,f(`[Client][WASM-AUTH] Sync token (${t}) hasToken=${!!i} tokenLen=${i?.length??0}`),i===null&&typeof n.clearIdentityCredential=="function"){n.clearIdentityCredential();return}o.call(n,i);}}installAuthTokenSync(){if(this.disposed||this.isSpaceWithSpaceKey()||this.authSyncUnsubscribe)return;let e=this.deps.onAuthChange(()=>{this.disposed||this.syncAuthTokenToWasm("auth-change").catch(t=>{this.disposed||console.warn("[Client][WASM-AUTH] Failed syncing auth token on auth change:",t);});});this.authSyncUnsubscribe=e;}async syncAuthTokenToWasm(e,t=false){if(this.disposed||this.isSpaceWithSpaceKey())return;let n=this.deps.getCurrentUser(),i=n&&n.getToken?await n.getToken(t):null;if(this.disposed)return;let o=!!i,s=i?.length||0,a=n?.id||null;this.lastWasmAuthSyncUserId===a&&this.lastWasmAuthSyncToken===i||(f(`[Client][WASM-AUTH] Sync token (${e}) hasToken=${o} tokenLen=${s} uid=${a||"none"} forceRefresh=${t}`),!this.disposed&&this.setWasmAuthToken(i,e));}async refreshRuntimeAuthToken(e="runtime-start"){this.disposed||this.deps.usesTicketOnlySignalingMode()||(await this.ensureAuthenticated("discovery"),!this.disposed&&(this.isSpaceWithSpaceKey()||await this.syncAuthTokenToWasm("auth-change",e==="managed-session")));}get currentUser(){return this.deps.getCurrentUser()}onAuthChange(e){if(this.disposed)return ()=>{};let t=true,n=this.deps.onAuthChange(o=>{!t||this.disposed||e(o);}),i=()=>{if(t){t=false;try{n();}finally{this.publicAuthChangeUnsubscribes.delete(i);}}};return this.publicAuthChangeUnsubscribes.add(i),i}async signInAnonymously(){return this.assertActive(),this.deps.signInAnonymously()}async signInWithPluto(){return this.assertActive(),this.deps.signInWithPluto()}async signOut(){if(!this.disposed&&(this.deps.beforeSignOut(),await this.deps.stopAuthActivity(),!this.disposed))return this.deps.signOut()}};var mt=class{constructor(e,t){this.ctx=e;this.deps=t;this.devicesById=new Map;this.deviceIdsByNodeId=new Map;this.activeScanningStops=new Set;this.activeSubscriptionStops=new Set;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(!this.disposed){this.disposed=true;for(let e of Array.from(this.activeScanningStops))try{e();}catch(t){console.warn("[Client] active device scanning unsubscribe failed",t);}this.activeScanningStops.clear();for(let e of Array.from(this.activeSubscriptionStops))try{e();}catch(t){console.warn("[Client] device directory subscription unsubscribe failed",t);}this.activeSubscriptionStops.clear();}}get byIdMap(){return this.devicesById}set byIdMap(e){this.devicesById=e instanceof Map?e:new Map;}get byNodeIdMap(){return this.deviceIdsByNodeId}set byNodeIdMap(e){this.deviceIdsByNodeId=e instanceof Map?e:new Map;}remember(e){if(!this.disposed&&e?.deviceId){if(this.devicesById.set(e.deviceId,e),typeof e.nodeId=="string"&&e.nodeId.trim()){let t=e.nodeId.trim();this.deviceIdsByNodeId.set(t,e.deviceId);}this.deps.onDeviceRemembered(e);}}getKnownDevice(e,t){let n=typeof e=="string"?e.trim():"";if(n){let o=this.devicesById.get(n);if(o)return o}let i=typeof t=="string"?t.trim():"";if(i){let o=this.deviceIdsByNodeId.get(i);if(o)return this.devicesById.get(o)??null}return null}getKnownDeviceIdForNode(e){let t=typeof e=="string"?e.trim():"";return t?this.deviceIdsByNodeId.get(t)??null:null}getKnownDeviceNodeId(e){let t=typeof e=="string"?e.trim():"";return t&&this.devicesById.get(t)?.nodeId?.trim()||null}rememberKnownDeviceForNode(e,t){if(this.disposed)return;let n=e.trim(),i=t.trim();!n||!i||this.deviceIdsByNodeId.set(n,i);}getKnownDevicePlatform(e,t){let n=this.getKnownDevice(e,t),i=typeof n?.platformType=="string"?n.platformType:typeof n?.platform_type=="string"?n.platform_type:null;return i?String(i).trim().toLowerCase():null}async refreshKnownDeviceCache(){if(this.disposed||!this.deps.requiresManagedTransportTrust())return;let e=await this.searchDevices().catch(()=>[]);this.disposed||e.forEach(t=>this.remember(t));}async searchDevices(){if(this.disposed)return [];if(await this.deps.ensureSignalingReadyForDiscovery("search"),this.disposed)return [];let e=await this.deps.searchDevices();return this.disposed?[]:(e.forEach(t=>{this.remember(t),this.deps.applyDiscoveredDevice(t);}),e)}async updateDevice(e,t){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.updateDevice(e,t));}async deleteDevice(e){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.deleteDevice(e));}async cleanupStaleDevices(){this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("search"),!this.disposed&&await this.deps.cleanupStaleDevices());}onDevicesChange(e){if(this.disposed)return ()=>{};let t=true,n=null,i=()=>{if(!(!t&&!n)){if(t=false,n)try{n();}finally{n=null;}this.activeSubscriptionStops.delete(i);}};return this.activeSubscriptionStops.add(i),(async()=>{await this.deps.ensureSignalingReadyForDiscovery("watch"),!(!t||this.disposed)&&(n=this.deps.onDevicesChange(o=>{!t||this.disposed||(o.forEach(s=>{this.remember(s),this.deps.applyDiscoveredDevice(s);}),e(o));}),(!t||this.disposed)&&i());})().catch(o=>{if(!(!t||this.disposed)){console.warn("[Client] Failed to initialize onDevicesChange listener:",o);try{e([]);}finally{i();}}}),i}async subscribeSessions(e,t){if(this.disposed)return ()=>{};if(await this.deps.ensureSignalingReadyForDiscovery("sessions"),this.disposed)return ()=>{};let n=true,i=await this.deps.subscribeSessions(e,s=>{if(n&&!this.disposed)return t(s)});if(this.disposed)return i(),()=>{};let o=()=>{if(n){n=false;try{i();}finally{this.activeSubscriptionStops.delete(o);}}};return this.activeSubscriptionStops.add(o),o}async startScanningLoop(e){if(this.disposed)return {stop:()=>{}};let t=new Set,n=false,i=null,o=null,s=e.localDeviceId;try{let c=await this.deps.getLocalDeviceId();if(this.disposed)return {stop:()=>{}};c&&(s=c);}catch{}i=this.onDevicesChange(c=>{n||this.disposed||e.onDevices?.(c);});let a=()=>{n=true,i&&(i(),i=null),o&&(o(),o=null),this.activeScanningStops.delete(a);};this.activeScanningStops.add(a);try{(e.onIncomingSession||e.acceptIncomingSession)&&(o=await this.subscribeSessions(s,async c=>{if(n||this.disposed)return;let d=c.sessionId||c.connectionId;if(!(!d||t.has(d))&&c.targetDeviceId===s&&c.initiatorDeviceId!==s&&!(c.state==="connected"||c.state==="closed"||c.state==="failed")){t.add(d);try{if(this.disposed)return;if(e.onIncomingSession){await e.onIncomingSession(c);return}(this.deps.getPeerStatus(c.initiatorDeviceId)==="connected"||e.isConnected?.(c.initiatorDeviceId))&&(this.deps.hasPeerScopes(c.initiatorDeviceId)||(e.hasProtectedConnectionIntent?.(c.initiatorDeviceId)??!1)||await this.deps.forceDisconnectPeer(c.initiatorDeviceId).catch(async()=>{await e.cleanupStaleConnection?.(c.initiatorDeviceId);})),c.initiatorNodeId&&await e.allowIncomingNodeId?.(c.initiatorNodeId);let p=await e.acceptIncomingSession?.(d,c.initiatorDeviceId);if(!p?.success)throw new Error(p?.error||"Failed to accept incoming signaling session");await e.onIncomingSessionAccepted?.(c);}catch(l){throw t.delete(d),l}}}));}catch(c){throw a(),c}return {stop:a}}};var Zr="relay-only endpoint ticket unavailable",es=12e3,ts=250,ns=1500;function is(r){return String(r?.message??r??"").toLowerCase().includes(Zr)}async function se(r,e={}){let t=e.windowMs??es,n=e.minDelayMs??ts,i=e.maxDelayMs??ns,o=Date.now(),s=0,a$1=null;for(;e.isActive?.()??true;){s+=1;try{return await r()}catch(c){if(a$1=c,!is(c))throw c;let d=Date.now()-o;if(d>=t)throw c;let l=Math.min(d$1(s,n,i),Math.max(0,t-d));l>0&&await a(l);}}throw a$1||new Error("endpoint ticket minting stopped before a ticket was available")}var vt=class{constructor(e,t,n){this.ctx=e;this.options=t;this.deps=n;this.managedPresenceGrant=null;this.disposed=false;this.activePresenceDescriptor=null;this.activePresenceStart=null;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true,this.managedPresenceGrant=null;let e=this.activePresenceDescriptor;this.activePresenceDescriptor=null,!(!e||!this.ctx.localNodeId)&&this.markOfflineDuringDispose(this.ctx.localNodeId);}markOfflineDuringDispose(e){let t=n=>{console.warn("[Client][PRESENCE] failed to mark offline during dispose",n);};try{Promise.resolve(this.deps.setOffline(e)).catch(t);}catch(n){t(n);}}assertActive(){if(this.disposed)throw new Error("[Client][PRESENCE] Presence controller is disposed")}resolvePresenceUserId(){let e=(this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0;return this.deps.getCurrentUser()?.id??(e?this.ctx.localNodeId:null)}async startSignalingPresenceLoop(e){if(this.disposed)return;let t=this.activePresenceDescriptor,n=(t?.metadata??"")===(e.metadata??"");if(t&&t.userId===e.userId&&t.nodeId===e.nodeId&&t.deviceName===e.deviceName&&t.ticket===e.ticket&&n){await this.activePresenceStart;return}this.activePresenceDescriptor=e;let i=this.deps.startPresenceLoop(e.userId,e.nodeId,e.deviceName,e.ticket,e.metadata);this.activePresenceStart=i;try{await i;}catch(o){throw this.activePresenceDescriptor===e&&(this.activePresenceDescriptor=null),o}finally{this.activePresenceStart===i&&(this.activePresenceStart=null);}}notifySignalingBackendChanged(){this.activePresenceDescriptor=null;}setManagedPresenceTicket(e){if(this.disposed)return;let t=e?.trim()||"";if(!t){this.managedPresenceGrant=null;return}let{irohTicket:n,tokenSuffix:i}=this.deps.splitCompoundTicket(t),o=i?this.deps.decodeCompoundTicketPayload(n,i):null;if(!o?.t||!o?.s)throw new Error("Managed presence ticket must be a compound ticket with an embedded token payload");this.managedPresenceGrant={scope:o.s,token:o.t,maxConnections:typeof o.m=="number"?o.m:0,compoundTicket:t,irohTicket:n};}clearManagedPresenceTicket(){this.managedPresenceGrant=null;}async resolvePresenceTicket(e){this.assertActive();let t=e?.trim();if(t)return t;if(this.managedPresenceGrant)return this.refreshManagedPresenceTicketIfNeeded();let n=this.options.ticket?.trim();return n||this.deps.getTicket()}async refreshManagedPresenceTicketIfNeeded(){let e$1=this.managedPresenceGrant;if(!e$1)return this.deps.getTicket();let t=e$1.irohTicket;try{t=await this.deps.getTicket();}catch{return e$1.compoundTicket}if(t===e$1.irohTicket)return e$1.compoundTicket;let n=this.ctx.wasmClient;if(n&&typeof n.endpoint_ticket_with_token=="function"){let i=n.endpoint_ticket_with_token.bind(n),o=await se(()=>i(e$1.scope,e$1.maxConnections),{isActive:()=>!this.disposed}),{irohTicket:s,tokenSuffix:a}=this.deps.splitCompoundTicket(o),c=a?this.deps.decodeCompoundTicketPayload(s,a):null;return e$1.irohTicket=s,e$1.compoundTicket=o,c?.t&&c?.s&&(e$1.token=c.t,e$1.scope=c.s,e$1.maxConnections=typeof c.m=="number"?c.m:0),e("[Client][PRESENCE] reminted managed compound ticket through Rust",{grantScope:e$1.scope}),e$1.compoundTicket}if(e$1.scope==="user-device")throw new Error("Managed user-device presence refresh requires Rust/WASM endpoint_ticket_with_token support.");return e$1.irohTicket=t,e$1.compoundTicket=this.deps.buildCompoundTicketWithPayload(t,e$1.token,e$1.scope,e$1.maxConnections),e("[Client][PRESENCE] rebuilt managed compound ticket after endpoint change",{grantScope:e$1.scope}),e$1.compoundTicket}async startPresenceLoop(e){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.ctx.localNodeId;if(!t)throw new Error("startPresenceLoop requires an initialized node");let n=this.resolvePresenceUserId();if(!n)throw new Error("startPresenceLoop requires an authenticated user");let i=await this.resolvePresenceTicket(e?.ticket);if(this.assertActive(),!i||!i.trim())throw new Error("startPresenceLoop requires a valid endpoint ticket");await this.startSignalingPresenceLoop({userId:n,nodeId:t,deviceName:e?.deviceName||this.options.deviceName||"Unknown Device",ticket:i,metadata:e?.metadata});}async startPresenceLoopForListen(){if(this.disposed)return;let e=this.ctx.localNodeId,t=this.resolvePresenceUserId();if(!t||!e)return;let n=await this.resolvePresenceTicket();this.disposed||await this.startSignalingPresenceLoop({userId:t,nodeId:e,deviceName:this.options.deviceName||"Unknown Device",ticket:n,metadata:""});}async setOffline(){this.disposed||(this.activePresenceDescriptor=null,this.ctx.localNodeId&&await this.deps.setOffline(this.ctx.localNodeId));}async updatePresence(e=true,t=3e5,n,i){if(this.disposed||!this.ctx.wasmClient)return;let o=(this.options.discoveryMode===void 0||this.options.discoveryMode==="space")&&typeof this.options.spaceKey=="string"&&this.options.spaceKey.trim().length>0;if(o&&(await this.deps.ensureAuthenticated("discovery"),this.disposed)||!this.deps.getCurrentUser()?.id&&!o)return;let a=this.ctx.localNodeId;if(!a)return;let c=await this.resolvePresenceTicket(i);if(this.disposed)return;if(!c||!c.trim())throw new Error("updatePresence requires a valid endpoint ticket");let d=n,l=await this.deps.getLocalDeviceId()||this.ctx.deviceId;if(this.disposed)return;if(!l)throw new Error("updatePresence requires a stable local device ID");try{let u=n?JSON.parse(n):{};u.deviceId||(u.deviceId=l,d=JSON.stringify(u));}catch{d=JSON.stringify({deviceId:l,rawMetadata:n});}let p=await m$1(d);await this.deps.updatePresence(a,c,e,t,p);}};var ft=class{constructor(e,t){this.ctx=e;this.deps=t;this.hostedAppSettingsLoaded=false;this.hostedAppSettingsLoad=null;this.backendConnectionStateUnsubscribe=null;this.signalingBackend=null;this.subscriptionGeneration=0;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}async refreshHostedAppSettings(e=false){if(this.disposed||this.deps.usesTicketOnlySignalingMode()||this.deps.getOptions().coordinationGateway||this.hostedAppSettingsLoaded&&!e)return;if(this.hostedAppSettingsLoad)return this.hostedAppSettingsLoad;let t=this.loadHostedAppSettings();this.hostedAppSettingsLoad=t;try{await t;}finally{this.hostedAppSettingsLoad===t&&(this.hostedAppSettingsLoad=null);}}async loadHostedAppSettings(){try{let{httpsCallable:e}=await import('./dist-FIVA6EPA.js');if(this.disposed)return;let t=a$3().getFunctions(),i=await e(t,"validateApiKey")({apiKey:this.deps.getApiKey()});if(this.disposed)return;let o=i.data;o.warning&&console.warn("[pluto-rtc]",o.warning),this.deps.setAppLimits(o.limits),o.discoveryMode&&this.deps.setDiscoveryMode(o.discoveryMode),this.deps.setRoomCreationMode(o.roomCreationMode??((this.deps.getOptions().discoveryMode??"space")==="space"?"client-open":"client-auth")),this.hostedAppSettingsLoaded=!0;}catch(e){if(this.disposed)return;console.warn("[pluto-rtc] Could not fetch hosted app settings, using local defaults.",e);}}setSignalingBackend(e){if(this.disposed)return;this.disposeBackendConnectionSubscription();let t=this.subscriptionGeneration,n=this.deps.getCurrentSignaling();this.deps.stopRoomLiveness(),this.stopAuthActivityBestEffort(n);let i=this.deps.createSignaling(e);this.signalingBackend=e,this.deps.installBackend(i,e),this.deps.onSignalingBackendChanged();let o=e.setCoreClient;typeof o=="function"&&o.call(e,this.deps.getCoreClientHost());try{Promise.resolve(e.checkForSSOToken()).catch(a=>{console.warn("[Client] backend SSO token check failed:",a);});}catch(a){console.warn("[Client] backend SSO token check failed:",a);}d$2("[Client] subscribing to backend connection state changes",{backendType:e?.constructor?.name??"unknown",hasGetConnectionStates:typeof e.getConnectionStates=="function",hasOnConnectionStateChange:typeof e.onStateChange=="function"});let s;try{s=i.onStateChange(a=>{this.disposed||t!==this.subscriptionGeneration||(this.deps.onBackendConnectionState(a),this.schedulePeerReconciliationBestEffort("backend-state"));});}catch(a){if(this.disposed||t!==this.subscriptionGeneration)return;console.warn("[Client] Failed to subscribe to backend connection state changes:",a);return}if(typeof s=="function"){let a=s;if(this.disposed||t!==this.subscriptionGeneration){this.callBackendConnectionStateUnsubscribe(a);return}this.backendConnectionStateUnsubscribe=a,d$2("[Client] backend connection state subscription established synchronously");}else s&&typeof s.then=="function"&&s.then(a=>{if(this.disposed||t!==this.subscriptionGeneration){this.callBackendConnectionStateUnsubscribe(a);return}this.backendConnectionStateUnsubscribe=a,d$2("[Client] backend connection state subscription established asynchronously");}).catch(a=>{this.disposed||t!==this.subscriptionGeneration||console.warn("[Client] Failed to subscribe to backend connection state changes:",a);});}async getLocalDeviceId(){return this.disposed?null:this.deps.getCurrentSignaling().getLocalDeviceId()}async getTurnCredentials(){return this.disposed?null:this.deps.getCurrentSignaling().getTurnCredentials()}setWasmClient(e){this.disposed||this.deps.getCurrentSignaling().setWasmClient(e);}async loadBrowserWasmRuntime(){let e=this.signalingBackend?.loadBrowserWasmRuntime;if(typeof e!="function")throw new Error("[OpenRTC] Browser WASM runtime is unavailable on the active signaling adapter.");return e.call(this.signalingBackend)}getCurrentUser(){return this.disposed?null:this.deps.getCurrentSignaling().currentUser}async waitForAuth(){this.disposed||await this.deps.getCurrentSignaling().waitForAuth();}onAuthChange(e){return this.disposed?()=>{}:this.deps.getCurrentSignaling().onAuthChange(e)}async signInAnonymously(){if(!this.disposed)return this.deps.getCurrentSignaling().signInAnonymously()}async signInWithPluto(){if(!this.disposed)return this.deps.getCurrentSignaling().signInWithPluto()}async signOut(){if(!this.disposed)return this.deps.getCurrentSignaling().signOut()}capabilities(){if(!this.disposed)return this.deps.getCurrentSignaling().capabilities?.()}startAutoConnect(e,t){this.disposed||this.deps.getCurrentSignaling().startAutoConnect(e,t);}async isConnected(e){return this.disposed?false:this.deps.getCurrentSignaling().isConnected(e)}notifyDisconnectRequested(e){this.disposed||this.deps.getCurrentSignaling().notifyDisconnectRequested(e);}forceReconnect(){this.disposed||this.deps.getCurrentSignaling().forceReconnect();}async startPresenceLoop(e,t,n,i,o){this.disposed||await this.deps.getCurrentSignaling().startPresenceLoop(e,t,n,i,o);}async setOffline(e){this.disposed||await this.deps.getCurrentSignaling().setOffline(e);}async updatePresence(e,t,n,i,o){this.disposed||await this.deps.getCurrentSignaling().updatePresence(e,t,n,i,o);}async searchDevices(){return this.disposed?[]:this.deps.getCurrentSignaling().searchDevices()}async updateDevice(e,t){this.disposed||await this.deps.getCurrentSignaling().updateDevice(e,t);}async deleteDevice(e){this.disposed||await this.deps.getCurrentSignaling().deleteDevice(e);}async cleanupStaleDevices(){this.disposed||await this.deps.getCurrentSignaling().cleanupStaleDevices();}onDevicesChange(e){return this.disposed?()=>{}:this.deps.getCurrentSignaling().onDevicesChange(e)}async subscribeSessions(e,t){return this.disposed?()=>{}:this.deps.getCurrentSignaling().subscribeSessions(e,t)}async stopAuthActivity(){this.disposed||(this.deps.stopRoomLiveness(),await this.stopAuthActivityFor(this.deps.getCurrentSignaling()));}dispose(){if(this.disposed)return;this.disposed=true,this.disposeBackendConnectionSubscription(),this.deps.stopRoomLiveness();let e=this.deps.getCurrentSignaling();this.stopAuthActivityBestEffort(e);}async stopAuthActivityFor(e){if(e&&typeof e.stopAuthActivity=="function")try{await e.stopAuthActivity();}catch(t){if(this.disposed)return;console.warn("[Client] signaling auth-scoped teardown failed",t);}}stopAuthActivityBestEffort(e){try{this.stopAuthActivityFor(e);}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}disposeBackendConnectionSubscription(){this.subscriptionGeneration+=1,this.callBackendConnectionStateUnsubscribe(this.backendConnectionStateUnsubscribe),this.backendConnectionStateUnsubscribe=null;}callBackendConnectionStateUnsubscribe(e){if(e)try{e();}catch(t){console.warn("[Client] backend connection-state unsubscribe failed",t);}}};function Io(r){let e$1=new WeakMap;return new zn({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getApiKey:()=>r.options.apiKey,getCurrentSignaling:()=>r.signaling,createSignaling:t=>new he(n(r.options),t),stopRoomLiveness:()=>r.rooms.stopHeartbeat(),installBackend:t=>{r.setSignaling(t),r.setRooms(new Te(r.roomClientHost,t));},setAppLimits:t=>{r.setAppLimits(t);},setDiscoveryMode:t=>{r.options.discoveryMode=t;},setRoomCreationMode:t=>{r.setRoomCreationMode(t);},getCoreClientHost:()=>({ensureManagedApplicationRoute:t=>r.ensureManagedApplicationRoute(t),waitForApplicationCryptoForPeer:(t,n)=>r.waitForApplicationCryptoForPeer(t,n),hasApplicationRouteForPeer:(t,n)=>r.hasApplicationRouteForPeer(t,n),rememberRouteRepairTokenFromTicket:t=>r.sessionTokens.rememberRouteRepairTokenFromTicket(t)}),schedulePeerReconciliation:t=>r.peerProjection.schedule(t),onBackendConnectionState:t=>{if(r.peerProjection.applyBackendConnectionState(t),t.transportState!=="connected"||t.replacementInProgress===true)return;let n=r.registry.get(t.connectionId);if(!n||n.isClosed||t.remoteNodeId&&t.remoteNodeId.trim()!==n.remoteNodeId)return;let i=t.transportStableId,o=t.transportGeneration;if(!Number.isSafeInteger(i)||Number(i)<=0||!Number.isSafeInteger(o)||Number(o)<=0){e("[Client] connected backend state lacks physical-generation authority",{connectionId:n.id,remoteNodeId:n.remoteNodeId,transportStableId:i??null,transportGeneration:o??null});return}let s=()=>n.handleBaseTransportAvailable("rust-backend-state",{transportState:t.transportState??t.state,transportGeneration:o,transportStableId:i}),a=`${o}:${i}`,c=false;r.managedTransportDialer.repairAdmissionForTransportGeneration(n.remoteNodeId,Number(i)).then(d=>{!d||n.isClosed||(r.sessionTokens.applyTrustApproval(n,d,"managed-transport-generation-repair"),c=true);}).catch(d=>{if(r.managedTransportDialer.isTerminalSessionTokenRejection(d)){let l=d instanceof Error?d.message:String(d);n.handleSessionAdmissionRejected(l),e("[Client][AUTH] current-generation admission rejected terminally",{connectionId:n.id,remoteNodeId:n.remoteNodeId,transportStableId:i,reason:l});return}e("[Client][AUTH] current-generation admission repair deferred",{connectionId:n.id,remoteNodeId:n.remoteNodeId,transportStableId:i,error:d instanceof Error?d.message:String(d)});}).finally(()=>{let d=s();!c||!d||n.isClosed||e$1.get(n)===a||(e$1.set(n,a),r.applicationRoute.refreshApplicationRouteHandshake(n,"rust-backend-generation-replaced").catch(l=>{e("[Client][HANDSHAKE] current-generation key refresh failed",{connectionId:n.id,remoteNodeId:n.remoteNodeId,transportStableId:i,transportGeneration:o,error:l instanceof Error?l.message:String(l)});}));});},beforeSignOut:()=>r.prepareStreamListenForSignOutIfExists(),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getTicket:()=>r.runtimeIdentity.getTicket(),ensureSignalingReadyForDiscovery:t=>r.runtimeReadiness.ensureSignalingReadyForDiscovery(t),requiresManagedTransportTrust:()=>r.runtimeStatus.requiresManagedTransportTrust(r.discoveryMode),onDeviceRemembered:t=>{r.applicationCrypto.reindexDevice(t);},applyDiscoveredDevice:t=>{r.peerServices.applyDiscoveredDevice(t);},getPeerStatus:t=>r.peerServices.getPeerStatus(t),hasPeerScopes:t=>r.peerServices.hasPeerScopes(t),forceDisconnectPeer:t=>r.peerServices.forceDisconnectPeer(t)})}var zn=class{constructor(e){this.host=e;}get auth(){return this._auth||(this._auth=new ht(this.host.getContext(),this.host.getOptions(),{usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode(),getCurrentUser:()=>this.backend.getCurrentUser(),waitForAuth:()=>this.backend.waitForAuth(),onAuthChange:e=>this.backend.onAuthChange(e),signInAnonymously:()=>this.backend.signInAnonymously(),signInWithPluto:()=>this.backend.signInWithPluto(),signOut:()=>this.backend.signOut(),beforeSignOut:()=>this.host.beforeSignOut(),stopAuthActivity:()=>this.backend.stopAuthActivity()})),this._auth}get backend(){return this._backend||(this._backend=new ft(this.host.getContext(),{getOptions:()=>this.host.getOptions(),getApiKey:()=>this.host.getApiKey(),usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode(),getCurrentSignaling:()=>this.host.getCurrentSignaling(),createSignaling:e=>this.host.createSignaling(e),stopRoomLiveness:()=>this.host.stopRoomLiveness(),installBackend:(e,t)=>this.host.installBackend(e,t),setAppLimits:e=>this.host.setAppLimits(e),setDiscoveryMode:e=>this.host.setDiscoveryMode(e),setRoomCreationMode:e=>this.host.setRoomCreationMode(e),getCoreClientHost:()=>this.host.getCoreClientHost(),onBackendConnectionState:e=>this.host.onBackendConnectionState(e),schedulePeerReconciliation:e=>this.host.schedulePeerReconciliation(e),onSignalingBackendChanged:()=>{this._presence?.notifySignalingBackendChanged();}})),this._backend}get presence(){return this._presence||(this._presence=new vt(this.host.getContext(),this.host.getOptions(),{ensureWasmRuntimeForP2P:()=>this.host.ensureWasmRuntimeForP2P(),ensureAuthenticated:e=>this.auth.ensureAuthenticated(e),getTicket:()=>this.host.getTicket(),getLocalDeviceId:()=>this.backend.getLocalDeviceId(),getCurrentUser:()=>this.backend.getCurrentUser(),startPresenceLoop:(e,t,n,i,o)=>this.backend.startPresenceLoop(e,t,n,i,o),setOffline:e=>this.backend.setOffline(e),updatePresence:(e,t,n,i,o)=>this.backend.updatePresence(e,t,n,i,o),splitCompoundTicket:e=>a$4(e),decodeCompoundTicketPayload:(e,t)=>d$5(e,t),buildCompoundTicketWithPayload:(e,t,n,i)=>c$6(e,t,n,i)})),this._presence}get devices(){return this._devices||(this._devices=new mt(this.host.getContext(),{ensureSignalingReadyForDiscovery:e=>this.host.ensureSignalingReadyForDiscovery(e),searchDevices:()=>this.backend.searchDevices(),updateDevice:(e,t)=>this.backend.updateDevice(e,t),deleteDevice:e=>this.backend.deleteDevice(e),cleanupStaleDevices:()=>this.backend.cleanupStaleDevices(),onDevicesChange:e=>this.backend.onDevicesChange(e),subscribeSessions:(e,t)=>this.backend.subscribeSessions(e,t),requiresManagedTransportTrust:()=>this.host.requiresManagedTransportTrust(),onDeviceRemembered:e=>this.host.onDeviceRemembered(e),applyDiscoveredDevice:e=>this.host.applyDiscoveredDevice(e),getPeerStatus:e=>this.host.getPeerStatus(e),hasPeerScopes:e=>this.host.hasPeerScopes(e),forceDisconnectPeer:e=>this.host.forceDisconnectPeer(e),getLocalDeviceId:()=>this.backend.getLocalDeviceId()})),this._devices}clearManagedPresenceTicketIfExists(){this._presence?.clearManagedPresenceTicket();}};var yt=class{constructor(e){this.localTerminalConnectionIds=new Set;this.connections=e??new Map;}get(e){return this.connections.get(e)}has(e){return this.connections.has(e)}set(e,t){this.connections.set(e,t);}delete(e){return this.connections.delete(e)}values(){return this.connections.values()}forEach(e){this.connections.forEach(e);}[Symbol.iterator](){return this.connections[Symbol.iterator]()}get size(){return this.connections.size}all(){return Array.from(this.connections.values())}applicationReady(e={}){return this.all().filter(t=>typeof t.isPayloadReady=="function"?t.isPayloadReady(e):!t.isClosed)}get backingMap(){return this.connections}set backingMap(e){this.connections=e instanceof Map?e:new Map;}getForPeer(e,t){for(let n of this.connections.values())if(e&&n.id===e||t&&(n.remoteNodeId===t||n.deviceId===t))return n;return null}markLocalTerminalClose(e){this.localTerminalConnectionIds.add(e);}clearLocalTerminalClose(e){this.localTerminalConnectionIds.delete(e);}hasLocalTerminalClose(e){return !!e&&this.localTerminalConnectionIds.has(e)&&!this.connections.has(e)}};var W=class W{constructor(e,t,n,i,o,s={}){this.receiveBuffer=new Uint8Array(0);this.writeMutex=Promise.resolve();this.closed=false;this.nativeSignalSender=null;this.applicationKeyAgreementObservationEpoch=0;this.lastApplicationPayloadTransport=null;this.lastTransportStatusFingerprint=null;this.lastBaseTransportGeneration=null;this.lastBaseTransportStableId=null;this.remoteDedicatedCarrierControl=false;this.remoteDedicatedCarrierControlReady=false;this.listeners=[];this.closeListeners=[];this.irohHealthListeners=[];this.pendingMessages=[];this.pendingEncryptedApplicationPayloads=[];this.applicationCryptoWaiters=[];this.id=e,this.localNodeId=t,this.remoteNodeId=n,this.deviceId=n,this.writer=i,this.reader=o,this.options=s,this.readLoop();}get isClosed(){return this.closed}get transportType(){return "iroh-relay"}setApplicationCrypto(e){this.options={...this.options,applicationCrypto:e},e&&(this.resolveApplicationCryptoWaiters(),this.flushPendingEncryptedApplicationPayloads());}markKeyAgreement(){return this.applicationKeyAgreementObservationEpoch+=1,this.applicationKeyAgreementObservationEpoch}getKeyAgreementEpoch(){return this.applicationKeyAgreementObservationEpoch}requireApplicationCrypto(){this.options={...this.options,requireApplicationCrypto:true};}isApplicationCryptoRequired(){return this.options.requireApplicationCrypto===true}isPayloadReady(e={}){if(this.closed||!this.hasRequiredApplicationCrypto()||!this.hasBaseApplicationRoute())return false;let t=e.preferredTransports??[];return t.length===0||t.includes(this.transportType)||t.includes("iroh")}payloadTransports(e={}){return this.isPayloadReady(e)?[this.transportType]:[]}admissionReady(e="session-token-trust-applied"){this.options.transportContext?.requestIrohCarrier?.();}requestTransportRecovery(e){this.options.transportContext?.requestIrohCarrier?.();}handleAppForeground(){this.options.transportContext?.requestIrohCarrier?.();}handleBaseTransportAvailable(e,t){if(t.transportState&&t.transportState!=="connected")return false;let n=Number(t.transportGeneration),i=Number(t.transportStableId);if(!Number.isSafeInteger(n)||n<=0||!Number.isSafeInteger(i)||i<=0)return false;if(this.lastBaseTransportGeneration!==null){if(n<this.lastBaseTransportGeneration)return false;if(n===this.lastBaseTransportGeneration)return i===this.lastBaseTransportStableId}return this.lastBaseTransportGeneration=n,this.lastBaseTransportStableId=i,this.remoteDedicatedCarrierControlReady=false,this.reportTransportStatusIfChanged(),this.options.transportContext?.requestIrohCarrier?.(),true}getTransportCapabilityAdvertisementEpoch(){return `${this.lastBaseTransportGeneration??0}:${this.lastBaseTransportStableId??0}`}getBaseTransportStableId(){return this.lastBaseTransportStableId}isCurrentSignal(e){if(this.closed||!e||typeof e!="object")return false;let t=e;return t.type==="handshake"&&["hello","capability-update","response","ack"].includes(String(t.action??""))||t.type==="#openrtc-iroh-carrier"&&(t.carrier==="web-rtc"||t.carrier==="moq-draft14")?true:t.type==="#pluto-signal"&&t.content?.transport==="webrtc"&&typeof t.content.negotiationId=="string"&&t.content.negotiationId.length>0}observeRemoteCarrierControlCapability(e,t){this.remoteDedicatedCarrierControl=e,this.remoteDedicatedCarrierControlReady=e&&t;}supportsDedicatedCarrierControl(){return !this.closed&&this.remoteDedicatedCarrierControl}isRemoteDedicatedCarrierControlReady(){return !this.closed&&this.remoteDedicatedCarrierControl&&this.remoteDedicatedCarrierControlReady}isLocalDedicatedCarrierControlReady(){return !this.closed&&!!this.options.applicationCrypto&&this.hasBaseApplicationRoute()}async getTransportDiagnostics(){return {...this.getTransportStatus(),transportStableId:this.lastBaseTransportStableId,transportGeneration:this.lastBaseTransportGeneration,routeGeneration:null,lifecycleOwner:"rust-logical-peer"}}async send(e,t={}){if(await this.waitForRequiredApplicationCrypto(),!this.isPayloadReady(t))throw new Error("[Connection] Application payload route is not ready.");await this.sendTyped(0,e,true);}lastPayloadTransport(){return this.lastApplicationPayloadTransport}async sendControl(e){await this.sendTyped(0,e,false);}async sendRawIrohFrame(e){await this.writeFrame(e);}getAvailableTransports(){return this.closed||!this.hasBaseApplicationRoute()?[]:[this.transportType]}async disconnect(){this.close("Explicit Disconnect");}handleSessionAdmissionRejected(e){this.close(`Session Admission Rejected: ${e}`);}onMessage(e){this.listeners.push(e);for(let t of this.pendingMessages)e(t);}onDisconnect(e){this.closeListeners.push(e);}injectData(e){this.handleData(e);}receiveFrameBody(e){if(e.length===0)return;if(W.isUntypedDataFrame(e)){let o=this.openUntypedApplicationPayload(e);o&&this.processDataPayload(o);return}let t=e[0]??0,n=e.slice(1);if(t===3){this.sendTyped(4,n,false).catch(()=>{});return}if(t===4){for(let o of this.irohHealthListeners)o("healthy");return}if(t===1||t===2)return;let i=this.openApplicationPayload(t,n);i&&this.processDataPayload(i);}receiveMessage(e){this.emitMessage(e);}receiveDataPayload(e){this.processDataPayload(e);}onWebRtcHeartbeatHealth(e){}onIrohHeartbeatHealth(e){this.irohHealthListeners.push(e);}reportTransportStatusIfChanged(){if(this.closed)return;let e={...this.getTransportStatus(),transportStableId:this.lastBaseTransportStableId??void 0,transportGeneration:this.lastBaseTransportGeneration??void 0},t=JSON.stringify(e);t!==this.lastTransportStatusFingerprint&&(this.lastTransportStatusFingerprint=t,Promise.resolve(this.options.onTransportStatusChange?.(e)).catch(()=>{}));}getTransportStatus(){return {activeTransport:this.transportType,parallelTransport:null}}getLatencySnapshot(){return {}}setNativeSignalSender(e){this.nativeSignalSender=e;}getControlFrameMode(){return this.options.controlFrameMode??"typed"}async sendNativeControlEnvelope(e){return this.getControlFrameMode()!=="native-main"||!this.nativeSignalSender?false:(await this.nativeSignalSender(e),true)}useNativeControl(e){this.options={...this.options,controlFrameMode:"native-main"},this.nativeSignalSender=e;}receiveInternalSignal(e){}hasRequiredApplicationCrypto(){return this.options.requireApplicationCrypto!==true||!!this.options.applicationCrypto}hasBaseApplicationRoute(){return this.options.hasBaseApplicationStream===false?false:!!this.writer||this.getControlFrameMode()==="native-main"&&!!this.nativeSignalSender&&typeof this.options.transportContext?.sendIrohApplicationFrame=="function"}async waitForRequiredApplicationCrypto(){if(this.hasRequiredApplicationCrypto())return;if(this.closed)throw new Error("[Connection] Connection closed before application crypto was ready.");let e=this.options.applicationCryptoWaitMs??W.DEFAULT_APPLICATION_CRYPTO_WAIT_MS;await new Promise((t,n)=>{let i={resolve:t,reject:n,timer:null};i.timer=setTimeout(()=>{let o=this.applicationCryptoWaiters.indexOf(i);o>=0&&this.applicationCryptoWaiters.splice(o,1),n(new Error("[Connection] Application crypto negotiation timed out."));},e),this.applicationCryptoWaiters.push(i);});}resolveApplicationCryptoWaiters(){for(let e of this.applicationCryptoWaiters.splice(0))e.timer&&clearTimeout(e.timer),e.resolve();}rejectApplicationCryptoWaiters(e){for(let t of this.applicationCryptoWaiters.splice(0))t.timer&&clearTimeout(t.timer),t.reject(e);}encodePayload(e){return typeof e=="string"?W.encoder.encode(e):e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):W.encoder.encode(JSON.stringify(e))}buildFrame(e,t){let n=new Uint8Array(5+t.length);return new DataView(n.buffer).setUint32(0,1+t.length,false),n[4]=e,n.set(t,5),n}async sendTyped(e,t,n){if(this.closed)throw new Error("[Connection] Logical peer connection is closed.");n&&await this.waitForRequiredApplicationCrypto();let i=this.encodePayload(t),o=n?this.options.applicationCrypto?.protectPayload(e,i)??i:i,s=this.buildFrame(e,o),a=this.options.transportContext;a?.sendIrohApplicationFrame&&(!this.writer||n&&this.options.controlFrameMode==="native-main")?await a.sendIrohApplicationFrame(s):await this.writeFrame(s),this.lastApplicationPayloadTransport=this.transportType;}async writeFrame(e){if(this.closed||!this.writer)throw new Error("[Connection] Logical Iroh stream is unavailable.");let t=this.writeMutex,n;this.writeMutex=new Promise(i=>{n=i;});try{if(await t,!this.writer)throw new Error("[Connection] Logical Iroh stream is unavailable.");await this.writer.write(e);}catch(i){throw this.close(`Send Error: ${String(i)}`),i}finally{n();}}openApplicationPayload(e,t){let n=this.options.applicationCrypto;if(!n)return a$5(t)?(this.queueEncryptedApplicationPayload(e,t),null):this.options.requireApplicationCrypto&&!this.isPlaintextBootstrapPayload(t)?null:t;let i=n.openPayload(e,t);return !i&&a$5(t)&&this.queueEncryptedApplicationPayload(e,t),i}openUntypedApplicationPayload(e){let t=this.options.applicationCrypto;if(!t)return a$5(e)?(this.queueEncryptedApplicationPayload("untyped",e),null):this.options.requireApplicationCrypto&&!this.isPlaintextBootstrapPayload(e)?null:e;let n=t.openPayload(0,e)??t.openPayload(3,e);return !n&&a$5(e)&&this.queueEncryptedApplicationPayload("untyped",e),n}isPlaintextBootstrapPayload(e){try{return JSON.parse(W.decoder.decode(e))?.type==="handshake"}catch{return false}}queueEncryptedApplicationPayload(e,t){this.pendingEncryptedApplicationPayloads.push({typeId:e,payload:new Uint8Array(t)}),this.pendingEncryptedApplicationPayloads.length>W.MAX_PENDING_ENCRYPTED_PAYLOADS&&this.pendingEncryptedApplicationPayloads.splice(0,this.pendingEncryptedApplicationPayloads.length-W.MAX_PENDING_ENCRYPTED_PAYLOADS);}flushPendingEncryptedApplicationPayloads(){let e=this.options.applicationCrypto;if(!e)return;let t=this.pendingEncryptedApplicationPayloads.splice(0),n=[];for(let i of t){let o=i.typeId==="untyped"?e.openPayload(0,i.payload)??e.openPayload(3,i.payload):e.openPayload(i.typeId,i.payload);o?i.typeId!==1&&i.typeId!==2&&this.processDataPayload(o):a$5(i.payload)&&n.push(i);}this.pendingEncryptedApplicationPayloads=n.slice(-W.MAX_PENDING_ENCRYPTED_PAYLOADS);}async readLoop(){if(this.reader)try{for(;!this.closed;){let{done:e,value:t}=await this.reader.read();if(e){if(this.getControlFrameMode()==="native-main"&&this.nativeSignalSender){this.reader=null,this.writer=null;return}this.close("Read Done (Remote Closed)");return}t&&this.handleData(t);}}catch(e){if(this.getControlFrameMode()==="native-main"&&this.nativeSignalSender){this.reader=null,this.writer=null;return}this.close(`Read Error: ${String(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 n=new DataView(this.receiveBuffer.buffer,this.receiveBuffer.byteOffset,this.receiveBuffer.byteLength).getUint32(0,false);if(n<1||this.receiveBuffer.length<4+n)return;this.receiveFrameBody(this.receiveBuffer.slice(4,4+n)),this.receiveBuffer=this.receiveBuffer.slice(4+n);}}static isUntypedDataFrame(e){let t=e[0];return t===123||t===91||a$5(e)||e.length>=4&&e[0]===68&&e[1]===86&&e[2]===67&&e[3]===72}processDataPayload(e){if(a$5(e)){let t=this.openUntypedApplicationPayload(e);t&&t!==e&&this.processDataPayload(t);return}try{let t=W.decoder.decode(e),n=W.encoder.encode(t);if(!(n.length===e.length&&n.every((o,s)=>o===e[s])))return this.emitMessage(e);try{this.emitMessage(JSON.parse(t));}catch{this.emitMessage(t);}}catch{this.emitMessage(e);}}emitMessage(e){this.pendingMessages.push(e),this.pendingMessages.length>W.MAX_PENDING_MESSAGES&&this.pendingMessages.splice(0,this.pendingMessages.length-W.MAX_PENDING_MESSAGES);for(let t of this.listeners)t(e);}close(e){if(!this.closed){if(this.closed=true,this.rejectApplicationCryptoWaiters(new Error(`[Connection] ${e}`)),this.pendingEncryptedApplicationPayloads=[],this.writer?.close().catch(()=>{}),this.options.transportContext?.readerCloseStrategy==="release-lock")try{this.reader?.releaseLock();}catch{}else this.reader?.cancel().catch(()=>{});this.writer=null,this.reader=null;for(let t of this.closeListeners)t();}}};W.decoder=new TextDecoder("utf-8",{fatal:true}),W.encoder=new TextEncoder,W.MAX_PENDING_MESSAGES=256,W.MAX_PENDING_ENCRYPTED_PAYLOADS=256,W.DEFAULT_APPLICATION_CRYPTO_WAIT_MS=1e4;var ne=W;async function ie(r,e$1,t){await h$2(r,e$1)&&e("[Client][CONNECT] Closed unused bi stream after adopting existing connection",{remoteNodeId:t??null,reason:e$1});}async function So(r){try{await r.refreshApplicationRouteHandshake(r.connection,r.reason,{forceReciprocal:!0});return}catch(e$1){let t=r.wasmClient.is_remote_admitted;if(!r.hasCompoundTicketToken||typeof t!="function")throw e$1;let n;try{n=await t.call(r.wasmClient,r.ticket),r.assertActive();}catch{throw e$1}if(n)throw e$1;e("[Client][AUTH] repairing admission after physical replacement",{nodeId:r.nodeId,connectionId:r.connection.id,reason:r.reason}),await r.representTicket(`${r.reason}:current-generation-admission-repair`),r.assertActive(),await r.refreshApplicationRouteHandshake(r.connection,`${r.reason}:after-current-generation-admission-repair`,{forceReciprocal:true});}}function Ct(){return new Error("Transport-only ticket-only channels do not expose a main message stream.")}var Vn=class extends ne{constructor(t){let n=new WritableStream({write(){throw Ct()}}).getWriter(),i=new ReadableStream().getReader();super(t.connectionId,t.localNodeId,t.remoteNodeId,n,i,{...t.options,controlFrameMode:"native-main",hasBaseApplicationStream:false});this.input=t;this.transportDisconnectStarted=false;}async send(){throw Ct()}async sendControl(){throw Ct()}async sendRawIrohFrame(){throw Ct()}async disconnect(){await super.disconnect(),!this.transportDisconnectStarted&&(this.transportDisconnectStarted=true,await this.disconnectNodeTransportBestEffort());}async disconnectForMainStreamReplacement(){await super.disconnect();}async disconnectNodeTransportBestEffort(){try{await this.input.disconnectNodeTransport(this.remoteNodeId);}catch{}}};function Po(r){return new Vn(r)}var It=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async connect(e$1,t=2e4,n,i,o){if(this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive(),!e$1||!e$1.trim())throw new Error("connect requires a non-empty endpoint ticket");let s=e$1.trim(),{irohTicket:a,tokenSuffix:c}=a$4(s),d=this.deps.getWasmClient(),l;try{l=await d.endpoint_id_from_ticket(a);}catch(b){throw new Error(`connect requires a valid endpoint ticket: ${b?.message||b}`)}this.assertActive();let p=null;if(c){let b=d$5(a,c);typeof b?.t=="string"&&(p=b.t,this.deps.rememberRouteRepairTokenForNode(l,b.t,c));}let u=this.deps.getDeterministicConnectionId(l),h=this.deps.getRegisteredChannel(i??null),f$1=this.deps.isTransportOnlyChannel(i);e("[Client][CONNECT] resolved ticket target",{nodeId:l,connectionId:u,channelId:i??null,registeredChannel:h?{id:h.id,readiness:h.readiness,promotionPolicy:h.promotionPolicy,signalingPolicy:h.signalingPolicy}:null,transportOnlyChannel:f$1,hasCompoundTicketToken:!!p});let m=c?d$5(a,c):null,v=o?.approvedScope??null;!v&&typeof m?.s=="string"&&m.s.trim()&&(v=m.s.trim());let y=this.ctx.registry.get(u);if(y&&(!p||o?.admissionAlreadyPresented===true)){let b=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,v,p,y);return this.deps.assignConnectionChannel(y,i),b&&(this.deps.initializeConnectionTrust(y,b),this.deps.bindConnectionDeviceIdInRust(y,b)),p?(this.deps.approveSessionTokenNode(l),this.deps.approveSessionTokenConnection(y.id),this.deps.applySessionTokenTrustApproval(y,v,"managed-transport-adoption"),this.deps.announceConnectionWhenStable(y),y):(await this.deps.refreshApplicationRouteHandshake(y,"connect-existing"),this.assertActive(),y)}let S=async b=>{f(`Initiating managed transport dial to ${l} (${b})...`);let T=await this.deps.ensureWasmManagedTransport(s,n??null,{skipIfConnected:o?.admissionAlreadyPresented===true,admissionAlreadyPresented:o?.admissionAlreadyPresented===true,timeoutMs:t});if(this.assertActive(),T.approvedScope)v=T.approvedScope,this.deps.setSessionTokenApprovedScope(u,T.approvedScope);else if(p&&!v){await this.schedulePeerReconciliationBestEffort("managed-dial-scope-lookup"),this.assertActive();let M=this.deps.getSessionTokenApprovedScope(u);if(typeof M=="string"&&M.trim())v=M.trim();else {let J=this.deps.getPeerState(n??l)?.scopes?.[0];typeof J=="string"&&J.trim()&&(v=J.trim());}}},C=async(b,T)=>So({connection:b,reason:T,nodeId:l,ticket:s,hasCompoundTicketToken:!!p,wasmClient:d,assertActive:()=>this.assertActive(),refreshApplicationRouteHandshake:(M,j,J)=>this.deps.refreshApplicationRouteHandshake(M,j,J),representTicket:S});try{await S("initial");}catch(b){if(this.deps.isLocalIrohRuntimeNotInitializedError(b)){let T=await this.deps.recoverLocalIrohRuntime("connect-managed-dial");if(this.assertActive(),!T)throw new Error(`Failed to initiate managed transport dial to ${l}: ${b?.message||b}`);try{await S("after-local-runtime-recovery");}catch(M){throw new Error(`Failed to initiate managed transport dial to ${l} after local Iroh runtime recovery: ${M?.message||M}`)}}else throw b}if(this.assertActive(),p){let b=v??o?.approvedScope??null,T=this.ctx.registry.get(u);if(T&&!T.isClosed){let M=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,b,p,T);this.deps.assignConnectionChannel(T,i),this.deps.initializeConnectionTrust(T,M),M&&this.deps.bindConnectionDeviceIdInRust(T,M),this.deps.approveSessionTokenNode(l),this.deps.approveSessionTokenConnection(T.id),this.deps.applySessionTokenTrustApproval(T,b,"dialer-compound-ticket-existing-connection"),this.deps.announceConnectionWhenStable(T),e("[Client][AUTH] adopted token-approved existing connection",{nodeId:l,connectionId:T.id,localNodeId:T.localNodeId,remoteNodeId:T.remoteNodeId,approvalScope:v||null});let j=T.disconnectForMainStreamReplacement;if(!f$1&&typeof j=="function")this.deps.cleanupReplacedConnection(T.id),await j.call(T),this.assertActive();else return await C(T,"dialer-compound-ticket-existing-connection"),this.assertActive(),T}}if(f$1){let b;b=Po({connectionId:u,localNodeId:this.ctx.localNodeId,remoteNodeId:l,options:{transportContext:this.deps.createTransportContext(l),applicationCrypto:this.deps.getOptions()?.applicationCrypto,requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),onTransportStatusChange:j=>this.deps.handleConnectionTransportStatus(b,j.activeTransport,j.parallelTransport)},disconnectNodeTransport:j=>this.deps.disconnectNodeTransport(j)});let T=v??o?.approvedScope??null,M=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,T,p,b);return this.deps.assignConnectionChannel(b,i),this.deps.initializeConnectionTrust(b,M),this.deps.registerConnection(b),M&&this.deps.bindConnectionDeviceIdInRust(b,M),p&&(this.deps.approveSessionTokenNode(l),this.deps.approveSessionTokenConnection(b.id),this.deps.applySessionTokenTrustApproval(b,T,"dialer-compound-ticket-transport-only")),this.deps.announceConnectionWhenStable(b),e("[Client][AUTH] using transport-only channel connection",{nodeId:l,connectionId:b.id,channelId:i??null,signalingMode:this.deps.getOptions().signalingMode??"hosted",hasCompoundTicketToken:!!p}),b}let P=await this.openMainBiStream(l,t);this.disposed&&(await ie(P,"dial-coordinator-disposed-after-open",l),this.assertActive());let k=this.ctx.registry.get(u);if(k&&!k.isClosed){let b=v??o?.approvedScope??null,T=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,b,p,k);return await ie(P,"late-dial-adopted-existing-connection",l),this.deps.assignConnectionChannel(k,i),this.deps.initializeConnectionTrust(k,T),T&&this.deps.bindConnectionDeviceIdInRust(k,T),p&&(this.deps.approveSessionTokenNode(l),this.deps.approveSessionTokenConnection(k.id),this.deps.applySessionTokenTrustApproval(k,b,"dialer-compound-ticket-late-existing-connection")),this.deps.announceConnectionWhenStable(k),e("[Client][CONNECT] adopted existing connection after async dial completed",{nodeId:l,connectionId:k.id,channelId:i??null,approvalScope:v||null}),await C(k,"late-dial-adopted-existing-connection"),this.assertActive(),k}let A=this.deps.shouldUseNativeMainFramingForPeer(l,this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,v??o?.approvedScope??null,p,null),!!p);A&&(await b$3(this.deps.writeNativeMainLabelHeaderOnBiStream(P,l),4e3,"writeNativeMainLabelHeaderOnBiStream"),this.disposed&&(await ie(P,"dial-coordinator-disposed-after-native-label",l),this.assertActive()));let R=this.createConnection({connId:u,nodeId:l,biStream:P,useNativeMainFraming:A});this.deps.assignConnectionChannel(R,i);let L=v??o?.approvedScope??null,N=this.deps.resolveExpectedDeviceIdForSessionTokenScope(n,L,p,R);if(this.deps.initializeConnectionTrust(R,N),this.disposed&&(await this.disconnectConnectionBestEffort(R),this.assertActive()),this.deps.registerConnection(R),N&&this.deps.bindConnectionDeviceIdInRust(R,N),p){await this.schedulePeerReconciliationBestEffort("compound-ticket-connect"),this.assertActive();let b=this.deps.getPeerState(R.id)??this.deps.getPeerState(l),T=this.deps.consumePendingSessionTokenTrustApproval(R.id);T.approved?this.deps.applySessionTokenTrustApproval(R,T.scope??L,"dialer-compound-ticket-pending"):b?.admissionState==="admitted"&&this.deps.applySessionTokenTrustApproval(R,L,"dialer-compound-ticket-rust-admitted"),e("[Client][AUTH] token-approved connection registered locally",{nodeId:l,connectionId:R.id,localNodeId:R.localNodeId,remoteNodeId:R.remoteNodeId,rustAdmissionState:b?.admissionState??null,pendingApproval:T.approved});}return this.deps.announceConnectionWhenStable(R),e("[Client][HANDSHAKE] sending hello (dial path)",{connectionId:R.id,remoteNodeId:R.remoteNodeId}),this.sendDialHelloInBackground(R),p&&(await C(R,"dialer-compound-ticket-new-connection"),this.assertActive()),R}async connectPeer(e$1){this.assertActive();let t=e$1.scope??"persistent";if(!e$1.ticket)throw new Error("connectPeer requires a ticket.");e("[Client][connectPeer] starting",{scope:t,channelId:e$1.channelId??null,hasDeviceId:!!e$1.deviceId,ticketLength:e$1.ticket.length});let n=a$4(e$1.ticket).tokenSuffix!==null;if(!n&&!this.deps.sessionTokenScopeAllowsDeviceBinding(t))throw new Error(`connectPeer requires a compound ticket with a session token for restricted scope '${t}'.`);if(e$1.keepManualDisconnect&&this.hasManualDisconnectProjection(e$1.deviceId))throw new Error(`connectPeer suppressed by manual disconnect for device ${e$1.deviceId}`);e$1.deviceId&&!n&&!e$1.keepManualDisconnect&&this.deps.clearManualDisconnectProjection(e$1.deviceId);let i=await this.connect(e$1.ticket,Math.max(1,e$1.timeoutMs??2e4),e$1.deviceId,e$1.channelId);this.assertActive();let o=this.deps.getSessionTokenApprovedScope(i.id),s=[...o?[o]:[],...this.deps.getPeerScopes(i.id)].filter((u,h,f)=>f.indexOf(u)===h),a=s.length>0?s:[t],d=s.length===0||a.some(u=>this.deps.sessionTokenScopeAllowsDeviceBinding(u))?e$1.deviceId:void 0,l=this.deps.resolvePromotionEligibility({connectionId:i.id,nodeId:i.remoteNodeId,deviceId:d??void 0}),p=d||i.remoteNodeId||i.deviceId||i.id;d&&n&&this.deps.clearManualDisconnectProjection(d),this.deps.hasRustPeerLifecycleProjection()?this.schedulePeerReconciliationInBackground("connect-peer"):this.deps.dispatchLiveConnectionProjection(i,{trustProjection:null,promotionEligible:l,peerId:p,deviceId:d,ticket:e$1.ticket,scopes:a,applicationRouteReady:this.deps.hasApplicationRouteForConnection(i)});for(let u of a)this.deps.addPeerScope(p,u);return i}hasManualDisconnectProjection(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;let n=this.deps.getWasmClient();if(n&&typeof n.is_auto_connect_excluded=="function"&&n.is_auto_connect_excluded(t)===true)return true;let i=this.deps.getPeerState(t);if(!i)return false;if(i.manualDisconnect===true)return true;let o=i,s=[i.error,o.lastDisconnectReason].filter(a=>typeof a=="string"&&a.length>0).join(" ");return /manual disconnect/i.test(s)}async openMainBiStream(e,t){this.assertActive();let n=null,i=0,o=500,s=Math.ceil(t/o),a$1=this.deps.getWasmClient(),c=a$1.open_native_main_control_bi;if(typeof c!="function")throw new Error("[Client][NATIVE-MAIN] open_native_main_control_bi is unavailable on this WASM build; the admission and key-agreement control plane cannot use a protected application stream. Rebuild the OpenRTC WASM runtime.");for(;i<s;){this.assertActive();try{n=await b$3(c.call(a$1,e),2500,"wasmClient.open_native_main_control_bi"),this.disposed&&(await ie(n,"dial-coordinator-disposed-during-open",e),this.assertActive());break}catch(d){if(this.disposed)throw d;i++,await a(o);}}if(!n)throw new Error(`Failed to establish connection to ${e} after ${t} ms`);return n}assertActive(){if(this.disposed)throw new Error("Connection dial cancelled because the client was disposed.")}createConnection(e$1){let{connId:t,nodeId:n,biStream:i,useNativeMainFraming:o}=e$1,s;if(s=new ne(t,this.deps.getLocalNodeId(),n,i.send.getWriter(),i.recv.getReader(),{transportContext:this.deps.createTransportContext(n),applicationCrypto:this.deps.getOptions()?.applicationCrypto,requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:o?"native-main":"typed",onTransportStatusChange:a=>this.deps.handleConnectionTransportStatus(s,a.activeTransport,a.parallelTransport)}),o&&this.deps.getWasmClient()){let a=this.deps.getWasmClient();s.setNativeSignalSender(async c=>{await this.deps.sendNativeSignalEnvelope(s,n,c,a);}),e("[Client][NATIVE-MAIN] Attached native signal sender to dial-path connection",{connectionId:s.id,remoteNodeId:n});}return s}sendDialHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send outgoing handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).catch(t);}catch(n){t(n);}}schedulePeerReconciliationBestEffort(e){try{return Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>[])}catch{return Promise.resolve([])}}schedulePeerReconciliationInBackground(e){if(!this.disposed)try{this.schedulePeerReconciliationBestEffort(e);}catch{}}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};var St=class{constructor(e){this.deps=e;this.connectionListeners=[];this.disconnectionListeners=[];this.announcedConnections=new Set;this.stabilityWaitEpochs=new Map;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.connectionListeners=[],this.disconnectionListeners=[],this.announcedConnections.clear(),this.stabilityWaitEpochs.clear());}findLiveConnectionForRemoteNode(e,t){let n=this.deps.registry.get(t);if(n&&!n.isClosed)return n;for(let i of this.deps.registry.values())if(i.remoteNodeId===e&&!i.isClosed)return i;return null}cleanupReplacedConnection(e){this.disposed||(this.deps.registry.delete(e),this.forgetAnnouncedConnection(e));}healOrphanTsConnection(e$1){if(this.disposed)return;let t=this.deps.registry.get(e$1);!t||t.isClosed||e("[Client][PEER-RECONCILE] observed orphan TS connection",{connectionId:e$1});}registerConnection(e){if(this.disposed)return;let t=this.deps.registry;t.clearLocalTerminalClose(e.id);let n=t.get(e.id);if(t.set(e.id,e),n&&n!==e&&this.forgetAnnouncedConnection(e.id),n&&n!==e&&!n.isClosed&&this.disconnectBestEffort(n),typeof e.setApplicationCrypto=="function"){let s=this.deps.resolveApplicationCryptoForPeer(e.remoteNodeId,e);s&&e.setApplicationCrypto(s);}this.flushPendingNativeMainHandshakesBestEffort(e.remoteNodeId,"connection-registered"),this.flushPendingNativeMainSignalsBestEffort(e.remoteNodeId,"connection-registered");let i=this.deps.getConnectionTrustState(e.id),o=i?.verifiedDeviceId??i?.expectedDeviceId??this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId)??null;o?this.deps.bindConnectionDeviceIdInRust(e,o):this.lookupConnectionDeviceBindingInBackground(e),i?.verified&&o&&this.deps.retireSupersededConnections(e,o,"registered-trusted-replacement"),this.deps.hasRustPeerLifecycleProjection()?this.schedulePeerReconciliationBestEffort("register-connection"):this.deps.applyConnectionTrustProjection(e),typeof e.reportTransportStatusIfChanged=="function"&&e.reportTransportStatusIfChanged(),e.onMessage(s=>{if(!this.disposed)try{Promise.resolve(this.deps.handleMessage(e,s)).catch(a=>{this.disposed||console.warn("[Client] connection message handler failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});});}catch(a){this.disposed||console.warn("[Client] connection message handler failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:a});}}),e.onDisconnect(()=>{if(this.disposed||t.get(e.id)!==e)return;let s=this.deps.hasRustPeerLifecycleProjection();s||t.markLocalTerminalClose(e.id);let a=this.deps.getExistingPeerProjectionForDisconnect(e);t.delete(e.id),this.deps.cleanupConnectionState(e.id,s?"physical-route":"logical-terminal"),s?this.schedulePeerReconciliationBestEffort("connection-disconnect"):this.deps.dispatchLiveConnectionProjection(e,{trustProjection:null,promotionEligible:this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),existingProjection:a,terminalTransportClose:true,applicationRouteReady:false}),this.announcedConnections.delete(e.id)&&this.emitDisconnection(e);});}announceConnectionWhenStable(e){let t=(this.stabilityWaitEpochs.get(e.id)??0)+1;this.stabilityWaitEpochs.set(e.id,t),(async()=>{if(this.disposed)return;let n=await this.waitForStableConnection(e);if(!this.disposed&&this.deps.registry.get(e.id)===e&&this.stabilityWaitEpochs.get(e.id)===t){if(!n){if(!e.isClosed){let i=this.deps.getConnectionTrustState(e.id);console.warn(`[Client] Suppressing unstable connection ${e.id}`,{deviceId:e.deviceId,transportStatus:typeof e.getTransportStatus=="function"?e.getTransportStatus():null,trustRequired:i?.required??null,trustVerified:i?.verified??null,trustFailed:i?.failed??null,trustFailureReason:i?.failureReason??null});}return}this.announcedConnections.has(e.id)||(this.announcedConnections.add(e.id),this.emitConnection(e));}})();}async waitForStableConnection(e){if(this.disposed)return false;let t=this.deps.initializeConnectionTrust(e),n=false,i=this.deps.hasApplicationRouteForConnection(e),o=this.deps.allowsTransportOnlyStability(e),s=this.deps.getWasmClient(),a$1=s&&typeof s.wait_for_peer=="function"?s.wait_for_peer:null;if(a$1)try{let l=await a$1.call(s,e.deviceId,this.deps.stableTimeoutMs);if(i=this.deps.hasApplicationRouteForConnection(e),l?.settledReady&&(!t.required||t.verified)&&(i||o))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:l?.settledReady??null,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null}),!1}catch{}let c=Date.now(),d=null;for(;Date.now()-c<this.deps.stableTimeoutMs;){if(this.disposed||e.isClosed||t.required&&t.failed)return false;let l=await this.deps.isCoreConnectionHealthy(e.deviceId);if(this.disposed)return false;if(n=l,i=this.deps.hasApplicationRouteForConnection(e),l){if(d===null&&(d=Date.now()),Date.now()-d>=this.deps.stableWindowMs&&(!t.required||t.verified)&&(i||o))return true}else d=null;await a(this.deps.stablePollMs);}return console.warn("[Client][STABILITY] connection did not become stable before timeout",{connectionId:e.id,deviceId:e.deviceId,trustRequired:t.required,trustVerified:t.verified,trustFailed:t.failed,trustFailureReason:t.failureReason??null,lastCoreHealthy:n,lastApplicationRouteReady:i,transportStatus:typeof e.getTransportStatus=="function"?e.getTransportStatus():null}),false}onConnection(e){return this.disposed?()=>{}:(this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);})}onDisconnection(e){return this.disposed?()=>{}:(this.disconnectionListeners.push(e),()=>{this.disconnectionListeners=this.disconnectionListeners.filter(t=>t!==e);})}isConnectionAnnounced(e){return this.announcedConnections.has(e)}forgetAnnouncedConnection(e){this.announcedConnections.delete(e),this.stabilityWaitEpochs.set(e,(this.stabilityWaitEpochs.get(e)??0)+1);}emitConnection(e){for(let t of [...this.connectionListeners])try{t(e);}catch(n){console.warn("[Client] connection listener failed",n);}}emitDisconnection(e){for(let t of [...this.disconnectionListeners])try{t(e);}catch(n){console.warn("[Client] disconnection listener failed",n);}}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}flushPendingNativeMainHandshakesBestEffort(e,t){if(!this.disposed)try{Promise.resolve(this.deps.flushPendingNativeMainHandshakesForNode(e,t)).catch(()=>{});}catch{}}flushPendingNativeMainSignalsBestEffort(e,t){if(!this.disposed)try{Promise.resolve(this.deps.flushPendingNativeMainSignalsForNode(e,t)).catch(()=>{});}catch{}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}lookupConnectionDeviceBindingInBackground(e){try{Promise.resolve(this.deps.searchDevices()).then(()=>{if(this.disposed)return;let t=this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId);t&&this.deps.bindConnectionDeviceIdInRust(e,t);}).catch(()=>{});}catch{}}};var Pt=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async handleMessage(e,t,n){if(this.disposed)return;let i=!!t&&typeof t=="object"&&t.type==="handshake",o=this.deps.requiresManagedTransportTrust()||this.deps.usesTicketOnlySignalingMode(),s=!o||this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)||this.deps.getConnectionTrustState(e.id)?.verified===true;if(!(!i&&s&&await(this.deps.handleIrohCarrierControl?.(e,t)??false))){if(i){await this.handleHandshake(e,t,n);return}else if(o&&!this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)){console.warn("[Client][SESSION-TOKEN] Dropping application message before admission",{connectionId:e.id,remoteNodeId:e.remoteNodeId}),this.disconnectBestEffort(e);return}this.deps.dispatchMessage(e,t);}}async handleHandshake(e$1,t,n){if(this.disposed)return false;let i=t.action??"hello",o=t.capabilities&&typeof t.capabilities=="object"?t.capabilities:void 0,s=o?.carrierSchema===2,a=s&&o?.webrtc===true,c=s&&o?.moq===true;typeof e$1.observeRemoteCarrierControlCapability=="function"&&e$1.observeRemoteCarrierControlCapability(s&&o?.dedicatedCarrierControl===true,s&&o?.dedicatedCarrierControlReady===true);let d=this.deps.requiresManagedTransportTrust();if(i==="hello"&&t.sessionToken){let u=await this.deps.validateIncomingSessionTokenWithRetry(t.sessionToken,e$1.id,{remoteNodeId:e$1.remoteNodeId,source:"handshake-hello",tokenPayload:typeof t.sessionTokenPayload=="string"?t.sessionTokenPayload:void 0});if(this.disposed)return false;if(!u.ok)return console.warn("[Client][SESSION-TOKEN] Rejecting connection \u2014 invalid session token",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,reason:u.reason,hasToken:!!t.sessionToken}),this.disconnectBestEffort(e$1),false;t.sessionToken&&this.deps.applySessionTokenTrustApproval(e$1,u.scope??null,"handshake-hello");}else i==="hello"&&d&&e("[Client][SESSION-TOKEN] Deferring tokenless managed hello pending admission",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId});let l=await this.deps.handleApplicationKeyAgreement(e$1,t,n).catch(u=>this.disposed?{remotePublicChanged:false,cryptoReady:false,replyAction:null,replyClaimId:null}:(console.warn("[Client][KEY-AGREEMENT] Handshake key agreement failed; closing connection",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,error:u}),this.disconnectBestEffort(e$1),{remotePublicChanged:false,cryptoReady:false,replyAction:null,replyClaimId:null}));if(this.disposed)return false;e("[Client][HANDSHAKE] received",{action:i,connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,channelId:t.channelId??this.deps.getConnectionChannelId(e$1.id)??null,carrierSchema:o?.carrierSchema??null,remoteSupportsWebRTC:a,remoteSupportsMoQ:c,hasSessionToken:!!t.sessionToken,hasTransportTrust:!!t.transportTrust});let p=t.capabilities?.applicationKeyAgreement===true&&l.cryptoReady?l.replyAction:null;return p&&this.sendHandshakeWithRecoveryInBackground(e$1,p,null,"application-key-agreement-confirmation","[Client][KEY-AGREEMENT] Failed to advance reciprocal key agreement",l.replyClaimId?()=>this.deps.releaseApplicationKeyAgreementReply(e$1.id,p,l.replyClaimId):void 0),this.deps.assignConnectionChannel(e$1,t.channelId??null),t.transportTrust||d?this.handleTransportTrustHandshakeInBackground(e$1,t,i,d):(t.action==="hello"||!t.action)&&t.sessionToken&&p!=="response"&&this.sendHandshakeWithRecoveryInBackground(e$1,"response",null,"session-token-response","[Client][SESSION-TOKEN] Failed to send response handshake"),true}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}sendHandshakeInBackground(e,t,n){let i=o=>{this.disposed||console.warn(n,{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:o});};try{Promise.resolve(this.deps.sendTransportHandshake(e,t)).catch(i);}catch(o){i(o);}}sendHandshakeWithRecoveryInBackground(e,t,n,i,o,s){let a=c=>{s?.(),!this.disposed&&console.warn(o,{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:c});};try{Promise.resolve(this.deps.sendTransportHandshakeWithRecovery(e,t,n,i)).catch(a);}catch(c){a(c);}}handleTransportTrustHandshakeInBackground(e,t,n,i){let o=s=>{this.disposed||console.warn("[Client][TRUST] Handshake processing failed",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:s});};try{Promise.resolve(this.handleTransportTrustHandshake(e,t,n,i)).catch(o);}catch(s){o(s);}}async handleTransportTrustHandshake(e$1,t,n,i){try{if(this.disposed)return;let o=n,s=t.transportTrust??null,a=this.deps.initializeConnectionTrust(e$1);if(s?.deviceId&&!a.expectedDeviceId&&this.deps.getKnownDevice(s.deviceId,e$1.remoteNodeId)&&(a.expectedDeviceId=s.deviceId),o==="hello"){let c=typeof s?.challenge=="string"?s.challenge:null;if(!c&&a.required)if(this.deps.isSessionTokenApproved(e$1.id,e$1.remoteNodeId)){let d=this.deps.getSessionTokenApprovedScope(e$1.id);a.required=!1,a.verified=!0,a.failed=!1,a.failureReason=void 0,a.issuedChallenge=null,this.deps.applyConnectionTrustProjection(e$1);let l=typeof s?.deviceId=="string"&&s.deviceId.trim()?s.deviceId.trim():a.expectedDeviceId??this.deps.getKnownDeviceIdForNode(e$1.remoteNodeId)??null;l&&this.deps.sessionTokenScopeAllowsDeviceBinding(d)&&this.deps.bindConnectionDeviceIdInRust(e$1,l),e("[Client][TRUST] Skipping challenge enforcement for session-token-approved connection",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:o});}else a.failureReason="missing-transport-trust-challenge",this.deps.applyConnectionTrustProjection(e$1),e("[Client][TRUST] Deferring missing hello challenge enforcement pending response/ack or session-token approval",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:o});if(await this.deps.sendTransportHandshakeWithRecovery(e$1,"response",c,`trust-${o}-response`),this.disposed)return}else if(o==="response"||o==="ack"){let c=await this.deps.verifyRemoteTransportTrust(e$1,s);if(this.disposed)return;if(!c.verified){if(c.stale){e("[Client][TRUST] Ignoring stale transport proof and requesting current challenge",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:o,reason:c.reason??"stale-transport-trust-response"}),await this.deps.sendTransportHandshakeWithRecovery(e$1,"hello",null,"stale-trust-response-rechallenge");return}if(this.deps.isSessionTokenApproved(e$1.id,e$1.remoteNodeId)){this.deps.applySessionTokenTrustApproval(e$1,null,"handshake-proof-bypass-after-session-token");return}if(c.reason==="missing-transport-trust-payload"||c.reason==="missing-signed-transport-challenge"){a.failureReason=c.reason,this.deps.applyConnectionTrustProjection(e$1),e("[Client][TRUST] Deferring absent optional transport proof pending session-token admission",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:o});return}a.required&&await this.deps.enforceConnectionTrustFailure(e$1,c.reason??"remote-transport-proof-invalid");return}if(this.deps.markConnectionTrustVerified(e$1,c.deviceId),o==="response"&&typeof s?.challenge=="string"&&(await this.deps.sendTransportHandshakeWithRecovery(e$1,"ack",s.challenge,"trust-response-ack"),this.disposed))return}else o==="capability-update"&&(this.deps.isSessionTokenApproved(e$1.id,e$1.remoteNodeId)||this.deps.getConnectionTrustState(e$1.id)?.verified);}catch(o){console.warn("[Client][TRUST] Handshake processing failed",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,error:o});}finally{let o=t.capabilities?.carrierSchema===2&&(t.capabilities.webrtc===true||t.capabilities.moq===true),s=!i||this.deps.isSessionTokenApproved(e$1.id,e$1.remoteNodeId)||this.deps.getConnectionTrustState(e$1.id)?.verified===true;this.disposed||await this.deps.ensureCurrentTransportCapabilityAdvertisement(e$1,"incoming-handshake-capability-replay"),!this.disposed&&o&&(s?await this.deps.observeIrohCarrierHandshake?.(e$1,t.capabilities):await this.deps.observeIrohCarrierHandshake?.(e$1,t.capabilities,false));}}};var wt=class wt{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}async handleUnhandledIncomingStreamEvent(e$1){if(await this.closeIfDisposed(e$1,"incoming-acceptor-disposed"))return;let{type:t,stream:n,remoteNodeId:i,traceId:o}=e$1,s=e$1.protocolHint;if(t==="bi"&&s==="native-main"&&(s=this.deps.normalizeAuthoritativeIncomingProtocolHint("native-main",i,o)??"native-main",e$1={...e$1,protocolHint:s}),!e$1.invalid){if(t==="bi"&&e$1.channel?.channelId===Kn){await this.receiveDefaultPeerStream(e$1);return}if(t==="bi"&&e$1.channel?.channelId){await ie(n,"unclaimed-named-channel",i);return}if(t==="uni"){if(!this.deps.shouldSkipIncomingStreamProbe()&&await this.deps.tryHandleNativeMainUniStream(n,i,o))return;await this.deps.cancelUnhandledIncomingUniStream(n,i);return}if(t==="bi"&&s==="native-main"){e("[Client][INCOMING] Handling native desktop main stream",{remoteNodeId:i,traceId:o||null}),this.handleNativeMainStreamInBackground(n,i,e$1.transportStableId,o,"[Client][NATIVE-MAIN] Background handler crashed",e$1.admissionCandidate===true);return}if(this.deps.shouldTreatIncomingStreamAsTransportOnly(e$1)){this.deps.logIncomingDiagnostic("bi:drop-unhandled-ticket-flow",{remoteNodeId:i||"unknown",traceId:o||null,protocolHint:s,channelId:e$1.channel?.channelId??null});return}t==="bi"&&s!=="explicit"&&await this.acceptIncomingBiStream(e$1);}}async receiveDefaultPeerStream(e){let t=e.stream,n=e.remoteNodeId,i=this.deps.getDeterministicConnectionId(n),o=this.deps.getConnection(i);if(!o||o.isClosed||!e$4(t)){await ie(t,"peer-default-without-live-connection",n);return}let s=t.recv.getReader(),a=t.send.getWriter(),c=new Uint8Array(0);try{for(;;){let{done:d,value:l}=await s.read();if(d)break;if(!l||l.byteLength===0)continue;let p=new Uint8Array(c.byteLength+l.byteLength);for(p.set(c),p.set(l,c.byteLength),c=p;c.byteLength>=4;){let u=new DataView(c.buffer,c.byteOffset,c.byteLength).getUint32(0,!1);if(u===0||u>wt.MAX_PEER_MESSAGE_FRAME_BYTES)throw new Error(`invalid peer-default frame length ${u}`);if(c.byteLength<4+u)break;o.receiveFrameBody(c.slice(4,4+u)),c=c.slice(4+u);}}if(c.byteLength!==0)throw new Error(`truncated peer-default frame (${c.byteLength} bytes)`)}catch(d){this.deps.logIncomingDiagnostic("peer-default:receive-failed",{connectionId:i,remoteNodeId:n,traceId:e.traceId??null,error:d});}finally{try{await a.close();}catch{}try{s.releaseLock();}catch{}try{a.releaseLock();}catch{}}}async acceptIncomingBiStream(e$1){if(await this.closeIfDisposed(e$1,"incoming-acceptor-disposed-before-accept"))return;let{stream:t,remoteNodeId:n,traceId:i}=e$1,o=e$1.protocolHint,s=this.deps.getDeterministicConnectionId(n),a=this.deps.getKnownDevice(null,n),c=typeof a?.platformType=="string"?String(a.platformType).toLowerCase():typeof a?.platform_type=="string"?String(a.platform_type).toLowerCase():null;if(!this.deps.usesTicketOnlySignalingMode()&&(c==="desktop"||c==="mobile")){e("[Client][INCOMING] Routing unhinted native peer stream through native-main handler",{connectionId:s,remoteNodeId:n,traceId:i||null,protocolHint:o,knownRemotePlatform:c}),this.handleNativeMainStreamInBackground(t,n,e$1.transportStableId,i,"[Client][NATIVE-MAIN] Unhinted native peer stream handler crashed",e$1.admissionCandidate===true);return}let d=this.deps.getConnection(s);if(d&&!d.isClosed){let m=await this.deps.isCoreConnectionHealthy(n).catch(()=>false);if(await this.closeIfDisposed(e$1,"incoming-acceptor-disposed-after-core-health"))return;let v=typeof d.getControlFrameMode=="function"&&d.getControlFrameMode()==="native-main";if(m){if(!v){e("[Client][INCOMING] Closing auxiliary bi stream while typed connection remains authoritative",{connectionId:s,remoteNodeId:n,traceId:i||null,protocolHint:o}),await ie(t,"typed-connection-auxiliary-stream",n);return}e("[Client][INCOMING] Routing auxiliary bi stream to native-main handler",{connectionId:s,remoteNodeId:n,traceId:i||null,protocolHint:o}),this.handleNativeMainStreamInBackground(t,n,e$1.transportStableId,i,"[Client][NATIVE-MAIN] Auxiliary stream handler crashed");return}if(e("[Client][INCOMING] Replacing existing connection main stream",{connectionId:s,remoteNodeId:n,traceId:i||null}),this.deps.cleanupReplacedConnection(s),await this.disconnectConnection(d),await this.closeIfDisposed(e$1,"incoming-acceptor-disposed-after-existing-disconnect"))return}let l=t;if(!e$4(l)){console.error("[Client][INCOMING] Unable to construct connection from invalid bi stream",{remoteNodeId:n});return}let p,u;try{p=l.send.getWriter(),u=l.recv.getReader();}catch(m){console.error("[Client][INCOMING] Failed to acquire incoming stream reader/writer",{remoteNodeId:n,error:m});return}let h;h=new ne(s,this.deps.getLocalNodeId(),n,p,u,{transportContext:this.deps.createTransportContext(n),applicationCrypto:this.deps.getOptions()?.applicationCrypto,requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:"typed",onTransportStatusChange:m=>this.deps.handleConnectionTransportStatus(h,m.activeTransport,m.parallelTransport)});let f=this.deps.getKnownDeviceIdForNode(n);if(this.deps.initializeConnectionTrust(h,f),this.disposed){await this.disconnectConnection(h);return}this.deps.registerConnection(h),f?this.deps.bindConnectionDeviceIdInRust(h,f):this.lookupAcceptedDeviceBindingInBackground(h,n),this.deps.announceConnectionWhenStable(h),e("[Client][HANDSHAKE] sending hello (incoming connection path)",{connectionId:h.id,remoteNodeId:h.remoteNodeId}),this.sendIncomingHelloInBackground(h);}handleNativeMainStreamInBackground(e,t,n,i,o,s=false){let a=c=>{this.disposed||console.error(o,{remoteNodeId:t,traceId:i||null,error:c});};try{let c=Number.isSafeInteger(n)&&Number(n)>0,d=s?this.deps.handleNativeMainStream(e,t,c?n:void 0,!0):c?this.deps.handleNativeMainStream(e,t,n):this.deps.handleNativeMainStream(e,t);Promise.resolve(d).catch(a);}catch(c){a(c);}}lookupAcceptedDeviceBindingInBackground(e,t){let n=i=>{this.disposed||console.warn("[Client][BIND] Accept-side searchDevices fallback failed",{connectionId:e.id,remoteNodeId:t,error:i});};try{Promise.resolve(this.deps.searchDevices()).then(()=>{if(this.disposed)return;let i=this.deps.getKnownDeviceIdForNode(t);i?this.deps.bindConnectionDeviceIdInRust(e,i):console.warn("[Client][BIND] Accept-side directory lookup found no deviceId for remote node",{connectionId:e.id,remoteNodeId:t});}).catch(n);}catch(i){n(i);}}sendIncomingHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send incoming handshake",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).catch(t);}catch(n){t(n);}}async disconnectConnection(e){try{await Promise.resolve(e.disconnect());}catch{}}async closeIfDisposed(e,t){return this.disposed?(e.type==="bi"?await ie(e.stream,t,e.remoteNodeId):e.type==="uni"&&await this.deps.cancelUnhandledIncomingUniStream(e.stream,e.remoteNodeId),true):false}};wt.MAX_PEER_MESSAGE_FRAME_BYTES=4*1024*1024;var bt=wt;function bo(r){return r==="desktop"||r==="mobile"||r==="native"}function wo(r,e,t=false){return true}function To(r){return !r}function Tt(r,e,t){return r}var $n={ready:false,phase:"frame-start",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};function Ro(r,e){let t=new TextEncoder().encode(JSON.stringify(r)),n=new TextEncoder().encode(e.label),i=new Uint8Array(5+n.byteLength+4+t.byteLength),o=new DataView(i.buffer),s=0;return i[s]=e.protocolByte,s+=1,o.setUint32(s,n.byteLength,false),s+=4,i.set(n,s),s+=n.byteLength,o.setUint32(s,t.byteLength,false),s+=4,i.set(t,s),i}async function ko(r,e,t,n,i=8e3){if(typeof window>"u"||typeof window.dispatchEvent!="function")return null;let o=[],s=c=>{o.push(Promise.resolve(c));};if(window.dispatchEvent(new CustomEvent(r,{detail:{remoteNodeId:e,remoteDeviceId:t,message:n,respondWith:s}})),o.length===0)return null;let a;try{let c=await Promise.race([Promise.allSettled(o),new Promise(d=>{a=setTimeout(()=>d([]),i);})]);for(let d of c)if(d.status==="fulfilled"&&d.value!==void 0&&d.value!==null)return d.value}finally{a&&clearTimeout(a);}return null}function Ao(r,e){if(r.byteLength===0)return $n;if(r[0]===e.protocolByte){if(r.byteLength<5)return $n;let i=new DataView(r.buffer,r.byteOffset,r.byteLength),o=i.getUint32(1,false);if(o>0&&o<=e.maxLabelBytes&&r.byteLength>=5+o&&new TextDecoder().decode(r.slice(5,5+o))===e.label){let a=5+o+4;if(r.byteLength<a)return {ready:false,phase:"frame-body",expectedFrameLength:0,consumedBytes:0,payloadBytes:new Uint8Array};let c=i.getUint32(5+o,false);if(c>e.maxFrameBytes)throw new Error(`native-main frame too large: ${c}`);return r.byteLength<a+c?{ready:false,phase:"frame-body",expectedFrameLength:c,consumedBytes:0,payloadBytes:new Uint8Array}:{ready:true,phase:"frame-body",expectedFrameLength:c,consumedBytes:a+c,payloadBytes:r.slice(a,a+c)}}}if(r.byteLength<4)return $n;let n=new DataView(r.buffer,r.byteOffset,r.byteLength).getUint32(0,false);if(n>e.maxFrameBytes)throw new Error(`legacy native-main frame too large: ${n}`);return r.byteLength<4+n?{ready:false,phase:"frame-body",expectedFrameLength:n,consumedBytes:0,payloadBytes:new Uint8Array}:{ready:true,phase:"frame-body",expectedFrameLength:n,consumedBytes:4+n,payloadBytes:r.slice(4,4+n)}}function Yn(r){return r.transports?.moq}function me(r){return !!Yn(r)}var Rt=class{constructor(e){this.deps=e;this.attempts=new Map;}isAvailable(){if(!me(this.deps.getOptions())||typeof WebTransport>"u")return false;let e=this.deps.getWasmClient();return typeof e?.__beginMoqCarrier=="function"&&typeof e?.__handleIrohCarrierControl=="function"&&typeof e?.__attachMoqCarrier=="function"}async configureWasm(e){if(typeof e.__configureMoqCarrier!="function")return;let t=Yn(this.deps.getOptions());await e.__configureMoqCarrier(!!t,t&&typeof t=="object"?t.relayUrl:void 0);}async prepare(e){this.retire(e.connectionId);let t={action:e,session:null,duplex:null,attached:false,failed:false,selected:false};this.attempts.set(e.connectionId,t);let n=Yn(this.deps.getOptions());if(!n||typeof n!="object"||!n.relayUrl?.trim()){await this.fail(t,"relay-failed");return}let i;try{i=j$1(n.relayUrl,n.accessToken);}catch(s){console.warn("[OpenRTC][Iroh MoQ carrier] relay configuration rejected",k$2(s,n.accessToken)),await this.fail(t,"relay-failed");return}let o=n.serverCertificateHashes?.length?{serverCertificateHashes:n.serverCertificateHashes}:void 0;try{let s=new WebTransport(i,o);if(await b$3(s.ready,15e3,"MoQ carrier relay connection"),!this.isCurrent(t)){s.close();return}let a=new a$6(s,new URL(n.relayUrl));if(t.session=a,a.onClose(()=>{this.isCurrent(t)&&this.fail(t,"relay-failed");}),await b$3(a.init(),1e4,"MoQ Draft 14 carrier setup"),await b$3(a.waitForSetup(),5e3,"MoQ Draft 14 carrier setup"),!this.isCurrent(t))return;let c=await this.deps.ensureBound();if(!this.isCurrent(t))return;await c.__moqCarrierPrepared(e.connectionId,e.upgradeId);}catch{await this.fail(t,"relay-failed");}}async activate(e,t){let n=this.attempts.get(e);if(!(!n||n.action.upgradeId!==t||!n.session||n.attached))try{let i=await b$3(n.session.openObjectStreamDuplex(n.action.publishNamespace,n.action.subscribeNamespace,n.action.trackName),12e3,"MoQ Draft 14 reliable object stream");if(!this.isCurrent(n)){i.close();return}n.duplex=i,n.attached=!0,await(await this.deps.ensureBound()).__attachMoqCarrier(n.action.connectionId,n.action.remoteEndpointId,i,n.action.upgradeId),console.debug("[OpenRTC][Iroh MoQ carrier] browser duplex attached",{connectionId:n.action.connectionId,upgradeId:n.action.upgradeId});}catch(i){n.attached=false,console.warn("[OpenRTC][Iroh MoQ carrier] Draft 14 duplex attachment failed",i),await this.fail(n,"draft14-datagram-unavailable");}}markSelected(e,t){let n=this.attempts.get(e);n?.action.upgradeId===t&&(n.selected=true);}currentUpgradeId(e){return this.attempts.get(e)?.action.upgradeId??null}async failCurrent(e,t){let n=this.attempts.get(e);n&&await this.fail(n,t);}retire(e,t){let n=this.attempts.get(e);if(!(!n||t&&n.action.upgradeId!==t)){this.attempts.delete(e);try{n.duplex?.close();}catch{}try{n.session?.close();}catch{}n.duplex=null,n.session=null;}}dispose(){for(let e of [...this.attempts.keys()])this.retire(e);}async fail(e,t){!this.isCurrent(e)||e.failed||(e.failed=true,await this.deps.reportFailure(e.action.connectionId,e.action.upgradeId,t));}isCurrent(e){return this.attempts.get(e.action.connectionId)===e&&!e.failed}};function No(r){return r.transports?.webrtc}function Y(r){return !!No(r)}var kt=class{constructor(e){this.deps=e;this.attempts=new Map;this.carrierCaps=new Map;this.disposed=false;this.boundWasm=null;this.committedCarrierReadiness=null;this.actionQueue=Promise.resolve();this.moqMechanism=new Rt({getOptions:()=>this.deps.getOptions(),getWasmClient:()=>this.deps.getWasmClient(),ensureBound:()=>this.ensureBound(),reportFailure:(t,n,i)=>this.reportMoqFailure(t,n,i)}),this.deps.registerDisposer(()=>this.dispose());}isCarrierAvailable(){if(!this.isWebRtcCarrierAdvertisable())return false;let e=this.deps.getWasmClient();return typeof e?.__beginWebRtcCarrier=="function"&&typeof e?.__beginPreferredIrohCarrier=="function"&&typeof e?.__advancePreferredIrohCarrier=="function"&&typeof e?.__configureWebRtcCarrier=="function"&&typeof e?.__setIrohCarrierActionHandler=="function"&&typeof e?.__handleIrohCarrierControl=="function"&&typeof e?.__attachWebRtcCarrier=="function"}isWebRtcCarrierAdvertisable(){return this.committedCarrierReadiness?.webrtc===true&&Y(this.deps.getOptions())&&typeof RTCPeerConnection<"u"}isMoqCarrierAvailable(){if(!this.isMoqCarrierAdvertisable())return false;let e=this.deps.getWasmClient();return this.moqMechanism.isAvailable()&&typeof e?.__beginPreferredIrohCarrier=="function"&&typeof e?.__advancePreferredIrohCarrier=="function"&&typeof e?.__configureMoqCarrier=="function"&&typeof e?.__setIrohCarrierActionHandler=="function"}isMoqCarrierAdvertisable(){return this.committedCarrierReadiness?.moq===true&&me(this.deps.getOptions())&&typeof WebTransport<"u"}async observeHandshake(e$1,t,n=true){if(this.disposed)return;let i=t?.carrierSchema===2;if(i&&this.carrierCaps.set(e$1.id,t),!n||!i||!(Y(this.deps.getOptions())||me(this.deps.getOptions())))return;let s=t.dedicatedCarrierControl===true,a=typeof e$1.isLocalDedicatedCarrierControlReady=="function"&&e$1.isLocalDedicatedCarrierControlReady(),c=typeof e$1.isRemoteDedicatedCarrierControlReady=="function"?e$1.isRemoteDedicatedCarrierControlReady():t.dedicatedCarrierControlReady===true;if(s&&(!c||!a)){e("[OpenRTC][Iroh carrier] deferred until control readiness",{connectionId:e$1.id,remoteEndpointId:e$1.remoteNodeId,localDedicatedControlReady:a,remoteDedicatedControlReady:c});return}let d=this.isCarrierAvailable(),l=this.isMoqCarrierAvailable(),p=t.webrtc===true&&d,u=t.moq===true&&l;e("[OpenRTC][Iroh carrier] observed trusted capability",{connectionId:e$1.id,remoteEndpointId:e$1.remoteNodeId,remoteWebRtc:t?.carrierSchema===2&&t.webrtc===true,localWebRtc:d,remoteMoq:t?.carrierSchema===2&&t.moq===true,localMoq:l}),await(await this.ensureBound()).__beginPreferredIrohCarrier(e$1.id,e$1.remoteNodeId,p,u);}async revisit(e){let t=this.carrierCaps.get(e.id);t&&await this.observeHandshake(e,t);}async applyConfiguredPolicy(){if(this.disposed||!this.deps.getWasmClient())return 0;let e=await this.ensureBound();return typeof e.__applyIrohCarrierPolicy!="function"?0:Number(await e.__applyIrohCarrierPolicy())||0}async prepareConfiguredCarriers(){if(this.disposed||!this.deps.getWasmClient())return;let e=await this.ensureBound();if(typeof e.__getIrohCarrierReadiness!="function")throw new Error("WASM build does not expose Iroh carrier readiness");let t=await e.__getIrohCarrierReadiness(),n=Y(this.deps.getOptions()),i=me(this.deps.getOptions());if(t?.actionHandlerInstalled!==true||t?.webrtcConfigured!==n||t?.moqConfigured!==i)throw this.committedCarrierReadiness=null,new Error(`Rust/WASM Iroh carrier readiness mismatch: ${JSON.stringify({expectedWebRtc:n,expectedMoq:i,readiness:t})}`);this.committedCarrierReadiness={webrtc:n,moq:i};}async handleControl(e$1,t){if(this.disposed||!this.isInternalCarrierFrame(t))return false;let n=t,o=!!await(await this.ensureBound()).__handleIrohCarrierControl(e$1.id,e$1.remoteNodeId,t);return e("[OpenRTC][Iroh carrier] control handled",{connectionId:e$1.id,frameType:n.type??null,carrier:n.carrier??n.content?.type??null,action:n.action??n.content?.type??null,upgradeId:n.upgradeId??n.content?.negotiationId??null,handled:o}),o}async retireConnection(e,t){return this.enqueueCarrierWork(()=>this.retireConnectionNow(e,t),{action:"retire-peer",connectionId:e})}async retireConnectionNow(e,t){let n=this.deps.getWasmClient();try{typeof n?.__retireIrohCarrierPeer=="function"?await n.__retireIrohCarrierPeer(e,t):(typeof n?.__retireWebRtcCarrier=="function"&&await n.__retireWebRtcCarrier(e,t),typeof n?.__retireMoqCarrier=="function"&&await n.__retireMoqCarrier(e,t),typeof n?.__forgetIrohCarrierPeer=="function"&&await n.__forgetIrohCarrierPeer(e));}finally{this.carrierCaps.delete(e),this.closeAttempt(e),this.moqMechanism.retire(e);}}async forgetConnection(e){return this.enqueueCarrierWork(async()=>{this.carrierCaps.delete(e);let t=this.deps.getWasmClient();typeof t?.__forgetIrohCarrierPeer=="function"&&await t.__forgetIrohCarrierPeer(e);},{action:"forget-peer",connectionId:e})}dispose(){if(this.disposed)return;this.disposed=true;let e=new Set([...this.carrierCaps.keys(),...this.attempts.keys()]);for(let t of e)this.retireConnection(t).catch(()=>this.closeAttempt(t));this.moqMechanism.dispose(),this.carrierCaps.clear(),this.committedCarrierReadiness=null,this.boundWasm&&typeof this.boundWasm.__setIrohCarrierActionHandler=="function"&&this.boundWasm.__setIrohCarrierActionHandler(void 0),this.boundWasm=null;}async ensureBound(){let e=this.deps.getWasmClient();if(!e)throw new Error("WASM runtime is unavailable for the Iroh WebRTC carrier");if(this.boundWasm!==e){if(this.committedCarrierReadiness=null,(Y(this.deps.getOptions())||me(this.deps.getOptions()))&&(typeof e.__beginPreferredIrohCarrier!="function"||typeof e.__advancePreferredIrohCarrier!="function")||typeof e.__setIrohCarrierActionHandler!="function"||Y(this.deps.getOptions())&&typeof e.__configureWebRtcCarrier!="function"||me(this.deps.getOptions())&&typeof e.__configureMoqCarrier!="function")throw new Error("WASM build does not expose the requested Iroh carrier actor");e.__setIrohCarrierActionHandler(i=>{this.enqueueCarrierWork(()=>this.handleAction(i),{action:i?.type??"unknown",connectionId:"connectionId"in i?i.connectionId:void 0}).catch(()=>{});}),this.boundWasm=e;}let t=this.deps.getOptions().transports?.privacy==="relay-only"||this.deps.getOptions().strictMode===true;return typeof e.__configureIrohRoutePolicy=="function"&&await e.__configureIrohRoutePolicy(t,this.deps.getOptions().transports?.optimizeFor??"balanced",this.deps.getOptions().transports?.priority??[]),typeof e.__configureWebRtcCarrier=="function"&&await e.__configureWebRtcCarrier(!!No(this.deps.getOptions()),t),await this.moqMechanism.configureWasm(e),e}enqueueCarrierWork(e,t){let n=this.actionQueue.then(e);return this.actionQueue=n.catch(i=>{console.warn("[OpenRTC][Iroh carrier] queued work failed",{action:t.action,connectionId:t.connectionId??null,error:i});}),n}isInternalCarrierFrame(e){if(!e||typeof e!="object")return false;let t=e;return t.type==="#openrtc-iroh-carrier"&&(t.carrier==="web-rtc"||t.carrier==="moq-draft14")||t.type==="#pluto-signal"&&t.content?.transport==="webrtc"}async handleAction(e$1){if(!this.disposed)switch(e("[OpenRTC][Iroh carrier] applying Rust-owned action",{action:e$1.type,connectionId:"connectionId"in e$1?e$1.connectionId:null,upgradeId:"upgradeId"in e$1?e$1.upgradeId:null,failureCode:"failureCode"in e$1?e$1.failureCode:null}),e$1.type){case "prepare-webrtc":await this.prepare(e$1);return;case "prepare-moq":await this.moqMechanism.prepare(e$1);return;case "activate-moq":await this.moqMechanism.activate(e$1.connectionId,e$1.upgradeId);return;case "send-control":{let t=this.deps.getConnection(e$1.connectionId,e$1.remoteEndpointId);if(!t||t.isClosed){await this.reportControlFailure(e$1);return}try{await this.deps.sendControl(t,e$1.envelope);}catch{await this.reportControlFailure(e$1);}return}case "start-webrtc":await this.start(e$1.connectionId,e$1.upgradeId);return;case "apply-webrtc-signal":await this.applySignal(e$1);return;case "retire-webrtc":this.closeAttempt(e$1.connectionId,e$1.upgradeId);return;case "retire-moq":this.moqMechanism.retire(e$1.connectionId,e$1.upgradeId);return;case "advance-carrier":{await(await this.ensureBound()).__advancePreferredIrohCarrier(e$1.connectionId,e$1.remoteEndpointId,e$1.failedRoute);return}case "selected":{if(e$1.carrier==="webrtc"){let t=this.attempts.get(e$1.connectionId);t?.action.upgradeId===e$1.upgradeId&&(t.selected=true);}else this.moqMechanism.markSelected(e$1.connectionId,e$1.upgradeId);return}}}async prepare(e){this.closeAttempt(e.connectionId);let t=this.deps.getRTCConfig()??{},n=new RTCPeerConnection(t),i={action:e,peerConnection:n,dataChannel:null,pendingCandidates:[],pendingLocalCandidates:[],localDescriptionSent:false,signalChain:Promise.resolve(),attached:false,failed:false,selected:false};this.attempts.set(e.connectionId,i),n.onicecandidate=o=>{if(!o.candidate||!this.isCurrent(i))return;let s=o.candidate.toJSON();if(!i.localDescriptionSent){i.pendingLocalCandidates.push(s);return}this.queueSignal(i,{type:"candidate",candidate:s}).catch(()=>this.reportFailure(e.connectionId,e.upgradeId,"signaling-failed"));},n.onconnectionstatechange=()=>{this.isCurrent(i)&&n.connectionState==="failed"&&this.reportFailure(e.connectionId,e.upgradeId,"ice-failed");},n.oniceconnectionstatechange=()=>{this.isCurrent(i)&&n.iceConnectionState==="failed"&&this.reportFailure(e.connectionId,e.upgradeId,"ice-failed");},this.installDataChannel(i,n.createDataChannel("openrtc-iroh-packets-v1",{negotiated:true,id:1,ordered:false,maxRetransmits:0,protocol:"openrtc-iroh-packets-v1"}));try{let o=await this.ensureBound();if(!this.isCurrent(i)){this.closeAttempt(e.connectionId,e.upgradeId);return}await o.__webRtcCarrierPrepared(e.connectionId,e.upgradeId);}catch(o){throw this.closeAttempt(e.connectionId,e.upgradeId),o}}installDataChannel(e,t){e.dataChannel=t,t.binaryType="arraybuffer",t.onopen=()=>{if(!this.isCurrent(e)||e.attached)return;e.attached=true;let n=this.deps.getWasmClient();Promise.resolve(n.__attachWebRtcCarrier(e.action.connectionId,e.action.remoteEndpointId,t,e.action.upgradeId)).catch(()=>(e.attached=false,this.reportFailure(e.action.connectionId,e.action.upgradeId,"data-channel-failed")));},t.onerror=()=>{this.reportFailure(e.action.connectionId,e.action.upgradeId,"data-channel-failed");},t.onclose=()=>{this.reportFailure(e.action.connectionId,e.action.upgradeId,"data-channel-failed");};}async start(e,t){let n=this.attempts.get(e);if(!(!n||n.action.upgradeId!==t))try{let i=await n.peerConnection.createOffer();if(!this.isCurrent(n))return;await n.peerConnection.setLocalDescription(i),await this.sendLocalDescription(n,i);}catch{await this.reportFailure(e,t,"signaling-failed");}}async applySignal(e){let t=this.attempts.get(e.connectionId);if(!t||t.action.upgradeId!==e.upgradeId)return;let n=e.signal.content;try{if(n?.type==="sdp"&&n.sdp){if(await t.peerConnection.setRemoteDescription(n.sdp),!this.isCurrent(t))return;for(let i of t.pendingCandidates.splice(0))await t.peerConnection.addIceCandidate(i);if(n.sdp.type==="offer"){let i=await t.peerConnection.createAnswer();await t.peerConnection.setLocalDescription(i),await this.sendLocalDescription(t,i);}}else n?.type==="candidate"&&n.candidate&&(t.peerConnection.remoteDescription?await t.peerConnection.addIceCandidate(n.candidate):t.pendingCandidates.push(n.candidate));}catch{await this.reportFailure(e.connectionId,e.upgradeId,"signaling-failed");}}async sendLocalDescription(e,t){if(await this.queueSignal(e,{type:"sdp",sdp:e.peerConnection.localDescription?.toJSON()??t}),!!this.isCurrent(e)){e.localDescriptionSent=true;for(let n of e.pendingLocalCandidates.splice(0))await this.queueSignal(e,{type:"candidate",candidate:n});}}queueSignal(e,t){let n=e.signalChain.then(async()=>{let i=this.deps.getConnection(e.action.connectionId,e.action.remoteEndpointId);if(!i||i.isClosed||!this.isCurrent(e))throw new Error("carrier control connection is unavailable");await this.deps.sendControl(i,{type:"#pluto-signal",content:{transport:"webrtc",negotiationId:e.action.upgradeId,...t}});});return e.signalChain=n.catch(()=>{}),n}async reportFailure(e,t,n){let i=this.attempts.get(e);if(!i||i.action.upgradeId!==t||i.failed)return;i.failed=true;let o=this.deps.getWasmClient();typeof o?.__webRtcCarrierFailed=="function"&&await o.__webRtcCarrierFailed(e,t,n);}async reportMoqFailure(e,t,n){let i=this.deps.getWasmClient();typeof i?.__moqCarrierFailed=="function"&&await i.__moqCarrierFailed(e,t,n);}async reportControlFailure(e){if(e.envelope.carrier==="moq-draft14"){await this.moqMechanism.failCurrent(e.connectionId,"relay-failed");return}let n=this.attempts.get(e.connectionId);n&&await this.reportFailure(e.connectionId,n.action.upgradeId,"signaling-failed");}isCurrent(e){return this.attempts.get(e.action.connectionId)===e&&!e.failed&&!this.disposed}closeAttempt(e,t){let n=this.attempts.get(e);!n||t&&n.action.upgradeId!==t||(this.attempts.delete(e),n.peerConnection.onicecandidate=null,n.peerConnection.oniceconnectionstatechange=null,n.peerConnection.onconnectionstatechange=null,n.peerConnection.ondatachannel=null,n.dataChannel&&(n.dataChannel.onopen=null,n.dataChannel.onerror=null,n.dataChannel.onclose=null,n.dataChannel.close()),n.peerConnection.close());}};function Do(r){let{host:e,transports:t,trustServices:n}=r;return new It(e.getContext(),{ensureWasmRuntimeForP2P:()=>e.ensureWasmRuntimeForP2P(),getOptions:()=>e.getOptions(),getWasmClient:()=>e.getWasmClient(),getLocalNodeId:()=>e.getLocalNodeId(),getDeterministicConnectionId:i=>t.peerIdentity.getDeterministicConnectionId(i),getRegisteredChannel:i=>e.getRegisteredChannel(i),isTransportOnlyChannel:i=>n.channelPolicy.isTransportOnlyChannel(i),rememberRouteRepairTokenForNode:(i,o,s)=>e.rememberRouteRepairTokenForNode(i,o,s),resolveExpectedDeviceIdForSessionTokenScope:(i,o,s,a)=>n.trust.resolveExpectedDeviceIdForSessionTokenScope(i,o,s,a),initializeConnectionTrust:(i,o)=>n.trust.initialize(i,o),refreshApplicationRouteHandshake:(i,o,s)=>t.applicationRoute.refreshApplicationRouteHandshake(i,o,s),ensureWasmManagedTransport:(i,o,s)=>e.ensureWasmManagedTransport(i,o,s),isLocalIrohRuntimeNotInitializedError:i=>e.isLocalIrohRuntimeNotInitializedError(i),recoverLocalIrohRuntime:i=>e.recoverLocalIrohRuntime(i),getSessionTokenApprovedScope:i=>e.getSessionTokenApprovedScope(i),setSessionTokenApprovedScope:(i,o)=>e.setSessionTokenApprovedScope(i,o),getPeerState:i=>e.getPeerState(i),assignConnectionChannel:(i,o)=>n.channelPolicy.assign(i,o),bindConnectionDeviceIdInRust:(i,o)=>n.deviceBinder.bindConnectionDeviceIdInRust(i,o),approveSessionTokenNode:i=>e.approveSessionTokenNode(i),approveSessionTokenConnection:i=>e.approveSessionTokenConnection(i),applySessionTokenTrustApproval:(i,o,s)=>e.applySessionTokenTrustApproval(i,o,s),announceConnectionWhenStable:i=>r.getLifecycle().announceConnectionWhenStable(i),disconnectNodeTransport:i=>t.health.disconnectNodeTransport(i),shouldUseNativeMainFramingForPeer:(i,o,s)=>wo(i,o,s),writeNativeMainLabelHeaderOnBiStream:(i,o)=>e.writeNativeMainLabelHeaderOnBiStream(i,o),createTransportContext:i=>t.contexts.create(i),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(i,o,s)=>t.health.handleCurrentConnectionTransportStatus(i,o,s),sendNativeSignalEnvelope:(i,o,s,a)=>e.sendNativeSignalEnvelope(i,o,s,a),registerConnection:i=>r.getLifecycle().registerConnection(i),cleanupReplacedConnection:i=>r.getLifecycle().cleanupReplacedConnection(i),schedulePeerReconciliation:i=>e.schedulePeerReconciliation(i),consumePendingSessionTokenTrustApproval:i=>e.consumePendingSessionTokenTrustApproval(i),sendTransportHandshake:(i,o)=>t.handshake.sendTransportHandshake(i,o),clearManualDisconnectProjection:i=>e.clearManualDisconnectProjection(i),getPeerScopes:i=>e.getPeerScopes(i),sessionTokenScopeAllowsDeviceBinding:i=>n.trust.sessionTokenScopeAllowsDeviceBinding(i),resolvePromotionEligibility:i=>n.channelPolicy.resolvePromotionEligibility(i),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),dispatchLiveConnectionProjection:(i,o)=>e.dispatchLiveConnectionProjection(i,o),hasApplicationRouteForConnection:i=>t.applicationRoute.hasApplicationRouteForConnection(i),isApplicationRouteReadyForConnection:i=>t.applicationRoute.isApplicationRouteReadyForConnection(i),addPeerScope:(i,o)=>e.addPeerScope(i,o)})}function Mo(r){let{host:e,transports:t,trustServices:n}=r;return new Pt({registerDisposer:i=>e.registerDisposer(i),resolveApplicationCryptoForPeer:(i,o)=>e.resolveApplicationCryptoForPeer(i,o),handleApplicationKeyAgreement:(i,o,s)=>e.handleApplicationKeyAgreement(i,o,s),releaseApplicationKeyAgreementReply:(i,o,s)=>e.releaseApplicationKeyAgreementReply(i,o,s),isWebRTCTransportEnabled:()=>Y(e.getOptions()),handleIrohCarrierControl:(i,o)=>t.browserCarrier.handleControl(i,o),observeIrohCarrierHandshake:(i,o,s)=>t.handshake.observeIrohCarrierHandshake(i,o,s),ensureCurrentTransportCapabilityAdvertisement:(i,o)=>t.handshake.ensureCurrentTransportCapabilityAdvertisement(i,o),requiresManagedTransportTrust:()=>e.requiresManagedTransportTrust(e.getDiscoveryMode()),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),getLocalNodeId:()=>e.getLocalNodeId(),validateIncomingSessionTokenWithRetry:(i,o,s)=>e.validateIncomingSessionTokenWithRetry(i,o,s),applySessionTokenTrustApproval:(i,o,s)=>e.applySessionTokenTrustApproval(i,o,s),getConnectionChannelId:i=>n.channelPolicy.getConnectionChannelId(i),sendTransportHandshake:(i,o)=>t.handshake.sendTransportHandshake(i,o),assignConnectionChannel:(i,o)=>n.channelPolicy.assign(i,o),initializeConnectionTrust:i=>n.trust.initialize(i),getKnownDevice:(i,o)=>e.getKnownDevice(i,o),isSessionTokenApproved:(i,o)=>e.isSessionTokenApproved(i,o),getSessionTokenApprovedScope:i=>e.getSessionTokenApprovedScope(i),sessionTokenScopeAllowsDeviceBinding:i=>n.trust.sessionTokenScopeAllowsDeviceBinding(i),applyConnectionTrustProjection:i=>e.applyConnectionTrustProjection(i),getKnownDeviceIdForNode:i=>e.getKnownDeviceIdForNode(i),bindConnectionDeviceIdInRust:(i,o)=>n.deviceBinder.bindConnectionDeviceIdInRust(i,o),sendTransportHandshakeWithRecovery:(i,o,s,a)=>t.handshake.sendTransportHandshakeWithRecovery(i,o,s,a),verifyRemoteTransportTrust:(i,o)=>n.trust.verifyRemoteTransportTrust(i,o),enforceConnectionTrustFailure:(i,o)=>n.trust.enforceFailure(i,o),markConnectionTrustVerified:(i,o)=>n.trust.markVerified(i,o),getConnectionTrustState:i=>n.trust.getStateByConnectionId(i),dispatchMessage:(i,o)=>e.dispatchIncomingMessage(i,o)})}function _o(r){let{host:e,registry:t,transports:n,trustServices:i}=r;return new bt({registerDisposer:o=>e.registerDisposer(o),normalizeAuthoritativeIncomingProtocolHint:(o,s,a)=>Tt(o),shouldSkipIncomingStreamProbe:()=>e.shouldSkipIncomingStreamProbe(),tryHandleNativeMainUniStream:(o,s,a)=>e.tryHandleNativeMainUniStream(o,s,a),cancelUnhandledIncomingUniStream:(o,s)=>e.cancelUnhandledIncomingUniStream(o,s,(a,c)=>e.logIncomingDiagnostic(a,c)),handleNativeMainStream:(o,s,a,c)=>{let d=Number.isSafeInteger(a)&&Number(a)>0;return c?e.handleNativeMainStream(o,s,d?a:void 0,true):d?e.handleNativeMainStream(o,s,a):e.handleNativeMainStream(o,s)},shouldTreatIncomingStreamAsTransportOnly:o=>e.shouldTreatIncomingStreamAsTransportOnly(o),logIncomingDiagnostic:(o,s)=>e.logIncomingDiagnostic(o,s),getDeterministicConnectionId:o=>n.peerIdentity.getDeterministicConnectionId(o),getKnownDevice:(o,s)=>e.getKnownDevice(o,s),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),getConnection:o=>t.get(o),isCoreConnectionHealthy:o=>n.health.isCoreConnectionHealthy(o),cleanupReplacedConnection:o=>r.getLifecycle().cleanupReplacedConnection(o),getLocalNodeId:()=>e.getLocalNodeId(),createTransportContext:o=>n.contexts.create(o),getOptions:()=>e.getOptions(),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(o,s,a)=>n.health.handleCurrentConnectionTransportStatus(o,s,a),getKnownDeviceIdForNode:o=>e.getKnownDeviceIdForNode(o),initializeConnectionTrust:(o,s)=>i.trust.initialize(o,s),registerConnection:o=>r.getLifecycle().registerConnection(o),bindConnectionDeviceIdInRust:(o,s)=>i.deviceBinder.bindConnectionDeviceIdInRust(o,s),searchDevices:()=>e.searchDevices(),announceConnectionWhenStable:o=>r.getLifecycle().announceConnectionWhenStable(o),sendTransportHandshake:(o,s)=>n.handshake.sendTransportHandshake(o,s)})}function Eo(r){let{host:e,registry:t,transports:n,trustServices:i}=r;return new St({registerDisposer:o=>e.registerDisposer(o),registry:t,resolveApplicationCryptoForPeer:(o,s)=>e.resolveApplicationCryptoForPeer(o,s),flushPendingNativeMainHandshakesForNode:(o,s)=>e.flushPendingNativeMainHandshakesForNode(o,s),flushPendingNativeMainSignalsForNode:(o,s)=>e.flushPendingNativeMainSignalsForNode(o,s),getConnectionTrustState:o=>i.trust.getStateByConnectionId(o),getKnownDeviceIdByNodeId:o=>e.getKnownDeviceIdForNode(o),bindConnectionDeviceIdInRust:(o,s)=>i.deviceBinder.bindConnectionDeviceIdInRust(o,s),searchDevices:()=>e.searchDevices(),retireSupersededConnections:(o,s,a)=>i.deviceBinder.retireSupersededConnections(o,s,a),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:o=>e.applyConnectionTrustProjection(o),schedulePeerReconciliation:o=>e.schedulePeerReconciliation(o),handleMessage:(o,s)=>r.getMessageHandler().handleMessage(o,s),getExistingPeerProjectionForDisconnect:o=>e.getPeerState(o.id)||e.getPeerProjectionList().find(s=>s.connectionIds.includes(o.id)||s.nodeId===o.deviceId),cleanupConnectionState:(o,s)=>{s!=="physical-route"&&(n.retireBrowserCarrierConnection(o),e.clearApplicationCryptoForConnection(o),i.trust.clearForConnection(o),i.channelPolicy.forget(o),e.clearSessionTokenConnectionApproval(o));},dispatchLiveConnectionProjection:(o,s)=>e.dispatchLiveConnectionProjection(o,s),resolvePromotionEligibility:o=>i.channelPolicy.resolvePromotionEligibility(o),enforceConnectionTrustFailure:(o,s)=>i.trust.enforceFailure(o,s),initializeConnectionTrust:o=>i.trust.initialize(o),getWasmClient:()=>e.getWasmClient(),isCoreConnectionHealthy:o=>n.health.isCoreConnectionHealthy(o),hasApplicationRouteForConnection:o=>n.applicationRoute.hasApplicationRouteForConnection(o),allowsTransportOnlyStability:o=>i.channelPolicy.allowsTransportOnlyStability(o),stableWindowMs:mo,stableTimeoutMs:vo,stablePollMs:fo})}function Bo(r){return new Jn({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,getLocalNodeId:()=>r.localNodeId,getDiscoveryMode:()=>r.discoveryMode,registerDisposer:e=>r.lifecycleScope.register(e),getTransportServices:()=>r.transportServices,getTrustServices:()=>r.trustServices,ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),ensureWasmManagedTransport:(e,t,n)=>r.managedTransportDialer.ensureWasmManagedTransport(e,t,n),isLocalIrohRuntimeNotInitializedError:e=>r.managedTransportDialer.isLocalIrohRuntimeNotInitializedError(e),recoverLocalIrohRuntime:e=>r.runtimeBootstrap.recoverLocalIrohRuntime(e),requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),getRegisteredChannel:e=>r.incomingStreamRouter.getRegisteredChannel(e),dispatchIncomingMessage:(e,t)=>r.incomingStreamRouter.dispatchMessage(e,t),shouldSkipIncomingStreamProbe:()=>r.incomingDiagnostics.shouldSkipIncomingStreamProbe(),cancelUnhandledIncomingUniStream:(e,t,n)=>r.incomingDiagnostics.cancelUnhandledIncomingUniStream(e,t,n),logIncomingDiagnostic:(e,t)=>r.incomingDiagnostics.logIncomingDiagnostic(e,t),shouldTreatIncomingStreamAsTransportOnly:e=>r.applicationIncomingStreams.shouldTreatIncomingStreamAsTransportOnly(e),tryHandleNativeMainUniStream:(e,t,n)=>r.nativeMain.tryHandleNativeMainUniStream(e,t??"",n),handleNativeMainStream:(e,t,n,i)=>{let o=Number.isSafeInteger(n)&&Number(n)>0;return i?r.nativeMain.handleNativeMainStream(e,t??"",o?n:void 0,true):o?r.nativeMain.handleNativeMainStream(e,t??"",n):r.nativeMain.handleNativeMainStream(e,t??"")},flushPendingNativeMainHandshakesForNode:(e,t)=>r.nativeMain.flushPendingHandshakesForNode(e,t),flushPendingNativeMainSignalsForNode:(e,t)=>r.nativeMain.flushPendingSignalsForNode(e,t),writeNativeMainLabelHeaderOnBiStream:(e,t)=>r.nativeMain.writeLabelHeaderOnBiStream(e,t),sendNativeSignalEnvelope:(e,t,n,i)=>r.nativeMain.sendSignalEnvelope(e,t,n,i),resolveApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.resolveForPeer(e,t),resyncApplicationCryptoToNative:e=>r.applicationCrypto.resyncConnectionKeyToNative(e),clearApplicationCryptoForConnection:e=>r.applicationCrypto.clearConnection(e),handleApplicationKeyAgreement:(e,t,n)=>r.applicationCrypto.handleKeyAgreement(e,t,n),releaseApplicationKeyAgreementReply:(e,t,n)=>r.applicationCrypto.releaseReplyClaim(e,t,n),shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),rememberRouteRepairTokenForNode:(e,t,n)=>r.sessionTokens.rememberRouteRepairTokenForNode(e,t,n),getSessionTokenApprovedScope:e=>r.sessionTokens.getApprovedScope(e),setSessionTokenApprovedScope:(e,t)=>r.sessionTokens.setApprovedScope(e,t),approveSessionTokenNode:e=>r.sessionTokens.approveNode(e),approveSessionTokenConnection:e=>r.sessionTokens.approveConnection(e),applySessionTokenTrustApproval:(e,t,n)=>r.sessionTokens.applyTrustApproval(e,t,n),consumePendingSessionTokenTrustApproval:e=>r.sessionTokens.consumePendingTrustApproval(e),validateIncomingSessionTokenWithRetry:(e,t,n)=>r.sessionTokens.validateIncomingSessionTokenWithRetry(e,t,n),isSessionTokenApproved:(e,t)=>r.sessionTokens.isApproved(e,t),clearSessionTokenConnectionApproval:e=>r.sessionTokens.clearConnectionApproval(e),getPeerState:e=>r.peerServices.getPeerState(e),getPeerScopes:e=>r.peerServices.getPeerScopes(e),addPeerScope:(e,t)=>r.peerServices.addPeerScope(e,t),clearManualDisconnectProjection:e=>r.peerServices.clearManualDisconnectProjection(e),getPeerProjectionList:()=>r.peerServices.listPeerStates(),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),dispatchLiveConnectionProjection:(e,t)=>r.peerProjection.dispatchLiveConnectionProjection(e,t),getKnownDevice:(e,t)=>r.deviceDirectory.getKnownDevice(e,t),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),searchDevices:()=>r.deviceDirectory.searchDevices()})}var Jn=class{constructor(e){this.host=e;this.registry=new yt;}get transports(){return this.host.getTransportServices()}get trustServices(){return this.host.getTrustServices()}get factoryHost(){return {host:this.host,registry:this.registry,transports:this.transports,trustServices:this.trustServices,getLifecycle:()=>this.lifecycle,getMessageHandler:()=>this.messageHandler}}get dialer(){return this._dialer??(this._dialer=Do(this.factoryHost))}get messageHandler(){return this._messageHandler??(this._messageHandler=Mo(this.factoryHost))}get incomingAcceptor(){return this._incomingAcceptor??(this._incomingAcceptor=_o(this.factoryHost))}get lifecycle(){return this._lifecycle??(this._lifecycle=Eo(this.factoryHost))}async ensureManagedApplicationRoute(e){let t=Math.max(1,e.timeoutMs??2e4),n=typeof e.approvedScope=="string"&&e.approvedScope.trim()?e.approvedScope.trim():null,i=await this.dialer.connect(e.ticket,t,e.expectedDeviceId,void 0,{admissionAlreadyPresented:n!==null}),o=this.registry.getForPeer(e.connectionId??void 0,e.remoteNodeId??i.remoteNodeId)??i;if(n&&this.host.applySessionTokenTrustApproval(o,n,"managed-transport-adoption"),await this.transports.applicationRoute.refreshApplicationRouteHandshake(o,"managed-transport-adoption",{forceReciprocal:true},t),!this.transports.applicationRoute.hasApplicationRouteForConnection(o))throw new Error(`[Client][HANDSHAKE] application route was not ready for current connection ${o.id}`);return o}};var At=class{constructor(){this.wasmClient=null;this.node=null;this.localNodeId="";this.deviceId=null;}};var Nt=class{constructor(e=(t,n)=>{console.warn(t,n);}){this.logError=e;this.disposers=[];this.destroyed=false;}get isDestroyed(){return this.destroyed}register(e){if(this.destroyed){try{e();}catch(t){this.logError("[Client] late disposer failed",t);}return}this.disposers.push(e);}destroy(){if(!this.destroyed){this.destroyed=true;for(let e of this.disposers.splice(0).reverse())try{e();}catch(t){this.logError("[Client] disposer failed during destroy",t);}}}};function ae(){if(typeof navigator>"u")return false;let r=navigator.userAgent||"",e=navigator.userAgentData?.platform||navigator.platform||"";return /iPhone|iPad|iPod|Android|Mobile|CriOS|FxiOS/i.test(`${r} ${e}`)}function Dt(){return typeof window>"u"?false:new URLSearchParams(window.location.search).has("ticket")}function Mt(r){return r?r.routing==="stream-envelope"&&r.readiness==="transport-only":false}function je(r){let e=r.signalingMode??"hosted",t=ae(),n=Dt(),i=e==="ticket-only",o=i&&t;return {flow:i?"ticket-only":"default",signalingMode:e,mobileBrowser:t,ticketQueryPresent:n,diagnosticsMode:o,skipIncomingBiProbe:o,skipIncomingChannelEnvelopeInspection:o,readerCloseStrategy:o?"release-lock":"cancel"}}var Re=class Re{constructor(e){this.deps=e;this.pendingReciprocalAdmissions=new Map;this.pendingSessionTokenResponseAcks=new Map;this.responsesInFlight=new Set;this.reciprocalConfirmationsInFlight=new Set;this.legacyReciprocalPresentationsInFlight=new Set;this.disposed=false;}dispose(){this.disposed=true,this.retirePendingReciprocalAdmissions("dispose"),this.legacyReciprocalPresentationsInFlight.clear();}retirePendingReciprocalAdmissions(e$1){(this.pendingReciprocalAdmissions.size>0||this.pendingSessionTokenResponseAcks.size>0)&&e("[Client][AUTH] retiring pending response ACK correlations",{reason:e$1,reciprocalCount:this.pendingReciprocalAdmissions.size,responseAckCount:this.pendingSessionTokenResponseAcks.size}),this.pendingSessionTokenResponseAcks.clear(),this.responsesInFlight.clear(),this.pendingReciprocalAdmissions.clear(),this.reciprocalConfirmationsInFlight.clear();}async acceptNativeMessage(e,t,n){if(this.disposed||!t)return false;let i=this.deps.getDeterministicConnectionId(t),o=this.deps.getConnection(i);if(o){try{Promise.resolve(this.deps.handleMessage(o,n)).catch(s=>{this.disposed||console.warn("[Client][NATIVE-MAIN] Existing connection message handling failed",{remoteNodeId:t,connectionId:o.id,error:s});});}catch(s){this.disposed||console.warn("[Client][NATIVE-MAIN] Existing connection message handling failed",{remoteNodeId:t,connectionId:o.id,error:s});}return false}if(n&&typeof n=="object"&&n.type==="handshake"&&(n.action==="hello"||!n.action)){let s=await this.deps.validateIncomingSessionToken(n.sessionToken??"",e??void 0,{remoteNodeId:t,source:"accept-native-message",tokenPayload:typeof n.sessionTokenPayload=="string"?n.sessionTokenPayload:void 0});if(this.disposed)return false;if(!s.ok)return console.warn("[Client][SESSION-TOKEN] Rejecting native connection \u2014 invalid session token",{remoteNodeId:t,reason:s.reason,hasToken:!!n.sessionToken}),true}return false}async resolveLocalHandshakePayload(){let e=await this.deps.getLocalDeviceId().catch(()=>null)||this.deps.getFallbackLocalDeviceId();if(!e)throw new Error("Local device id unavailable for native handshake response");let t=this.deps.isNativeRuntime(),n=t?this.deps.isLikelyMobileBrowser()?"mobile":"desktop":"web",i=t?{canHost:true,canSync:true,readOnly:false}:{canHost:false,canSync:true,readOnly:false},o=n==="mobile"?"Mobile Device":n==="desktop"?"Desktop Device":"Browser Device";return {deviceId:e,deviceName:this.deps.getConfiguredDeviceName()||o,platformType:n,capabilities:i,protocolVersion:this.deps.getNativeMainProtocolVersion(),timestamp:Date.now()}}async handleHandshakeRequest(e$1,t,n){if(this.disposed)return;let i=await this.resolveLocalHandshakePayload();this.disposed||(await this.deps.writeNativeMainMessage(e$1,{channel:"handshake",action:"response",requestId:n.requestId,payload:{accepted:true,...i},timestamp:Date.now()}),!this.disposed&&(this.schedulePeerReconciliationBestEffort("native-main-handshake"),e("[Client][NATIVE-MAIN] Responded to desktop handshake",{remoteNodeId:t,requestId:n.requestId??null,localDeviceId:i.deviceId})));}async handleSessionTokenRequest(e$1,t,n,i,o){if(this.disposed)return false;let s=this.deps.getSessionTokenRejectionCooldown(t),a=this.deps.getNativeMainConnectionId(t);if(s!==void 0&&Date.now()-s<Re.TOKEN_REJECTION_COOLDOWN_MS)return await this.deps.writeNativeMainMessage(e$1,{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:"session-token-rejection-cooldown",connectionId:a},timestamp:Date.now()}),console.warn("[Client][AUTH] session-token presentation during rejection cooldown \u2014 wrote rejection for dialer",{remoteNodeId:t,connectionId:a}),false;if(this.responsesInFlight.has(a))return await this.deps.writeNativeMainMessage(e$1,{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:false,reason:"session-token-response-in-progress",connectionId:a},timestamp:Date.now()}),false;this.responsesInFlight.add(a);let c=false;try{let d=n.payload&&typeof n.payload.token=="string"?n.payload.token.trim():"",l=n.payload&&typeof n.payload.tokenPayload=="string"?n.payload.tokenPayload.trim():void 0,p=n.payload&&typeof n.payload.deviceId=="string"&&n.payload.deviceId.trim()||null,u=n.payload?.responseAckRequested===!0&&Number.isSafeInteger(i)&&Number(i)>0&&typeof o=="string"&&o.trim().length>0,h=await this.deps.validateIncomingSessionToken(d,a,{remoteNodeId:t,source:"native-main-session-token",tokenPayload:l||void 0});if(this.disposed)return !1;let f,m=n.payload?.reciprocalRequested===!0,v=m&&n.payload?.reciprocalMode==="inline-v1"&&Number.isSafeInteger(i)&&Number(i)>0&&typeof o=="string"&&o.trim().length>0;if(h.ok&&u&&v){let C=n.payload?.streamContract==="persistent-control"?"persistent-control":"one-shot-admission";try{let P=this.createPresentationId();f={...await this.deps.getReciprocalSessionAdmission(t,C,Number(i),o,P),presentationId:P};}catch(P){this.disposed||console.warn("[Client][AUTH] reciprocal session admission unavailable",{remoteNodeId:t,connectionId:a,error:P});}}if(this.disposed)return !1;let y=h.ok&&u,S=h.ok?"session-token-response-ack-required":h.reason??"session-token-rejected";if(await this.deps.writeNativeMainMessage(e$1,y?{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:!0,scope:h.scope??null,connectionId:a,...f?{reciprocalPresentation:f}:{},...f?{reciprocalMode:"inline-v1"}:{}},timestamp:Date.now()}:{channel:"session-token",action:"response",requestId:n.requestId,payload:{approved:!1,reason:S,connectionId:a},timestamp:Date.now()}),this.disposed)return !1;if(y&&f&&i){for(let[C,P]of this.pendingReciprocalAdmissions)P.remoteNodeId===t&&P.transportStableId===i&&this.pendingReciprocalAdmissions.delete(C);this.pendingReciprocalAdmissions.set(f.presentationId,{connectionId:a,remoteNodeId:t,transportStableId:i,streamInstanceId:o,presentationId:f.presentationId});}if(y){let C={connectionId:a,remoteNodeId:t,transportStableId:Number(i),streamInstanceId:o,scope:h.scope??null,claimedDeviceId:p,legacyReciprocalRequested:m&&(!v||!f)};return this.pendingSessionTokenResponseAcks.set(a,C),b$3(new Promise(()=>{}),Re.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_MS,"session-token response ACK").catch(()=>{this.pendingSessionTokenResponseAcks.get(a)===C&&(this.pendingSessionTokenResponseAcks.delete(a),this.responsesInFlight.delete(a),e("[Client][AUTH] session-token response ACK timed out",{connectionId:a,remoteNodeId:t,transportStableId:C.transportStableId,streamInstanceId:C.streamInstanceId}));}),c=!0,!0}return console.warn("[Client][AUTH] host rejected managed session token",{remoteNodeId:t,connectionId:a,reason:S,hasToken:d.length>0}),this.deps.setSessionTokenRejectionCooldown(t,Date.now()),this.deps.disconnectRemoteNode(t),!1}finally{c||this.responsesInFlight.delete(a);}}async handleSessionTokenResponseAck(e$1,t,n,i){let o=typeof t.payload?.connectionId=="string"?t.payload.connectionId.trim():"",s=false,a=o?this.pendingSessionTokenResponseAcks.get(o):void 0;if(a&&a.remoteNodeId===e$1&&a.transportStableId===n&&a.streamInstanceId===i){this.pendingSessionTokenResponseAcks.delete(o);let h=false;try{h=await this.deps.acknowledgeSessionTokenResponse(o,e$1,a.transportStableId,a.claimedDeviceId);}catch(f){console.warn("[Client][AUTH] response ACK owner commit failed",{remoteNodeId:e$1,connectionId:o,transportStableId:n,error:f});}finally{this.responsesInFlight.delete(o);}h&&!this.disposed&&(this.applyAcknowledgedSessionTokenApproval(a),s=true);}else a&&console.warn("[Client][AUTH] ignored stale session-token response ACK",{remoteNodeId:e$1,connectionId:o,transportStableId:n??null});let c=typeof t.payload?.reciprocalPresentationId=="string"?t.payload.reciprocalPresentationId.trim():"";if(!c||!Number.isSafeInteger(n)||Number(n)<=0)return s;let d=this.pendingReciprocalAdmissions.get(c);if(!d||d.remoteNodeId!==e$1||d.transportStableId!==n||d.streamInstanceId!==i||t.payload?.connectionId!==d.connectionId)return console.warn("[Client][AUTH] ignored stale reciprocal admission ACK",{remoteNodeId:e$1,transportStableId:n??null,presentationId:c}),s;if(this.reciprocalConfirmationsInFlight.has(c))return true;this.reciprocalConfirmationsInFlight.add(c);let l=t.payload?.reciprocalAccepted===true,p=typeof t.payload?.reciprocalScope=="string"&&t.payload.reciprocalScope.trim()||null,u=false;try{u=await this.deps.confirmReciprocalSessionAdmission(e$1,n,d.streamInstanceId,d.presentationId,l,p);}catch(h){console.warn("[Client][AUTH] reciprocal admission confirmation failed",{remoteNodeId:e$1,transportStableId:n,presentationId:c,error:h});}finally{this.reciprocalConfirmationsInFlight.delete(c);}return u&&this.pendingReciprocalAdmissions.delete(c),l?u?(e("[Client][AUTH] reciprocal admission committed",{remoteNodeId:e$1,transportStableId:n,presentationId:c,approvalScope:p}),this.schedulePeerReconciliationBestEffort("reciprocal-session-admission-committed"),true):(console.warn("[Client][AUTH] reciprocal admission ACK failed generation-bound confirmation",{remoteNodeId:e$1,transportStableId:n,presentationId:c}),this.schedulePeerReconciliationBestEffort("reciprocal-session-admission-stale"),true):(console.warn("[Client][AUTH] reciprocal admission was not committed by peer",{remoteNodeId:e$1,transportStableId:n,presentationId:c,reason:t.payload?.reciprocalReason??"rejected"}),this.schedulePeerReconciliationBestEffort("reciprocal-session-admission-rejected"),true)}applyAcknowledgedSessionTokenApproval(e$1){let t=this.deps.getConnection(e$1.connectionId);t&&!t.isClosed?(this.deps.applySessionTokenTrustApproval(t,e$1.scope,"native-main-session-token"),this.deps.refreshApplicationRouteHandshake(t,"session-token-approval").catch(n=>{console.warn("[Client][AUTH] application-route refresh after token approval failed",{connectionId:t.id,remoteNodeId:e$1.remoteNodeId,error:n});})):(this.deps.rememberPendingSessionTokenTrustApproval(e$1.connectionId,e$1.scope),this.deps.markSessionTokenApprovedNode(e$1.remoteNodeId),this.deps.markSessionTokenApprovedConnection(e$1.connectionId)),this.deps.clearSessionTokenRejectionCooldown(e$1.remoteNodeId),this.deps.clearTrustFailureCooldown(e$1.remoteNodeId),e("[Client][AUTH] host committed acknowledged managed session token",{remoteNodeId:e$1.remoteNodeId,connectionId:e$1.connectionId,scope:e$1.scope}),this.schedulePeerReconciliationBestEffort("session-token-approval"),e$1.legacyReciprocalRequested&&this.scheduleLegacyReciprocalSessionAdmission(e$1.remoteNodeId,e$1.connectionId),(!t||t.isClosed)&&this.kickstartApprovedControlConnection(e$1.remoteNodeId,e$1.connectionId);}handleNativeMainStreamClosed(e,t,n){if(!(!Number.isSafeInteger(t)||Number(t)<=0)){for(let[i,o]of this.pendingSessionTokenResponseAcks)o.remoteNodeId===e&&o.transportStableId===t&&o.streamInstanceId===n&&(this.pendingSessionTokenResponseAcks.delete(i),this.responsesInFlight.delete(i));for(let[i,o]of this.pendingReciprocalAdmissions)o.remoteNodeId===e&&o.transportStableId===t&&o.streamInstanceId===n&&(this.pendingReciprocalAdmissions.delete(i),this.reciprocalConfirmationsInFlight.delete(i));}}createPresentationId(){let e=globalThis.crypto?.randomUUID;return typeof e=="function"?e.call(globalThis.crypto):`reciprocal-${Date.now()}-${Math.random().toString(36).slice(2)}`}scheduleLegacyReciprocalSessionAdmission(e,t){this.disposed||this.legacyReciprocalPresentationsInFlight.has(t)||(this.legacyReciprocalPresentationsInFlight.add(t),queueMicrotask(()=>{if(this.disposed){this.legacyReciprocalPresentationsInFlight.delete(t);return}this.deps.presentLegacyReciprocalSessionAdmission(e).catch(n=>{this.disposed||console.warn("[Client][AUTH] legacy reciprocal session admission failed",{remoteNodeId:e,connectionId:t,error:n});}).finally(()=>{this.legacyReciprocalPresentationsInFlight.delete(t);});}));}kickstartApprovedControlConnection(e$1,t){let n=i=>{this.disposed||console.warn("[Client][AUTH] post-approval kickstart error",{remoteNodeId:e$1,connectionId:t,error:i});};try{Promise.resolve(this.deps.ensureIncomingConnectionForRemoteNode(e$1)).then(i=>{this.disposed||(i?e("[Client][AUTH] post-approval kickstart opened control connection",{remoteNodeId:e$1,connectionId:i.id}):console.warn("[Client][AUTH] post-approval kickstart failed to open control connection",{remoteNodeId:e$1,connectionId:t}));}).catch(n);}catch(i){n(i);}}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};Re.TOKEN_REJECTION_COOLDOWN_MS=5e3,Re.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_MS=2e3;var _t=Re;var Et=class{constructor(e){this.deps=e;this.pendingConnections=new Map;this.disposed=false;}dispose(){this.disposed=true,this.pendingConnections.clear();}async ensureIncomingConnectionForRemoteNode(e$1){if(this.disposed)return null;let t=this.deps.getDeterministicConnectionId(e$1),n=this.deps.getConnection(t);if(n&&!n.isClosed)return this.attachNativeSignalSenderIfEligible(n,e$1),n;let i=this.pendingConnections.get(t);if(i)return i;let o=this.deps.getTrustFailureCooldown(e$1),s=this.deps.getTrustFailureCooldownMs();if(o!==void 0&&Date.now()-o<s&&!this.deps.isSessionTokenApprovedNode(e$1))return e("[Client][TRUST] Skipping connection rebuild for node in trust-failure cooldown",{remoteNodeId:e$1,cooldownRemainingMs:s-(Date.now()-o)}),null;let a=this.createIncomingConnection(t,e$1);this.pendingConnections.set(t,a);try{return await a}finally{this.pendingConnections.delete(t);}}attachNativeSignalSenderIfEligible(e$1,t){let n=typeof e$1.getControlFrameMode=="function"?e$1.getControlFrameMode():"typed";e("[Client][NATIVE-MAIN] Reusing existing control connection",{connectionId:e$1.id,remoteNodeId:t,controlFrameMode:n});let i=this.deps.getKnownDevicePlatform(this.deps.getKnownDeviceIdForNode(t),t);if(!this.deps.isNativeMainPeerPlatform(i)&&!this.deps.isSessionTokenApprovedNode(t))return;let o=this.deps.getWasmClient();if(!o||typeof o.open_bi!="function")return;let s=async a=>{await this.deps.sendNativeSignalEnvelope(e$1,t,a,o);};n!=="native-main"&&typeof e$1.useNativeControl=="function"?(e$1.useNativeControl(s),e("[Client][NATIVE-MAIN] Promoted bootstrap connection to native control route",{connectionId:e$1.id,remoteNodeId:t})):n==="native-main"&&e$1.setNativeSignalSender(s);}async createIncomingConnection(e$1,t){if(this.disposed)return null;let n=this.deps.getWasmClient();if(!n||typeof n.open_bi!="function")return null;let i=this.deps.getKnownDeviceIdForNode(t);if(!this.deps.getKnownDevicePlatform(i,t)&&!this.deps.isSessionTokenApprovedNode(t))return e("[Client][NATIVE-MAIN] Deferring native-main connection creation until peer platform is known",{remoteNodeId:t,connectionId:e$1,knownDeviceId:i}),null;let s;try{s=await this.deps.openNativeSignalBiStream(n,t);}catch(c){return console.warn("[Client][NATIVE-MAIN] Failed to open control stream for native signal routing",{remoteNodeId:t,connectionId:e$1,error:c}),null}if(this.disposed)return await h$2(s,"native-main-connection-disposed-after-open"),null;try{await this.deps.writeNativeMainLabelHeaderOnBiStream(s,t);}catch(c){return console.warn("[Client][NATIVE-MAIN] Failed to write label header on control stream",{remoteNodeId:t,connectionId:e$1,error:c}),null}if(this.disposed)return await h$2(s,"native-main-connection-disposed-after-label"),null;let a;return a=new ne(e$1,this.deps.getLocalNodeId(),t,s.send.getWriter(),s.recv.getReader(),{transportContext:this.deps.createTransportContext(t),applicationCrypto:this.deps.getApplicationCrypto(),requireApplicationCrypto:this.deps.shouldNegotiateApplicationKeyAgreement(),controlFrameMode:"native-main",onTransportStatusChange:c=>this.deps.handleConnectionTransportStatus(a,c.activeTransport,c.parallelTransport)}),a.setNativeSignalSender(async c=>{await this.deps.sendNativeSignalEnvelope(a,t,c,n);}),this.deps.initializeConnectionTrust(a,i),this.deps.markConnectionTrustVerified(a,i),this.deps.registerConnection(a),this.deps.announceConnectionWhenStable(a),e("[Client][HANDSHAKE] sending hello (native signal routing path)",{connectionId:a.id,remoteNodeId:a.remoteNodeId}),this.sendNativeRoutingHelloInBackground(a),e("[Client][NATIVE-MAIN] Created control connection for native signal routing",{connectionId:a.id,remoteNodeId:t,channelId:this.deps.getConnectionChannelId(a.id)??null,rtcEnabled:this.deps.isWebRTCTransportEnabled()}),a}sendNativeRoutingHelloInBackground(e){let t=n=>{this.disposed||console.warn("[Client][TRUST] Failed to send outgoing handshake for native signal routing",{connectionId:e.id,remoteNodeId:e.remoteNodeId,error:n});};try{Promise.resolve(this.deps.sendTransportHandshake(e,"hello")).catch(t);}catch(n){t(n);}}};var Bt=class{constructor(e,t,n=[0,250,1e3,2500]){this.maxPerNode=e;this.ttlMs=t;this.retryDelaysMs=n;this.pendingByNodeId=new Map;this.retryTimers=new Set;this.disposed=false;}queue(e$1,t,n,i,o,s){if(this.disposed)return;let a=this.pendingByNodeId.get(e$1)??[];a.push({message:t,source:n,traceId:i??null,transportStableId:s,receivedAtMs:Date.now()}),a.length>this.maxPerNode&&a.splice(0,a.length-this.maxPerNode),this.pendingByNodeId.set(e$1,a),e("[Client][NATIVE-MAIN] Queued TS handshake until control connection is registered",{remoteNodeId:e$1,action:t.action??"hello",source:n,traceId:i||null,pendingCount:a.length});for(let c of this.retryDelaysMs){let d=setTimeout(()=>{this.retryTimers.delete(d),!this.disposed&&o(e$1,`queued-handshake-retry:${c}`);},c);this.retryTimers.add(d);}}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.retryTimers)clearTimeout(e);this.retryTimers.clear(),this.pendingByNodeId.clear();}}async flush(e$1,t,n){if(this.disposed)return false;let i=this.pendingByNodeId.get(e$1);if(!i||i.length===0)return false;let o=n.findManualDisconnectProjectionForNativeNode(e$1);if(o)return this.pendingByNodeId.delete(e$1),e("[Client][NATIVE-MAIN] Dropped queued TS handshakes for manually disconnected peer",{remoteNodeId:e$1,peerId:o.peerId,droppedCount:i.length,trigger:t}),false;let s=n.findLiveConnectionForRemoteNode(e$1);if(s||(s=await n.ensureIncomingConnectionForRemoteNode(e$1).catch(()=>null)),this.disposed)return false;if(!s){let a=Date.now(),c=i.filter(d=>a-d.receivedAtMs<=this.ttlMs);return c.length===0?(this.pendingByNodeId.delete(e$1),console.warn("[Client][NATIVE-MAIN] Dropping queued TS handshakes after control connection did not appear",{remoteNodeId:e$1,trigger:t,droppedCount:i.length})):c.length!==i.length&&this.pendingByNodeId.set(e$1,c),false}this.pendingByNodeId.delete(e$1),e("[Client][NATIVE-MAIN] Replaying queued TS handshakes to Connection",{remoteNodeId:e$1,connectionId:s.id,trigger:t,count:i.length});for(let a of i){if(this.disposed)return false;await n.handleMessage(s,a.message,a.transportStableId);}return true}};var rs="main",ss="signal";function Lo(r){let e=new TextEncoder().encode(r),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}function qe(){return Lo(rs)}function xo(){return Lo(ss)}function Ge(r){let e=JSON.stringify(r),t=new TextEncoder().encode(e),n=new Uint8Array(1+t.byteLength);return n[0]=0,n.set(t,1),n}function ve(r){let e=new ArrayBuffer(4+r.byteLength);new DataView(e).setUint32(0,r.byteLength,false);let n=new Uint8Array(e);return n.set(r,4),n}var Lt=class{constructor(e,t){this.config=e;this.deps=t;}protocolConfig(){return {protocolByte:this.config.protocolByte,label:this.config.label,maxLabelBytes:this.config.maxLabelBytes,maxFrameBytes:this.config.maxFrameBytes}}encodeFrame(e){return Ro(e,this.protocolConfig())}async dispatchMessage(e,t){return ko(this.config.eventName,e,this.deps.getRemoteDeviceId(e),t)}async writeAck(e,t,n=null){let i=this.deps.getReceiverDeviceId();await this.writeMessage(e,{channel:"native-main",action:"ack",requestId:t.requestId,payload:{received:true,channel:t.channel,action:t.action,...i?{receiverDeviceId:i}:{},...n!==null?{handlerResponse:n}:{}},timestamp:Date.now(),from:"web"});}async writeMessage(e,t){await e.write(this.encodeFrame(t));}async writeLabeledMessage(e,t){await e.write(qe()),await e.write(ve(new TextEncoder().encode(JSON.stringify(t))));}async writeLabelHeaderOnBiStream(e,t){let n=e.send.getWriter();try{await n.write(qe());}catch(i){throw console.warn("[Client][NATIVE-MAIN] Label header write failed",{remoteNodeId:t,error:i}),i}finally{try{n.releaseLock();}catch{}}}};var oe=class oe{constructor(e){this.deps=e;this.disposed=false;this.activeReaders=new Set;}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.activeReaders)this.cancelReaderBestEffort(e);this.activeReaders.clear();}}async handleNativeMainStream(e$1,t,n,i=false){if(this.disposed||!e$4(e$1))return;let o,s,a=false;try{o=e$1.recv.getReader(),s=e$1.send.getWriter();}catch(m){console.warn("[Client][NATIVE-MAIN] Unable to acquire stream handles",{remoteNodeId:t,error:m});return}this.activeReaders.add(o);let c$1=this.createStreamInstanceId(),d=e$1.native_signal_only===true,l=i?{phase:"request"}:void 0,p=new Uint8Array(0),u="stream-active",h=0,f=()=>{d||a||(this.deps.registerInboundNativeMainWriter(t,s,n),a=true);};try{for(;!this.disposed;){let m=this.tryExtractNativeMainPayload(p);for(;!m.ready&&!this.disposed;){let y=o.read(),S=l?.phase==="response-ack"?l.responseAckDeadlineAtMs:void 0,{done:C,value:P}=S===void 0?await y:await b$3(y,Math.max(0,S-Date.now()),()=>new Error(oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_REASON));if(this.disposed)return;if(C){u=m.phase==="frame-start"?h>0?"remote-closed-after-frame":"remote-closed-before-frame-length":"remote-closed-mid-frame",!d&&(h===0||m.phase!=="frame-start")&&this.schedulePeerReconciliationBestEffort("native-main-stream-close"),m.phase==="frame-start"?e("[Client][NATIVE-MAIN] Remote closed native main stream",{remoteNodeId:t,handledFrameCount:h}):console.warn("[Client][NATIVE-MAIN] Native main stream ended mid-frame",{remoteNodeId:t,messageLen:m.expectedFrameLength,bufferedBytes:p.byteLength});return}P&&P.byteLength>0&&(p=c([p,new Uint8Array(P)]));try{m=this.tryExtractNativeMainPayload(p);}catch(k){u="invalid-native-main-frame",console.warn("[Client][NATIVE-MAIN] Invalid native main frame",{remoteNodeId:t,error:k});return}}if(m.expectedFrameLength===0){p=p.slice(m.consumedBytes);continue}let v=m.payloadBytes;p=p.slice(m.consumedBytes),h+=1,await this.handleNativeMainPayloadBytes(v,t,s,void 0,"bi",f,n,c$1,l),l?.phase==="complete"&&(f(),i=!1,l=void 0,u="admission-candidate-promoted");}}catch(m){if(this.disposed)return;let v=m instanceof Error&&m.message===oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_REASON;u=v?oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_REASON:"handler-error",v||this.schedulePeerReconciliationBestEffort("native-main-handler-error"),console.error("[Client][NATIVE-MAIN] Native main stream handler failed",{remoteNodeId:t,error:m});}finally{if(this.deps.handleNativeMainStreamClosed(t,n,c$1),a&&this.deps.clearInboundNativeMainWriter(t,s,u),this.activeReaders.delete(o),i){this.cancelReaderBestEffort(o,u);try{l?.phase==="complete"?await s.close():await s.abort(u);}catch{}}try{s.releaseLock();}catch{}try{o.releaseLock();}catch{}}}tryExtractNativeMainPayload(e){return Ao(e,this.deps.getProtocolConfig())}async tryHandleNativeMainUniStream(e,t,n){if(this.disposed||!e||typeof e.getReader!="function")return false;let i;try{i=e.getReader();}catch{return false}this.activeReaders.add(i);let o=new Uint8Array(0),s=false;try{for(;!this.disposed;){let a=this.tryExtractNativeMainPayload(o);for(;!a.ready&&!this.disposed;){let{done:c$1,value:d}=await i.read();if(this.disposed||c$1)return s;d&&d.byteLength>0&&(o=c([o,new Uint8Array(d)])),a=this.tryExtractNativeMainPayload(o);}s=!0,o=o.slice(a.consumedBytes),await this.handleNativeMainPayloadBytes(a.payloadBytes,t,null,n,"uni");}return s}catch(a){return this.disposed?s:s?(console.warn("[Client][NATIVE-MAIN] Read-only native main uni handler failed",{remoteNodeId:t,traceId:n||null,error:a}),true):false}finally{this.activeReaders.delete(i);try{i.releaseLock();}catch{}}}async handleFreshMainResponseStream(e,t,n){if(this.disposed||!e||typeof e.getReader!="function")return false;let i;try{i=e.getReader();}catch{return false}this.activeReaders.add(i);let o=new Uint8Array(0);try{for(;!this.disposed;){let s=this.tryExtractNativeMainPayload(o);if(s.ready)return await this.handleNativeMainPayloadBytes(s.payloadBytes,t,null,"fresh-main-response","uni",void 0,n),!0;let a=await b$3(i.read(),oe.FRESH_MAIN_RESPONSE_TIMEOUT_MS,"native-main fresh response");if(a.done)return !1;a.value?.byteLength&&(o=c([o,new Uint8Array(a.value)]));}return !1}catch(s){return this.disposed||console.warn("[Client][NATIVE-MAIN] Fresh main response failed",{remoteNodeId:t,error:s}),false}finally{this.activeReaders.delete(i),this.cancelReaderBestEffort(i,"native-main-fresh-response-complete");try{i.releaseLock();}catch{}}}async handleNativeMainPayloadBytes(e$1,t,n,i,o,s,a,c,d){if(this.disposed)return;let l=e$1.byteLength>1&&e$1[0]===0?e$1.slice(1):e$1,p;try{p=JSON.parse(new TextDecoder().decode(l));}catch(m){if(d)throw new Error(`admission candidate sent a non-JSON payload: ${String(m)}`);let v=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;v?v.receiveDataPayload(l):console.warn("[Client][NATIVE-MAIN] Dropping binary app payload: no control connection",{remoteNodeId:t,traceId:i||null,source:o,error:m});return}if(d){let m=p,v=m.channel==="session-token"&&m.action==="request"&&m.payload?.responseAckRequested===true,y=m.channel==="session-token"&&m.action==="event"&&m.payload?.responseAck===true;if(d.phase==="request"&&!v||d.phase==="response-ack"&&!y||d.phase==="complete")throw new Error(`invalid admission candidate frame in ${d.phase} phase`)}let u=this.deps.findManualDisconnectProjectionForNativeNode(t);if(this.isHandshakeMessage(p)){if(s?.(),u){e("[Client][NATIVE-MAIN] Dropping TS handshake for manually disconnected peer",{remoteNodeId:t,peerId:u.peerId,action:p.action??"hello",source:o});return}let m=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!m){this.deps.queuePendingNativeMainHandshake(t,p,o,i||null,a);return}e("[Client][NATIVE-MAIN] Routed TS handshake to Connection",{remoteNodeId:t,connectionId:m.id,action:p.action??"hello",source:o}),await this.deps.handleMessage(m,p,a);return}if(this.isNativeSignalEnvelope(p)){if(s?.(),e("[Client][NATIVE-MAIN] Received #pluto-signal envelope",{remoteNodeId:t,signalType:p.content?.type??null,transport:p.content?.transport??null,source:o}),u){e("[Client][NATIVE-MAIN] Dropping native WebRTC signal for manually disconnected peer",{remoteNodeId:t,peerId:u.peerId,signalType:p.content?.type??null,source:o});return}let m=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!m){this.deps.queuePendingNativeMainSignal(t,p.content,o,i||null);return}if(p.content?.transport==="webrtc"){await this.deps.handleMessage(m,p,a);return}m.receiveInternalSignal(p.content),e("[Client][NATIVE-MAIN] Routed #pluto-signal to Connection",{remoteNodeId:t,connectionId:m.id,signalType:p.content?.type??null,source:o});return}if(this.isIrohCarrierControlFrame(p)){if(s?.(),u){e("[Client][NATIVE-MAIN] Dropping Iroh carrier control for manually disconnected peer",{remoteNodeId:t,peerId:u.peerId,carrier:p.carrier,action:p.action,source:o});return}let m=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!m){console.warn("[Client][NATIVE-MAIN] Dropping Iroh carrier control: no admitted connection",{remoteNodeId:t,carrier:p.carrier,action:p.action,source:o}),this.schedulePeerReconciliationBestEffort("iroh-carrier-control-without-connection");return}await this.deps.handleMessage(m,p,a);return}let h=p;if(e("[Client][NATIVE-MAIN] Received native main message",{remoteNodeId:t,channel:h.channel,action:h.action,requestId:h.requestId??null,source:o}),h.channel==="handshake"&&h.action==="request"){n&&await this.deps.handleNativeHandshakeRequest(n,t,h);return}if(h.channel==="session-token"&&h.action==="request"){if(n){let m=await this.deps.handleNativeSessionTokenRequest(n,t,h,a,c);if(d&&!m)throw new Error("admission candidate request did not establish ACK ownership");d&&(d.phase="response-ack",d.responseAckDeadlineAtMs=Date.now()+oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_MS);}return}if(h.channel==="session-token"&&h.action==="event"&&h.payload?.responseAck===true){let m=await this.deps.handleNativeSessionTokenResponseAck(t,h,a,c);if(d){if(!m)throw new Error("admission candidate response ACK did not commit");d.phase="complete";}return}if(!h.channel&&!h.action&&!h.requestId){s?.();let m=await this.deps.ensureIncomingConnectionForRemoteNode(t);if(this.disposed)return;if(!m){console.warn("[Client][NATIVE-MAIN] Dropping app payload: no control connection",{remoteNodeId:t,traceId:i||null,source:o});return}m.receiveMessage(p);return}let f=await this.deps.dispatchNativeMainMessage(t,h);this.disposed||n&&await this.writeReceiveAckBestEffort(n,h,f,t,o);}isNativeSignalEnvelope(e){if(!e||typeof e!="object")return false;let t=e;return t.type==="#pluto-signal"&&typeof t.content=="object"&&t.content!==null}isIrohCarrierControlFrame(e){if(!e||typeof e!="object")return false;let t=e;return t.type==="#openrtc-iroh-carrier"&&(t.carrier==="web-rtc"||t.carrier==="moq-draft14")&&typeof t.action=="string"}isHandshakeMessage(e){return !e||typeof e!="object"?false:e.type==="handshake"}cancelReaderBestEffort(e,t="native-main-payload-router-disposed"){try{Promise.resolve(e.cancel(t)).catch(()=>{});}catch{}}createStreamInstanceId(){let e=globalThis.crypto?.randomUUID;return typeof e=="function"?e.call(globalThis.crypto):`native-main-stream-${Date.now()}-${Math.random().toString(36).slice(2)}`}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}async writeReceiveAckBestEffort(e,t,n,i,o){if(!this.disposed)try{await this.deps.writeNativeMainReceiveAck(e,t,n);}catch(s){if(this.disposed)return;console.warn("[Client][NATIVE-MAIN] Failed to ack native main message",{remoteNodeId:i,channel:t.channel,action:t.action,source:o,error:s});}}};oe.FRESH_MAIN_RESPONSE_TIMEOUT_MS=5e3,oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_MS=2e3,oe.SESSION_TOKEN_RESPONSE_ACK_TIMEOUT_REASON="admission-candidate-response-ack-timeout";var xt=oe;var Ft=class{constructor(e,t,n=[0,250,1e3,2500]){this.maxPerNode=e;this.ttlMs=t;this.retryDelaysMs=n;this.pendingByNodeId=new Map;this.retryTimers=new Set;this.disposed=false;}queue(e$1,t,n,i,o){if(this.disposed)return;let s=this.pendingByNodeId.get(e$1)??[];s.push({content:t,source:n,traceId:i??null,receivedAtMs:Date.now()}),s.length>this.maxPerNode&&s.splice(0,s.length-this.maxPerNode),this.pendingByNodeId.set(e$1,s),e("[Client][NATIVE-MAIN] Queued native WebRTC signal until control connection is registered",{remoteNodeId:e$1,signalType:t?.type??null,source:n,traceId:i||null,pendingCount:s.length});for(let a of this.retryDelaysMs){let c=setTimeout(()=>{this.retryTimers.delete(c),!this.disposed&&o(e$1,`queued-signal-retry:${a}`);},a);this.retryTimers.add(c);}}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.retryTimers)clearTimeout(e);this.retryTimers.clear(),this.pendingByNodeId.clear();}}async flush(e$1,t,n){if(this.disposed)return false;let i=this.pendingByNodeId.get(e$1);if(!i||i.length===0)return false;let o=n.findManualDisconnectProjectionForNativeNode(e$1);if(o)return this.pendingByNodeId.delete(e$1),e("[Client][NATIVE-MAIN] Dropped queued native WebRTC signals for manually disconnected peer",{remoteNodeId:e$1,peerId:o.peerId,droppedCount:i.length,trigger:t}),false;let s=n.findLiveConnectionForRemoteNode(e$1);if(s||(s=await n.ensureIncomingConnectionForRemoteNode(e$1).catch(()=>null)),this.disposed)return false;if(!s){let a=Date.now(),c=i.filter(d=>a-d.receivedAtMs<=this.ttlMs);return c.length===0?(this.pendingByNodeId.delete(e$1),console.warn("[Client][NATIVE-MAIN] Dropping queued native WebRTC signals after control connection did not appear",{remoteNodeId:e$1,trigger:t,droppedCount:i.length})):c.length!==i.length&&this.pendingByNodeId.set(e$1,c),false}this.pendingByNodeId.delete(e$1),e("[Client][NATIVE-MAIN] Replaying queued native WebRTC signals to Connection",{remoteNodeId:e$1,connectionId:s.id,trigger:t,count:i.length});for(let a of i){if(this.disposed)return false;s.receiveInternalSignal(a.content);}return true}};var Ot=class{constructor(e){this.deps=e;this.disposed=false;}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Native main signal sender is disposed")}isCurrent(e,t){return e.isCurrentSignal(t)}async openNativeSignalBiStream(e,t){this.assertActive();let n=e.open_native_main_control_bi;if(typeof n=="function"){let i=await n.call(e,t);return this.assertActive(),i}throw new Error("[Client][NATIVE-MAIN] open_native_main_control_bi is unavailable on this WASM build; native-main signaling cannot open a control stream under mandatory application crypto. Rebuild the openrtc WASM (pnpm --filter openrtc build:wasm).")}async sendViaDedicatedStream(e,t,n,i){if(this.assertActive(),!this.isCurrent(n,i))return;let o=ve(Ge(i)),s=e.send_native_main_control_frame;if(typeof s=="function"){await s.call(e,t,o),this.assertActive();return}let a=await this.openNativeSignalBiStream(e,t);if(this.assertActive(),!this.isCurrent(n,i))return;let c=a.send.getWriter();try{if(await c.write(xo()),this.disposed||!this.isCurrent(n,i))return;await c.write(o),await c.close();}catch(d){throw console.warn("[Client][NATIVE-MAIN] Dedicated-stream signal send failed",{remoteNodeId:t,signalType:i?.content?.type??null,error:d}),d}finally{try{c.releaseLock();}catch{}}}async sendViaFreshMainStream(e,t,n,i){if(this.assertActive(),!this.isCurrent(n,i))return;let o=ve(Ge(i)),s=await this.openNativeSignalBiStream(e,t);if(this.assertActive(),!this.isCurrent(n,i))return;this.deps.handleFreshMainResponse(s.recv,t,s.transport_stable_id);let a=s.send.getWriter();try{if(await a.write(qe()),this.disposed||!this.isCurrent(n,i))return;await a.write(o),await a.close();}finally{try{a.releaseLock();}catch{}}}async sendEnvelope(e$1,t,n,i){if(this.disposed)return;if(!this.isCurrent(e$1,n)){e("[Client][NATIVE-MAIN] Dropping signal from retired negotiation generation",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null});return}n?.content?.transport??null;let s=n?.type==="handshake",c=n?.type==="#openrtc-iroh-carrier"||n?.type==="#pluto-signal"&&n?.content?.transport==="webrtc"||s,d=this.deps.isSessionTokenApprovedNode(t)&&this.deps.isSessionTokenApprovedConnection(e$1.id),l=d,p=this.deps.supportsDedicatedCarrierControl?.(t,e$1.id)===true,u=this.deps.shouldUseDedicatedCarrierControl?.(t,e$1.id)===true,h=l&&u;if(s&&l&&p&&!u)try{if(await this.sendViaFreshMainStream(i,t,e$1,n),this.disposed||!this.isCurrent(e$1,n))return;e("[Client][NATIVE-MAIN] Signal route=fresh-main-bootstrap",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null});return}catch(y){console.warn("[Client][NATIVE-MAIN] Fresh main bootstrap send failed; falling back",{connectionId:e$1.id,remoteNodeId:t,error:y});}if(c&&h)try{if(await this.sendViaDedicatedStream(i,t,e$1,n),this.disposed||!this.isCurrent(e$1,n))return;e("[Client][NATIVE-MAIN] Signal route=dedicated-carrier-control",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null});return}catch(y){console.warn("[Client][NATIVE-MAIN] Dedicated carrier-control send failed; falling back",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,error:y});}let f=this.deps.isSessionTokenApprovedNode(t),m=this.deps.isSessionTokenApprovedConnection(e$1.id),v=await this.deps.sendViaInboundControlStream(t,n,{ignoreCooldown:c,isCurrent:()=>this.isCurrent(e$1,n)});if(!(this.disposed||!this.isCurrent(e$1,n))){if(v.sent){e("[Client][NATIVE-MAIN] Sent native signal over inbound control stream",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs}),e("[Client][NATIVE-MAIN] Signal route=inbound-control",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs}),e("[SIGNAL-STREAM][TS] reply-on-persistent-writer",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,writerId:v.writerId,writerAgeMs:v.writerAgeMs});return}if(e("[Client][NATIVE-MAIN] Signal route=inbound-control-unavailable",{connectionId:e$1.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:f,hasApprovedConnectionId:m,hasApprovedDedicatedStream:d,preferDedicatedSignalPath:c,canUseDedicatedStream:l,remoteSupportsDedicatedControl:p,remoteDedicatedControlReady:u}),h)try{if(await this.sendViaDedicatedStream(i,t,e$1,n),this.disposed)return;e("[Client][NATIVE-MAIN] Sent native signal over dedicated stream",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null}),e("[Client][NATIVE-MAIN] Signal route=dedicated-open_bi",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:v.reason});return}catch(y){console.warn("[Client][NATIVE-MAIN] Dedicated-stream signal send failed; trying labelled main route",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,error:y});}try{if(this.disposed||!this.isCurrent(e$1,n)||(await this.sendViaFreshMainStream(i,t,e$1,n),this.disposed||!this.isCurrent(e$1,n)))return;e("[Client][NATIVE-MAIN] Signal route=fresh-main-fallback",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,negotiationId:n?.content?.negotiationId??null,inboundFallbackReason:v.reason});}catch(y){throw console.warn("[Client][NATIVE-MAIN] Labelled native-main control route unavailable",{connectionId:e$1.id,remoteNodeId:t,signalType:n?.content?.type??null,error:y}),new Error("[Client][NATIVE-MAIN] native-main control route unavailable: a Rust-owned labelled main/signal route or admitted native-main writer is required.")}}}};var as=2e3,Ht=class{constructor(){this.writers=new Map;this.writeMutexes=new Map;this.writerMeta=new Map;this.standbyWriters=new Map;this.bypassUntilMs=new Map;this.writerSeq=0;this.disposed=false;}dispose(){if(!this.disposed){this.disposed=true;for(let e of this.writers.values())try{e.releaseLock();}catch{}for(let e of this.standbyWriters.values())for(let t of e)try{t.writer.releaseLock();}catch{}this.writers.clear(),this.writeMutexes.clear(),this.writerMeta.clear(),this.standbyWriters.clear(),this.bypassUntilMs.clear();}}registerInboundWriter(e$1,t,n){if(this.disposed){try{t.releaseLock();}catch{}return}let i=this.writers instanceof Map?this.writers:null,o=this.writerMeta instanceof Map?this.writerMeta:null,s=this.standbyWriters instanceof Map?this.standbyWriters:null;if(!i||!e$1||!t)return;let a=i.get(e$1),c=o?.get(e$1);this.writerSeq+=1;let d=this.writerSeq,l=Number.isSafeInteger(n)&&Number(n)>0?Number(n):null,p={id:d,registeredAtMs:Date.now(),transportStableId:l};if(a&&a!==t&&l!==null&&c?.transportStableId===l){let u=s?.get(e$1)??[];u.push({writer:t,meta:p}),s?.set(e$1,u),e("[Client][NATIVE-MAIN] Same-generation control writer deferred",{remoteNodeId:e$1,writerId:d,activeWriterId:c.id,transportStableId:l}),e("[SIGNAL-STREAM][TS] writer-deferred",{remoteNodeId:e$1,writerId:d,activeWriterId:c.id,transportStableId:l});return}i.set(e$1,t),o?.set(e$1,p),this.bypassUntilMs instanceof Map&&this.bypassUntilMs.delete(e$1),e("[Client][NATIVE-MAIN] Inbound control writer registered",{remoteNodeId:e$1,writerId:d,replacedExistingWriter:!!a&&a!==t,transportStableId:l}),e("[SIGNAL-STREAM][TS] writer-registered",{remoteNodeId:e$1,writerId:d,replacedExistingWriter:!!a&&a!==t,transportStableId:l});}clearInboundWriter(e$1,t,n,i="stream-finalize"){if(this.disposed)return;let o=this.writers instanceof Map?this.writers:null,s=this.writeMutexes instanceof Map?this.writeMutexes:null,a=this.writerMeta instanceof Map?this.writerMeta:null,c=this.standbyWriters instanceof Map?this.standbyWriters:null;if(!o||!s)return;let d=o.get(e$1),l=a?.get(e$1),p=c?.get(e$1)??[],u=p.filter(h=>h.writer!==t);if(d===t){o.delete(e$1),a?.delete(e$1);let h=u.findIndex(m=>m.meta.transportStableId===l?.transportStableId),f=h>=0?u.splice(h,1)[0]:void 0;u.length>0?c?.set(e$1,u):c?.delete(e$1),f?(o.set(e$1,f.writer),a?.set(e$1,f.meta),this.bypassUntilMs.delete(e$1)):(this.bypassUntilMs.set(e$1,Date.now()+n),s.delete(e$1)),e("[Client][NATIVE-MAIN] Inbound control writer cleared",{remoteNodeId:e$1,writerId:l?.id??null,ageMs:l?Date.now()-l.registeredAtMs:null,reason:i,promotedWriterId:f?.meta.id??null}),e("[SIGNAL-STREAM][TS] writer-cleared",{remoteNodeId:e$1,writerId:l?.id??null,ageMs:l?Date.now()-l.registeredAtMs:null,reason:i,promotedWriterId:f?.meta.id??null});}else u.length>0?c?.set(e$1,u):c?.delete(e$1),e("[Client][NATIVE-MAIN] Inbound control writer clear skipped (mismatch)",{remoteNodeId:e$1,activeWriterId:l?.id??null,reason:i,removedStandby:u.length!==p.length});}async sendViaInboundControlStream(e,t,n,i={}){if(this.disposed)return {sent:false,reason:"writer-registry-disposed",writerId:null,writerAgeMs:null,error:null};let o=this.writers instanceof Map?this.writers:null,s=this.writeMutexes instanceof Map?this.writeMutexes:null,a=this.writerMeta instanceof Map?this.writerMeta:null;if(!o||!s)return {sent:false,reason:"writer-or-mutex-map-unavailable",writerId:null,writerAgeMs:null,error:null};let c=a?.get(e),d=this.bypassUntilMs instanceof Map?this.bypassUntilMs:null,l=d?.get(e)??0;if(!i.ignoreCooldown&&l>Date.now())return {sent:false,reason:"inbound-writer-cooldown",writerId:c?.id??null,writerAgeMs:c?Date.now()-c.registeredAtMs:null,error:null};let p=o.get(e),u=c?.id??null,h=c?Date.now()-c.registeredAtMs:null;if(!p)return d?.set(e,Date.now()+n),{sent:false,reason:"no-inbound-writer",writerId:u,writerAgeMs:h,error:null};let f=ve(Ge(t)),m=s.get(e)??Promise.resolve(),v,y=new Promise(S=>{v=S;});s.set(e,y);try{if(await m.catch(()=>{}),i.isCurrent&&!i.isCurrent())return {sent:!1,reason:"retired-negotiation-generation",writerId:u,writerAgeMs:h,error:null};let S=Math.max(1,i.writeTimeoutMs??as);return await b$3(p.write(f),S,()=>new Error(`native-main inbound writer timed out after ${S}ms`)),{sent:!0,reason:"sent",writerId:u,writerAgeMs:h,error:null}}catch(S){this.clearInboundWriter(e,p,n,"write-failed-or-timed-out");let C=p;typeof C.abort=="function"&&C.abort(S).catch(()=>{});let P=S?.message??String(S),k=P.includes("inbound writer timed out after");return console.warn("[Client][NATIVE-MAIN] Inbound control-stream signal send failed",{remoteNodeId:e,signalType:t?.content?.type??null,writerId:u,writerAgeMs:h,error:S}),{sent:false,reason:k?"inbound-writer-write-timeout":"inbound-writer-write-failed",writerId:u,writerAgeMs:h,error:P}}finally{v(),s.get(e)===y&&s.delete(e);}}};var Ut=class{constructor(e,t,n){this.deps=e;this.protocolConfig=t;this.timingConfig=n;this.writers=new Ht;this.disposed=false;this.messageIO=new Lt({eventName:t.eventName,protocolByte:t.protocolByte,label:t.label,maxLabelBytes:t.maxLabelBytes,maxFrameBytes:t.maxFrameBytes},{getReceiverDeviceId:()=>e.getReceiverDeviceId(),getRemoteDeviceId:i=>e.getKnownDeviceIdForNode(i)}),this.handshakeQueue=new Bt(n.pendingHandshakeMaxPerNode,n.pendingHandshakeTtlMs),this.signalQueue=new Ft(n.pendingHandshakeMaxPerNode,n.pendingHandshakeTtlMs),this.deps.registerDisposer(()=>this.dispose());}get writerRegistry(){return this.writers}get connectionController(){return this.getConnections()}get handshakeQueueController(){return this.handshakeQueue}get messageIOController(){return this.messageIO}get payloadRouterController(){return this.getPayloadRouter()}dispose(){this.disposed=true,this.handshakeQueue.dispose(),this.signalQueue.dispose(),this.admission?.dispose(),this.connections?.dispose(),this.payloadRouter?.dispose(),this.writers.dispose(),this.signalSender?.dispose();}retirePendingReciprocalAdmissions(e){this.admission?.retirePendingReciprocalAdmissions(e);}async acceptNativeMessage(e,t,n){return this.disposed?false:this.getAdmission().acceptNativeMessage(e,t,n)}tryHandleNativeMainUniStream(e,t,n){return this.disposed?Promise.resolve(false):this.getPayloadRouter().tryHandleNativeMainUniStream(e,t,n)}handleFreshMainResponseStream(e,t,n){this.disposed||this.getPayloadRouter().handleFreshMainResponseStream(e,t,n).catch(()=>{});}handleNativeMainStream(e,t,n,i){if(this.disposed)return Promise.resolve();let o=Number.isSafeInteger(n)&&Number(n)>0;return i?this.getPayloadRouter().handleNativeMainStream(e,t,o?n:void 0,true):o?this.getPayloadRouter().handleNativeMainStream(e,t,n):this.getPayloadRouter().handleNativeMainStream(e,t)}writeLabelHeaderOnBiStream(e,t){return this.disposed?Promise.resolve():this.messageIO.writeLabelHeaderOnBiStream(e,t)}openSignalBiStream(e,t){return this.disposed?Promise.reject(new Error("Native main controller is disposed")):this.getSignalSender().openNativeSignalBiStream(e,t)}async sendSignalEnvelope(e,t,n,i){this.disposed||await this.getSignalSender().sendEnvelope(e,t,n,i);}ensureIncomingConnectionForRemoteNode(e){return this.disposed?Promise.resolve(null):this.getConnections().ensureIncomingConnectionForRemoteNode(e)}flushPendingHandshakesForNode(e,t){return this.disposed?Promise.resolve(false):this.handshakeQueue.flush(e,t,{findManualDisconnectProjectionForNativeNode:n=>this.deps.findManualDisconnectProjectionForNativeNode(n),findLiveConnectionForRemoteNode:n=>this.deps.findLiveConnectionForRemoteNode(n),ensureIncomingConnectionForRemoteNode:n=>this.deps.ensureIncomingConnectionForRemoteNode(n),handleMessage:(n,i,o)=>Promise.resolve(this.deps.handleMessage(n,i,o))})}flushPendingSignalsForNode(e,t){return this.disposed?Promise.resolve(false):this.signalQueue.flush(e,t,{findManualDisconnectProjectionForNativeNode:n=>this.deps.findManualDisconnectProjectionForNativeNode(n),findLiveConnectionForRemoteNode:n=>this.deps.findLiveConnectionForRemoteNode(n),ensureIncomingConnectionForRemoteNode:n=>this.deps.ensureIncomingConnectionForRemoteNode(n)})}getSignalSender(){return this.signalSender||(this.signalSender=new Ot({isSessionTokenApprovedNode:e=>this.deps.isSessionTokenApprovedNode(e),isSessionTokenApprovedConnection:e=>this.deps.isSessionTokenApprovedConnection(e),supportsDedicatedCarrierControl:(e,t)=>{let n=this.deps.getConnection(t);return typeof n?.supportsDedicatedCarrierControl=="function"&&n.supportsDedicatedCarrierControl()},shouldUseDedicatedCarrierControl:(e,t)=>{if(this.deps.getConnectionChannelId(t)==="drive-view")return false;let n=this.deps.getConnection(t);return typeof n?.isRemoteDedicatedCarrierControlReady=="function"&&n.isRemoteDedicatedCarrierControlReady()},sendViaInboundControlStream:(e,t,n)=>this.writers.sendViaInboundControlStream(e,t,this.timingConfig.inboundWriterRetryCooldownMs,n),handleFreshMainResponse:(e,t,n)=>this.handleFreshMainResponseStream(e,t,n)}),this.disposed&&this.signalSender.dispose()),this.signalSender}getConnections(){return this.connections||(this.connections=new Et({getDeterministicConnectionId:e=>this.deps.getDeterministicConnectionId(e),getConnection:e=>this.deps.getConnection(e),getWasmClient:()=>this.deps.getWasmClient(),getLocalNodeId:()=>this.deps.getLocalNodeId(),getKnownDeviceIdForNode:e=>this.deps.getKnownDeviceIdForNode(e),getKnownDevicePlatform:(e,t)=>this.deps.getKnownDevicePlatform(e,t),isNativeMainPeerPlatform:e=>this.deps.isNativeMainPeerPlatform(e),getTrustFailureCooldown:e=>this.deps.getTrustFailureCooldown(e),getTrustFailureCooldownMs:()=>this.timingConfig.trustFailureCooldownMs,isSessionTokenApprovedNode:e=>this.deps.isSessionTokenApprovedNode(e),openNativeSignalBiStream:(e,t)=>this.openSignalBiStream(e,t),writeNativeMainLabelHeaderOnBiStream:(e,t)=>this.writeLabelHeaderOnBiStream(e,t),sendNativeSignalEnvelope:(e,t,n,i)=>this.sendSignalEnvelope(e,t,n,i),createTransportContext:e=>this.deps.createTransportContext(e),getApplicationCrypto:()=>this.deps.getApplicationCrypto(),shouldNegotiateApplicationKeyAgreement:()=>this.deps.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(e,t,n)=>this.deps.handleConnectionTransportStatus(e,t,n??null),initializeConnectionTrust:(e,t)=>{this.deps.initializeConnectionTrust(e,t);},markConnectionTrustVerified:(e,t)=>{this.deps.markConnectionTrustVerified(e,t);},registerConnection:e=>this.deps.registerConnection(e),announceConnectionWhenStable:e=>this.deps.announceConnectionWhenStable(e),sendTransportHandshake:(e,t)=>this.deps.sendTransportHandshake(e,t),getConnectionChannelId:e=>this.deps.getConnectionChannelId(e),isWebRTCTransportEnabled:()=>this.deps.isWebRTCTransportEnabled()}),this.disposed&&this.connections.dispose()),this.connections}getAdmission(){return this.admission||(this.admission=new _t({getDeterministicConnectionId:e=>this.deps.getDeterministicConnectionId(e),getNativeMainConnectionId:e=>this.deps.getNativeMainConnectionId(e),getConnection:e=>this.deps.getConnection(e),handleMessage:(e,t)=>this.deps.handleMessage(e,t),getLocalDeviceId:()=>this.deps.getLocalDeviceId(),getFallbackLocalDeviceId:()=>this.deps.getFallbackLocalDeviceId(),getConfiguredDeviceName:()=>this.deps.getConfiguredDeviceName(),getNativeMainProtocolVersion:()=>this.protocolConfig.protocolVersion,isNativeRuntime:()=>this.deps.isNativeRuntime(),isLikelyMobileBrowser:()=>this.deps.isLikelyMobileBrowser(),writeNativeMainMessage:(e,t)=>this.messageIO.writeLabeledMessage(e,t),validateIncomingSessionToken:(e,t,n)=>this.deps.validateIncomingSessionToken(e,t,n),acknowledgeSessionTokenResponse:(e,t,n,i)=>this.deps.acknowledgeSessionTokenResponse(e,t,n,i),applySessionTokenTrustApproval:(e,t,n)=>this.deps.applySessionTokenTrustApproval(e,t,n),rememberPendingSessionTokenTrustApproval:(e,t)=>this.deps.rememberPendingSessionTokenTrustApproval(e,t),markSessionTokenApprovedNode:e=>this.deps.markSessionTokenApprovedNode(e),markSessionTokenApprovedConnection:e=>this.deps.markSessionTokenApprovedConnection(e),clearSessionTokenRejectionCooldown:e=>this.deps.clearSessionTokenRejectionCooldown(e),getSessionTokenRejectionCooldown:e=>this.deps.getSessionTokenRejectionCooldown(e),setSessionTokenRejectionCooldown:(e,t)=>this.deps.setSessionTokenRejectionCooldown(e,t),clearTrustFailureCooldown:e=>{this.deps.clearTrustFailureCooldown(e);},schedulePeerReconciliation:e=>this.deps.schedulePeerReconciliation(e),refreshApplicationRouteHandshake:(e,t)=>this.deps.refreshApplicationRouteHandshake(e,t),ensureIncomingConnectionForRemoteNode:e=>this.deps.ensureIncomingConnectionForRemoteNode(e),getReciprocalSessionAdmission:(e,t,n,i,o)=>this.deps.getReciprocalSessionAdmission(e,t,n,i,o),presentLegacyReciprocalSessionAdmission:e=>this.deps.presentLegacyReciprocalSessionAdmission(e),confirmReciprocalSessionAdmission:(e,t,n,i,o,s)=>this.deps.confirmReciprocalSessionAdmission(e,t,n,i,o,s),disconnectRemoteNode:e=>this.deps.disconnectRemoteNode(e)}),this.disposed&&this.admission.dispose()),this.admission}getPayloadRouter(){return this.payloadRouter||(this.payloadRouter=new xt({getProtocolConfig:()=>this.messageIO.protocolConfig(),registerInboundNativeMainWriter:(e,t,n)=>this.writers.registerInboundWriter(e,t,n),clearInboundNativeMainWriter:(e,t,n)=>this.writers.clearInboundWriter(e,t,this.timingConfig.inboundWriterRetryCooldownMs,n),schedulePeerReconciliation:e=>this.deps.schedulePeerReconciliation(e),ensureIncomingConnectionForRemoteNode:e=>this.deps.ensureIncomingConnectionForRemoteNode(e),queuePendingNativeMainHandshake:(e,t,n,i,o)=>this.handshakeQueue.queue(e,t,n,i,(s,a)=>{this.flushPendingHandshakesForNode(s,a);},o),queuePendingNativeMainSignal:(e,t,n,i)=>this.signalQueue.queue(e,t,n,i,(o,s)=>{this.flushPendingSignalsForNode(o,s);}),findManualDisconnectProjectionForNativeNode:e=>this.deps.findManualDisconnectProjectionForNativeNode(e),handleMessage:(e,t,n)=>this.deps.handleMessage(e,t,n),handleNativeHandshakeRequest:(e,t,n)=>this.getAdmission().handleHandshakeRequest(e,t,n),handleNativeSessionTokenRequest:(e,t,n,i,o)=>this.getAdmission().handleSessionTokenRequest(e,t,n,i,o),handleNativeSessionTokenResponseAck:(e,t,n,i)=>this.getAdmission().handleSessionTokenResponseAck(e,t,n,i),handleNativeMainStreamClosed:(e,t,n)=>this.getAdmission().handleNativeMainStreamClosed(e,t,n),dispatchNativeMainMessage:(e,t)=>this.messageIO.dispatchMessage(e,t),writeNativeMainReceiveAck:(e,t,n)=>this.messageIO.writeAck(e,t,n)}),this.disposed&&this.payloadRouter.dispose()),this.payloadRouter}};function Fo(r){let{host:e}=r;return new Ut({registerDisposer:t=>e.registerDisposer(t),getDeterministicConnectionId:t=>e.getDeterministicConnectionId(t),getNativeMainConnectionId:t=>e.getNativeMainConnectionId(t),getConnection:t=>e.getConnection(t),getWasmClient:()=>e.getWasmClient(),getLocalNodeId:()=>e.getLocalNodeId(),getReceiverDeviceId:()=>e.getDeviceId()??e.getOptions().localDeviceId??null,getKnownDeviceIdForNode:t=>e.getKnownDeviceIdForNode(t),getKnownDevicePlatform:(t,n)=>e.getKnownDevicePlatform(t,n),isNativeMainPeerPlatform:t=>bo(t),getTrustFailureCooldown:t=>e.getTrustFailureCooldown(t),isSessionTokenApprovedNode:t=>e.isSessionTokenApprovedNode(t),isSessionTokenApprovedConnection:t=>e.isSessionTokenApprovedConnection(t),createTransportContext:t=>e.createTransportContext(t),getApplicationCrypto:()=>e.getApplicationCrypto(),shouldNegotiateApplicationKeyAgreement:()=>e.shouldNegotiateApplicationKeyAgreement(),handleConnectionTransportStatus:(t,n,i)=>e.handleConnectionTransportStatus(t,n,i??null),initializeConnectionTrust:(t,n)=>{e.initializeConnectionTrust(t,n);},markConnectionTrustVerified:(t,n)=>{e.markConnectionTrustVerified(t,n);},registerConnection:t=>e.registerConnection(t),announceConnectionWhenStable:t=>e.announceConnectionWhenStable(t),sendTransportHandshake:(t,n)=>e.sendTransportHandshake(t,n),getConnectionChannelId:t=>e.getConnectionChannelId(t),isWebRTCTransportEnabled:()=>Y(e.getOptions()),getLocalDeviceId:()=>e.getLocalDeviceId(),getFallbackLocalDeviceId:()=>e.getDeviceId()||e.getOptions().localDeviceId||null,getConfiguredDeviceName:()=>e.getOptions().deviceName,isNativeRuntime:()=>typeof window<"u"&&typeof window.__TAURI__<"u",isLikelyMobileBrowser:()=>ae(),validateIncomingSessionToken:(t,n,i)=>e.validateIncomingSessionToken(t,n,i),acknowledgeSessionTokenResponse:async(t,n,i,o)=>{let s=e.getWasmClient(),a=s?.acknowledge_session_token_response;return typeof a!="function"?false:a.call(s,t,n,BigInt(i),o??void 0)},applySessionTokenTrustApproval:(t,n,i)=>e.applySessionTokenTrustApproval(t,n,i),rememberPendingSessionTokenTrustApproval:(t,n)=>e.rememberPendingSessionTokenTrustApproval(t,n),markSessionTokenApprovedNode:t=>e.markSessionTokenApprovedNode(t),markSessionTokenApprovedConnection:t=>e.markSessionTokenApprovedConnection(t),clearSessionTokenRejectionCooldown:t=>e.clearSessionTokenRejectionCooldown(t),getSessionTokenRejectionCooldown:t=>e.getSessionTokenRejectionCooldown(t),setSessionTokenRejectionCooldown:(t,n)=>e.setSessionTokenRejectionCooldown(t,n),clearTrustFailureCooldown:t=>{e.clearTrustFailureCooldown(t);},schedulePeerReconciliation:t=>e.schedulePeerReconciliation(t),refreshApplicationRouteHandshake:(t,n)=>e.refreshApplicationRouteHandshake(t,n),ensureIncomingConnectionForRemoteNode:t=>r.getController().ensureIncomingConnectionForRemoteNode(t),getReciprocalSessionAdmission:async(t,n,i,o,s)=>{let a=e.getRouteRepairSessionTokenForNode(t),c=e.getRouteRepairSessionTokenPayloadForNode(t);if(!a||!c)throw new Error("pending reciprocal session token is unavailable");let d=await e.getLocalDeviceId().catch(()=>null);if(!d)throw new Error("local device identity is unavailable for reciprocal admission");let l=e.getWasmClient();if(typeof l?.prepare_reciprocal_admission!="function")throw new Error("WASM runtime does not support inline reciprocal admission");return await l.prepare_reciprocal_admission(t,BigInt(i),o,s,a,c,d,n),{token:a,tokenPayload:c,deviceId:d,streamContract:n}},presentLegacyReciprocalSessionAdmission:async t=>{let n=e.getWasmClient(),i=e.getRouteRepairSessionTokenForNode(t),o=e.getRouteRepairSessionTokenPayloadForNode(t);if(!i||!o)throw new Error("pending reciprocal session token is unavailable");let s=await e.getLocalDeviceId().catch(()=>null);if(typeof n?.present_session_token=="function"){await n.present_session_token(t,i,o,s);return}throw new Error("WASM runtime does not support legacy reciprocal session admission")},confirmReciprocalSessionAdmission:async(t,n,i,o,s,a)=>{let c=e.getWasmClient();return typeof c?.confirm_reciprocal_admission!="function"?false:c.confirm_reciprocal_admission(t,BigInt(n),i,o,s,a)},disconnectRemoteNode:t=>e.disconnectRemoteNode(t),findManualDisconnectProjectionForNativeNode:t=>e.findManualDisconnectProjectionForNativeNode(t),findLiveConnectionForRemoteNode:t=>e.findLiveConnectionForRemoteNode(t),handleMessage:(t,n,i)=>e.handleMessage(t,n,i)},{eventName:ao,protocolByte:pt,label:ut,maxLabelBytes:gt,maxFrameBytes:ro,protocolVersion:so},{trustFailureCooldownMs:po,inboundWriterRetryCooldownMs:uo,pendingHandshakeTtlMs:co,pendingHandshakeMaxPerNode:lo})}function Oo(r){return new Qn({registerDisposer:e=>r.lifecycleScope.register(e),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,getLocalNodeId:()=>r.localNodeId,getDeviceId:()=>r.deviceId,getDeterministicConnectionId:e=>r.peerIdentity.getDeterministicConnectionId(e),getNativeMainConnectionId:e=>r.peerIdentity.getNativeMainConnectionId(e),getConnection:e=>r.registry.get(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),getKnownDevicePlatform:(e,t)=>r.deviceDirectory.getKnownDevicePlatform(e,t),getTrustFailureCooldown:e=>r.connectionTrust.getFailureCooldown(e),getRouteRepairSessionTokenForNode:e=>r.sessionTokens.getRouteRepairTokenForNode(e),getRouteRepairSessionTokenPayloadForNode:e=>r.sessionTokens.getRouteRepairTokenPayloadForNode(e),isSessionTokenApprovedNode:e=>r.sessionTokens.isApprovedNode(e),isSessionTokenApprovedConnection:e=>r.sessionTokens.isApprovedConnection(e),createTransportContext:e=>r.transportContexts.create(e),getApplicationCrypto:()=>r.options?.applicationCrypto,shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),handleConnectionTransportStatus:(e,t,n)=>r.transportHealth.handleCurrentConnectionTransportStatus(e,t,n),initializeConnectionTrust:(e,t)=>{r.connectionTrust.initialize(e,t);},markConnectionTrustVerified:(e,t)=>{r.connectionTrust.markVerified(e,t);},registerConnection:e=>r.connectionLifecycle.registerConnection(e),announceConnectionWhenStable:e=>r.connectionLifecycle.announceConnectionWhenStable(e),sendTransportHandshake:(e,t)=>r.transportHandshake.sendTransportHandshake(e,t),getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),validateIncomingSessionToken:(e,t,n)=>r.sessionTokens.validateIncomingSessionTokenWithRetry(e,t,n),applySessionTokenTrustApproval:(e,t,n)=>r.sessionTokens.applyTrustApproval(e,t,n),rememberPendingSessionTokenTrustApproval:(e,t)=>r.sessionTokens.rememberPendingTrustApproval(e,t),markSessionTokenApprovedNode:e=>r.sessionTokens.approveNode(e),markSessionTokenApprovedConnection:e=>r.sessionTokens.approveConnection(e),clearSessionTokenRejectionCooldown:e=>r.sessionTokens.clearRejectionCooldown(e),getSessionTokenRejectionCooldown:e=>r.sessionTokens.getRejectionCooldown(e),setSessionTokenRejectionCooldown:(e,t)=>r.sessionTokens.setRejectionCooldown(e,t),clearTrustFailureCooldown:e=>{r.connectionTrust.clearFailureCooldown(e);},schedulePeerReconciliation:e=>r.peerProjection.schedule(e),refreshApplicationRouteHandshake:(e,t)=>r.applicationRoute.refreshApplicationRouteHandshake(e,t),disconnectRemoteNode:e=>r.runtimeConnections.disconnectNodeBestEffort(e),findManualDisconnectProjectionForNativeNode:e=>r.peerIdentity.findManualDisconnectProjectionForNativeNode(e),findLiveConnectionForRemoteNode:e=>{let t=r.peerIdentity.getDeterministicConnectionId(e);return r.connectionLifecycle.findLiveConnectionForRemoteNode(e,t)},handleMessage:(e,t,n)=>r.connectionMessageHandler.handleMessage(e,t,n)})}var Qn=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getController:()=>this.controller}}get controller(){return this._controller??(this._controller=Fo(this.factoryHost))}writeLabelHeaderOnBiStream(e,t){return this.controller.writeLabelHeaderOnBiStream(e,t)}flushPendingHandshakesForNode(e,t){return this.controller.flushPendingHandshakesForNode(e,t)}flushPendingSignalsForNode(e,t){return this.controller.flushPendingSignalsForNode(e,t)}};var Wt=class{constructor(e,t){this.peerLifecycle=e;this.deps=t;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}watchPeerStates(e){return this.peerLifecycle.watch(e)}getPeerState(e){return this.peerLifecycle.get(e)}listConnectedPeers(){return this.peerLifecycle.listConnected()}isPeerPromotionEligible(e){return this.deps.resolvePromotionEligibility(e)}addPeerScope(e,t="persistent"){let n=this.deps.getWasmClient();return n&&typeof n.add_peer_scope=="function"?(n.add_peer_scope(e,t).then(()=>{this.disposed||this.deps.scheduleRefreshPeerSnapshot();}).catch(()=>{}),this.peerLifecycle.get(e)):this.peerLifecycle.addScope(e,t)}releasePeerScope(e,t){let n=this.deps.getWasmClient();return n&&typeof n.release_peer_scope=="function"?(n.release_peer_scope(e,t??null).then(()=>{this.disposed||this.deps.scheduleRefreshPeerSnapshot();}).catch(()=>{}),this.peerLifecycle.get(e)):this.peerLifecycle.releaseScope(e,t)}getPeerScopes(e){return this.peerLifecycle.get(e)?.scopes??[]}isSamePeer(e,t){let n=this.peerLifecycle.get(e),i=this.peerLifecycle.get(t);return n&&i?n.peerId===i.peerId:false}clearManualDisconnectProjection(e){let t=this.peerLifecycle.get(e);this.peerLifecycle.dispatch({type:"ManualDisconnectCleared",peerId:t?.peerId??e,deviceId:t?.deviceId??e,deviceIdHint:t?.deviceIdHint,nodeId:t?.nodeId,connectionId:t?.connectionId});}async disconnectPeer(e,t="persistent"){let n=this.peerLifecycle.releaseScope(e,t);n&&n.scopes.length>0||await this.forceDisconnectPeer(e);}async forceDisconnectPeer(e){let t=this.peerLifecycle.releaseScope(e),n=this.getPeerCandidates(t?.peerId||e);if(await Promise.allSettled(Array.from(n).map(async i=>{let o=Array.from(this.deps.getConnections()).filter(a=>{let c=a.id.trim().toLowerCase(),d=a.deviceId.trim().toLowerCase();return i===d||i===c||c.includes(i)});await Promise.allSettled(o.map(a=>a.disconnect()));let s=t?.nodeId||(o[0]?.deviceId??null);s&&i===s.trim().toLowerCase()&&await this.deps.disconnectNode(s).catch(()=>{});})),this.deps.hasRustPeerLifecycleProjection()){if(this.disposed)return;await this.deps.schedulePeerReconciliation("disconnect-node").catch(()=>{});}this.disposed||this.peerLifecycle.dispatch({type:"ManualDisconnect",peerId:t?.peerId??e,deviceId:t?.deviceId,deviceIdHint:t?.deviceIdHint,nodeId:t?.nodeId,connectionId:t?.connectionId});}async getPeerHealth(e){let t=this.peerLifecycle.get(e);return t?t.health:"unknown"}getPeerCandidates(e){let t=this.peerLifecycle.get(e),n=new Set;return [e,t?.peerId,t?.deviceId,t?.nodeId,t?.connectionId,...t?.connectionIds??[]].forEach(o=>{if(!o)return;let s=o.trim().toLowerCase();s&&n.add(s);}),n}};function fe(r){if(!r)return null;let e=r.trim();return e?e.toLowerCase():null}function Xn(r){return r.deviceId||r.deviceIdHint||r.peerId||null}function jt(r){return [...r].sort()}function ke(r,e){return r?r.peerId===e.peerId&&(r.deviceId??null)===(e.deviceId??null)&&(r.deviceIdHint??null)===(e.deviceIdHint??null)&&(r.nodeId??null)===(e.nodeId??null)&&(r.connectionId??null)===(e.connectionId??null)&&(r.ticket??null)===(e.ticket??null)&&!!r.online==!!e.online&&(r.deviceName??null)===(e.deviceName??null)&&(r.platformType??null)===(e.platformType??null)&&r.status===e.status&&!!r.logicalSessionTerminal==!!e.logicalSessionTerminal&&r.health===e.health&&(r.lifecycleStage??null)===(e.lifecycleStage??null)&&(r.generation??null)===(e.generation??null)&&(r.baseTransportState??null)===(e.baseTransportState??null)&&(r.admissionState??null)===(e.admissionState??null)&&(r.transportState??null)===(e.transportState??null)&&(r.protocolState??null)===(e.protocolState??null)&&!!r.routable==!!e.routable&&(r.transportStableId??null)===(e.transportStableId??null)&&(r.transportGeneration??null)===(e.transportGeneration??null)&&(r.routeGeneration??null)===(e.routeGeneration??null)&&(r.activeTransport??null)===(e.activeTransport??null)&&(r.fallbackTransport??null)===(e.fallbackTransport??null)&&(r.parallelTransport??null)===(e.parallelTransport??null)&&!!r.manualDisconnect==!!e.manualDisconnect&&(r.lastAuthoritativeEventAt??null)===(e.lastAuthoritativeEventAt??null)&&(r.lastTransientEventAt??null)===(e.lastTransientEventAt??null)&&(r.promotionEligible??true)===(e.promotionEligible??true)&&(r.error??null)===(e.error??null)&&JSON.stringify(jt(r.connectionIds))===JSON.stringify(jt(e.connectionIds))&&JSON.stringify(jt(r.scopes))===JSON.stringify(jt(e.scopes)):false}function Gt(r){return r==="closed"||r==="disconnected"||r==="failed"}function Zn(r){let{status:e,health:t,lifecycleStage:n,generation:i,baseTransportState:o,admissionState:s,transportState:a,protocolState:c,routable:d,logicalSessionTerminal:l,transportStableId:p,transportGeneration:u,routeGeneration:h,activeTransport:f,fallbackTransport:m,parallelTransport:v,connectionId:y,error:S,...C}=r;return C}function Uo(r){if(Gt(r.status))return "closed";let e=(r.transportState??"").trim().toLowerCase();return e==="connected"||r.connectionId||r.activeTransport?"connected":e==="connecting"||r.status==="connecting"?"connecting":e==="failed"||e==="degraded"?"degraded":"unknown"}function cs(r){if(r.manualDisconnect||Gt(r.status))return "closed";if(r.routable===true||r.protocolState==="routable")return "protocol-ready";if(r.admissionState==="admitted")return "admitted";let e=r.baseTransportState??Uo(r);return e==="connected"?"base-connected":e==="degraded"||r.health==="suspect"||r.health==="stale"?"degraded":r.status==="connecting"?"dialing":"discovered"}function ds(r){return Gt(r.status)?r.status:r.routable===true||r.protocolState==="routable"?"connected":r.status}function Ho(r){return {peerId:r.peerId,deviceId:r.deviceId??null,deviceIdHint:r.deviceIdHint??null,nodeId:r.nodeId??null,connectionId:r.connectionId??null,status:r.status,health:r.health,lifecycleStage:r.lifecycleStage??null,generation:r.generation??null,baseTransportState:r.baseTransportState??null,admissionState:r.admissionState??null,transportState:r.transportState??null,protocolState:r.protocolState??null,routable:r.routable??null,transportStableId:r.transportStableId??null,transportGeneration:r.transportGeneration??null,routeGeneration:r.routeGeneration??null,activeTransport:r.activeTransport??null,parallelTransport:r.parallelTransport??null,manualDisconnect:r.manualDisconnect??false,scopes:r.scopes,error:r.error??null}}function ls(r,e$1,t){let n={event:r,before:e$1?Ho(e$1):null,after:Ho(t)};e("[OpenRTC][projection]",n);}var qt=class{constructor(){this.peers=new Map;this.aliases=new Map;this.watchers=new Set;this.disposed=false;}resolveCanonicalPeerId(e){let t=[e.deviceId,e.deviceIdHint,e.nodeId,e.peerId,e.connectionId];for(let n of t){let i=fe(n);if(!i)continue;let o=this.aliases.get(i);if(o)return o}return Xn(e)}setAlias(e,t){let n=fe(e);n&&this.aliases.set(n,t);}snapshot(e){let t=e.baseTransportState??Uo(e),n=e.routable,i=e.protocolState;return {peerId:e.peerId,deviceId:e.deviceId,deviceIdHint:e.deviceIdHint,nodeId:e.nodeId,connectionId:e.connectionId,connectionIds:Array.from(e.connectionIds.values()),ticket:e.ticket,online:e.online,deviceName:e.deviceName,platformType:e.platformType,status:ds(e),health:e.health,lifecycleStage:e.lifecycleStage??cs(e),generation:e.generation??e.transportGeneration,baseTransportState:t,admissionState:e.admissionState,transportState:e.transportState,protocolState:i,settledReady:n===true,readinessState:n===true?"routable":i,readinessReason:n===true?"peer-projection-routable":e.error,routable:n,logicalSessionTerminal:e.logicalSessionTerminal===true,transportStableId:e.transportStableId,transportGeneration:e.transportGeneration,routeGeneration:e.routeGeneration,activeTransport:e.activeTransport,fallbackTransport:e.fallbackTransport,parallelTransport:e.parallelTransport,manualDisconnect:e.manualDisconnect,lastAuthoritativeEventAt:e.lastAuthoritativeEventAt,lastTransientEventAt:e.lastTransientEventAt,promotionEligible:e.promotionEligible,scopes:Array.from(e.scopes.values()),lastSeenAt:e.lastSeenAt,error:e.error}}emit(){if(this.disposed)return;let e=this.list();this.watchers.forEach(t=>t(e));}rekeyPeer(e,t){let n=this.peers.get(e);if(!n)throw new Error(`Cannot rekey missing peer ${e}`);if(e===t)return n;this.peers.delete(e),n.peerId=t,this.peers.set(t,n);for(let[i,o]of this.aliases.entries())o===e&&this.aliases.set(i,t);return n}upsert(e){let t=e,n=this.resolveCanonicalPeerId(t)??Xn(t);if(!n)throw new Error("Peer projection upsert requires a device-keyed identifier.");let i=Xn(t)??n,o=this.peers.get(n),s=!!o;o||(o={peerId:n,connectionIds:new Set,status:t.status??"disconnected",health:t.health??"unknown",scopes:new Set},this.peers.set(n,o));let a=s?this.snapshot(o):void 0;if(i!==o.peerId){let f=t.deviceId||o.deviceId||t.deviceIdHint||o.deviceIdHint||t.nodeId||o.nodeId||o.peerId;f&&f!==o.peerId&&(o=this.rekeyPeer(o.peerId,f));}s&&typeof t.transportGeneration=="number"&&typeof o.transportGeneration=="number"&&t.transportGeneration<o.transportGeneration&&t.manualDisconnect!==true&&(t=Zn(t)),s&&typeof t.routeGeneration=="number"&&typeof o.routeGeneration=="number"&&(typeof t.transportGeneration!="number"||typeof o.transportGeneration!="number"||t.transportGeneration===o.transportGeneration)&&t.routeGeneration<o.routeGeneration&&t.manualDisconnect!==true&&(t=Zn(t)),t.logicalSessionTerminal===true&&t.connectionId!==void 0&&o.connectionId!==void 0&&t.connectionId!==o.connectionId&&t.manualDisconnect!==true&&(t=Zn(t)),t.deviceId&&(o.deviceId=t.deviceId),t.deviceIdHint!==void 0&&(o.deviceIdHint=t.deviceIdHint),t.nodeId&&(o.nodeId=t.nodeId);let c=t.connectionId!==void 0&&o.connectionId!==void 0&&t.connectionId!==o.connectionId||t.transportGeneration!==void 0&&o.transportGeneration!==void 0&&t.transportGeneration>o.transportGeneration||t.transportStableId!==void 0&&t.transportStableId!==null&&o.transportStableId!==void 0&&o.transportStableId!==null&&t.transportStableId!==o.transportStableId,d=t.routable===true||t.protocolState==="routable";c&&(o.generation=void 0,o.lifecycleStage=void 0,o.fallbackTransport=null,o.parallelTransport=null),t.connectionId&&(o.connectionId=t.connectionId,o.connectionIds.add(t.connectionId)),t.ticket!==void 0&&(o.ticket=t.ticket),t.online!==void 0&&(o.online=t.online),t.deviceName!==void 0&&(o.deviceName=t.deviceName),t.platformType!==void 0&&(o.platformType=t.platformType);let l=s&&(o.manualDisconnect===true||Gt(o.status)&&typeof o.error=="string"&&o.error.toLowerCase().includes("manual disconnect")),p=t.status==="connected"||t.status==="connecting"||t.routable===true||t.protocolState==="routable"||t.transportState==="connected"||t.activeTransport!==void 0||t.parallelTransport!==void 0;if(l&&p){let f=this.snapshot(o);return ke(a,f)||this.emit(),f}if(p&&(o.lifecycleStage==="closed"&&t.lifecycleStage===void 0&&(o.lifecycleStage=void 0),o.baseTransportState==="closed"&&t.baseTransportState===void 0&&(o.baseTransportState=void 0),o.transportState==="closed"&&t.transportState===void 0&&(o.transportState=void 0),o.protocolState==="closed"&&t.protocolState===void 0&&(o.protocolState=void 0)),t.status&&(o.status=t.status),t.health&&(o.health=t.health),t.lifecycleStage!==void 0&&(o.lifecycleStage=t.lifecycleStage),t.generation!==void 0&&(o.generation=t.generation),t.baseTransportState!==void 0&&(o.baseTransportState=t.baseTransportState),t.admissionState!==void 0&&(o.admissionState=t.admissionState),t.transportState!==void 0&&(o.transportState=t.transportState),t.protocolState!==void 0&&(o.protocolState=t.protocolState),t.routable!==void 0&&(o.routable=t.routable),t.logicalSessionTerminal!==void 0&&(o.logicalSessionTerminal=t.logicalSessionTerminal),t.transportStableId!==void 0&&(o.transportStableId=t.transportStableId),t.transportGeneration!==void 0&&(o.transportGeneration=t.transportGeneration),t.routeGeneration!==void 0&&(o.routeGeneration=t.routeGeneration),t.activeTransport!==void 0&&(o.activeTransport=t.activeTransport),t.fallbackTransport!==void 0&&(o.fallbackTransport=t.fallbackTransport),t.parallelTransport!==void 0&&(o.parallelTransport=t.parallelTransport),t.manualDisconnect!==void 0&&(o.manualDisconnect=t.manualDisconnect),t.lastAuthoritativeEventAt!==void 0&&(o.lastAuthoritativeEventAt=t.lastAuthoritativeEventAt),t.lastTransientEventAt!==void 0&&(o.lastTransientEventAt=t.lastTransientEventAt),t.promotionEligible!==void 0&&(o.promotionEligible=t.promotionEligible),(t.transportState!==void 0||t.transportStableId!==void 0||t.activeTransport!==void 0||t.parallelTransport!==void 0)&&!d&&(o.routable=false,o.protocolState==="routable"&&(o.protocolState=o.transportState==="connected"?"transport-only":o.transportState)),t.clearError?(o.error=void 0,t.manualDisconnect!==true&&(o.manualDisconnect=false)):t.error!==void 0&&(o.error=t.error,t.error.toLowerCase().includes("manual disconnect")&&(o.manualDisconnect=true)),t.lastSeenAt!==void 0&&(o.lastSeenAt=t.lastSeenAt),t.scopes)for(let f of t.scopes)o.scopes.add(f);(o.status==="closed"||o.status==="failed"||o.status==="disconnected")&&(o.routable=false,o.transportStableId=null,o.activeTransport=void 0,o.fallbackTransport=null,o.parallelTransport=null,o.baseTransportState="closed",o.lifecycleStage="closed",(!o.transportState||o.transportState==="connected")&&(o.transportState="closed"),(!o.protocolState||o.protocolState==="routable")&&(o.protocolState="closed")),this.setAlias(o.peerId,o.peerId),this.setAlias(o.deviceId,o.peerId),this.setAlias(o.deviceIdHint,o.peerId),this.setAlias(o.nodeId,o.peerId),this.setAlias(o.connectionId,o.peerId);for(let f of o.connectionIds)this.setAlias(f,o.peerId);let h=this.snapshot(o);return ke(a,h)||(ls(s?"upsert":"create",a??null,h),this.emit()),h}dispatch(e){let t={peerId:e.peerId,deviceId:e.deviceId,deviceIdHint:e.deviceIdHint,nodeId:e.nodeId,connectionId:e.connectionId};switch(e.type){case "ConnectionStateProjected":{let{type:n,...i}=e;return this.upsert(i)}case "ManualDisconnectCleared":return this.upsert({...t,status:"disconnected",health:"unknown",manualDisconnect:false,clearError:true,lastSeenAt:Date.now()});case "RosterDeviceDiscovered":return this.upsert({...t,deviceName:e.deviceName,platformType:e.platformType,ticket:e.ticket,online:e.online??true,scopes:e.scopes,lastSeenAt:e.lastSeenAt??Date.now()});case "PresenceOnline":return this.upsert({...t,online:true,lastSeenAt:e.lastSeenAt??Date.now()});case "PresenceOffline":return this.upsert({...t,online:false});case "DialStarted":return this.get(this.targetLookupId(t))?.status==="connected"?this.get(this.targetLookupId(t)):this.upsert({...t,status:"connecting"});case "BaseTransportConnected":return this.upsert({...t,status:this.get(this.targetLookupId(t))?.status==="connected"?void 0:"connecting",transportState:"connected",baseTransportState:"connected",transportGeneration:e.transportGeneration});case "AdmissionAccepted":return this.upsert({...t,admissionState:"admitted"});case "AdmissionRejected":return this.upsert({...t,admissionState:"rejected",error:e.reason});case "ControlPathClosed":return this.upsert({...t,status:"disconnected"});case "HealthObserved":return this.updateHealth(this.targetLookupId(t),e.health);case "ManualDisconnect":return this.upsert({...t,status:"closed",health:"stale",manualDisconnect:true,error:"manual disconnect"});case "ExplicitUnshare":return this.upsert({...t,status:"closed",manualDisconnect:true,error:"explicit unshare"})}}targetLookupId(e){return e.deviceId||e.deviceIdHint||e.peerId||e.nodeId||e.connectionId||""}upsertDevice(e){return this.upsert({deviceId:e.deviceId,nodeId:e.nodeId,ticket:e.ticket,online:e.online,deviceName:e.deviceName,platformType:e.platformType,lastSeenAt:typeof e.updatedAt=="number"?e.updatedAt:typeof e.lastSeenAt=="number"?e.lastSeenAt:Date.now()})}watch(e){return this.disposed?()=>{}:(this.watchers.add(e),e(this.list()),()=>{this.watchers.delete(e);})}dispose(){this.disposed=true,this.watchers.clear();}get(e){let t=fe(e),n=t?this.aliases.get(t):void 0,i=n&&this.peers.get(n)||this.peers.get(e);return i?this.snapshot(i):void 0}list(){return Array.from(this.peers.values()).map(e=>this.snapshot(e)).sort((e,t)=>{let n=e.lastSeenAt??0,i=t.lastSeenAt??0;return n!==i?i-n:e.peerId.localeCompare(t.peerId)})}listConnected(){return this.list().filter(e=>e.status==="connected")}addScope(e,t="persistent"){let n=this.resolveRecord(e);if(!n)return;let i=this.snapshot(n);n.scopes.add(t);let o=this.snapshot(n);return ke(i,o)||this.emit(),o}releaseScope(e,t){let n=this.resolveRecord(e);if(!n)return;let i=this.snapshot(n);t?n.scopes.delete(t):n.scopes.clear();let o=this.snapshot(n);return ke(i,o)||this.emit(),o}hasScopes(e){return (this.resolveRecord(e)?.scopes.size??0)>0}removeConnection(e){let t=this.resolveRecord(e);if(!t)return;let n=this.snapshot(t),i=fe(e);if(i){let s=Array.from(t.connectionIds).find(a=>fe(a)===i);s&&t.connectionIds.delete(s);}t.connectionId&&fe(t.connectionId)===i&&(t.connectionId=Array.from(t.connectionIds)[0]),t.connectionIds.size===0&&t.status==="connected"&&(t.status="closed",t.routable=false,t.transportState="closed",t.protocolState="closed");let o=this.snapshot(t);return ke(n,o)||this.emit(),o}updateHealth(e,t,n){let i=this.resolveRecord(e);if(!i)return;let o=this.snapshot(i);i.health=t,n&&(i.status=n),i.lastSeenAt=Date.now();let s=this.snapshot(i);return ke(o,s)||this.emit(),s}resolveRecord(e){let t=fe(e),n=t?this.aliases.get(t):void 0;return n&&this.peers.get(n)||this.peers.get(e)}};function Wo(r){return r.settledReady?"routable":r.hasActiveConnection?"transport-only":r.rustStatusIsConnecting?"connecting":"closed"}function jo(r){return r.hasActiveConnection?"connected":r.rustStatusIsConnecting?"connecting":r.mappedStatusIsTerminal?"closed":"unknown"}function ps(r){return r.isClosed?"closed":"connected"}function qo(r){let{connection:e,trustProjection:t,existingProjection:n,terminalTransportClose:i}=r;if(i){let c=n?.peerId??r.peerId??r.deviceId??r.deviceIdHint??e.id;return !c&&!r.deviceId&&!r.deviceIdHint?null:{event:{type:"ConnectionStateProjected",peerId:c,deviceId:n?.deviceId??r.deviceId,deviceIdHint:n?.deviceIdHint??r.deviceIdHint,nodeId:n?.nodeId??e.deviceId,connectionId:e.id,status:"closed",health:"stale",baseTransportState:"closed",transportState:"closed",protocolState:"closed",routable:false,promotionEligible:r.promotionEligible,lastSeenAt:Date.now()}}}if(t)return {event:{type:"ConnectionStateProjected",peerId:t.deviceId??e.remoteNodeId??e.id,deviceId:t.deviceId??void 0,deviceIdHint:t.deviceId??e.remoteNodeId??void 0,nodeId:e.remoteNodeId||e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:t.health,transportState:ps(e),activeTransport:e.getTransportStatus().activeTransport,protocolState:t.protocolState,routable:t.routable,promotionEligible:r.promotionEligible,error:t.error,lastSeenAt:Date.now()}};if(r.peerId||r.deviceId)return {event:{type:"ConnectionStateProjected",peerId:r.peerId??r.deviceId??e.remoteNodeId??e.id,deviceId:r.deviceId,nodeId:e.deviceId,connectionId:e.id,ticket:r.ticket,status:e.isClosed?"closed":"connected",health:"healthy",activeTransport:e.getTransportStatus().activeTransport,promotionEligible:r.promotionEligible,scopes:r.scopes,lastSeenAt:Date.now()}};let o=n?.peerId||n?.deviceId||n?.deviceIdHint,s=n?.deviceId,a=n?.deviceIdHint;return !o&&!s&&!a?null:{event:{type:"ConnectionStateProjected",peerId:o,deviceId:s,deviceIdHint:a,nodeId:e.deviceId,connectionId:e.id,status:e.isClosed?"closed":"connected",health:e.isClosed?"stale":"healthy",activeTransport:e.getTransportStatus().activeTransport,promotionEligible:r.promotionEligible,lastSeenAt:Date.now()}}}function Go(r,e){let t=r.activeConnectionId||r.candidates?.[0]||void 0,n=e.mapRustPeerStatus(r.status);String(n).trim().toLowerCase();let s=typeof r.readinessState=="string"&&r.readinessState.trim().length>0?r.readinessState==="routable":!!r.settledReady,a=e.mapRustPeerHealth(r.health),c=e.localTerminalClosed===true&&!!t,d=s,l=e.applicationRouteFailed&&!d,p=c?d:e.trustProjection?e.trustProjection.routable&&s:s,u=r.status==="connecting",h=Wo({settledReady:p,hasActiveConnection:!!t,rustStatusIsConnecting:u}),f=p,m=h;return {event:{type:"ConnectionStateProjected",peerId:r.peerId??e.transientPeerId??e.anonymousSpacePeerId,deviceId:e.trustProjection?.deviceId??r.deviceId??void 0,deviceIdHint:r.deviceIdHint,nodeId:r.nodeId,connectionId:t,status:c&&!d?"closed":l?"failed":f?"connected":n,health:c&&!d||l?"stale":e.trustProjection?.health??a,generation:r.transportGeneration,baseTransportState:c&&!d?"closed":jo({hasActiveConnection:!!t,rustStatusIsConnecting:u,mappedStatusIsTerminal:n==="closed"||n==="failed"||n==="disconnected"}),admissionState:c&&!d?"unknown":p||t?"admitted":"unknown",transportState:c&&!d?"closed":t?"connected":r.status==="connecting"?"connecting":"closed",protocolState:c&&!d?"closed":m,routable:f,logicalSessionTerminal:r.logicalSessionTerminal===true,transportStableId:c&&!d?void 0:r.transportStableId??void 0,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration,activeTransport:c&&!d?void 0:r.activeTransport,fallbackTransport:c&&!d?void 0:r.parallelTransport??null,parallelTransport:c&&!d?void 0:r.parallelTransport??null,promotionEligible:e.promotionEligible,scopes:e.sessionScopes,error:c&&!d?"local-transport-closed":l?"application-route-timeout":e.trustProjection?.error??(f?void 0:r.error??void 0),clearError:f,lastSeenAt:r.lastSeenAtMs}}}function us(r){return !(!r.projectedDeviceId&&!r.projectedDeviceIdHint&&!r.existingProjection&&!r.anonymousTerminalProjectionAllowed&&!r.localTerminalClosed)}function Ko(r,e){if(!us(e))return null;let t=e.localTerminalClosed===true,n=p(r.activeTransport)?r.routable===true:e.liveConnection?e.applicationRouteReady:r.routable===true,i=r.routable===true&&n&&!e.terminalState,o=t&&!i,s=e.terminalState||o,a=s?false:e.trustProjection?e.trustProjection.routable:r.routable,c=a&&n,d=o?"closed":e.terminalState?r.protocolState??"closed":c?"routable":r.transportState==="connected"?"transport-only":e.trustProjection?.protocolState??r.protocolState,l=s?o?"local-transport-closed":r.error??r.lastDisconnectReason??e.trustProjection?.error:e.trustProjection?.error??r.error,p$1=s?"stale":e.trustProjection?.health??(c||r.transportState==="connected"?"healthy":r.state==="failed"||r.state==="closed"?"stale":"unknown");return {event:{type:"ConnectionStateProjected",peerId:e.existingProjection?.peerId??(e.anonymousTerminalProjectionAllowed?r.remoteNodeId??r.connectionId:void 0),deviceId:e.projectedDeviceId,deviceIdHint:e.projectedDeviceIdHint,nodeId:r.remoteNodeId??e.existingProjection?.nodeId??void 0,connectionId:r.connectionId,status:o?"closed":r.state==="connected"?"connected":r.state==="connecting"||r.state==="new"?"connecting":r.state==="failed"?"failed":r.state==="closed"?"closed":"disconnected",health:p$1,generation:r.transportGeneration,baseTransportState:s?"closed":r.transportState==="connected"?"connected":r.transportState==="connecting"||r.state==="connecting"||r.state==="new"?"connecting":r.transportState==="failed"?"degraded":"unknown",admissionState:a||r.readinessState==="routable"?"admitted":s?"unknown":"pending",transportState:o?"closed":r.transportState,protocolState:d,routable:c,logicalSessionTerminal:r.logicalSessionTerminal===true,transportStableId:o?void 0:r.transportStableId??void 0,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration,activeTransport:o?void 0:r.activeTransport,fallbackTransport:o?void 0:r.parallelTransport??null,parallelTransport:o?void 0:r.parallelTransport??null,error:l,lastAuthoritativeEventAt:r.updatedAt??Date.now(),lastSeenAt:r.updatedAt??Date.now()}}}var ei=2e3,ti=3e3,Kt=class{constructor(e=ei,t=ti){this.tsGraceMs=e;this.rustGraceMs=t;this.tsOrphanSince=new Map;this.rustOrphanSince=new Map;this.reportedRustOrphans=new Set;}evaluateTsOrphans(e,t){let n=new Set(e);for(let o of [...this.tsOrphanSince.keys()])n.has(o)||this.tsOrphanSince.delete(o);for(let o of n)this.tsOrphanSince.has(o)||this.tsOrphanSince.set(o,t);let i=[];for(let o of n){let s=this.tsOrphanSince.get(o);s!==void 0&&t-s>=this.tsGraceMs&&i.push(o);}return {toDisconnect:i}}evaluateRustOrphans(e,t){let n=new Set(e);for(let o of [...this.rustOrphanSince.keys()])n.has(o)||(this.rustOrphanSince.delete(o),this.reportedRustOrphans.delete(o));for(let o of n)this.rustOrphanSince.has(o)||this.rustOrphanSince.set(o,t);let i=[];for(let o of n){let s=this.rustOrphanSince.get(o);s!==void 0&&t-s>=this.rustGraceMs&&!this.reportedRustOrphans.has(o)&&(this.reportedRustOrphans.add(o),i.push(o));}return {toReport:i}}clear(){this.tsOrphanSince.clear(),this.rustOrphanSince.clear(),this.reportedRustOrphans.clear();}};function zo(r){let e=String(r??"").trim().toLowerCase();return e==="connected"||e==="connecting"||e==="new"}function gs(r){let e=String(r.state??"").trim().toLowerCase();return e==="connected"||e==="connecting"||e==="new"}function ni(r){return r.activeConnectionId||r.candidates?.[0]||void 0}function hs(r,e,t){return e.some(i=>ni(i)===r&&zo(i.status))?true:t.some(i=>i.connectionId===r&&gs(i))}function ms(r,e){return r.routable===true&&(r.connectionId===e||r.connectionIds.includes(e))}function vs(r){let e=[],t=[];if(r.hasRustProjection)for(let[n,i]of r.connections)i.isClosed||hs(n,r.rustSessions,r.backendStates)||e.push(n);for(let n of r.rustSessions){let i=ni(n);if(!i||!zo(n.status)||!(n.settledReady===true||n.readinessState==="routable"||r.peerStates.some(a=>ms(a,i))))continue;let s=r.connections.get(i);(!s||s.isClosed)&&t.push(i);}return {orphanTsConnectionIds:e,orphanRustRecordConnectionIds:t}}function fs(r,e,t,n=Date.now()){if(!r.hasRustPeerLifecycleProjection())return t.clear(),{reportedDrift:{orphanTsConnectionIds:[],orphanRustRecordConnectionIds:[]},closedTsConnectionIds:[]};t.evaluateTsOrphans(e.orphanTsConnectionIds,n);let{toReport:i}=t.evaluateRustOrphans(e.orphanRustRecordConnectionIds,n);return {reportedDrift:{orphanTsConnectionIds:e.orphanTsConnectionIds,orphanRustRecordConnectionIds:i},closedTsConnectionIds:[]}}var zt=class{constructor(e){this.run=e;this.inFlight=null;this.queuedReason=null;this.disposed=false;this.stats={scheduled:0,coalesced:0,ran:0,orphanTsConnection:0,orphanRustRecord:0,orphanTsConnectionHealed:0};}getStats(){return this.stats}dispose(){this.disposed=true,this.queuedReason=null;}recordDrift(e){e.orphanTsConnectionIds.length>0&&(this.stats.orphanTsConnection+=e.orphanTsConnectionIds.length,d$2("[Client][PEER-RECONCILE] orphan_ts_connection",{count:e.orphanTsConnectionIds.length,connectionIds:e.orphanTsConnectionIds})),e.orphanRustRecordConnectionIds.length>0&&(this.stats.orphanRustRecord+=e.orphanRustRecordConnectionIds.length,d$2("[Client][PEER-RECONCILE] orphan_rust_record",{count:e.orphanRustRecordConnectionIds.length,connectionIds:e.orphanRustRecordConnectionIds}));}recordSelfHeal(e){e.closedTsConnectionIds.length>0&&(this.stats.orphanTsConnectionHealed+=e.closedTsConnectionIds.length,d$2("[Client][PEER-RECONCILE] orphan_ts_connection_healed",{count:e.closedTsConnectionIds.length,connectionIds:e.closedTsConnectionIds})),this.recordDrift(e.reportedDrift);}schedule(e){return this.disposed?Promise.resolve([]):(this.stats.scheduled+=1,this.inFlight?(this.stats.coalesced+=1,this.queuedReason=e,d$2("[Client][PEER-RECONCILE] coalesced",{reason:e}),this.inFlight):(d$2("[Client][PEER-RECONCILE] started",{reason:e}),this.inFlight=this.executeRun(e),this.inFlight))}async executeRun(e){let t=e;try{for(;;){this.stats.ran+=1;let n=await this.run(t);d$2("[Client][PEER-RECONCILE] finished",{reason:t,stats:this.getStats()});let i=this.queuedReason;if(this.queuedReason=null,this.disposed)return [];if(!i)return n;t=i,d$2("[Client][PEER-RECONCILE] rerun",{reason:t});}}finally{this.inFlight=null;}}};async function Vo(r,e){let t=r.hasRustPeerLifecycleProjection(),n=false,i=[];if(r.wasmClient&&typeof r.wasmClient.peer_sessions=="function"){let l=await r.wasmClient.peer_sessions();if(Array.isArray(l)){i=l;for(let p of l){let u=ni(p);if(!r.hasResolvablePeerIdentity({deviceId:p.deviceId,deviceIdHint:p.deviceIdHint,nodeId:p.nodeId,connectionId:u})){d$2("[Client][PEER-SNAPSHOT] skipping rust session without identity",{status:p.status,health:p.health,settledReady:p.settledReady});continue}r.applyComposedRustSession(p),n=true;}}}(await r.searchDevices().catch(()=>[])).forEach(l=>{if(!r.hasResolvablePeerIdentity({deviceId:l.deviceId??null,nodeId:l.nodeId??null})){d$2("[Client][PEER-SNAPSHOT] skipping device projection without identity",{deviceName:l.deviceName??null,online:l.online??null});return}r.peerLifecycle.upsertDevice(l);}),t||r.connections.forEach(l=>{r.syncConnectionPeerLifecycle(l);});let s=await r.signaling.getConnectionStates().catch(()=>[]);s.forEach(l=>{r.applyBackendConnectionState(l);});let a=r.peerLifecycle.list(),c=vs({hasRustProjection:t,connections:r.connections,rustSessions:i,backendStates:s,peerStates:a}),d=r.getOrphanDriftTracker?.();if(d){let l=fs(r,c,d);r.recordReconciliationSelfHeal?.(l);}else r.recordReconciliationDrift?.(c);return t&&!n&&s.length===0,a}function ii(r,e){return r&&typeof r.supportsRustPeerLifecycleProjection=="function"&&r.supportsRustPeerLifecycleProjection()?true:!!(e&&typeof e.peer_sessions=="function")}var Vt=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.orphanDriftTracker=new Kt(t.orphanReconciliationGrace?.tsConnectionMs??ei,t.orphanReconciliationGrace?.rustRecordMs??ti),this.scheduler=new zt(n=>Vo(this.asReconciliationHost())),this.ctx.registerDisposer(()=>this.dispose());}schedule(e){return this.scheduler.schedule(e)}dispose(){this.disposed=true,this.scheduler.dispose(),this.orphanDriftTracker.clear();}getStats(){return this.scheduler.getStats()}hasRustPeerLifecycleProjection(){return ii(this.deps.getSignaling(),this.getPeerSessionReader())}dispatchLiveConnectionProjection(e,t){if(this.disposed)return;let n=qo({connection:e,...t});n&&this.dispatchComposedConnectionState(n.event);}applyConnectionTrustProjection(e){if(this.disposed||this.hasRustPeerLifecycleProjection())return;let t=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.deps.getConnectionTrustProjection({connectionId:e.id,nodeId:e.remoteNodeId}),i=this.deps.hasApplicationRouteForConnection(e);if(!n){this.syncConnectionPeerLifecycle(e);return}this.dispatchLiveConnectionProjection(e,{trustProjection:n,promotionEligible:t,applicationRouteReady:i});}applyBackendConnectionState(e){if(this.disposed||!e?.connectionId)return;let t=this.deps.getConnectionTrustProjection({connectionId:e.connectionId,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.remoteNodeId??void 0}),n=this.getPeerState(e.connectionId)??(e.remoteNodeId?this.getPeerState(e.remoteNodeId):void 0),i=e.deviceId??t?.deviceId??n?.deviceId??void 0,o=e.deviceIdHint??n?.deviceIdHint??void 0,s=e.state==="closed"||e.state==="failed"||e.state==="disconnected",a=this.deps.hasLocalTerminalConnectionClose(e.connectionId),c=(s||a)&&!!(e.connectionId||e.remoteNodeId);if(!i&&!o&&!n&&!c)return;d$2("[Client] applyBackendConnectionState",{connectionId:e.connectionId,deviceId:i??null,deviceIdHint:o??null,remoteNodeId:e.remoteNodeId??null,state:e.state,transportState:e.transportState??null,protocolState:e.protocolState??null,routable:e.routable??null,updatedAt:e.updatedAt??null,error:e.error??null,mappedPeerId:n?.peerId??null});let d=this.ctx.registry.get(e.connectionId)??(e.remoteNodeId?this.deps.getConnectionForPeer(void 0,e.remoteNodeId):null),l=this.deps.hasApplicationRouteForConnection(d),p=Ko(e,{trustProjection:t,existingProjection:n,liveConnection:d,applicationRouteReady:l,terminalState:s,localTerminalClosed:a,anonymousTerminalProjectionAllowed:c,projectedDeviceId:i,projectedDeviceIdHint:o});p&&this.dispatchComposedConnectionState(p.event);}applyComposedRustSession(e){if(this.disposed)return;let t=e.activeConnectionId||e.candidates?.[0],n=this.deps.hasLocalTerminalConnectionClose(t),i=e.scopes??[],o=!!e.nodeId&&this.deps.sessionTokenApprovedNodes().has(e.nodeId)||!!t&&this.deps.sessionTokenApprovedConnectionIds().has(t),s=!e.peerId&&!e.deviceId&&!e.deviceIdHint&&o?`session-token:${i[0]??"unscoped"}:${e.nodeId??t}`:void 0,a=!e.peerId&&!e.deviceId&&!e.deviceIdHint&&this.ctx.discoveryMode==="space"?e.nodeId??t:void 0,c=this.deps.resolvePromotionEligibility({connectionId:t||void 0,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.nodeId??void 0}),d=this.deps.getConnectionTrustProjection({connectionId:t||void 0,deviceId:e.deviceId??void 0,deviceIdHint:e.deviceIdHint??void 0,nodeId:e.nodeId??void 0}),l=this.deps.getConnectionForPeer(t||void 0,e.nodeId??void 0),p=this.deps.hasApplicationRouteForConnection(l),u=Go(e,{trustProjection:d,promotionEligible:c,liveConnection:l,applicationRouteReady:p,applicationRouteFailed:false,localTerminalClosed:n,mapRustPeerStatus:h=>this.mapRustPeerStatus(h),mapRustPeerHealth:h=>this.mapRustPeerHealth(h),peerId:e.peerId,transientPeerId:s,anonymousSpacePeerId:a,sessionScopes:i});this.dispatchComposedConnectionState(u.event);}syncConnectionPeerLifecycle(e){if(this.disposed)return;let t=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId}),n=this.getPeerState(e.id)||this.listPeerStates().find(i=>i.connectionIds.includes(e.id)||i.nodeId===e.deviceId);this.dispatchLiveConnectionProjection(e,{trustProjection:null,promotionEligible:t,existingProjection:n,applicationRouteReady:this.deps.hasApplicationRouteForConnection(e)});}mapRustPeerStatus(e){switch((e||"").toLowerCase()){case "connected":return "connected";case "connecting":case "pending":return "connecting";case "failed":return "failed";case "closing":case "closed":return "closed";default:return "disconnected"}}mapRustPeerHealth(e){switch((e||"").toLowerCase()){case "healthy":return "healthy";case "suspect":return "suspect";case "stale":return "stale";default:return "unknown"}}asReconciliationHost(){return {hasRustPeerLifecycleProjection:()=>this.hasRustPeerLifecycleProjection(),wasmClient:this.getPeerSessionReader(),signaling:this.deps.getSignaling(),peerLifecycle:this.deps.peerLifecycle,connections:this.ctx.registry,discoveryMode:this.ctx.discoveryMode,sessionTokenApprovedNodes:this.deps.sessionTokenApprovedNodes(),sessionTokenApprovedConnectionIds:this.deps.sessionTokenApprovedConnectionIds(),hasResolvablePeerIdentity:e=>this.hasResolvablePeerIdentity(e),applyComposedRustSession:e=>this.applyComposedRustSession(e),applyBackendConnectionState:e=>this.applyBackendConnectionState(e),searchDevices:()=>this.deps.searchDevices(),syncConnectionPeerLifecycle:e=>this.syncConnectionPeerLifecycle(e),getOrphanDriftTracker:()=>this.orphanDriftTracker,recordReconciliationSelfHeal:e=>this.scheduler.recordSelfHeal(e),recordReconciliationDrift:e=>this.scheduler.recordDrift(e)}}getPeerSessionReader(){return this.ctx.wasmClient&&typeof this.ctx.wasmClient=="object"?this.ctx.wasmClient:null}hasResolvablePeerIdentity(e){if(e.deviceId||e.deviceIdHint)return true;let t=[e.nodeId,e.connectionId].map(o=>typeof o=="string"?o.trim():"").filter(o=>o.length>0);if(this.ctx.discoveryMode==="space"&&t.length>0)return true;let n=this.deps.sessionTokenApprovedNodes(),i=this.deps.sessionTokenApprovedConnectionIds();return t.some(o=>!!this.getPeerState(o)||n.has(o)||i.has(o))}dispatchComposedConnectionState(e){let t=this.deps.peerLifecycle.dispatch(e);if(e.logicalSessionTerminal===true&&t?.logicalSessionTerminal===true&&t.status==="closed"&&!t.routable&&!t.settledReady)for(let n of t.connectionIds)this.deps.forgetAnnouncedConnection(n);}getPeerState(e){let t=this.deps.peerLifecycle;return typeof t.get=="function"?t.get(e):void 0}listPeerStates(){let e=this.deps.peerLifecycle;return typeof e.list=="function"?e.list():[]}};function $o(r){return new oi({getContext:()=>r.getClientContext(),getWasmClient:()=>r.wasmClient,getSignaling:()=>r.signaling,getConnections:()=>r.registry.values(),disconnectNode:e=>r.runtimeConnections.disconnectNode(e),registerDisposer:e=>r.lifecycleScope.register(e),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),getOrphanReconciliationGrace:()=>r.options?.orphanReconciliationGrace,getSessionTokenApprovedNodes:()=>r.sessionTokens.getApprovedNodes(),getSessionTokenApprovedConnectionIds:()=>r.sessionTokens.getApprovedConnectionIds(),resolvePromotionEligibility:e=>r.connectionChannelPolicy.resolvePromotionEligibility(e),getConnectionTrustProjection:e=>r.connectionTrust.getProjection(e),getConnectionForPeer:(e,t)=>r.registry.getForPeer(e??void 0,t??void 0),hasApplicationRouteForConnection:e=>r.transportServices.hasApplicationRouteForConnectionSnapshot(e,e?.id,e?.remoteNodeId),isApplicationRouteReadyForConnection:e=>r.transportServices.isApplicationRouteReady(e),hasLocalTerminalConnectionClose:e=>r.registry.hasLocalTerminalClose(e),searchDevices:()=>r.deviceDirectory.searchDevices(),healOrphanTsConnection:e=>r.connectionLifecycle.healOrphanTsConnection(e),forgetAnnouncedConnection:e=>r.connectionLifecycle.forgetAnnouncedConnection(e)})}var oi=class{constructor(e){this.host=e;this.store=new qt;this.host.registerDisposer(()=>{this.store.dispose();});}get projection(){return this._projection||(this._projection=new Vt(this.host.getContext(),{orphanReconciliationGrace:this.host.getOrphanReconciliationGrace(),sessionTokenApprovedNodes:()=>this.host.getSessionTokenApprovedNodes(),sessionTokenApprovedConnectionIds:()=>this.host.getSessionTokenApprovedConnectionIds(),resolvePromotionEligibility:e=>this.host.resolvePromotionEligibility(e),getConnectionTrustProjection:e=>this.host.getConnectionTrustProjection(e),getConnectionForPeer:(e,t)=>this.host.getConnectionForPeer(e,t),hasApplicationRouteForConnection:e=>this.host.hasApplicationRouteForConnection(e),isApplicationRouteReadyForConnection:e=>this.host.isApplicationRouteReadyForConnection(e),hasLocalTerminalConnectionClose:e=>this.host.hasLocalTerminalConnectionClose(e),searchDevices:()=>this.host.searchDevices(),healOrphanTsConnection:e=>this.host.healOrphanTsConnection(e),forgetAnnouncedConnection:e=>this.host.forgetAnnouncedConnection(e),getSignaling:()=>this.host.getSignaling(),peerLifecycle:this.store})),this._projection}get client(){return this._client||(this._client=new Wt(this.store,{getWasmClient:()=>this.host.getWasmClient(),getConnections:()=>this.host.getConnections(),disconnectNode:e=>this.host.disconnectNode(e),hasRustPeerLifecycleProjection:()=>this.host.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>this.projection.schedule(e),scheduleRefreshPeerSnapshot:()=>this.projection.schedule("peer-lifecycle-client").then(()=>{}),registerDisposer:e=>this.host.registerDisposer(e),resolvePromotionEligibility:e=>this.host.resolvePromotionEligibility(e)})),this._client}getProjectionStats(){return this._projection?.getStats()}watchPeerStates(e){return this.store.watch?.(e)??(()=>{})}getPeerState(e){return this.store.get?.(e)}listConnectedPeers(){return this.store.listConnected?.()??[]}listPeerStates(){return this.store.list?.()??[]}getPeerScopes(e){return this.getPeerState(e)?.scopes??[]}getPeerStatus(e){return this.getPeerState(e)?.status}hasPeerScopes(e){return this.store.hasScopes?.(e)??this.getPeerScopes(e).length>0}isSamePeer(e,t){let n=this.getPeerState(e),i=this.getPeerState(t);return !!n&&!!i&&n.peerId===i.peerId}getPeerHealth(e){return this.getPeerState(e)?.health??"unknown"}isPeerPromotionEligible(e){return this.client.isPeerPromotionEligible(e)}addPeerScope(e,t="persistent"){return this.client.addPeerScope(e,t)}releasePeerScope(e,t){return this.client.releasePeerScope(e,t)}clearManualDisconnectProjection(e){this.client.clearManualDisconnectProjection(e);}disconnectPeer(e,t="persistent"){return this.client.disconnectPeer(e,t)}forceDisconnectPeer(e){return this.client.forceDisconnectPeer(e)}applyDiscoveredDevice(e){this.store.upsertDevice?.(e);}};function ys(r){return to({get wasmClient(){return r.getWasmClient()},get roomCreationMode(){return r.getRoomCreationMode()},get appLimits(){return r.getAppLimits()},ensureAuthenticated:e=>r.ensureAuthenticated(e),getTicketWithToken:(e,t)=>r.getTicketWithToken(e,t),getNodeId:()=>r.getNodeId(),connect:(e,t)=>r.connect(e,t),refreshHostedAppSettings:e=>r.refreshHostedAppSettings(e),getRoomBackendTag:()=>r.getRoomBackendTag()})}function Yo(r){return ys({getWasmClient:()=>r.wasmClient,getRoomCreationMode:()=>r.getRoomCreationMode(),getAppLimits:()=>r.getAppLimits(),ensureAuthenticated:e=>r.auth.ensureAuthenticated(e),getTicketWithToken:(e,t)=>r.sessionTokens.getTicketWithToken(e,t),getNodeId:()=>r.runtimeIdentity.getNodeId(),connect:(e,t)=>r.connectionDialer.connect(e,t),refreshHostedAppSettings:e=>r.signalingBackendController.refreshHostedAppSettings(e),getRoomBackendTag:()=>r.runtimeStatus.getRoomBackendTag()})}var $t=class{constructor(e,t={}){this.ctx=e;this.deps=t;this.browserBackgrounded=false;this.disposed=false;this.removeBrowserListeners=null;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.removeBrowserListeners?.(),this.removeBrowserListeners=null);}installListeners(){if(this.disposed||this.removeBrowserListeners||typeof document>"u"||typeof window>"u")return;let e=()=>{if(this.disposed)return;let o=document.visibilityState==="hidden";this.handleBackgroundState(o,"visibilitychange");},t=()=>{this.disposed||this.handleBackgroundState(false,"pageshow");},n=()=>{this.disposed||(this.syncCoordinationAvailability("online"),this.reconcileConnectionsAfterAvailabilityHint("online"));},i=()=>{this.disposed||this.syncCoordinationAvailability("offline");};e(),document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",t),window.addEventListener("online",n),window.addEventListener("offline",i),this.removeBrowserListeners=()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",t),window.removeEventListener("online",n),window.removeEventListener("offline",i);};}async handleBackgroundState(e,t){if(this.disposed)return;let n=this.browserBackgrounded!==e;this.browserBackgrounded=e,this.syncCoordinationAvailability(t);let i=this.ctx.wasmClient;if(i&&typeof i.set_app_backgrounded=="function")try{await i.set_app_backgrounded(e);}catch(o){console.warn("[Client][APP] Failed to propagate background state to wasm runtime",{backgrounded:e,source:t,error:o});}this.disposed||!e&&n&&this.reconcileConnectionsAfterAvailabilityHint(t);}reconcileConnectionsAfterForeground(e){this.reconcileConnectionsAfterAvailabilityHint(e);}syncCoordinationAvailability(e){this.deps.setCoordinationHostAvailability?.({available:!this.browserBackgrounded&&(typeof navigator>"u"||navigator.onLine!==false),reason:e});}reconcileConnectionsAfterAvailabilityHint(e$1){if(this.disposed)return;let t=this.ctx.wasmClient;(typeof t?.__reconcileIrohCarriersAfterNetworkChange=="function"||typeof t?.__reconcilePersistentIrohProtocols=="function")&&Promise.resolve().then(()=>t?.__reconcileIrohCarriersAfterNetworkChange?.()).then(()=>t?.__reconcilePersistentIrohProtocols?.()).catch(n=>{console.warn("[Client][APP] Rust Iroh availability reconcile failed",{source:e$1,error:n});});for(let n of this.ctx.registry.values())n.isClosed||(e("[Client][APP] Availability recovery reconcile",{source:e$1,connectionId:n.id,remoteNodeId:n.remoteNodeId}),n.handleAppForeground());}};var Yt=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.admissionRepairInFlight=new Map;this.repairedAdmissionByNode=new Map;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true,this.admissionRepairInFlight.clear(),this.repairedAdmissionByNode.clear();}assertActive(){if(this.disposed)throw new Error("Managed transport dialer is disposed")}async repairAdmissionForTransportGeneration(e,t){if(this.assertActive(),!e||!Number.isSafeInteger(t)||t<=0)return null;let n=this.deps.getRouteRepairTokenForNode?.(e)?.trim()??"",i=this.deps.getRouteRepairTokenPayloadForNode?.(e)?.trim()??"";if(!n||!i)return null;let o=`${n.length}:${n}:${i}`,s=this.repairedAdmissionByNode.get(e);if(s?.transportStableId===t&&s.credentialKey===o)return s.approvedScope;let a=this.admissionRepairInFlight.get(e);if(a?.transportStableId===t&&a.credentialKey===o)return a.promise;let c=this.performAdmissionRepair(e,t,n,i);this.admissionRepairInFlight.set(e,{transportStableId:t,credentialKey:o,promise:c});try{let d=await c,l=this.admissionRepairInFlight.get(e);return l?.promise!==c||l.transportStableId!==t||l.credentialKey!==o||!this.isCurrentRouteRepairCredential(e,n,i)?null:(this.repairedAdmissionByNode.set(e,{transportStableId:t,credentialKey:o,approvedScope:d}),d)}finally{this.admissionRepairInFlight.get(e)?.promise===c&&this.admissionRepairInFlight.delete(e);}}async performAdmissionRepair(e$1,t,n,i){let o=this.ctx.wasmClient;if(!o)return null;let s=(await this.deps.getLocalDeviceId().catch(()=>null))?.trim()||this.deps.getFallbackLocalDeviceId()?.trim()||null;this.assertActive();let a=4;for(let c=1;c<=a;c+=1){if(!this.isCurrentRouteRepairCredential(e$1,n,i))return null;try{let d=await this.presentSessionTokenToHost(o,e$1,n,i,s,2e4);return this.assertActive(),this.isCurrentRouteRepairCredential(e$1,n,i)?(e("[ManagedTransportDialer] repaired admission for physical generation",{remoteNodeId:e$1,transportStableId:t,attempt:c}),d):null}catch(d){if(this.isTerminalSessionTokenRejection(d))throw this.deps.forgetRouteRepairTokenForNode?.(e$1,n,i),this.repairedAdmissionByNode.delete(e$1),d;if(!this.isCurrentRouteRepairCredential(e$1,n,i))return null;if(!this.isTransientSessionTokenPresentationError(d)||c>=a)throw d;console.warn("[ManagedTransportDialer] current-generation admission repair lost transiently; retrying",{remoteNodeId:e$1,transportStableId:t,attempt:c,nextAttempt:c+1,error:d instanceof Error?d.message:String(d)}),await this.sleepSessionTokenRetry(c),this.assertActive();}}return null}isCurrentRouteRepairCredential(e,t,n){return this.deps.getRouteRepairTokenForNode?.(e)?.trim()===t&&this.deps.getRouteRepairTokenPayloadForNode?.(e)?.trim()===n}normalizeConnectResult(e,t,n,i){let o=e&&typeof e=="object"?e:{},s=typeof o.connectionId=="string"&&o.connectionId.trim()?o.connectionId.trim():t,a=typeof o.remoteNodeId=="string"&&o.remoteNodeId.trim()?o.remoteNodeId.trim():n,c=typeof o.deviceId=="string"&&o.deviceId.trim()?o.deviceId.trim():i??null,d=typeof o.deviceIdHint=="string"&&o.deviceIdHint.trim()?o.deviceIdHint.trim():c,l=typeof o.state=="string"&&o.state.trim()?o.state.trim():"connected",p=typeof o.approvedScope=="string"&&o.approvedScope.trim()?o.approvedScope.trim():typeof o.approved_scope=="string"&&o.approved_scope.trim()?o.approved_scope.trim():null;return {connectionId:s,deviceId:c,deviceIdHint:d,remoteNodeId:a,state:l,approvedScope:p}}async ensureWasmManagedTransport(e,t,n){this.assertActive();let i=this.ctx.wasmClient;if(!i||typeof i.connect_device!="function")throw new Error("[Client] WASM managed transport requires connect_device()");let o=n?.timeoutMs??2e4,s=e.trim(),{irohTicket:a,tokenSuffix:c}=a$4(s),d=c===null?s:a,l=c!==null?d$5(a,c):null;if(c!==null&&!l)throw new Error("invalid compound ticket payload for endpoint ticket");let p=typeof l?.t=="string"&&l.t.trim()?l.t.trim():null;if(c!==null&&!p)throw new Error("invalid compound ticket payload for endpoint ticket");let u=await i.endpoint_id_from_ticket(a);this.assertActive(),p&&c&&this.deps.rememberRouteRepairTokenForNode(u,p,c);let h=this.deps.getDeterministicConnectionId(u),f=p?await this.deps.getLocalDeviceId().catch(()=>null):null,m=p&&(f?.trim()||this.deps.getFallbackLocalDeviceId()?.trim())||null;if(this.assertActive(),n?.skipIfConnected&&typeof i.is_connected=="function")try{let P=await i.is_connected(u);if(this.assertActive(),P){let k=c===null?this.deps.getApprovedScope(h):null;if(!(c!==null&&!k&&!n?.admissionAlreadyPresented))return {connectionId:h,deviceId:t??null,deviceIdHint:t??null,remoteNodeId:u,state:"connected",approvedScope:k}}}catch(P){if(this.disposed)throw P}let v=await b$3(i.connect_device(t??null,d),o,"wasmClient.connect_device");this.assertActive();let y=this.normalizeConnectResult(v,h,u,t??null),S=y.approvedScope??(c===null?this.deps.getApprovedScope(y.connectionId):null);if(c!==null&&!S&&!n?.admissionAlreadyPresented){let A=0,R=0,L=0;for(;!S;)try{if(S=await this.presentSessionTokenToHost(i,u,p,c,m,o),!S&&(L+=1,L>=4))break}catch(N){if(this.isAuthoritativeDeviceBindingPendingError(N)){if(R+=1,R>=6)throw N;console.warn("[ManagedTransportDialer] waiting for authoritative directory binding before retrying admission",{nodeId:u,remoteDeviceId:t??null,claimedLocalDeviceId:m,attempt:R,nextAttempt:R+1,error:N instanceof Error?N.message:String(N)}),await this.sleepAuthoritativeBindingRetry(R),this.assertActive();continue}if(A+=1,!this.isTransientSessionTokenPresentationError(N)||A>=4)throw N;console.warn("[ManagedTransportDialer] session-token presentation lost transiently; redialing over iroh",{nodeId:u,remoteDeviceId:t??null,claimedLocalDeviceId:m,attempt:A,nextAttempt:A+1,error:N instanceof Error?N.message:String(N)}),await this.sleepSessionTokenRetry(A),v=await b$3(i.connect_device(t??null,d),o,`wasmClient.connect_device(session-token-retry-${A})`),this.assertActive(),y=this.normalizeConnectResult(v,h,u,t??null),S=y.approvedScope??(c===null?this.deps.getApprovedScope(y.connectionId):null);}this.assertActive();}let C=S?{...y,approvedScope:S}:y;if(c!==null&&!C.approvedScope&&!n?.admissionAlreadyPresented)throw new Error("Failed to present session token: session token admission failed");return C}async presentSessionTokenToHost(e,t,n,i,o,s){try{if(typeof e.present_session_token=="function"){let a=await b$3(e.present_session_token(t,n,i,o),s,"wasmClient.present_session_token");return this.normalizeApprovedScope(a)}}catch(a){let c=a instanceof Error?a.message:String(a);throw new Error(`Failed to present session token: ${c}`)}return null}normalizeApprovedScope(e){return typeof e=="string"&&e.trim()?e.trim():null}isTransientSessionTokenPresentationError(e){if(this.isTerminalSessionTokenRejection(e))return false;let t=e instanceof Error?e.message:typeof e=="string"?e:String(e?.message??e??"");return /session-token-response|missing connection for session-token presentation|failed to open bi-stream|connection lost|stream finished early|0 bytes read|locallyclosed|connection closed|stream closed|reset/i.test(t)}isTerminalSessionTokenRejection(e){let t=e instanceof Error?e.message:typeof e=="string"?e:String(e?.message??e??"");return /\[session-token-response:rejected\]/i.test(t)}isAuthoritativeDeviceBindingPendingError(e){let t=e instanceof Error?e.message:typeof e=="string"?e:String(e?.message??e??"");return /authoritative-device-binding-pending/i.test(t)}isLocalIrohRuntimeNotInitializedError(e){let t=e instanceof Error?e.message:typeof e=="string"?e:String(e?.message??e??"");return /\bIroh node not initialized\b|\bNode not initialized\b/i.test(t)}sleepSessionTokenRetry(e){let t=Math.min(500,100*Math.max(1,e));return a(t)}sleepAuthoritativeBindingRetry(e){return a(d$1(e,200,1500))}};function Cs(r){let t=(Array.isArray(r.urls)?r.urls:[r.urls]).filter(n=>typeof n=="string"&&!n.startsWith("stun:"));return t.length===0?null:{...r,urls:Array.isArray(r.urls)?t:t[0]}}function Is(r){let t=(Array.isArray(r.urls)?r.urls:[r.urls]).filter(n=>{let i=typeof n=="string"?n.trim().toLowerCase():"";return !i.startsWith("turn:")&&!i.startsWith("turns:")});return t.length===0?null:{...r,urls:Array.isArray(r.urls)?t:t[0]}}function Ss(r){return r?.map(e=>Is(e)).filter(e=>e!==null)}function Jo(r){if(r)return r.map(e=>Cs(e)).filter(e=>e!==null)}async function Qo(r,e,t){for(let n=0;n<e;n+=1){if(await r().catch(()=>false))return true;n<e-1&&await a(t);}return false}function ri(r){return !!r?.signaling?.nativeIpc&&r?.transport?.wasm===false&&r?.fallback?.wasm===false}var Jt=class{constructor(e){this.host=e;this.wasmLoaded=false;this.initPromise=null;this.initPendingTimer=null;this.disposed=false;this.host.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true,this.initPromise=null,this.clearInitPendingTimer();}clearInitPendingTimer(){this.initPendingTimer&&(clearInterval(this.initPendingTimer),this.initPendingTimer=null);}async bootstrapRuntime(e){let t=e.initializeClient??true;if(e.platform==="web")return await e.initializeWeb?.(),t&&await this.init(),{ready:true,mode:"web"};let n=e.quickPollAttempts??5,i=e.quickPollIntervalMs??300,o=e.retryPollAttempts??8,s=e.retryPollIntervalMs??300,a=e.nativeInitEventTimeoutMs??4e3;if(!e.isNativeReady)return console.warn("[Client][INIT] No isNativeReady callback provided for native platform; treating runtime as not ready"),{ready:false,mode:"native"};if(!await Qo(e.isNativeReady,n,i)){await e.retryNativeInit?.();let[d,l]=await Promise.all([e.waitForNativeInitEvent?.(a)??Promise.resolve(false),Qo(e.isNativeReady,o,s)]);if(!(d||l))return {ready:false,mode:"native"}}return t&&await this.init(),{ready:true,mode:"native"}}async init(){if(!this.disposed){if(this.initPromise)return this.initPromise;if(!(this.wasmLoaded&&this.host.wasmClient&&this.host.localNodeId)){if(this.usesNativeIpcOnly())throw this.nativeWasmInitForbiddenError("Client.init()");return this.initPromise=(async()=>{try{f("[Client][INIT] Loading WASM module...");let{initWasm:e,WasmClient:t,start:n}=await this.host.loadBrowserWasmRuntime();if(await e(),this.disposed)return;n(),this.wasmLoaded=!0,f("[Client][INIT] WASM module loaded");let i=typeof this.host.options.apiKey=="string"?this.host.options.apiKey.trim():"",o=typeof this.host.options.spaceKey=="string"?this.host.options.spaceKey.trim():"",s=(this.host.options.discoveryMode===void 0||this.host.options.discoveryMode==="space")&&!!i&&!!o,a=c$4(this.host.options);if(s){let f$1=await b$1(i,o);if(this.disposed)return;a=`space::${f$1}`,f(`[Client][INIT] space mode: WASM rooms routed to spaces/${f$1.slice(0,8)}...`);}if(this.disposed)return;this.host.setEffectiveRoomBackendTag(a);let c=new t(i);if(this.assertConfiguredCarrierSurface(c),typeof c.setRelay=="function"&&await c.setRelay(this.host.options.transports?.relay!==!1),this.disposed||(this.host.setWasmClient(c),f("PlutoRTC WASM Core Initialized"),await this.configureWebRtcIceServers(),this.disposed)||this.host.hasConfiguredIrohCarrier()&&(await this.host.prepareConfiguredIrohCarriers(),this.disposed))return;let d=`iroh_secret_key_${f$1(this.host.options)}`,l=this.resolveIrohPersistenceMode(),p=await this.resolveIrohSecretKeyBytes(d,l);if(this.disposed||(this.host.setDeviceId(await this.host.getLocalDeviceId().catch(()=>null)),this.disposed))return;let u=Date.now();f(`[Client][INIT][IROH] start persistence=${l} hasSecretKey=${!!p} secretKeyLen=${p?.length||0} hasStoredDeviceId=${!!this.host.deviceId}`),this.clearInitPendingTimer(),this.initPendingTimer=setInterval(()=>{let f=Date.now()-u;console.warn(`[Client][INIT][IROH] pending elapsedMs=${f} hasWasmClient=${!!this.host.wasmClient}`);},5e3);let h="";try{let f=this.host.options.transports?.iroh&&typeof this.host.options.transports.iroh=="object"&&this.host.options.transports.iroh.testRelayUrl?.trim()||void 0;h=await b$3(f?c.initIrohWithTestRelay(p,f):c.init_iroh(p),2e4);}catch(f){let m=Date.now()-u;throw new Error(`[Client] init_iroh stalled or failed: ${f?.message||f}; elapsed_ms=${m}; persistence=${l}; has_secret_key=${!!p}`)}finally{this.clearInitPendingTimer();}if(this.disposed)return;if(f(`[Client][INIT][IROH] complete elapsedMs=${Date.now()-u} nodeId=${h}`),!h)throw new Error("[Client] init_iroh returned empty node id");if(this.host.setLocalNodeId(h),this.host.deviceId||this.host.setDeviceId(await this.host.getLocalDeviceId().catch(()=>null)),this.disposed||(this.host.setNode({initialized:!0,localNodeId:h}),this.host.setSignalingWasmClient(c),this.host.installAppLifecycleListeners(),l==="persistent"&&!this.host.options.secretKey&&(await this.persistCurrentIrohSecret(d,p,h),this.disposed)))return;this.host.hasConfiguredIrohCarrier()&&this.broadcastCarrierReadyCapabilityInBackground();}catch(e){throw console.error("Failed to initialize PlutoRTC:",e),this.initPromise=null,e}})(),this.initPromise}}}broadcastCarrierReadyCapabilityInBackground(){try{Promise.resolve(this.host.broadcastTransportCapabilityUpdate("carrier-capabilities-ready")).catch(e$1=>{this.disposed||e("[Client] Late Iroh carrier capability update failed",e$1);});}catch(e$1){if(this.disposed)return;e("[Client] Late Iroh carrier capability update failed",e$1);}}assertConfiguredCarrierSurface(e){let t=!!this.host.options.transports?.webrtc,n=!!this.host.options.transports?.moq;if((t||n)&&(typeof e?.__beginPreferredIrohCarrier!="function"||typeof e?.__advancePreferredIrohCarrier!="function"||typeof e?.__getIrohCarrierReadiness!="function"))throw new Error("[OpenRTC] The browser WASM artifact does not include preferred Iroh carrier arbitration and readiness.");if(t&&(typeof e?.__beginWebRtcCarrier!="function"||typeof e?.__handleIrohCarrierControl!="function"||typeof e?.__attachWebRtcCarrier!="function"))throw new Error("[OpenRTC] The browser WASM artifact does not include configured WebRTC carrier support.");if(n&&(typeof e?.__beginMoqCarrier!="function"||typeof e?.__handleIrohCarrierControl!="function"||typeof e?.__attachMoqCarrier!="function"))throw new Error("[OpenRTC] The browser WASM artifact does not include configured MoQ carrier support.")}async recoverLocalIrohRuntime(e$1){if(this.disposed)return false;let t=this.host.wasmClient;if(!t||typeof t.init_iroh!="function")return false;try{let n=`iroh_secret_key_${f$1(this.host.options)}`,i=this.resolveIrohPersistenceMode(),o=await this.resolveIrohSecretKeyBytes(n,i);e("[Client][CONNECT] recovering local Iroh runtime",{reason:e$1,hadLocalNodeId:!!this.host.localNodeId,nodeInitialized:!!this.host.node?.initialized,persistenceMode:i,hasSecretKey:!!o});let s=this.host.options.transports?.iroh&&typeof this.host.options.transports.iroh=="object"&&this.host.options.transports.iroh.testRelayUrl?.trim()||void 0,a=await b$3(s?t.initIrohWithTestRelay(o,s):t.init_iroh(o),2e4);return this.disposed||typeof a!="string"||!a?!1:(this.host.setLocalNodeId(a),this.host.setNode({initialized:!0,localNodeId:a}),i==="persistent"&&!this.host.options.secretKey&&await this.persistCurrentIrohSecret(n,o,a),!0)}catch(n){return e("[Client][CONNECT] local Iroh runtime recovery failed",{reason:e$1,error:n instanceof Error?n.message:String(n)}),false}}usesNativeIpcOnly(){return ri(this.host.capabilities())}nativeWasmInitForbiddenError(e){let t=this.host.capabilities(),n=`[Client][NATIVE-GUARD] Refusing WASM runtime init during ${e}. This OpenRTC client is using the native IPC runtime with WASM fallback disabled; desktop/Tauri must initialize Iroh through the Rust backend only.`;return console.error(n,{capabilities:t}),new Error(n)}async resolveIrohSecretKeyBytes(e,t){if(this.host.options.secretKey){let o=this.host.options.secretKey.match(/.{1,2}/g);return o?new Uint8Array(o.map(s=>parseInt(s,16))):void 0}if(t!=="persistent")return;let i=(await this.loadPersistedIrohSecretHex(e))?.match(/.{1,2}/g);return i?new Uint8Array(i.map(o=>parseInt(o,16))):void 0}async persistCurrentIrohSecret(e,t,n){let i=t??(typeof this.host.wasmClient?.iroh_secret_key=="function"?await this.host.wasmClient.iroh_secret_key().catch(()=>{}):void 0);if(i&&i.length>0){let o=Array.from(i).map(s=>Number(s).toString(16).padStart(2,"0")).join("");await this.persistIrohSecretHex(e,o),f(`[Client][INIT][IROH] persisted secret key bytes=${i.length} nodeId=${n}`);}else console.warn(`[Client][INIT][IROH] unable to persist secret key for nodeId=${n}`);}resolveIrohPersistenceMode(){return this.host.options.endpointIdPersistence??this.host.options.nodeIdPersistence??(typeof this.host.options.transports?.iroh=="object"?this.host.options.transports.iroh.persistenceMode:void 0)??"ephemeral"}getTauriInvoke(){if(typeof window>"u")return null;let e=window.__TAURI_INTERNALS__;return !e||typeof e.invoke!="function"?null:e.invoke.bind(e)}async loadPersistedIrohSecretHex(e){let t=g$1()?this.getTauriInvoke():null;if(t){let n=await t("openrtc_load_iroh_secret",{namespaceKey:e}).catch(()=>null);if(typeof n=="string"&&n.trim().length>0)return n.trim()}if(typeof sessionStorage<"u"){let n=sessionStorage.getItem(e);if(n)return n}if(typeof localStorage<"u"){let n=localStorage.getItem(e);if(n)return typeof sessionStorage<"u"&&sessionStorage.setItem(e,n),localStorage.removeItem(e),n}return null}async persistIrohSecretHex(e,t){let n=g$1()?this.getTauriInvoke():null;if(n){await n("openrtc_save_iroh_secret",{namespaceKey:e,secretHex:t}),typeof localStorage<"u"&&localStorage.removeItem(e);return}typeof sessionStorage<"u"&&sessionStorage.setItem(e,t),typeof localStorage<"u"&&localStorage.removeItem(e);}async getTurnCredentialsForTransportConfig(){return typeof this.host.options.turnCredentialsProvider=="function"?await this.host.options.turnCredentialsProvider()??null:await this.host.getTurnCredentials()??null}async configureWebRtcIceServers(){let e=this.host.options.transports?.webrtc,t=e&&typeof e=="object"?e:void 0,n=this.host.options.transports?.relay!==false,i=n&&!!t&&(t.useTurn===true||t.privacyMode===true||this.host.options.strictMode===true);if(!n&&t&&(t.iceServers=Ss(t.iceServers),t.useTurn=false,t.privacyMode=false,t.iceTransportPolicy="all"),i)try{let o=await this.getTurnCredentialsForTransportConfig();if(this.disposed)return;if(o&&o.iceServers){let s=Array.isArray(o.iceServers)?o.iceServers:[o.iceServers];t?.privacyMode||this.host.options.strictMode?(s=Jo(s)??[],f(`[Client] Strict / Privacy Mode: Filtered STUN servers. Remaining=${s.length}`)):f(`[Client] Automatically fetched ${s.length} TURN servers.`),this.host.options.transports||(this.host.options.transports={}),this.host.options.transports.webrtc||(this.host.options.transports.webrtc={});let a=this.host.options.transports.webrtc||i$1;a.iceServers||(a.iceServers=[]),(this.host.options.strictMode||a.privacyMode)&&(a.iceServers=Jo(a.iceServers)??[]),a.iceServers.push(...s);}}catch(o){console.warn("[Client] Failed to auto-fetch TURN credentials:",o);}if(!this.host.options.strictMode&&!t?.privacyMode){if(this.disposed)return;let o=this.host.options.transports?.webrtc;o&&o.useDefaultIceServers!==false&&(!o.iceServers||Array.isArray(o.iceServers)&&o.iceServers.length===0)&&(f("[Client] No ICE servers provided. Using default public STUN servers."),o.iceServers=[...h$1]);}}};var Qt=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime connection service is disposed")}async connectRaw(e,t=2e4){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let n=await this.deps.ensureWasmManagedTransport(e,null,{timeoutMs:t});return this.assertActive(),{connectionId:n.connectionId,localNodeId:this.ctx.localNodeId??"",remoteNodeId:n.remoteNodeId??n.deviceId??""}}async startAutoConnect(e){if(this.disposed||(await this.deps.ensureSignalingReadyForDiscovery("watch"),this.disposed))return;let t=this.deps.getCurrentUserId();if(!t)throw new Error("startAutoConnect requires an authenticated user");let n=e||await this.deps.getLocalDeviceId()||this.deps.getFallbackDeviceId();if(!this.disposed){if(!n)throw new Error("startAutoConnect requires a local device identity");this.deps.startAutoConnect(t,n);}}async isConnected(e){if(this.disposed||(await this.deps.ensureWasmRuntimeForP2P(),this.disposed)||!e||!e.trim())return false;let t=this.ctx.wasmClient;if(t&&typeof t.is_connected=="function"){let i=await t.is_connected(e);if(this.disposed)return false;if(i)return true}let n=await this.deps.isConnected(e);return this.disposed?false:!!n}async disconnectNode(e){if(this.disposed||!e||!e.trim())return;let t=Array.from(this.ctx.registry.values()).filter(n=>n.deviceId===e);await Promise.allSettled(t.map(n=>this.disconnectConnectionBestEffort(n))),!this.disposed&&await this.deps.disconnectNodeTransport(e);}disconnectNodeBestEffort(e){try{this.disconnectNode(e).catch(()=>{});}catch{}}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};var Xt=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime identity service is disposed")}async getTicket(){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let e=await se(()=>this.ctx.wasmClient.endpoint_ticket(),{isActive:()=>!this.disposed});return this.assertActive(),e}async getNodeId(){return this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive(),this.ctx.localNodeId??""}async getNodeIdFromTicket(e){if(this.disposed)return null;let t=e.trim();if(!t)return null;let{irohTicket:n}=a$4(t),i=this.ctx.wasmClient;if(!i||typeof i.endpoint_id_from_ticket!="function")return null;try{let o=await i.endpoint_id_from_ticket(n);return this.disposed?null:o}catch{return null}}};var Zt=class{constructor(e,t){this.ctx=e;this.deps=t;this.loggedNativeDiscoveryWasmSkip=false;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Runtime readiness service is disposed")}async ensureWasmRuntimeForP2P(){if(this.assertActive(),!(this.ctx.wasmClient&&this.ctx.localNodeId)&&(await this.deps.init(),this.assertActive(),!this.ctx.wasmClient||!this.ctx.localNodeId))throw new Error("Node not initialized")}async ensureSignalingReadyForDiscovery(e$1){if(this.disposed||this.deps.usesTicketOnlySignalingMode())return;let t=this.deps.usesNativeIpcOnly();if(!this.deps.getWasmLoaded()&&t)this.loggedNativeDiscoveryWasmSkip||(this.loggedNativeDiscoveryWasmSkip=true,e(`[Client][NATIVE-GUARD] Discovery ${e$1} is using native IPC readiness; skipped WASM init.`));else if(!this.deps.getWasmLoaded()&&!(this.ctx.wasmClient&&this.ctx.localNodeId)&&(await this.deps.init(),this.disposed))return;try{await this.deps.ensureAuthenticated("discovery");}catch(n){console.warn(`[Client][AUTH] ensureAuthenticated failed for ${e$1}:`,n);}this.disposed;}};var Ps={scheduled:0,coalesced:0,ran:0,orphanTsConnection:0,orphanRustRecord:0,orphanTsConnectionHealed:0},en=class{constructor(e){this.deps=e;}usesTicketOnlySignalingMode(){return (this.deps.getOptions()?.signalingMode??"hosted")==="ticket-only"}getRoomBackendTag(){return this.deps.getEffectiveRoomBackendTag()}requiresManagedTransportTrust(e){return !this.usesTicketOnlySignalingMode()&&e!=="space"&&!!this.deps.getSignalingCurrentUser()?.id}getSignalingTelemetry(){return {transport:"runtime-bridge",wasmLoaded:this.deps.getWasmLoaded(),peerReconciliation:this.reconciliationStats()}}reconciliationStats(){return this.deps.reconciliationStats()??Ps}getProtocolCapabilities(){let e=d$6(),t=this.deps.capabilities(),n=this.deps.getOptions().transports,i=n?.iroh!==false,o=!!n?.webrtc,s=n?.ble===true||typeof n?.ble=="object"&&n.ble.enabled!==false,a=typeof n?.moq=="object"&&typeof n.moq.relayUrl=="string"&&n.moq.relayUrl.trim().length>0;for(let d of Object.values(e)){if(d.routeImplementation==="path-label"){d.configured=void 0;continue}d.configured=d.baseProtocol==="iroh"?i:d.baseProtocol==="webrtc"?o:a;}e.ble.configured=s;let c=(d,l,p)=>{e[d].configured=l,e[d].available=l&&p,l?p||(e[d].reason=`The running host did not report '${d}' as available.`):e[d].reason=`Protocol '${d}' is not enabled in ClientOptions.transports.`;};return c("iroh",i,t?.transport.irohQuic===true||t?.adapter==="browser-wasm"),c("webrtc",o,t?.transport.webRtc===true),c("moq",a,t?.transport.moq===true),e.ble.available=s&&t?.transport.ble===true,s?t?.transport.ble!==true&&(e.ble.reason="The running host did not report 'ble' as compiled and enabled."):e.ble.reason="Protocol 'ble' is not enabled in ClientOptions.transports.",e}async getRuntimeStatus(){let e="unknown";return typeof window<"u"&&(e=window.__TAURI__?"tauri":"browser"),{runtime:e,wasmLoaded:this.deps.getWasmLoaded(),localNodeId:this.deps.getLocalNodeId()||void 0,userId:this.deps.getSignalingCurrentUser()?.id??void 0}}};function Xo(r){let{host:e}=r;return new Jt({get options(){return e.getOptions()},get wasmClient(){return e.getWasmClient()},get node(){return e.getNode()},get localNodeId(){return e.getLocalNodeId()},get deviceId(){return e.getDeviceId()},loadBrowserWasmRuntime:()=>e.loadBrowserWasmRuntime(),setWasmClient:t=>e.setWasmClient(t),setSignalingWasmClient:t=>e.setSignalingWasmClient(t),setNode:t=>e.setNode(t),setLocalNodeId:t=>e.setLocalNodeId(t),setDeviceId:t=>e.setDeviceId(t),setEffectiveRoomBackendTag:t=>e.setEffectiveRoomBackendTag(t),usesTicketOnlySignalingMode:()=>r.getStatus().usesTicketOnlySignalingMode(),ensureAuthenticated:t=>e.ensureAuthenticated(t),syncAuthTokenToWasm:(t,n)=>e.syncAuthTokenToWasm(t,n),installAuthTokenSync:()=>e.installAuthTokenSync(),installAppLifecycleListeners:()=>r.getAppLifecycle().installListeners(),isWebRTCTransportEnabled:()=>e.isWebRTCTransportEnabled(),hasConfiguredIrohCarrier:()=>{let t=e.getOptions().transports;return !!t?.webrtc||!!t?.moq},prepareConfiguredIrohCarriers:()=>e.prepareConfiguredIrohCarriers(),getLocalDeviceId:()=>e.getLocalDeviceId(),getTurnCredentials:()=>e.getTurnCredentials(),capabilities:()=>e.capabilities(),broadcastTransportCapabilityUpdate:t=>e.broadcastTransportCapabilityUpdate(t),registerDisposer:t=>e.registerDisposer(t)})}function Zo(r){let{host:e}=r;return new Qt(e.getContext(),{ensureWasmRuntimeForP2P:()=>r.getReadiness().ensureWasmRuntimeForP2P(),ensureSignalingReadyForDiscovery:t=>r.getReadiness().ensureSignalingReadyForDiscovery(t),ensureWasmManagedTransport:(t,n,i)=>r.getManagedDialer().ensureWasmManagedTransport(t,n,i),getCurrentUserId:()=>e.getCurrentUserId(),getLocalDeviceId:()=>e.getLocalDeviceId(),getFallbackDeviceId:()=>e.getDeviceId(),startAutoConnect:(t,n)=>e.startAutoConnect(t,n),isConnected:t=>e.isConnected(t),disconnectNodeTransport:t=>e.disconnectNodeTransport(t)})}function er(r){return new Yt(r.getContext(),{getDeterministicConnectionId:e=>r.getDeterministicConnectionId(e),getApprovedScope:e=>r.getApprovedScope(e),getLocalDeviceId:()=>r.getLocalDeviceId(),getFallbackLocalDeviceId:()=>r.getDeviceId()??r.getOptions().localDeviceId??null,rememberRouteRepairTokenForNode:(e,t,n)=>r.rememberRouteRepairTokenForNode(e,t,n),forgetRouteRepairTokenForNode:(e,t,n)=>r.forgetRouteRepairTokenForNode?.(e,t,n),getRouteRepairTokenForNode:e=>r.getRouteRepairTokenForNode?.(e),getRouteRepairTokenPayloadForNode:e=>r.getRouteRepairTokenPayloadForNode?.(e)})}function tr(r){return new Xt(r.host.getContext(),{ensureWasmRuntimeForP2P:()=>r.getReadiness().ensureWasmRuntimeForP2P()})}function nr(r){let{host:e}=r;return new Zt(e.getContext(),{init:()=>r.getBootstrap().init(),usesTicketOnlySignalingMode:()=>r.getStatus().usesTicketOnlySignalingMode(),usesNativeIpcOnly:()=>ri(e.capabilities()),getWasmLoaded:()=>r.getBootstrapWasmLoaded(),ensureAuthenticated:t=>e.ensureAuthenticated(t),syncAuthTokenToWasm:t=>e.syncAuthTokenToWasm(t)})}function ir(r){let{host:e}=r;return new en({getEffectiveRoomBackendTag:()=>e.getEffectiveRoomBackendTag(),getLocalNodeId:()=>e.getLocalNodeId(),getOptions:()=>e.getOptions(),reconciliationStats:()=>e.reconciliationStats(),capabilities:()=>e.capabilities(),getSignalingCurrentUser:()=>({id:e.getCurrentUserId()}),getWasmLoaded:()=>r.getBootstrapWasmLoaded()})}function or(r){return new $t(r.getContext(),{setCoordinationHostAvailability:e=>r.setCoordinationHostAvailability(e)})}function rr(r){return new si({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getWasmClient:()=>r.wasmClient,setWasmClient:e=>{r.wasmClient=e;},getNode:()=>r.node,setNode:e=>{r.node=e;},getLocalNodeId:()=>r.localNodeId,setLocalNodeId:e=>{r.localNodeId=e;},getDeviceId:()=>r.deviceId,setDeviceId:e=>{r.deviceId=e;},setEffectiveRoomBackendTag:e=>{r.setEffectiveRoomBackendTag(e);},getEffectiveRoomBackendTag:()=>r.getEffectiveRoomBackendTag(),reconciliationStats:()=>r.getExistingPeerReconciliationStats(),getCurrentUserId:()=>r.signalingBackendController.getCurrentUser()?.id??null,capabilities:()=>r.signalingBackendController.capabilities(),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),getTurnCredentials:()=>r.signalingBackendController.getTurnCredentials(),loadBrowserWasmRuntime:()=>r.signalingBackendController.loadBrowserWasmRuntime(),setSignalingWasmClient:e=>r.signalingBackendController.setWasmClient(e),startAutoConnect:(e,t)=>r.signalingBackendController.startAutoConnect(e,t),isConnected:e=>r.signalingBackendController.isConnected(e),disconnectNodeTransport:e=>r.transportHealth.disconnectNodeTransport(e),getDeterministicConnectionId:e=>r.peerIdentity.getDeterministicConnectionId(e),getApprovedScope:e=>r.sessionTokens.getApprovedScope(e),rememberRouteRepairTokenForNode:(e,t,n)=>r.sessionTokens.rememberRouteRepairTokenForNode(e,t,n),forgetRouteRepairTokenForNode:(e,t,n)=>r.sessionTokens.forgetRouteRepairTokenForNode(e,t,n),getRouteRepairTokenForNode:e=>r.sessionTokens.getRouteRepairTokenForNode(e),getRouteRepairTokenPayloadForNode:e=>r.sessionTokens.getRouteRepairTokenPayloadForNode(e),ensureAuthenticated:e=>r.auth.ensureAuthenticated(e),syncAuthTokenToWasm:(e,t)=>r.auth.syncAuthTokenToWasm(e,t),installAuthTokenSync:()=>r.auth.installAuthTokenSync(),isWebRTCTransportEnabled:()=>Y(r.options),prepareConfiguredIrohCarriers:()=>r.browserCarrier.prepareConfiguredCarriers(),broadcastTransportCapabilityUpdate:e=>r.transportHandshake.broadcastTransportCapabilityUpdate(e),setCoordinationHostAvailability:e=>r.signaling.setCoordinationHostAvailability?.(e),registerDisposer:e=>r.lifecycleScope.register(e)})}var si=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getBootstrap:()=>this.bootstrap,getBootstrapWasmLoaded:()=>this._bootstrap?.wasmLoaded??false,getManagedDialer:()=>this.managedDialer,getReadiness:()=>this.readiness,getStatus:()=>this.status,getAppLifecycle:()=>this.appLifecycle}}get bootstrap(){return this._bootstrap??(this._bootstrap=Xo(this.factoryHost))}get connections(){return this._connections??(this._connections=Zo(this.factoryHost))}get managedDialer(){return this._managedDialer??(this._managedDialer=er(this.host))}get identity(){return this._identity??(this._identity=tr(this.factoryHost))}get readiness(){return this._readiness??(this._readiness=nr(this.factoryHost))}get status(){return this._status??(this._status=ir(this.factoryHost))}get appLifecycle(){return this._appLifecycle??(this._appLifecycle=or(this.host))}};function tn(r){let e=r;return !!e&&typeof e.ensureConnectionApplicationCrypto=="function"&&typeof e.handleConnectionApplicationCryptoHandshake=="function"&&typeof e.connectionApplicationCryptoReady=="function"&&typeof e.protectConnectionApplicationPayload=="function"&&typeof e.openConnectionApplicationPayload=="function"}var nn=class{constructor(e,t){this.ctx=e;this.deps=t;this.negotiatedByConnectionId=new Map;this.negotiatedByPeerId=new Map;this.negotiatedFingerprintByCrypto=new WeakMap;this.waiters=[];this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}getApplicationCrypto(e){return e?this.deps.getConfiguredApplicationCrypto()??(this.rustOwnedConnectionReady(e.id)?this.negotiatedByConnectionId.get(e.id):void 0):this.deps.getConfiguredApplicationCrypto()}getNegotiatedForPeer(e){let t=typeof e=="string"?e.trim():"";if(!t)return;let n=Array.from(this.ctx.registry.values()).reverse().find(d=>!d.isClosed&&(d.id===t||d.remoteNodeId===t));if(n)return this.rustOwnedConnectionReady(n.id)?this.negotiatedByConnectionId.get(n.id):void 0;let i=this.deps.getKnownDeviceNodeId(t),o=[this.deps.getPeerState(t),i?this.deps.getPeerState(i):void 0].filter(d=>!!d);for(let d of o){let l=d.connectionId?.trim();if(l)return this.rustOwnedConnectionReady(l)?this.negotiatedByConnectionId.get(l):void 0;for(let p of [...d.connectionIds??[]].reverse()){let u=p?.trim();if(!u||!this.rustOwnedConnectionReady(u))continue;let h=this.negotiatedByConnectionId.get(u);if(h)return h}}let a=Array.from(this.ctx.registry.values()).filter(d=>{let l=this.deps.getKnownDeviceIdForNode(d.remoteNodeId);return d.id===t||d.remoteNodeId===t||d.deviceId===t||i&&d.remoteNodeId===i||l===t}).filter(d=>!d.isClosed).reverse(),c=a.find(d=>d.id===t||d.remoteNodeId===t)??a.find(d=>!!i&&d.remoteNodeId===i)??a[0];return c?this.rustOwnedConnectionReady(c.id)?this.negotiatedByConnectionId.get(c.id):void 0:this.negotiatedByPeerId.get(t)}resolveForPeer(e,t){let n=this.deps.getConfiguredApplicationCrypto();if(n)return n;if(t)return this.rustOwnedConnectionReady(t)?this.negotiatedByConnectionId.get(t.id):void 0;if(e)return this.getNegotiatedForPeer(e)}waitForPeer(e,t=1e4){let n=this.resolveForPeer(e);return n||!e||t<=0||this.disposed?Promise.resolve(n):new Promise(i=>{let o={peerId:e,resolve:i,timer:setTimeout(()=>{this.waiters=this.waiters.filter(s=>s!==o),i(void 0);},t)};this.waiters.push(o);})}dispose(){if(this.disposed)return;this.disposed=true;let e=this.waiters.splice(0);for(let t of e)clearTimeout(t.timer),t.resolve(void 0);this.negotiatedByConnectionId.clear(),this.negotiatedByPeerId.clear();}clearConnection(e){let t=this.negotiatedByConnectionId.get(e),n=this.wasmClient;try{n?.clearConnectionApplicationCryptoKey?.(e);}catch(i){console.warn("[Client][KEY-AGREEMENT] Failed to retire native application crypto",{connectionId:e,error:i});}if(this.negotiatedByConnectionId.delete(e),!(!t||Array.from(this.negotiatedByConnectionId.values()).includes(t)))for(let[i,o]of this.negotiatedByPeerId)o===t&&this.negotiatedByPeerId.delete(i);}notifyWaiters(){if(this.waiters.length===0)return;let e=[];for(let t of this.waiters){let n=this.resolveForPeer(t.peerId);if(!n){e.push(t);continue}clearTimeout(t.timer),t.resolve(n);}this.waiters=e;}resolveStreamTools(e$1,t){let n=this.resolveForPeer(e$1,t);return n&&e("[Client][KEY-AGREEMENT] Resolved application stream crypto",{peerId:e$1??null,connectionId:t?.id??null,keyFingerprint:this.negotiatedFingerprintByCrypto.get(n)??"configured"}),n?c$7(n):void 0}shouldNegotiateKeyAgreement(){return !this.deps.getConfiguredApplicationCrypto()&&!this.hasRustKeyAgreementOwner()}hasRustKeyAgreementOwner(){return tn(this.wasmClient)}rustOwnedConnectionReady(e,t){let n=this.wasmClient;if(!n||!tn(n))return true;let i=typeof e=="string"?this.ctx.registry.get(e):e;if(!i||i.isClosed)return false;let o=i.getBaseTransportStableId(),s=Number.isSafeInteger(t)&&Number(t)>0?Number(t):o;return Number.isSafeInteger(s)&&Number(s)>0&&n.connectionApplicationCryptoReady?.(i.id,BigInt(Number(s)))===true}async ensureRustOwnedConnection(e,t,n){if(this.deps.getConfiguredApplicationCrypto())return true;let i=this.wasmClient;return !this.hasRustKeyAgreementOwner()||!i?.ensureConnectionApplicationCrypto?false:(this.markRequired(e),await i.ensureConnectionApplicationCrypto(e.id,e.remoteNodeId,BigInt(Math.max(1,Math.trunc(t))),o=>this.sendRustOwnedHandshakeFrame(e,o)),this.installRustOwnedProjection(e,n))}async sendRustOwnedHandshakeFrame(e,t){if(!t||typeof t!="object"||Array.isArray(t)||t instanceof Map||t.type!=="handshake")throw new Error("[OpenRTC] Rust application-crypto handshake must be a JSON object");if(!await e.sendNativeControlEnvelope(t)){if(e.getControlFrameMode()==="native-main")throw new Error("[OpenRTC] Rust application-crypto handshake requires the labelled native-main route");await e.sendControl(t);}}installRustOwnedProjection(e$1,t,n){let i=this.wasmClient;if(!i||!this.hasRustKeyAgreementOwner()||!this.rustOwnedConnectionReady(e$1,n))return false;let o=this.negotiatedByConnectionId.get(e$1.id);o||(o={requireEncrypted:true,protectPayload:(a,c)=>{let d=i.protectConnectionApplicationPayload?.(e$1.id,a,Array.from(c));if(!d)throw new Error("[OpenRTC] Rust application crypto owner is unavailable");return new Uint8Array(d)},openPayload:(a,c)=>{try{let d=i.openConnectionApplicationPayload?.(e$1.id,a,Array.from(c));return d||e("[Client][KEY-AGREEMENT] Rust rejected application payload",{connectionId:e$1.id,typeId:a,payloadBytes:c.byteLength}),d?new Uint8Array(d):null}catch(d){return e("[Client][KEY-AGREEMENT] Rust failed to open application payload",{connectionId:e$1.id,typeId:a,payloadBytes:c.byteLength,error:d instanceof Error?d.message:String(d)}),null}}},this.negotiatedFingerprintByCrypto.set(o,"rust-owned"),this.index(e$1,o)),e$1.setApplicationCrypto(o);let s=this.ctx.registry.get(e$1.id);return s&&s!==e$1&&!s.isClosed&&s.setApplicationCrypto(o),e$1.markKeyAgreement(),this.notifyWaiters(),e("[Client][KEY-AGREEMENT] projected Rust-owned application crypto",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,reason:t}),true}async handleKeyAgreement(e,t,n){if(this.hasRustKeyAgreementOwner()){this.markRequired(e);let i=k$1(t.applicationKeyAgreement);if(!i)return {remotePublicChanged:false,cryptoReady:false,replyAction:null,replyClaimId:null};let o=await this.wasmClient?.handleConnectionApplicationCryptoHandshake?.(e.id,e.remoteNodeId,Number.isSafeInteger(n)&&Number(n)>0?BigInt(Number(n)):null,t.action??null,Array.from(i));o&&await this.sendRustOwnedHandshakeFrame(e,o);let s=this.installRustOwnedProjection(e,`rust-key-agreement:${t.action??"hello"}`,n);return s&&this.deps.notifyApplicationRouteReady(e,`rust-key-agreement:${t.action??"hello"}`),{remotePublicChanged:false,cryptoReady:s,replyAction:null,replyClaimId:null}}if(this.deps.getConfiguredApplicationCrypto())return {remotePublicChanged:false,cryptoReady:false,replyAction:null,replyClaimId:null};throw this.markRequired(e),new Error(`[OpenRTC] shared Rust application-crypto owner is unavailable for ${e.id}`)}async resyncConnectionKeyToNative(e){return this.hasRustKeyAgreementOwner()?this.installRustOwnedProjection(e,"rust-generation-projection"):false}releaseReplyClaim(e,t,n){}index(e,t){this.negotiatedByConnectionId.set(e.id,t);let n=new Set([e.id,e.remoteNodeId,e.deviceId,this.deps.getKnownDeviceIdForNode(e.remoteNodeId)??""]);for(let i of n){let o=typeof i=="string"?i.trim():"";o&&this.negotiatedByPeerId.set(o,t);}}getForConnectionOrPeer(e,t){return this.negotiatedByConnectionId.get(e)??this.negotiatedByPeerId.get(t)}indexPeer(e,t){let n=typeof e=="string"?e.trim():"";n&&this.negotiatedByPeerId.set(n,t);}reindexDevice(e){let t=typeof e.nodeId=="string"?e.nodeId.trim():"";if(!t||!e.deviceId)return;let n=this.getNegotiatedForPeer(t);n&&this.negotiatedByPeerId.set(e.deviceId,n);}async syncRequiredToNative(e){let t=this.wasmClient;!t||typeof t.setConnectionApplicationCryptoRequired!="function"||await t.setConnectionApplicationCryptoRequired(e);}markRequired(e){typeof e.requireApplicationCrypto=="function"&&e.requireApplicationCrypto(),this.syncRequiredToNative(e.id).catch(t=>{console.warn("[Client][KEY-AGREEMENT] Failed to sync required-crypto flag to native runtime",{connectionId:e.id,error:t});});}hydrateAdoptedConnection(e,t){return this.hasRustKeyAgreementOwner()?this.installRustOwnedProjection(e,t):false}get wasmClient(){return this.ctx.wasmClient}};var ws=15e3,Ts=2,Rs=150,on=class{constructor(e,t){this.ctx=e;this.deps=t;this.pendingTrustApprovals=new Map;this.pendingTrustApprovalScopes=new Map;this.rejectionCooldowns=new Map;this.approvedNodes=new Set;this.approvedConnectionIds=new Set;this.approvedScopesByConnectionId=new Map;this.routeRepairTokenByNodeId=new Map;this.routeRepairTokenPayloadByNodeId=new Map;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){if(this.disposed)return;this.disposed=true,this.deps.retirePendingReciprocalAdmissions("session-token-service-dispose"),this.deps.clearManagedPresenceTicket(),this.clearInMemoryState();let e=this.wasmClient;e&&typeof e.clear_session_tokens=="function"&&e.clear_session_tokens();}async getTicketWithToken(e,t=0){if(this.disposed)throw new Error("Session token service is disposed");await this.deps.ensureWasmRuntimeForP2P();let n=this.wasmClient;if(n&&typeof n.endpoint_ticket_with_token=="function"){let o=n.endpoint_ticket_with_token.bind(n);return await se(()=>o(e,t),{isActive:()=>!this.disposed})}if(e.trim()==="user-device")throw new Error("Managed user-device admission requires Rust/WASM endpoint_ticket_with_token support.");let i=await this.deps.getTicket();return this.buildCompoundTicketWithToken(i,e,t)}buildCompoundTicketWithToken(e,t,n=0){if(this.disposed)throw new Error("Session token service is disposed");let i=b$4(),o=t.trim()==="user-device"?void 0:Date.now()+9e5,s=this.wasmClient;return s&&typeof s.register_session_token=="function"&&(typeof o=="number"&&typeof s.register_token_until=="function"?s.register_token_until(i,t,n,BigInt(o)):s.register_session_token(i,t,n)),c$6(e,i,t,n,o)}registerSessionToken(e,t,n,i){if(this.disposed)return;let o=this.wasmClient;if(o&&typeof o.register_session_token=="function")if(typeof i=="number"){if(typeof o.register_token_until!="function")throw new Error("This OpenRTC WASM runtime cannot enforce admission-token expiry.");o.register_token_until(e,t,n,BigInt(i));}else o.register_session_token(e,t,n);}revokeSessionToken(e){if(this.disposed)return;h("Client.revokeSessionToken",{tokenLength:e.length}),this.deps.retirePendingReciprocalAdmissions("session-token-revoke");let t=this.wasmClient;if(t&&typeof t.revoke_session_token=="function"){let n=t.revoke_session_token(e),i=Array.isArray(n)?n.filter(o=>typeof o=="string"&&!!o.trim()):[];for(let o of i){let s=this.ctx.registry.get(o);this.clearConnectionApproval(o),s&&(this.approvedNodes.delete(s.remoteNodeId),this.disconnectConnectionBestEffort(s));}}}async revokeTokensByScope(e){if(this.disposed)return [];h("Client.revokeTokensByScope",{grantScope:e}),this.deps.retirePendingReciprocalAdmissions(`session-token-scope-revoke:${e}`);let t=e.trim(),n=Array.from(this.ctx.registry.values()).filter(u=>this.deps.getPeerScopes(u.id).some(h=>h===t)),i=Array.from(new Set([...Array.from(this.approvedScopesByConnectionId.entries()).filter(([,u])=>u===t).map(([u])=>u),...n.map(u=>u.id)])),o=new Map(Array.from(this.ctx.registry.values()).map(u=>[u.id,u])),s=Array.from(new Set([...n,...i.map(u=>o.get(u)).filter(u=>!!u)]));if(await this.deps.ensureWasmRuntimeForP2P(),this.disposed)return [];let a=this.wasmClient,c=a&&typeof a.revoke_tokens_by_scope=="function"?await a.revoke_tokens_by_scope(e):[],d=Array.from(new Set([...Array.isArray(c)?c:[],...i]));if(d.length===0)return [];let l=Array.from(new Set([...s,...d.map(u=>o.get(u)??this.ctx.registry.get(u)).filter(u=>!!u)])),p=new Set(l.map(u=>u.remoteNodeId?.trim()).filter(u=>!!u));for(let u of d)this.clearConnectionApproval(u);for(let u of p)this.approvedNodes.delete(u),this.routeRepairTokenByNodeId.delete(u),this.routeRepairTokenPayloadByNodeId.delete(u);return await Promise.allSettled(l.map(u=>this.disconnectConnectionBestEffort(u))),d}async clearSessionTokens(){if(h("Client.clearSessionTokens",{}),this.deps.retirePendingReciprocalAdmissions("session-token-clear"),this.disposed){this.clearInMemoryState();return}if(await this.deps.ensureWasmRuntimeForP2P(),this.deps.clearManagedPresenceTicket(),this.disposed){this.clearInMemoryState();return}this.clearInMemoryState();let e=this.wasmClient;e&&typeof e.clear_session_tokens=="function"&&e.clear_session_tokens();}async validateIncomingSessionToken(e,t,n){if(this.disposed)return {ok:false,reason:"session-token-service-disposed"};let i=this.wasmClient;if(!i||typeof i.validate_session_token!="function")return e.trim()?{ok:false,reason:"session-token-validator-unavailable"}:{ok:true};try{let o="";return t&&typeof i.validate_connection_token=="function"?o=n===void 0?await i.validate_connection_token(e,t):await i.validate_connection_token(e,t,n):o=i.validate_session_token(e),{ok:!0,scope:o||void 0}}catch(o){return {ok:false,reason:o?.message||`${o}`}}}async validateIncomingSessionTokenWithRetry(e$1,t,n){if(this.disposed)return {ok:false,reason:"session-token-service-disposed"};let i=await this.validateIncomingSessionToken(e$1,t,n?.tokenPayload);if(i.ok||!e$1||!(i.reason??"").toLowerCase().includes("unknown session token"))return i;for(let s=1;s<=Ts;s+=1){if(await a(Rs*s),this.disposed)return {ok:false,reason:"session-token-service-disposed"};if(i=await this.validateIncomingSessionToken(e$1,t,n?.tokenPayload),i.ok)return e("[Client][SESSION-TOKEN] validation recovered after retry",{source:n?.source??"unknown",remoteNodeId:n?.remoteNodeId??null,connectionId:t??null,attempt:s}),i}return i}rememberPendingTrustApproval(e,t){if(this.disposed||!e)return;this.pendingTrustApprovals.set(e,Date.now());let n=typeof t=="string"?t.trim():"";n?this.pendingTrustApprovalScopes.set(e,n):this.pendingTrustApprovalScopes.delete(e);}consumePendingTrustApproval(e){if(this.disposed)return {approved:false};let t=this.pendingTrustApprovals.get(e);if(!t)return {approved:false};let n=this.pendingTrustApprovalScopes.get(e)??null;return this.pendingTrustApprovals.delete(e),this.pendingTrustApprovalScopes.delete(e),Date.now()-t>ws?{approved:false}:{approved:true,scope:n}}applyTrustApproval(e$1,t,n="session-token"){if(this.disposed||!e$1||e$1.isClosed)return;let o=(typeof t=="string"?t.trim():"")||this.approvedScopesByConnectionId.get(e$1.id)||"";this.rememberPendingTrustApproval(e$1.id,o),this.rejectionCooldowns.delete(e$1.remoteNodeId),this.deps.clearTrustFailureCooldown(e$1.remoteNodeId),this.approvedNodes.add(e$1.remoteNodeId),this.approvedConnectionIds.add(e$1.id),o&&this.approvedScopesByConnectionId.set(e$1.id,o);let s=this.deps.sessionTokenScopeAllowsDeviceBinding(o),a=s?this.deps.getKnownDeviceIdForNode(e$1.remoteNodeId):null,c=this.deps.initializeConnectionTrust(e$1,a);c.required=false,c.verified=true,c.failed=false,c.failureReason=void 0,c.issuedChallenge=null,s?c.verifiedDeviceId=c.verifiedDeviceId??c.expectedDeviceId??a??null:(c.verifiedDeviceId=null,c.expectedDeviceId=null),this.deps.applyConnectionTrustProjection(e$1);let d=s?c.verifiedDeviceId??c.expectedDeviceId??a??null:null;d&&this.deps.bindConnectionDeviceIdInRust(e$1,d),o&&this.deps.addPeerScope(e$1.id,o),e("[Client][AUTH] session-token approval applied to connection trust",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,scope:t??null,source:n}),e$1.admissionReady?.("session-token-trust-applied");}clearConnectionApproval(e){this.disposed||(this.approvedConnectionIds.delete(e),this.approvedScopesByConnectionId.delete(e),this.pendingTrustApprovals.delete(e),this.pendingTrustApprovalScopes.delete(e));}approveNode(e){this.disposed||this.approvedNodes.add(e);}approveConnection(e){this.disposed||this.approvedConnectionIds.add(e);}isApproved(e,t){return this.approvedConnectionIds.has(e)||this.approvedNodes.has(t)}isApprovedNode(e){return this.approvedNodes.has(e)}isApprovedConnection(e){return this.approvedConnectionIds.has(e)}getApprovedNodes(){return this.approvedNodes}getApprovedConnectionIds(){return this.approvedConnectionIds}clearRejectionCooldown(e){this.rejectionCooldowns.delete(e);}getRejectionCooldown(e){return this.rejectionCooldowns.get(e)}setRejectionCooldown(e,t){this.disposed||this.rejectionCooldowns.set(e,t);}getApprovedScope(e){return this.approvedScopesByConnectionId.get(e)??null}setApprovedScope(e,t){this.disposed||this.approvedScopesByConnectionId.set(e,t);}rememberRouteRepairTokenForNode(e,t,n){this.disposed||(this.routeRepairTokenByNodeId.set(e,t),this.routeRepairTokenPayloadByNodeId.set(e,n));}forgetRouteRepairTokenForNode(e,t,n){this.routeRepairTokenByNodeId.get(e)!==t||this.routeRepairTokenPayloadByNodeId.get(e)!==n||(this.routeRepairTokenByNodeId.delete(e),this.routeRepairTokenPayloadByNodeId.delete(e));}async rememberRouteRepairTokenFromTicket(e){if(this.disposed)return false;let t=e.trim();if(!t)return false;let{irohTicket:n,tokenSuffix:i}=a$4(t);if(!i)return false;let o=d$5(n,i),s=typeof o?.t=="string"?o.t.trim():"",a=this.wasmClient;if(!s||typeof a?.endpoint_id_from_ticket!="function")return false;let c=String(await a.endpoint_id_from_ticket(n)).trim();return !c||this.disposed?false:(this.rememberRouteRepairTokenForNode(c,s,i),true)}getRouteRepairTokenForNode(e){return this.routeRepairTokenByNodeId.get(e)}getRouteRepairTokenPayloadForNode(e){return this.routeRepairTokenPayloadByNodeId.get(e)}clearInMemoryState(){this.routeRepairTokenByNodeId.clear(),this.routeRepairTokenPayloadByNodeId.clear(),this.pendingTrustApprovals.clear(),this.pendingTrustApprovalScopes.clear(),this.rejectionCooldowns.clear(),this.approvedNodes.clear(),this.approvedConnectionIds.clear(),this.approvedScopesByConnectionId.clear();}get wasmClient(){return this.ctx.wasmClient}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}};function sr(r){return new ai({getContext:()=>r.getClientContext(),getOptions:()=>r.options,ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getTicket:()=>r.runtimeIdentity.getTicket(),clearManagedPresenceTicketIfExists:()=>r.accessServices.clearManagedPresenceTicketIfExists(),retirePendingReciprocalAdmissionsIfExists:e=>r.retirePendingReciprocalAdmissionsIfExists(e),clearTrustFailureCooldown:e=>{r.connectionTrust.clearFailureCooldown(e);},sessionTokenScopeAllowsDeviceBinding:e=>r.connectionTrust.sessionTokenScopeAllowsDeviceBinding(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),initializeConnectionTrust:(e,t)=>r.connectionTrust.initialize(e,t),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>r.connectionDeviceBinder.bindConnectionDeviceIdInRust(e,t),addPeerScope:(e,t)=>{r.peerServices.addPeerScope(e,t);},getPeerScopes:e=>r.peerServices.getPeerScopes(e),getConfiguredApplicationCrypto:()=>r.options?.applicationCrypto,getKnownDeviceNodeId:e=>r.deviceDirectory.getKnownDeviceNodeId(e),getPeerState:e=>r.peerServices.getPeerState(e),notifyApplicationRouteReady:(e,t)=>r.applicationRoute.notifyApplicationRouteReady(e,t)})}var ai=class{constructor(e){this.host=e;}get sessionTokens(){return this._sessionTokens||(this._sessionTokens=new on(this.host.getContext(),{ensureWasmRuntimeForP2P:()=>this.host.ensureWasmRuntimeForP2P(),getTicket:()=>this.host.getTicket(),clearManagedPresenceTicket:()=>this.host.clearManagedPresenceTicketIfExists(),retirePendingReciprocalAdmissions:e=>this.host.retirePendingReciprocalAdmissionsIfExists(e),clearTrustFailureCooldown:e=>this.host.clearTrustFailureCooldown(e),sessionTokenScopeAllowsDeviceBinding:e=>this.host.sessionTokenScopeAllowsDeviceBinding(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),initializeConnectionTrust:(e,t)=>this.host.initializeConnectionTrust(e,t),applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>this.host.bindConnectionDeviceIdInRust(e,t),addPeerScope:(e,t)=>this.host.addPeerScope(e,t),getPeerScopes:e=>this.host.getPeerScopes(e)})),this._sessionTokens}get applicationCrypto(){return this._applicationCrypto||(this._applicationCrypto=new nn(this.host.getContext(),{getConfiguredApplicationCrypto:()=>this.host.getConfiguredApplicationCrypto(),getKnownDeviceNodeId:e=>this.host.getKnownDeviceNodeId(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),getPeerState:e=>this.host.getPeerState(e),notifyApplicationRouteReady:(e,t)=>this.host.notifyApplicationRouteReady(e,t)})),this._applicationCrypto}resolveExistingApplicationCryptoForPeer(e,t){return this._applicationCrypto?.resolveForPeer(e,t)}getApplicationCrypto(e){return this.host.getConfiguredApplicationCrypto()||!e?this.host.getConfiguredApplicationCrypto():this.applicationCrypto.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.host.getConfiguredApplicationCrypto()||!e&&!t?this.host.getConfiguredApplicationCrypto():this.applicationCrypto.resolveForPeer(e,t)}clearApplicationCryptoForConnection(e){this._applicationCrypto?.clearConnection(e);}releaseApplicationKeyAgreementReply(e,t,n){this._applicationCrypto?.releaseReplyClaim(e,t,n);}waitForApplicationCryptoForPeer(e,t=0){return this.host.getConfiguredApplicationCrypto()||!e||t<=0?Promise.resolve(this.host.getConfiguredApplicationCrypto()):this.applicationCrypto.waitForPeer(e,t)}};var rn=class{constructor(e){this.deps=e;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}buildApplicationIncomingStreamEvent(e){if(this.disposed)return e;if((e.protocolHint==="explicit"||!!e.channel?.channelId)&&e.applicationAuthorized!==true&&!this.deps.isManagedApplicationStreamAuthorized(e.remoteNodeId))return this.deps.logIncomingDiagnostic("session-token:drop-unadmitted-application-stream",{remoteNodeId:e.remoteNodeId||"unknown",traceId:e.traceId||null,protocolHint:e.protocolHint??null,channelId:e.channel?.channelId??null}),{...e,invalid:true};if(this.shouldTreatIncomingStreamAsTransportOnly(e))return e;let n=this.deps.resolveCryptoStreams(e.remoteNodeId);if(!n||e.invalid||e.protocolHint==="explicit"||e.protocolHint==="native-main")return e;try{if(e.type==="uni"){let i=e.stream;return !i||typeof i.getReader!="function"?e:i.applicationCryptoWrapped===!0?{...e,applicationCrypto:n}:{...e,stream:n.wrapReadable(i),applicationCrypto:n}}if(e.type==="bi"&&e$4(e.stream)){let i=e.stream;return i?.applicationCryptoWrapped===!0?{...e,applicationCrypto:n}:e.protocolHint==="control"?{...e,applicationCrypto:n}:{...e,stream:{...i,send:n.wrapWritable(i.send),recv:n.wrapReadable(i.recv)},applicationCrypto:n}}}catch(i){this.deps.logIncomingDiagnostic("application-crypto:wrap-listener-stream-failed",{remoteNodeId:e.remoteNodeId||"unknown",traceId:e.traceId||null,protocolHint:e.protocolHint??null,error:i});}return e}shouldTreatIncomingStreamAsTransportOnly(e){if(this.disposed||e.type!=="bi")return false;let t=e.channel?.channelId;return t?this.deps.isTransportOnlyChannel(t):e.protocolHint!=="explicit"?false:this.deps.usesTicketOnlySignalingMode()?true:this.deps.hasTransportOnlyConnectionForRemoteNode(e.remoteNodeId)}};var sn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}assertActive(){if(this.disposed)throw new Error("Application stream controller is disposed")}async closeWritableBestEffort(e){if(e)try{let t=e.getWriter?.();if(!t)return;try{await t.close();}catch{}finally{try{t.releaseLock();}catch{}}}catch{}}async openBi(e$1){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.ctx.wasmClient;if(typeof t.open_peer_bi!="function")throw new Error("[OpenRTC] Rust protected peer-stream open is unavailable in this runtime.");e("[Client][OPEN-BI] Opening bidirectional application stream",{peerId:e$1});let n=await t.open_peer_bi(e$1,5e3);return this.disposed&&(await h$2(n,"application-stream-controller-disposed-after-open-bi"),this.assertActive()),e("[Client][OPEN-BI] Bidirectional application stream opened",{peerId:e$1,endpointId:n?.endpoint_id??n?.endpointId??null,applicationCryptoWrapped:n?.applicationCryptoWrapped===true}),{readable:n.recv,writable:n.send}}async openUni(e){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let t=this.ctx.wasmClient;if(typeof t.open_peer_uni!="function")throw new Error("[OpenRTC] Rust protected peer-stream open is unavailable in this runtime.");let n=await t.open_peer_uni(e,5e3),i=n?.writable??n;return this.disposed&&(await this.closeWritableBestEffort(i),this.assertActive()),i}async sendFrame(e,t){this.assertActive(),await this.deps.ensureWasmRuntimeForP2P(),this.assertActive();let n=this.ctx.wasmClient;if(typeof n.send_peer_application_frame!="function")throw new Error("[OpenRTC] Rust protected application-frame send is unavailable in this runtime.");await n.send_peer_application_frame(e,t,5e3),this.assertActive();}};function Ke(r){try{let e=r?.type;return typeof e=="string"?e:"unknown"}catch{return "unknown"}}function Ne(r){try{let e=r?.endpointId;if(typeof e=="string"&&e.trim().length>0)return e}catch{}try{let e=r?.endpoint_id;if(typeof e=="string"&&e.trim().length>0)return e}catch{}return "unknown"}function ci(r){try{let e=r?.transportStableId??r?.transport_stable_id;if(Number.isSafeInteger(e)&&Number(e)>0)return Number(e)}catch{}return null}function ar(r){try{let e=r?.protocolHint;if(e==="control"||e==="explicit"||e==="native-main")return e}catch{}return null}function cr(r){try{if(!r||!("channel"in r))return {present:!1,channel:null};let e=r.channel;if(e==null)return {present:!0,channel:null};if(typeof e!="object")return {present:!1,channel:null};let t=typeof e.channelId=="string"?e.channelId.trim():"";if(!t)return {present:!1,channel:null};let n=e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)?e.metadata:null;return {present:!0,channel:{channelId:t,metadata:n}}}catch{return {present:false,channel:null}}}var Ae=class Ae{constructor(e){this.wasmClient=e;this.clients=new Set;this.listenLoopTask=null;this.activeDispatches=new Set;this.activeReader=null;}addClient(e){this.clients.has(e)||(this.clients.add(e),this.ensureListening());}removeClient(e){this.clients.delete(e),this.clients.size===0&&this.activeReader?.cancel("no active incoming-stream clients").catch(()=>{});}dispatchIncomingAsync(e,t){let n=Ne(e),i=performance.now(),o=this.dispatchIncoming(e).then(()=>{let s=performance.now()-i;s>50&&console.warn(`[PERFORMANCE] handleIncomingStream loop took abnormally long: ${Math.round(s)}ms`,{endpointId:n,type:t});}).catch(s=>{console.error("[Client][INCOMING] Failed to handle incoming stream via shared hub",{remoteNodeId:n,type:t,error:s instanceof Error?s.message:String(s)});}).finally(()=>{this.activeDispatches.delete(o);});this.activeDispatches.add(o);}ensureListening(){this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null,this.clients.size>0&&this.ensureListening();}));}getPrimaryClient(){let e=this.clients.values().next();return e.done?null:e.value}getChannelTargetClients(e){return Array.from(this.clients).reverse().filter(t=>t.hasIncomingChannelListener(e))}async dispatchIncoming(e){let t=this.getPrimaryClient();if(!t)return;let n=Array.from(this.clients).some(a=>a.shouldInspectIncomingChannelEnvelope()),i=await t.normalizeIncomingStreamEvent(e,{inspectChannelEnvelope:n}),o=i.channel?.channelId?.trim();if(o&&t.isInternalSessionChannel(o)){await t.handleUnhandledIncomingStreamEvent(i);return}if(o){for(let a of this.getChannelTargetClients(o))if(a.dispatchIncomingChannelListeners(i))return}let s=this.getPrimaryClient();if(s){if(i.protocolHint==="native-main"){await s.handleUnhandledIncomingStreamEvent(i);return}s.dispatchIncomingGenericListeners(i)||await s.handleUnhandledIncomingStreamEvent(i);}}async listenLoop(){let e$1=0;for(;;){if(this.clients.size===0)return;let t=null;try{let i=(await this.wasmClient.incoming_streams()).getReader();for(t=i,this.activeReader=i,e$1=0,ae()&&Dt()&&e("[Client][INCOMING][MOBILE] shared-hub reader acquired",{sharedHubClients:this.clients.size});this.clients.size>0;){let{done:o,value:s}=await i.read();if(o)throw new Error("incoming stream reader closed unexpectedly");if(!s)continue;let a=Ke(s);a!=="uni"&&e("[Client][INCOMING] Received stream from WASM node",{type:a,endpointId:Ne(s),sharedHubClients:this.clients.size}),this.dispatchIncomingAsync(s,a);}}catch(n){if(this.clients.size===0)return;e$1+=1;let i=d$1(e$1,Ae.RETRY_MIN_DELAY_MS,Ae.RETRY_MAX_DELAY_MS);console.warn("[Client][INCOMING] Shared listen loop restarting after stream failure",{attempt:e$1,delayMs:i,mobile:ae(),error:n}),await a(i);}finally{if(this.activeReader===t&&(this.activeReader=null),t)try{t.releaseLock(),ae()&&Dt()&&e("[Client][INCOMING][MOBILE] shared-hub reader released",{sharedHubClients:this.clients.size});}catch{}}}}};Ae.RETRY_MIN_DELAY_MS=250,Ae.RETRY_MAX_DELAY_MS=2e3;var an=Ae;var dr=Symbol.for("openrtc.shared-incoming-stream-hubs");function ks(){let r=globalThis,e=r[dr];return e||(e=new WeakMap,r[dr]=e),e}var ze=class ze{constructor(e,t){this.ctx=e;this.deps=t;this.listening=false;this.presenceStarted=false;this.listenLoopTask=null;this.hubClient={hasIncomingChannelListener:n=>this.deps.hasIncomingChannelListener(n),hasAnyIncomingChannelListeners:()=>this.deps.hasAnyIncomingChannelListeners(),shouldInspectIncomingChannelEnvelope:()=>this.deps.shouldInspectIncomingChannelEnvelope(),isInternalSessionChannel:n=>this.deps.isInternalSessionChannel(n),normalizeIncomingStreamEvent:(n,i)=>this.deps.normalizeIncomingStreamEvent(n,i),dispatchIncomingChannelListeners:n=>this.deps.dispatchIncomingChannelListeners(n),dispatchIncomingGenericListeners:n=>this.deps.dispatchIncomingGenericListeners(n),handleUnhandledIncomingStreamEvent:n=>this.deps.handleUnhandledIncomingStreamEvent(n)},this.ctx.registerDisposer(()=>this.stop());}async start(e={}){if(this.listening)return;await this.deps.ensureWasmRuntimeForP2P();let t=false;this.markListening(false);try{let n=this.getSharedIncomingStreamHub();n?(n.addClient(this.hubClient),t=!0):this.listenLoopTask||(this.listenLoopTask=this.listenLoop().finally(()=>{this.listenLoopTask=null;})),e.startPresence!==!1&&(await this.deps.startPresenceForListen(),this.presenceStarted=!0);}catch(n){throw this.markStopped(),this.presenceStarted=false,t&&this.getSharedIncomingStreamHub()?.removeClient(this.hubClient),n}}stop(){let e=this.listening;if(this.markStopped(),e)for(let t of Array.from(this.ctx.registry.values()))t.isClosed||this.disconnectBestEffort(t);this.getSharedIncomingStreamHub()?.removeClient(this.hubClient),e&&this.presenceStarted&&this.deps.setOfflinePresence(),this.presenceStarted=false;}prepareForSignOut(){this.markStopped(),this.presenceStarted=false;}isListening(){return this.listening}markListening(e=true){this.listening=true,this.presenceStarted=e;}markStopped(){this.listening=false;}getSharedIncomingStreamHub(){let e=this.ctx.wasmClient;if(!e||typeof e.incoming_streams!="function"||e.__openrtcNativeCapabilityProjection===true)return null;let t=e,n=ze.incomingStreamHubs.get(t);return n||(n=new an(e),ze.incomingStreamHubs.set(t,n)),n}async listenLoop(){await this.deps.getIncomingStreamRouter().listenLoop({isListening:()=>this.listening,getWasmClient:()=>this.ctx.wasmClient,handleIncomingStream:e=>this.handleIncomingStream(e),shouldVerboseIncomingDiagnostics:()=>this.deps.shouldVerboseIncomingDiagnostics(),getLocalNodeId:()=>this.ctx.localNodeId||null,retryMinDelayMs:this.deps.retryMinDelayMs,retryMaxDelayMs:this.deps.retryMaxDelayMs});}async handleIncomingStream(e){return this.deps.handleIncomingStream(e)}shouldInspectIncomingChannelEnvelope(){return this.deps.shouldInspectIncomingChannelEnvelope()}normalizeIncomingStreamEvent(e,t={}){return this.deps.normalizeIncomingStreamEvent(e,t)}dispatchIncomingChannelListeners(e){return this.deps.dispatchIncomingChannelListeners(e)}dispatchIncomingGenericListeners(e){return this.deps.dispatchIncomingGenericListeners(e)}handleUnhandledIncomingStreamEvent(e){return this.deps.handleUnhandledIncomingStreamEvent(e)}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}};ze.incomingStreamHubs=ks();var cn=ze;var dn=class{constructor(e){this.deps=e;this.traceSequence=0;}getRuntimeSafetyProfile(){return this.deps.getRuntimeSafetyProfileOverride()??je(this.deps.getOptions()??{})}shouldVerboseIncomingDiagnostics(){return this.getRuntimeSafetyProfile().diagnosticsMode}shouldInspectIncomingChannelEnvelope(){return this.getRuntimeSafetyProfile().skipIncomingChannelEnvelopeInspection?false:this.deps.hasAnyIncomingChannelListeners()||this.deps.requiresIncomingChannelEnvelopeInspection()}nextIncomingTraceId(e,t){Number.isFinite(this.traceSequence)||(this.traceSequence=0),this.traceSequence+=1;let n=t&&t.length>0?t.slice(0,8):"unknown";return `${e}-${n}-${this.traceSequence.toString(36)}`}logIncomingDiagnostic(e$1,t){this.shouldVerboseIncomingDiagnostics()&&e(`[Client][INCOMING][MOBILE] ${e$1}`,t);}safeReleaseReaderLock(e,t,n,i=(o,s)=>this.logIncomingDiagnostic(o,s)){try{e.releaseLock(),i("releaseLock:ok",{context:t,traceId:n||null});}catch(o){console.warn("[Client][INCOMING] releaseLock failed",{context:t,traceId:n||null,error:o});}}async cancelUnhandledIncomingUniStream(e,t,n=(i,o)=>this.logIncomingDiagnostic(i,o)){if(!(!e||typeof e!="object")){if(this.shouldVerboseIncomingDiagnostics()){n("uni:drop-unhandled",{remoteNodeId:t||"unknown"});return}try{let i=e;if(typeof i.cancel=="function")return;if(typeof i.getReader=="function"){let o=i.getReader();try{await o.read().catch(()=>{});}finally{try{o.releaseLock();}catch{}}f("[Client][INCOMING] Released unhandled uni stream reader",{remoteNodeId:t});}}catch(i){console.warn("[Client][INCOMING] Failed to cancel unhandled uni stream",{remoteNodeId:t,error:i});}}}shouldSkipIncomingStreamProbe(){return this.getRuntimeSafetyProfile().skipIncomingBiProbe===true}};var ln=class{constructor(e,t){this.config=e;this.deps=t;}async normalize(e,t){return this.deps.router.normalizeIncomingStreamEvent(e,t,this.normalizationDeps())}async extractIncomingChannelEnvelope(e,t,n){return this.deps.router.extractIncomingChannelEnvelope(e,t,this.channelInspectionDeps(),n)}async classifyBiIncomingStream(e,t){return this.deps.router.classifyBiIncomingStream(e,this.channelInspectionDeps(),t)}async maybeOpenEncryptedExplicitBiStream(e,t,n){return this.deps.router.maybeOpenEncryptedExplicitBiStream(e,this.cryptoProbeConfig(),this.cryptoProbeDeps(),t,n)}wrapIncomingBi(e,t,n){return this.deps.router.wrapIncomingBi(e,this.cryptoProbeDeps(),t,n)}async maybeOpenEncryptedControlBiStream(e,t,n){return this.deps.router.maybeOpenEncryptedControlBiStream(e,this.cryptoProbeConfig(),this.cryptoProbeDeps(),t,n)}async detectNativeMainStream(e,t,n){return this.deps.router.detectNativeMainStream(e,t,{nativeMainProtocolByte:this.config.nativeMainProtocolByte,explicitProtocolByte:this.config.explicitProtocolByte,label:this.config.nativeMainLabel,maxLabelBytes:this.config.nativeMainMaxLabelBytes},this.channelInspectionDeps(),n)}channelInspectionDeps(){return {inspectIncomingStreamPrefix:(e,t)=>{let n=this.deps.getWasmClient();if(typeof n?.inspectIncomingStreamPrefix!="function")throw new Error("[OpenRTC] Shared Rust incoming-stream classifier is unavailable.");return n.inspectIncomingStreamPrefix(e,t)},decodeIncomingChannelEnvelope:e=>{let t=this.deps.getWasmClient();if(typeof t?.decodeIncomingChannelEnvelope!="function")throw new Error("[OpenRTC] Shared Rust channel-envelope decoder is unavailable.");return t.decodeIncomingChannelEnvelope(e)},logIncomingDiagnostic:(e,t)=>this.deps.logIncomingDiagnostic(e,t),releaseReaderLock:(e,t,n)=>this.deps.releaseReaderLock(e,t,n)}}cryptoProbeConfig(){return {explicitProtocolByte:this.config.explicitProtocolByte,maxEncryptedFrameBytes:this.config.maxEncryptedFrameBytes,probeDeadlineMs:this.config.probeDeadlineMs}}cryptoProbeDeps(){return {...this.channelInspectionDeps(),resolveApplicationCryptoForPeer:e=>this.deps.resolveApplicationCryptoForPeer(e),waitForApplicationCryptoForPeer:e=>this.deps.waitForApplicationCryptoForPeer(e,this.config.explicitApplicationCryptoWaitMs),resolveCryptoStreams:e=>this.deps.resolveCryptoStreams(e)}}normalizationDeps(){return {...this.cryptoProbeDeps(),nextIncomingTraceId:(e,t)=>this.deps.nextIncomingTraceId(e,t),normalizeAuthoritativeIncomingProtocolHint:(e,t,n)=>Tt(e),shouldStripIncomingMainLabel:()=>To(this.deps.shouldSkipIncomingStreamProbe()),shouldSkipIncomingBiProbeForRemoteNode:e=>this.deps.shouldSkipIncomingBiProbeForRemoteNode(e),inferTicketFlowBiProtocolHint:e=>this.deps.inferTicketFlowBiProtocolHint(e),shouldSkipIncomingStreamProbe:()=>this.deps.shouldSkipIncomingStreamProbe(),isTransportOnlyChannel:e=>this.deps.isTransportOnlyChannel(e),detectNativeMainStream:(e,t,n)=>this.detectNativeMainStream(e,t,n),extractIncomingChannelEnvelope:(e,t,n)=>this.extractIncomingChannelEnvelope(e,t,n),classifyBiIncomingStream:(e,t)=>this.classifyBiIncomingStream(e,t),wrapIncomingBi:(e,t,n)=>this.wrapIncomingBi(e,t,n),maybeOpenEncryptedExplicitBiStream:(e,t,n)=>this.maybeOpenEncryptedExplicitBiStream(e,t,n),maybeOpenEncryptedControlBiStream:(e,t,n)=>this.maybeOpenEncryptedControlBiStream(e,t,n)}}};var Ve=class extends Error{},pn=class{wrapIncomingBi(e,t,n,i){if(!e$4(e)||e?.applicationCryptoWrapped===true)return e;let o=t.resolveCryptoStreams(n);if(!o)return e;try{return {...e,send:o.wrapWritable(e.send),recv:o.wrapReadable(e.recv),applicationCryptoWrapped:!0}}catch(s){return t.logIncomingDiagnostic("application-crypto:early-wrap-incoming-bi-failed",{remoteNodeId:n||"unknown",traceId:i||null,error:s}),e}}async maybeOpenEncryptedExplicitBiStream(e,t,n,i,o){let s=n.resolveApplicationCryptoForPeer(o);if(!e$4(e))return e;let a;try{a=e.recv.getReader();}catch{return e}let c$1=(v,y,S=null)=>i$2(a,v,{context:y,traceId:i,pendingRead:S,release:C=>n.releaseReaderLock(a,`${y}:${C}`,i),log:(C,P)=>n.logIncomingDiagnostic(C,P)}),d=v=>g$2(e,v),l=[],p=new Uint8Array(0),u=null,h=Date.now()+t.probeDeadlineMs,f=async()=>{let v=await j$2(a,h);return v.status==="timeout"?(u=v.pendingRead??null,false):v.status==="done"?false:(v.value&&v.value.byteLength>0&&(l.push(v.value),p=c(l)),true)},m=()=>u?(n.logIncomingDiagnostic("explicit-crypto:probe-deadline",{traceId:i||null,endpointId:o||"unknown",bufferedBytes:p.byteLength}),d(c$1(p,"explicit-crypto:probe-deadline",u))):null;try{for(;p.byteLength<5&&await f(););let v=m();if(v)return v;if(p.byteLength<5||p[0]!==t.explicitProtocolByte)return d(c$1(p,"explicit-crypto:not-probeable"));let y=new DataView(p.buffer,p.byteOffset+1,p.byteLength-1).getUint32(0,!1);if(y===0||y>t.maxEncryptedFrameBytes){let A=p.slice(1);return this.looksLikeApplicationCryptoEnvelope(A)?(s||(n.logIncomingDiagnostic("explicit-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),s=await n.waitForApplicationCryptoForPeer(o)),s?(n.logIncomingDiagnostic("explicit-crypto:unframed-encrypted-body",{traceId:i||null,endpointId:o||"unknown"}),d(this.unframedEncryptedExplicitReadable(a,A,s,t.explicitProtocolByte,n,i))):this.rejectEncryptedStreamWithoutCrypto(a,n,i,o,"explicit-crypto:unframed-encrypted-body-missing-key")):d(c$1(p,"explicit-crypto:not-encrypted-length"))}let S=5+y;for(;p.byteLength<S&&await f(););let C=m();if(C)return C;if(p.byteLength<S)return d(c$1(p,"explicit-crypto:truncated-probe"));let P=p.slice(5,S);if(!a$5(P))return d(c$1(p,"explicit-crypto:legacy-plaintext"));if(s||(n.logIncomingDiagnostic("explicit-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),s=await n.waitForApplicationCryptoForPeer(o)),!s)return n.logIncomingDiagnostic("explicit-crypto:encrypted-body-missing-key",{traceId:i||null,endpointId:o||"unknown"}),this.rejectEncryptedStreamWithoutCrypto(a,n,i,o,"explicit-crypto:encrypted-body-missing-key");let k=c$1(p.slice(1),"explicit-crypto:encrypted-body");return d(this.encryptedExplicitReadable(k,s,t.explicitProtocolByte,n,i))}catch(v){if(v instanceof Ve)throw v;return n.logIncomingDiagnostic("explicit-crypto:probe-error",{traceId:i||null,error:v?.message||String(v)}),d(c$1(p,"explicit-crypto:probe-error"))}}async maybeOpenEncryptedControlBiStream(e,t,n,i,o){if(!e$4(e)||e?.applicationCryptoWrapped===true)return e;let s;try{s=e.recv.getReader();}catch{return e}let a=(m,v,y=null)=>i$2(s,m,{context:v,traceId:i,pendingRead:y,release:S=>n.releaseReaderLock(s,`${v}:${S}`,i),log:(S,C)=>n.logIncomingDiagnostic(S,C)}),c$1=m=>g$2(e,m),d=[],l=new Uint8Array(0),p=null,u=Date.now()+t.probeDeadlineMs,h=async()=>{let m=await j$2(s,u);return m.status==="timeout"?(p=m.pendingRead??null,false):m.status==="done"?false:(m.value&&m.value.byteLength>0&&(d.push(m.value),l=c(d)),true)},f=()=>p?(n.logIncomingDiagnostic("control-crypto:probe-deadline",{traceId:i||null,endpointId:o||"unknown",bufferedBytes:l.byteLength}),c$1(a(l,"control-crypto:probe-deadline",p))):null;try{for(;l.byteLength<4&&await h(););let m=f();if(m)return m;if(l.byteLength<4)return c$1(a(l,"control-crypto:not-probeable"));let v=new DataView(l.buffer,l.byteOffset,l.byteLength).getUint32(0,!1);if(v===0||v>t.maxEncryptedFrameBytes)return c$1(a(l,"control-crypto:plaintext-length"));let y=4+Math.min(v,7);for(;l.byteLength<y&&await h(););let S=f();if(S)return S;if(l.byteLength<y)return c$1(a(l,"control-crypto:truncated-probe"));let C=l.slice(4,y);if(!this.looksLikeApplicationCryptoEnvelope(C))return c$1(a(l,"control-crypto:plaintext-frame"));let P=n.resolveApplicationCryptoForPeer(o);if(P||(n.logIncomingDiagnostic("control-crypto:await-key",{traceId:i||null,endpointId:o||"unknown"}),P=await n.waitForApplicationCryptoForPeer(o)),!P)return n.logIncomingDiagnostic("control-crypto:encrypted-body-missing-key",{traceId:i||null,endpointId:o||"unknown"}),this.rejectEncryptedStreamWithoutCrypto(s,n,i,o,"control-crypto:encrypted-body-missing-key");n.logIncomingDiagnostic("control-crypto:encrypted-frame",{traceId:i||null,endpointId:o||"unknown",frameLength:v});let k=c$7(P);return {...e,send:k.wrapWritable(e.send),recv:k.wrapReadable(a(l,"control-crypto:encrypted-frame")),applicationCryptoWrapped:!0}}catch(m){if(m instanceof Ve)throw m;return n.logIncomingDiagnostic("control-crypto:probe-error",{traceId:i||null,endpointId:o||"unknown",error:m?.message||String(m)}),c$1(a(l,"control-crypto:probe-error"))}}encryptedExplicitReadable(e,t,n,i,o){let a=c$7(t).wrapReadable(e).getReader(),c=false;return new ReadableStream({async pull(d){if(!c){c=true,d.enqueue(new Uint8Array([n]));return}try{let{done:l,value:p}=await a.read();if(l){d.close(),a.releaseLock();return}p&&d.enqueue(p);}catch(l){d.error(l);try{a.releaseLock();}catch{}}},async cancel(d){try{await a.cancel(d);}catch{}try{a.releaseLock();}catch{}i.logIncomingDiagnostic("explicit-crypto:cancel",{traceId:o||null});}})}unframedEncryptedExplicitReadable(e,t,n,i,o,s){let a=false,c$1=false;return new ReadableStream({async pull(d){if(!a){a=true,d.enqueue(new Uint8Array([i]));return}if(c$1){d.close();return}c$1=true;let l=[t];try{for(;;){let{done:h,value:f}=await e.read();if(h)break;f&&f.byteLength>0&&l.push(new Uint8Array(f));}let p=c(l),u=n.openPayload(3,p);if(!u)throw new Error("[OpenRTC] encrypted explicit body failed authentication");d.enqueue(u),d.close();}catch(p){d.error(p);}finally{try{e.releaseLock();}catch{}}},async cancel(d){try{await e.cancel(d);}catch{}try{e.releaseLock();}catch{}o.logIncomingDiagnostic("explicit-crypto:unframed-cancel",{traceId:s||null});}})}looksLikeApplicationCryptoEnvelope(e){return e.byteLength>=7&&e[0]===79&&e[1]===82&&e[2]===84&&e[3]===67&&e[4]===69&&e[5]===49}async rejectEncryptedStreamWithoutCrypto(e,t,n,i,o){let s=new Ve(`[OpenRTC] rejected encrypted stream without negotiated application crypto (${o})`);try{await e.cancel(s);}catch{}throw t.releaseReaderLock(e,o,n),t.logIncomingDiagnostic("application-crypto:stream-rejected",{traceId:n||null,endpointId:i||"unknown",context:o}),s}};var De=class{async extractIncomingUniChannelEnvelope(e,t,n,i){let o={send:new WritableStream,recv:e,endpoint_id:t},s=await this.extractIncomingChannelEnvelope(o,t,n,i);return {stream:s.stream.recv,channel:s.channel}}async extractIncomingChannelEnvelope(e$1,t,n,i){if(!e$4(e$1))return {stream:e$1,channel:null};let o;try{o=e$1.recv.getReader(),n.logIncomingDiagnostic("channel-envelope:reader-acquired",{traceId:i||null,remoteNodeId:t||"unknown"});}catch(p){return console.warn("[Client][CHANNEL] Incoming stream recv reader unavailable; skipping channel envelope inspection",{remoteNodeId:t,traceId:i||null,error:p}),{stream:e$1,channel:null}}let s=(p,u)=>i$2(o,p,{context:u,traceId:i,release:h=>n.releaseReaderLock(o,`${u}:${h}`,i),log:(h,f)=>n.logIncomingDiagnostic(h,f)}),a=p=>g$2(e$1,p),c$1=new Uint8Array,d=n.decodeIncomingChannelEnvelope(c$1);try{for(;d.status==="need-more";){let{done:p,value:u}=await o.read();if(p)break;u?.byteLength&&(c$1=c([c$1,new Uint8Array(u)]),d=n.decodeIncomingChannelEnvelope(c$1));}}catch(p){return console.warn("[Client][CHANNEL] Failed reading incoming channel envelope prefix",{remoteNodeId:t,traceId:i||null,error:p}),n.releaseReaderLock(o,"extractIncomingChannelEnvelope:read-prefix-failed",i),{stream:e$1,channel:null}}if(d.status!=="decoded")return e("[Client][CHANNEL] Incoming stream did not contain a complete channel envelope",{remoteNodeId:t,traceId:i||null,bufferedBytes:c$1.byteLength,rustDecision:d.status}),{stream:a(s(c$1,"extractIncomingChannelEnvelope:not-envelope")),channel:null};let l=a(s(c$1.slice(d.consumedPrefixLen),"extractIncomingChannelEnvelope:channel-envelope-consumed"));return e("[Client][CHANNEL] Incoming channel envelope consumed",{remoteNodeId:t,traceId:i||null,channelId:d.channel.channelId,metadata:d.channel.metadata?Object.keys(d.channel.metadata):[],bufferedBytes:c$1.byteLength,remainingBytes:Math.max(0,c$1.byteLength-d.consumedPrefixLen)}),{stream:l,channel:d.channel}}async classifyBiIncomingStream(e$1,t,n){if(!e$4(e$1))return {stream:e$1,protocolHint:"unknown"};let i;try{i=e$1.recv.getReader();}catch{return {stream:e$1,protocolHint:"unknown"}}let o=new Uint8Array,s=t.inspectIncomingStreamPrefix(o,false);try{for(;s.status==="need-more";){let{done:d,value:l}=await i.read();if(d){s=t.inspectIncomingStreamPrefix(o,!0);break}l?.byteLength&&(o=c([o,new Uint8Array(l)]),s=t.inspectIncomingStreamPrefix(o,!1));}}catch{return t.releaseReaderLock(i,"classifyBiIncomingStream:read-failed",n),{stream:e$1,protocolHint:"unknown"}}if(!o.byteLength)return t.releaseReaderLock(i,"classifyBiIncomingStream:empty-first-read",n),e("[Client][INCOMING] classifyBiIncomingStream: empty read",{traceId:n||null}),{stream:e$1,protocolHint:"unknown"};let a=s.status==="complete"?s.protocolHint:"unknown";return e("[Client][INCOMING] classifyBiIncomingStream: Rust prefix decision",{traceId:n||null,protocolHint:a,bufferedBytes:o.byteLength}),{stream:g$2(e$1,i$2(i,o,{context:"classifyBiIncomingStream:inspected-prefix",traceId:n,release:d=>t.releaseReaderLock(i,`classifyBiIncomingStream:inspected-prefix:${d}`,n),log:(d,l)=>t.logIncomingDiagnostic(d,l)})),protocolHint:a}}async detectNativeMainStream(e$1,t,n,i,o){if(!e$4(e$1))return {handled:false,stream:e$1,protocolHint:"unknown"};let s;try{s=e$1.recv.getReader();}catch(m){return console.warn("[Client][NATIVE-MAIN] Incoming stream recv reader unavailable",{remoteNodeId:t,traceId:o||null,error:m}),{handled:false,stream:e$1,protocolHint:"control"}}let a=(m,v)=>i$2(s,m,{context:v,traceId:o,release:y=>i.releaseReaderLock(s,`${v}:${y}`,o),log:(y,S)=>i.logIncomingDiagnostic(y,S)}),c$1=m=>g$2(e$1,m),d=new Uint8Array,l=false,p=i.inspectIncomingStreamPrefix(d,l);try{for(;p.status==="need-more";){let{done:m,value:v}=await s.read();if(m){l=!0,p=i.inspectIncomingStreamPrefix(d,!0);break}v?.byteLength&&(d=c([d,new Uint8Array(v)]),p=i.inspectIncomingStreamPrefix(d,!1));}}catch(m){return console.warn("[Client][NATIVE-MAIN] Failed reading incoming prefix",{remoteNodeId:t,traceId:o||null,error:m}),i.releaseReaderLock(s,"detectNativeMainStream:read-prefix-failed",o),{handled:false,stream:e$1,protocolHint:"control"}}if(p.status!=="complete"||p.protocolHint!=="native-main")return {handled:false,stream:c$1(a(d,"detectNativeMainStream:not-native-main")),protocolHint:p.status==="complete"?p.protocolHint:"control"};let u=p.nativeMainLabel,h=u==="signal";if(u!==n.label&&!h)return {handled:false,stream:c$1(a(d,"detectNativeMainStream:label-mismatch")),protocolHint:"control"};let f=c$1(a(d.slice(p.consumedPrefixLen),"detectNativeMainStream:label-consumed"));return h&&(f.native_signal_only=true),e("[Client][NATIVE-MAIN] Detected desktop native main stream",{remoteNodeId:t,traceId:o||null,label:u,nativeSignalOnly:h}),{handled:true,stream:f,protocolHint:"native-main"}}};var un=class{constructor(){this.protocolInspector=new De;}async normalize(e,t,n){let i=n.resolveCryptoStreams(t.endpointId),o=!!i,s=i?i.wrapReadable(e):e,a=t.authoritativeChannel;if(!a&&t.inspectChannelEnvelope){let c=await this.protocolInspector.extractIncomingUniChannelEnvelope(s,t.endpointId,n,t.traceId);s=c.stream,a=c.channel;}return o&&Object.defineProperty(s,"applicationCryptoWrapped",{configurable:true,value:true}),{stream:s,channel:a}}};var gn=class{constructor(e){this.deps=e;this.messageListeners=[];this.roomRequestListeners=[];this.streamListeners=[];this.channelStreamListeners=new Map;this.registeredChannels=new Map;this.protocolInspector=new De;this.cryptoProbe=new pn;this.uniStreamNormalizer=new un;this.disposed=false;this.deps?.registerDisposer(()=>this.dispose());for(let t of this.deps?.defaultChannels??[])this.registerChannel(t);}dispose(){this.disposed||(this.disposed=true,this.messageListeners=[],this.roomRequestListeners=[],this.streamListeners=[],this.channelStreamListeners.clear(),this.registeredChannels.clear());}onMessage(e){return this.disposed?()=>{}:(this.messageListeners.push(e),()=>{this.messageListeners=this.messageListeners.filter(t=>t!==e);})}dispatchMessage(e,t){if(!this.disposed)for(let n of [...this.messageListeners])try{n(e,t);}catch(i){console.warn("[Client] message listener failed",i);}}onIncomingStream(e){return this.disposed?()=>{}:(this.streamListeners.push(e),()=>{this.streamListeners=this.streamListeners.filter(t=>t!==e);})}hasIncomingStreamListeners(){return this.streamListeners.length>0}getRegisteredChannel(e){let t=typeof e=="string"?e.trim():"";return t?this.registeredChannels.get(t)??null:null}registerChannel(e){if(this.disposed)return;let t=e.id.trim();if(!t)throw new Error("Channel registration requires a non-empty channel id.");this.registeredChannels.set(t,{...e,id:t});}unregisterChannel(e){let t=e.trim();t&&(this.registeredChannels.delete(t),this.channelStreamListeners.delete(t));}listChannels(){return Array.from(this.registeredChannels.values())}onChannelStream(e,t){if(this.disposed)return ()=>{};let n=e.trim();if(!n)throw new Error("Channel stream listener requires a non-empty channel id.");let i=this.channelStreamListeners.get(n)??new Set;return i.add(t),this.channelStreamListeners.set(n,i),()=>{let o=this.channelStreamListeners.get(n);o&&(o.delete(t),o.size===0&&this.channelStreamListeners.delete(n));}}hasIncomingChannelListener(e){let t=e.trim();return t?(this.channelStreamListeners.get(t)?.size??0)>0:false}hasAnyIncomingChannelListeners(){for(let e of this.channelStreamListeners.values())if(e.size>0)return true;return false}requiresIncomingChannelEnvelopeInspection(){for(let e of this.registeredChannels.values())if(e.kind==="system"&&e.routing==="session-default")return true;return false}isInternalSessionChannel(e){let t=this.getRegisteredChannel(e);return t?.kind==="system"&&t.routing==="session-default"}dispatchIncomingChannelListeners(e){let t=e.channel?.channelId?.trim();if(!t)return false;let n=this.channelStreamListeners.get(t);if(!n)return false;for(let i of [...n])try{if(i(e)===!0)return !0}catch(o){console.warn("[Client] incoming channel stream listener failed",o);}return false}dispatchIncomingGenericListeners(e){for(let t of [...this.streamListeners])try{if(t(e)===!0)return !0}catch(n){console.warn("[Client] incoming stream listener failed",n);}return false}onRoomJoinRequest(e){return this.disposed?()=>{}:(this.roomRequestListeners.push(e),()=>{this.roomRequestListeners=this.roomRequestListeners.filter(t=>t!==e);})}async listenLoop(e$1){let t=0;for(;e$1.isListening();){let n=e$1.getWasmClient();if(!n||typeof n.incoming_streams!="function"){console.warn("[Client][INCOMING] incoming_streams is unavailable; stopping listen loop");return}let i=null;try{i=(await n.incoming_streams()).getReader();let s=i;for(t=0,e$1.shouldVerboseIncomingDiagnostics()&&e("[Client][INCOMING][MOBILE] direct listen reader acquired",{localNodeId:e$1.getLocalNodeId()});e$1.isListening();){let{done:a,value:c}=await s.read();if(a)throw new Error("incoming stream reader closed unexpectedly");if(!c)continue;let d=Ke(c);d!=="uni"&&e("[Client][INCOMING] Received stream from WASM node",{type:d,endpointId:Ne(c)});try{await e$1.handleIncomingStream(c);}catch(l){let p=c,u=Ke(p),h=Ne(p);console.error("[Client][INCOMING] Failed to handle incoming stream",{remoteNodeId:h,type:u,error:l});}}}catch(o){if(!e$1.isListening())break;t+=1;let s=d$1(t,e$1.retryMinDelayMs,e$1.retryMaxDelayMs);console.warn("[Client][INCOMING] Listen loop restarting after stream failure",{attempt:t,delayMs:s,mobile:ae(),error:o}),await a(s);}finally{if(i)try{n?.__openrtcNativeCapabilityProjection===!0?await i.cancel("incoming listen loop ended").catch(()=>{}):i.releaseLock(),e$1.shouldVerboseIncomingDiagnostics()&&e("[Client][INCOMING][MOBILE] direct listen reader released",{localNodeId:e$1.getLocalNodeId()});}catch{}}}}async handleIncomingStream(e$1,t){let n=await t.normalizeIncomingStreamEvent(e$1,{inspectChannelEnvelope:t.shouldInspectIncomingChannelEnvelope()});if(n.admissionCandidate===true&&n.protocolHint!=="native-main"){e("[Client][INCOMING] dropped non-admission reconnect candidate",{remoteNodeId:n.remoteNodeId||"unknown",traceId:n.traceId||null,protocolHint:n.protocolHint??null,channelId:n.channel?.channelId??null});return}let i=t.buildApplicationIncomingStreamEvent(n);if(!n.invalid&&i.invalid)return;if(this.isInternalSessionChannel(i.channel?.channelId)){await t.handleUnhandledIncomingStreamEvent(i);return}if(this.dispatchIncomingChannelListeners(i))return;if(n.protocolHint==="native-main"){await t.handleUnhandledIncomingStreamEvent(n);return}this.dispatchIncomingGenericListeners(i)||await t.handleUnhandledIncomingStreamEvent(n);}async normalizeIncomingStreamEvent(e$1,t,n){let i="bi",o=e$1,s="",a="",c=null,d=null,l=null,p=false,u=false,h={present:false,channel:null},f=false;try{f="type"in e$1;}catch{f=false;}if(f){i=Ke(e$1);try{o=e$1.stream;}catch{o=null;}try{let P=e$1.connectionId??e$1.connection_id;s=typeof P=="string"?P.trim():"";}catch{s="";}let C=Ne(e$1);a=C==="unknown"?"":C,c=ci(e$1),l=ar(e$1),h=cr(e$1);try{p=e$1.applicationAuthorized===!0;}catch{p=false;}try{u=e$1.admissionCandidate===!0;}catch{u=false;}}else {try{a=e$1.endpoint_id??"";}catch{a="";}c=ci(e$1);}let m=n.nextIncomingTraceId("incoming",a);l=n.normalizeAuthoritativeIncomingProtocolHint(l,a,m);let v=h.present&&h.channel!==null;n.logIncomingDiagnostic("normalize:start",{traceId:m,hasType:f,type:i,endpointId:a||"unknown",inspectChannelEnvelope:!!t?.inspectChannelEnvelope,authoritativeProtocolHint:l??null,authoritativeChannel:v}),i!=="uni"&&e("[Client][INCOMING] handleIncomingStream called",{hasType:f,type:i,endpointId:a});let y="unknown",S=l===null&&!!t?.inspectChannelEnvelope;if(i==="bi"){let C=f$2(o,a,c);if(!C||!e$4(C)){let A=false,R=false;try{A=!!o?.send;}catch{}try{R=!!o?.recv;}catch{}return console.error("[Client][INCOMING] Invalid bidirectional stream payload",{remoteNodeId:a,...c?{transportStableId:c}:{},hasSend:A,hasRecv:R}),{type:"bi",stream:o,...s?{connectionId:s}:{},remoteNodeId:a,...c?{transportStableId:c}:{},traceId:m,protocolHint:"unknown",channel:null,applicationCrypto:n.resolveCryptoStreams(a),invalid:true}}o=C,c=C.transport_stable_id??c;let P=false;if(l===null&&!v&&n.shouldStripIncomingMainLabel()){let A=await n.detectNativeMainStream(o,a,m);o=A.stream,P=true,y=A.protocolHint;}else l==="native-main"&&(y="native-main");if(y!=="native-main"){if(v)d=h.channel;else if(S){let L=await n.extractIncomingChannelEnvelope(o,a,m);o=L.stream,d=L.channel;}if(!(l==="explicit"||l==="control"||l==="native-main")&&!n.isTransportOnlyChannel(d?.channelId)&&(l!==null||v||d)&&(o=n.wrapIncomingBi(o,a,m)),l!==null)y=l,n.logIncomingDiagnostic("bi:use-authoritative-metadata",{traceId:m,endpointId:a||"unknown",protocolHint:y,hasChannelEnvelope:!!d});else if(v)y="unknown",n.logIncomingDiagnostic("bi:use-authoritative-channel-metadata",{traceId:m,endpointId:a||"unknown",hasChannelEnvelope:true});else if(n.shouldSkipIncomingBiProbeForRemoteNode(a)){let L=n.inferTicketFlowBiProtocolHint(a);if(y=L.protocolHint,n.logIncomingDiagnostic("bi:skip-probe-ticket-flow",{traceId:m,endpointId:a||"unknown",inferredProtocolHint:y,hasExistingConnection:L.hasExistingConnection,hasMagicLinkScope:L.hasMagicLinkScope}),!d&&!P&&n.shouldStripIncomingMainLabel()){let N=await n.detectNativeMainStream(o,a,m);o=N.stream,y=N.protocolHint;}}else {let L=await n.classifyBiIncomingStream(o,m);if(o=L.stream,y=L.protocolHint,y!=="explicit"&&!P&&n.shouldStripIncomingMainLabel()){let N=await n.detectNativeMainStream(o,a,m);o=N.stream,y=N.protocolHint;}}}let k=!n.shouldSkipIncomingStreamProbe()&&!n.isTransportOnlyChannel(d?.channelId);if(k&&y==="explicit"&&o?.applicationCryptoWrapped!==true)o=await n.maybeOpenEncryptedExplicitBiStream(o,m,a);else if(k&&y==="control"&&o?.applicationCryptoWrapped!==true&&(o=await n.maybeOpenEncryptedControlBiStream(o,m,a),o?.applicationCryptoWrapped===true)){let A=await n.classifyBiIncomingStream(o,m);o=A.stream,y=A.protocolHint,n.logIncomingDiagnostic("bi:reclassify-decrypted-stream",{traceId:m,endpointId:a||"unknown",protocolHint:y});}if(!d&&S&&o?.applicationCryptoWrapped===true){let A=await n.extractIncomingChannelEnvelope(o,a,m);o=A.stream,d=A.channel;}}else if(i==="uni"&&o&&typeof o.getReader=="function"){let C=await this.uniStreamNormalizer.normalize(o,{endpointId:a,traceId:m,inspectChannelEnvelope:S,authoritativeChannel:v?h.channel:null},n);o=C.stream,d=C.channel;}return n.logIncomingDiagnostic("normalize:done",{traceId:m,endpointId:a||"unknown",type:i,protocolHint:y,hasChannelEnvelope:!!d}),{type:i,stream:o,...s?{connectionId:s}:{},remoteNodeId:a,...c?{transportStableId:c}:{},traceId:m,protocolHint:y,channel:d,applicationCrypto:n.resolveCryptoStreams(a),...p?{applicationAuthorized:true}:{},...u?{admissionCandidate:true}:{}}}async extractIncomingChannelEnvelope(e,t,n,i){return this.protocolInspector.extractIncomingChannelEnvelope(e,t,n,i)}async classifyBiIncomingStream(e,t,n){return this.protocolInspector.classifyBiIncomingStream(e,t,n)}wrapIncomingBi(e,t,n,i){return this.cryptoProbe.wrapIncomingBi(e,t,n,i)}async maybeOpenEncryptedExplicitBiStream(e,t,n,i,o){return this.cryptoProbe.maybeOpenEncryptedExplicitBiStream(e,t,n,i,o)}async maybeOpenEncryptedControlBiStream(e,t,n,i,o){return this.cryptoProbe.maybeOpenEncryptedControlBiStream(e,t,n,i,o)}async detectNativeMainStream(e,t,n,i,o){return this.protocolInspector.detectNativeMainStream(e,t,n,i,o)}};function ur(r){let{host:e}=r;return new gn({explicitProtocolByte:2,defaultChannels:yo,registerDisposer:t=>e.registerDisposer(t)})}function gr(r){let{host:e}=r,t=e.getPresenceForIncomingListen();return new cn(e.getContext(),{ensureWasmRuntimeForP2P:()=>e.ensureWasmRuntimeForP2P(),startPresenceForListen:()=>t.startPresenceLoopForListen(),setOfflinePresence:()=>{t.setOffline();},shouldInspectIncomingChannelEnvelope:()=>r.getDiagnostics().shouldInspectIncomingChannelEnvelope(),handleIncomingStream:n=>r.getRouter().handleIncomingStream(n,{shouldInspectIncomingChannelEnvelope:()=>r.getDiagnostics().shouldInspectIncomingChannelEnvelope(),normalizeIncomingStreamEvent:(i,o)=>r.getNormalizer().normalize(i,o),buildApplicationIncomingStreamEvent:i=>r.getApplicationIncoming().buildApplicationIncomingStreamEvent(i),handleUnhandledIncomingStreamEvent:i=>e.handleUnhandledIncomingStreamEvent(i)}),hasIncomingChannelListener:n=>r.getRouter().hasIncomingChannelListener(n),hasAnyIncomingChannelListeners:()=>r.getRouter().hasAnyIncomingChannelListeners(),isInternalSessionChannel:n=>r.getRouter().isInternalSessionChannel(n),normalizeIncomingStreamEvent:(n,i)=>r.getNormalizer().normalize(n,i),dispatchIncomingChannelListeners:n=>r.getRouter().dispatchIncomingChannelListeners(n),dispatchIncomingGenericListeners:n=>r.getRouter().dispatchIncomingGenericListeners(n),handleUnhandledIncomingStreamEvent:n=>e.handleUnhandledIncomingStreamEvent(n),shouldVerboseIncomingDiagnostics:()=>r.getDiagnostics().shouldVerboseIncomingDiagnostics(),getIncomingStreamRouter:()=>r.getRouter(),retryMinDelayMs:go,retryMaxDelayMs:ho})}function hr(r,e){return new dn({getOptions:()=>r.getOptions(),getRuntimeSafetyProfileOverride:()=>r.getRuntimeSafetyProfile(),hasAnyIncomingChannelListeners:()=>e().hasAnyIncomingChannelListeners(),requiresIncomingChannelEnvelopeInspection:()=>e().requiresIncomingChannelEnvelopeInspection()})}function mr(r){let{host:e}=r;return new ln({explicitProtocolByte:2,maxEncryptedFrameBytes:16777216,probeDeadlineMs:oo,nativeMainProtocolByte:pt,nativeMainLabel:ut,nativeMainMaxLabelBytes:gt,explicitApplicationCryptoWaitMs:1500},{router:r.getRouter(),getWasmClient:()=>e.getContext().wasmClient,nextIncomingTraceId:(t,n)=>r.getDiagnostics().nextIncomingTraceId(t,n),logIncomingDiagnostic:(t,n)=>r.getDiagnostics().logIncomingDiagnostic(t,n),releaseReaderLock:(t,n,i)=>r.getDiagnostics().safeReleaseReaderLock(t,n,i),shouldSkipIncomingStreamProbe:()=>r.getDiagnostics().shouldSkipIncomingStreamProbe(),shouldSkipIncomingBiProbeForRemoteNode:t=>e.shouldSkipIncomingBiProbeForRemoteNode(t),inferTicketFlowBiProtocolHint:t=>e.inferTicketFlowBiProtocolHint(t),isTransportOnlyChannel:t=>e.isTransportOnlyChannel(t),resolveApplicationCryptoForPeer:t=>e.resolveApplicationCryptoForPeer(t),waitForApplicationCryptoForPeer:(t,n)=>e.waitForApplicationCryptoForPeer(t,n),resolveCryptoStreams:t=>e.resolveCryptoStreams(t)})}function vr(r){let{host:e}=r;return new rn({registerDisposer:t=>e.registerDisposer(t),resolveCryptoStreams:t=>e.resolveCryptoStreams(t),logIncomingDiagnostic:(t,n)=>r.getDiagnostics().logIncomingDiagnostic(t,n),isTransportOnlyChannel:t=>e.isTransportOnlyChannel(t),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),hasTransportOnlyConnectionForRemoteNode:t=>e.hasTransportOnlyConnectionForRemoteNode(t),isManagedApplicationStreamAuthorized:t=>e.isManagedApplicationStreamAuthorized(t)})}function fr(r){return new sn(r.getContext(),{ensureWasmRuntimeForP2P:()=>r.ensureWasmRuntimeForP2P()})}function yr(r){return new di({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getRuntimeSafetyProfile:()=>r.runtimeSafetyProfile,registerDisposer:e=>r.lifecycleScope.register(e),ensureWasmRuntimeForP2P:()=>r.runtimeReadiness.ensureWasmRuntimeForP2P(),getPresenceForIncomingListen:()=>r.presence,handleUnhandledIncomingStreamEvent:e=>r.incomingConnectionAcceptor.handleUnhandledIncomingStreamEvent(e),shouldSkipIncomingBiProbeForRemoteNode:e=>r.transportHealth.shouldSkipIncomingBiProbeForRemoteNode(e),inferTicketFlowBiProtocolHint:e=>r.peerIdentity.inferTicketFlowBiProtocolHint(e),isTransportOnlyChannel:e=>r.connectionChannelPolicy.isTransportOnlyChannel(e),hasTransportOnlyConnectionForRemoteNode:e=>r.transportHealth.hasTransportOnlyConnectionForRemoteNode(e),isManagedApplicationStreamAuthorized:e=>{if(!(r.runtimeStatus.usesTicketOnlySignalingMode()||r.runtimeStatus.requiresManagedTransportTrust(r.discoveryMode)))return true;let n=e?.trim();return n?r.sessionTokens.isApproved(r.peerIdentity.getDeterministicConnectionId(n),n):false},getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),resolveApplicationCryptoForPeer:e=>r.applicationCrypto.resolveForPeer(e),waitForApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.waitForPeer(e,t),resolveCryptoStreams:e=>r.applicationCrypto.resolveStreamTools(e)})}var di=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getRouter:()=>this.router,getDiagnostics:()=>this.diagnostics,getNormalizer:()=>this.normalizer,getApplicationIncoming:()=>this.applicationIncoming}}get router(){return this._router??(this._router=ur(this.factoryHost))}get listen(){return this._listen??(this._listen=gr(this.factoryHost))}get diagnostics(){return this._diagnostics??(this._diagnostics=hr(this.host,()=>this.router))}get normalizer(){if(this._normalizer||(this._normalizer=mr(this.factoryHost)),!this._generationFencedNormalizer){let e=this._normalizer;this._generationFencedNormalizer=new Proxy(e,{get:(t,n)=>{if(n==="normalize")return async(o,s)=>(await this.assertCurrentIncomingTransport(o),e.normalize(o,s));let i=Reflect.get(e,n,e);return typeof i=="function"?i.bind(e):i}});}return this._generationFencedNormalizer}async assertCurrentIncomingTransport(e){let t=e,n;try{n=t.type;}catch{return}if(n!=="bi"&&n!=="uni")return;let i,o;try{i=t.endpointId??t.endpoint_id,o=t.transportStableId??t.transport_stable_id;}catch{throw new Error("Rejected incoming stream with unreadable transport generation")}if(typeof i!="string"||i.trim().length===0||!Number.isSafeInteger(o)||Number(o)<=0)throw new Error("Rejected incoming stream without a valid transport generation");let s=this.host.getContext().wasmClient,a=typeof s?.isCurrentTransport=="function"?s.isCurrentTransport.bind(s):typeof s?.is_current_transport_stable_id=="function"?s.is_current_transport_stable_id.bind(s):null;if(!a)throw new Error("Rejected incoming stream because generation validation is unavailable");if(!await a(i.trim(),BigInt(Number(o))))throw new Error("Rejected incoming stream from a retired transport generation")}get applicationIncoming(){return this._applicationIncoming??(this._applicationIncoming=vr(this.factoryHost))}get applicationStreams(){return this._applicationStreams??(this._applicationStreams=fr(this.host))}prepareListenForSignOut(){this._listen?.prepareForSignOut();}stopListenIfExists(){this._listen?.stop();}};function hn(r,e,t,n,i=false){if(!r||r.isClosed)return false;if(!(i||typeof r.isApplicationCryptoRequired=="function"&&r.isApplicationCryptoRequired()))return true;let s=n??r.remoteNodeId??t??r.deviceId;return !!e(s,r)}var mn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}hasApplicationRouteForPeer(e,t){let n=this.deps.getConnectionForPeer(e,t);return hn(n,this.deps.resolveApplicationCryptoForPeer,e,t,this.deps.hasRustApplicationCryptoOwner())}hasApplicationRouteForConnection(e){return hn(e,this.deps.resolveApplicationCryptoForPeer,e?.id,e?.remoteNodeId,this.deps.hasRustApplicationCryptoOwner())}isApplicationRouteReadyForConnection(e){return this.hasApplicationRouteForConnection(e)}async refreshApplicationRouteHandshake(e,t,n={},i=2e4){if(this.disposed||e.isClosed)return;if(this.hasApplicationRouteForConnection(e)){this.notifyApplicationRouteReady(e,t);return}if(!this.deps.hasRustApplicationCryptoOwner())throw new Error(`[Client][HANDSHAKE] shared Rust application-crypto owner is unavailable for ${e.id}`);let o=await this.deps.ensureRustApplicationCrypto(e,i,t);if(this.disposed||e.isClosed||!o||!this.hasApplicationRouteForConnection(e))throw new Error(`[Client][HANDSHAKE] Rust application route was not ready for ${e.id}`);this.notifyApplicationRouteReady(e,`${t}:rust-owned`);}notifyApplicationRouteReady(e$1,t){this.disposed||e$1.isClosed||!this.hasApplicationRouteForConnection(e$1)||(e("[Client][HANDSHAKE] application route ready",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,reason:t}),this.deps.hasRustPeerLifecycleProjection()?(this.deps.reportApplicationRouteReady(e$1,t),this.schedulePeerReconciliationBestEffort("application-route-ready")):this.deps.applyConnectionTrustProjection(e$1),this.deps.isConnectionAnnounced(e$1.id)||this.deps.announceConnectionWhenStable(e$1));}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var vn=class{constructor(e,t){this.ctx=e;this.deps=t;}getDeterministicConnectionId(e){return this.ctx.localNodeId?this.ctx.localNodeId<=e?`${this.ctx.localNodeId}-${e}`:`${e}-${this.ctx.localNodeId}`:`native-main-${e}`}getNativeMainConnectionId(e){return this.getDeterministicConnectionId(e)}findManualDisconnectProjectionForNativeNode(e){let t=typeof e=="string"?e.trim().toLowerCase():"";if(!t)return null;let n=this.getNativeMainConnectionId(e).trim().toLowerCase(),i=o=>{if(!o)return false;let s=String(o.status??"").toLowerCase(),a=String(o.error??"").toLowerCase();return (s==="closed"||s==="disconnected"||s==="failed")&&a.includes("manual disconnect")};for(let o of [e,n]){let s=this.deps.getPeerState(o);if(i(s))return s}return this.deps.listPeerStates().find(o=>{if(!i(o))return false;let s=String(o.nodeId??"").trim().toLowerCase(),a=String(o.connectionId??"").trim().toLowerCase(),c=Array.isArray(o.connectionIds)?o.connectionIds.map(d=>String(d??"").trim().toLowerCase()):[];return s===t||a===n||a.endsWith(`-${t}`)||c.includes(n)||c.some(d=>d.endsWith(`-${t}`))})??null}hasKnownConnectionForRemoteNode(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;if(this.ctx.registry.has(this.getDeterministicConnectionId(t)))return true;for(let n of this.ctx.registry.values()){let i=n;if(i.id===t||i.remoteNodeId===t||i.deviceId===t)return true}return false}inferTicketFlowBiProtocolHint(e){let t=typeof e=="string"?e.trim():"",n=this.hasKnownConnectionForRemoteNode(t),i=false;try{let o=this.deps.getPeerState(t);i=Array.isArray(o?.scopes)&&o.scopes.includes("magic-link");}catch{i=false;}return {protocolHint:this.deps.hasAnyIncomingChannelListeners()||this.deps.hasIncomingStreamListeners()||i?"explicit":"control",hasExistingConnection:n,hasMagicLinkScope:i}}};var fn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}hasTransportOnlyConnectionForRemoteNode(e){if(this.disposed)return false;let t=typeof e=="string"?e.trim():"";if(!t)return false;for(let n of this.ctx.registry.values())if(n.remoteNodeId===t&&this.deps.isTransportOnlyConnectionId(n.id))return true;return false}shouldSkipIncomingBiProbeForRemoteNode(e){return this.disposed||!this.deps.getRuntimeSafetyProfile().skipIncomingBiProbe?false:this.deps.usesTicketOnlySignalingMode()?true:this.hasTransportOnlyConnectionForRemoteNode(e)}async disconnectNodeTransport(e){if(this.disposed||!e||!e.trim())return;let t=this.ctx.wasmClient;if(t&&typeof t.disconnect=="function")try{await t.disconnect(e);}catch{}this.disposed||this.deps.notifyDisconnectRequested(e);}async isCoreConnectionHealthy(e){if(this.disposed||!e)return false;let t=this.ctx.wasmClient;if(t&&typeof t.is_connected=="function")try{let n=!!await t.is_connected(e);return this.disposed?!1:n}catch{}try{let n=await this.deps.isConnected(e);return this.disposed?!1:n}catch{return false}}handleConnectionTransportStatus(e,t,n){this.disposed||this.reportConnectionTransportStatus(e,t,n);}handleCurrentConnectionTransportStatus(e,t,n){return this.disposed?Promise.resolve(false):this.reportCurrentConnectionTransportStatus(e,t,n).then(i=>i!==null)}async reportCurrentConnectionTransportStatus(e,t,n){if(this.disposed||!this.matchesCurrentConnectionIdentityRoute(e,t,n))return null;let i=await this.readCurrentGenerationSnapshot(e.id);return !i||!this.matchesCurrentConnectionIdentityRoute(e,t,n)?null:this.reportConnectionTransportStatus(e.id,t,n,i.transportStableId,i.transportGeneration,i.routeGeneration)}handleConnectionApplicationRouteReady(e,t){this.disposed||this.reportConnectionApplicationRouteReady(e,t);}handleCurrentConnectionApplicationRouteReady(e,t){this.disposed||this.reportCurrentConnectionApplicationRouteReady(e,t);}async reportConnectionTransportStatus(e$1,t,n,i,o,s,a=true){if(this.disposed||!this.matchesCurrentConnectionRoute(e$1,t,n))return null;let c=await this.readCurrentGenerationObservation(e$1,i,o,s);if(!c||!this.matchesCurrentConnectionRoute(e$1,t,n))return null;let d=this.ctx.wasmClient;if(!d||typeof d.report_transport_status!="function")return null;try{let l=await d.report_transport_status(e$1,t,n??null,BigInt(c.transportStableId),BigInt(c.transportGeneration),BigInt(c.routeGeneration));return this.disposed||l==null?null:(a&&this.deps.hasRustPeerLifecycleProjection()&&this.schedulePeerReconciliationBestEffort("transport-status-report"),this.generationObservationFromSnapshot(l))}catch(l){return this.disposed||e("[Client] Failed to report active transport to Rust",{connectionId:e$1,activeTransport:t,parallelTransport:n??null,error:l}),null}}async reportConnectionApplicationRouteReady(e,t){if(this.disposed)return;let n=await this.reportConnectionTransportStatus(e,t.activeTransport,t.parallelTransport??null,t.transportStableId,t.transportGeneration,t.routeGeneration,false);n&&await this.settleConnectionApplicationRoute(e,t.activeTransport,t.parallelTransport??null,n);}async reportCurrentConnectionApplicationRouteReady(e,t){if(this.disposed||!this.matchesCurrentConnectionIdentityRoute(e,t.activeTransport,t.parallelTransport))return false;let n=null;for(let i=0;i<2&&!n;i+=1){let o=await this.readCurrentGenerationSnapshot(e.id);if(!o||!this.matchesCurrentConnectionIdentityRoute(e,t.activeTransport,t.parallelTransport))return false;n=await this.reportConnectionTransportStatus(e.id,t.activeTransport,t.parallelTransport??null,o.transportStableId,o.transportGeneration,o.routeGeneration,false),!n&&i===0&&await Promise.resolve();}return !n||!this.matchesCurrentConnectionIdentityRoute(e,t.activeTransport,t.parallelTransport)?false:this.settleConnectionApplicationRoute(e.id,t.activeTransport,t.parallelTransport??null,n)}async settleConnectionApplicationRoute(e$1,t,n,i){if(this.disposed||!this.matchesCurrentConnectionRoute(e$1,t,n))return false;let o=this.ctx.wasmClient;if(!o||typeof o.report_managed_connection_settled!="function")return false;try{let s=await o.report_managed_connection_settled(e$1,!0,null,BigInt(i.transportStableId),BigInt(i.transportGeneration),BigInt(i.routeGeneration));return this.disposed||s==null||!this.matchesCurrentConnectionRoute(e$1,t,n)?!1:(this.deps.hasRustPeerLifecycleProjection()&&this.schedulePeerReconciliationBestEffort("application-route-ready"),!0)}catch(s){return this.disposed||e("[Client] Failed to settle proven application route in Rust",{connectionId:e$1,activeTransport:t,parallelTransport:n,error:s}),false}}async readCurrentGenerationObservation(e,t,n,i){if(!Number.isSafeInteger(t)||Number(t)<=0||!Number.isSafeInteger(n)||Number(n)<=0||!Number.isSafeInteger(i)||Number(i)<0)return null;let o=await this.readCurrentGenerationSnapshot(e);return !o||t!==o.transportStableId||n!==o.transportGeneration||i!==o.routeGeneration?null:o}async readCurrentGenerationSnapshot(e){let t=this.ctx.wasmClient;if(!t||typeof t.connection_state!="function")return null;try{let n=await t.connection_state(e);if(this.disposed||!n||typeof n!="object")return null;let i=n,o=typeof i.transportStableId=="number"?i.transportStableId:i.activeTransportStableId??i.active_transport_stable_id,s=typeof i.transportGeneration=="number"?i.transportGeneration:i.transport_generation,a=typeof i.routeGeneration=="number"?i.routeGeneration:i.route_generation;return !Number.isSafeInteger(o)||Number(o)<=0||!Number.isSafeInteger(s)||Number(s)<=0||!Number.isSafeInteger(a)||Number(a)<0?null:{transportStableId:Number(o),transportGeneration:Number(s),routeGeneration:Number(a)}}catch{return null}}generationObservationFromSnapshot(e){if(!e||typeof e!="object")return null;let t=e,n=t.transportStableId??t.activeTransportStableId??t.active_transport_stable_id,i=t.transportGeneration??t.transport_generation,o=t.routeGeneration??t.route_generation;return !Number.isSafeInteger(n)||Number(n)<=0||!Number.isSafeInteger(i)||Number(i)<=0||!Number.isSafeInteger(o)||Number(o)<0?null:{transportStableId:Number(n),transportGeneration:Number(i),routeGeneration:Number(o)}}matchesCurrentConnectionRoute(e,t,n){let i=this.ctx.registry.get(e);if(!i||i.isClosed||typeof i.getTransportStatus!="function")return false;if(this.deps.hasRustPeerLifecycleProjection())return true;let o=i.getTransportStatus();return o.activeTransport===t&&(o.parallelTransport??null)===(n??null)}matchesCurrentConnectionIdentityRoute(e,t,n){return this.ctx.registry.get(e.id)===e&&this.matchesCurrentConnectionRoute(e.id,t,n)}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var Ns=[...d];function Cr({transportPriority:r,rankRoutes:e,disableIrohFallback:t,runtimeSafetyProfile:n,requestIrohCarrier:i,sendIrohApplicationFrame:o}){let s=r||Ns;return {priorities:s,rankRoutes:e?a=>e(s,a):void 0,disableIrohFallback:t||false,requestIrohCarrier:i,sendIrohApplicationFrame:o,runtimeFlow:n.flow,readerCloseStrategy:n.readerCloseStrategy}}var yn=class{constructor(e){this.deps=e;}create(e){let t=this.deps.getOptions();return Cr({transportPriority:t?.transportPriority,rankRoutes:(n,i)=>this.deps.rankRoutes(n,i),disableIrohFallback:t?.disableIrohFallback,runtimeSafetyProfile:this.deps.getRuntimeSafetyProfile(),requestIrohCarrier:()=>this.deps.requestIrohCarrier(e),sendIrohApplicationFrame:n=>this.deps.sendIrohApplicationFrame(e,n)})}};var Cn=class{constructor(e){this.deps=e;this.disposed=false;this.advertisedTransportCapabilities=new WeakMap;this.postInboundTransportCapabilities=new WeakMap;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}getConnectionControlFrameMode(e){return typeof e.getControlFrameMode=="function"?e.getControlFrameMode():"typed"}async observeIrohCarrierHandshake(e,t,n=true){this.disposed||await this.deps.observeIrohCarrierHandshake?.(e,t,n);}async ensureCurrentTransportCapabilityAdvertisement(e,t){if(this.disposed||e.isClosed||!this.canAdvertiseTransportCapabilities(e))return;let n=this.currentTransportCapabilityFingerprint(e);if(t==="incoming-handshake-capability-replay"){if(this.postInboundTransportCapabilities.get(e)===n)return;await this.sendTransportHandshakeWithRecovery(e,"capability-update",null,t),this.postInboundTransportCapabilities.set(e,n);return}this.advertisedTransportCapabilities.get(e)!==n&&await this.sendTransportHandshakeWithRecovery(e,"capability-update",null,t);}async sendConnectionControlEnvelope(e,t,n={}){if(this.disposed)return;let i=this.getConnectionControlFrameMode(e),o=(s,a)=>b$3(s,this.deps.attemptTimeoutMs,()=>new Error(`[Client][HANDSHAKE] ${a} control send timed out after ${this.deps.attemptTimeoutMs}ms`));if(i==="native-main"){let s=e.sendNativeControlEnvelope;if(typeof s!="function")throw new Error("[Client][HANDSHAKE] native-main control route unavailable: a Rust-owned labelled main/signal route or admitted native-main writer is required.");if(await o(s.call(e,t),"native-main-labelled-control"))return;throw new Error("[Client][HANDSHAKE] native-main control route unavailable: the Rust-owned labelled main/signal route and admitted native-main writer declined the frame.")}if(typeof e.sendControl=="function"){await o(e.sendControl(t),"typed-control");return}await o(e.send(t),"legacy-typed-control");}async sendTransportHandshake(e$1,t,n,i={}){if(this.disposed)return;let o=this.currentTransportCapabilities(e$1),s=this.transportCapabilityFingerprint(e$1,o),a=o,c=t==="hello"?this.deps.getPendingSessionToken(e$1.remoteNodeId):void 0,d=t==="hello"?this.deps.getPendingSessionTokenPayload(e$1.remoteNodeId):void 0;e("[Client][HANDSHAKE] sending",{action:t,connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,channelId:this.deps.getConnectionChannelId(e$1.id)??null,capabilities:a,hasSessionToken:!!c,hasSessionTokenPayload:!!d,hasChallengeToSign:!!n});let l={type:"handshake",action:t,capabilities:a,moq:a.moq,channelId:this.deps.getConnectionChannelId(e$1.id)??void 0,...c?{sessionToken:c}:{},...c&&d?{sessionTokenPayload:d}:{}},p=await this.deps.buildLocalTransportTrustPayload(e$1,n);if(!this.disposed){if(e("[Client][HANDSHAKE] local trust payload status",{action:t,connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,hasTransportTrustPayload:!!p,hasChallengeInPayload:!!p?.challenge}),!p){if(this.deps.requiresManagedTransportTrust()){let u=this.deps.initializeConnectionTrust(e$1);u.failed=true,u.failureReason="local-trusted-identity-unavailable",console.warn("[Client][TRUST] Unable to attach local transport trust payload for managed trust handshake",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,action:t});}await this.sendConnectionControlEnvelope(e$1,l,i),this.rememberAdvertisedTransportCapabilities(e$1,s);return}await this.sendConnectionControlEnvelope(e$1,{...l,transportTrust:p},i),this.rememberAdvertisedTransportCapabilities(e$1,s),e("[Client][HANDSHAKE] sent OK",{action:t,connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId});}}async sendTransportHandshakeWithRecovery(e,t,n,i){for(let o=0;o<this.deps.maxRecoveryAttempts;o+=1){if(this.disposed)return;if(e.isClosed)throw new Error("[Client][HANDSHAKE] connection closed before handshake recovery completed");let s=i==="incoming-handshake-capability-replay",a$1=this.getConnectionControlFrameMode(e)==="native-main"&&(s?o%2===0:o%2===1);try{await this.sendTransportHandshake(e,t,n,{preferNativeSignalRoute:a$1});return}catch(c){let d=o>=this.deps.maxRecoveryAttempts-1;if(console.warn("[Client][HANDSHAKE] control handshake send failed; retrying if budget remains",{connectionId:e.id,remoteNodeId:e.remoteNodeId,action:t,reason:i,attempt:o+1,maxAttempts:this.deps.maxRecoveryAttempts,preferNativeSignalRoute:a$1,finalAttempt:d,error:c}),d)throw c;let l=this.deps.recoveryBackoffMs[Math.min(o,this.deps.recoveryBackoffMs.length-1)]??0;if(l>0&&(await a(l),this.disposed))return}}}async broadcastTransportCapabilityUpdate(e$1){if(this.disposed)return;if(this.deps.isWebRTCTransportEnabled())for(let o of this.deps.getConnections()){if(this.disposed)return;o.requestTransportRecovery("transport-capability-update");}if(this.disposed)return;let t=Array.from(this.deps.getConnections()).filter(o=>!o.isClosed&&this.canAdvertiseTransportCapabilities(o)).map(async o=>{await this.sendTransportHandshake(o,"capability-update");}),i=(await Promise.allSettled(t)).filter(o=>o.status==="rejected");i.length>0&&e("[Client] Some transport capability updates failed",{reason:e$1,failures:i.length});}currentTransportCapabilities(e){let t=this.deps.isWebRtcCarrierEnabled?.()??false,n=this.deps.isMoqCarrierEnabled?.()??false,i=typeof e.isLocalDedicatedCarrierControlReady=="function"&&e.isLocalDedicatedCarrierControlReady();return {carrierSchema:2,webrtc:t,moq:n,dedicatedCarrierControl:t||n,dedicatedCarrierControlReady:(t||n)&&i,ble:this.deps.isBleTransportEnabled()}}canAdvertiseTransportCapabilities(e){return !(this.deps.requiresManagedTransportTrust()||this.deps.usesTicketOnlySignalingMode())||this.deps.isSessionTokenApproved(e.id,e.remoteNodeId)}currentTransportCapabilityFingerprint(e){return this.transportCapabilityFingerprint(e,this.currentTransportCapabilities(e))}transportCapabilityFingerprint(e,t){let n=e.getTransportCapabilityAdvertisementEpoch,i=typeof n=="function"?n.call(e):"unknown";return JSON.stringify({physicalEpoch:i,capabilities:t})}rememberAdvertisedTransportCapabilities(e,t){this.advertisedTransportCapabilities.set(e,t);}};function Ds(r){let e=r.transports?.ble;return e===true||!!e&&typeof e=="object"&&e.enabled!==false}function Ir(r,e){return Ds(r)&&e?.transport.ble===true}function Sr(r){let{host:e}=r;return new mn(e.getContext(),{getConnectionForPeer:(t,n)=>e.getConnectionForPeer(t,n)??null,resolveApplicationCryptoForPeer:(t,n)=>e.resolveApplicationCryptoForPeer(t,n),hasRustApplicationCryptoOwner:()=>e.hasRustApplicationCryptoOwner(),ensureRustApplicationCrypto:(t,n,i)=>e.ensureRustApplicationCrypto(t,n,i),reportApplicationRouteReady:(t,n)=>{let i=t.getTransportStatus();r.getHealth().handleCurrentConnectionApplicationRouteReady(t,{...i,reason:n});},applyConnectionTrustProjection:t=>e.applyConnectionTrustProjection(t),announceConnectionWhenStable:t=>e.announceConnectionWhenStable(t),isConnectionAnnounced:t=>e.isConnectionAnnounced(t),hasRustPeerLifecycleProjection:()=>e.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:t=>e.schedulePeerReconciliation(t)})}function Pr(r){let{host:e}=r;return new Cn({isWebRTCTransportEnabled:()=>Y(e.getOptions()),isWebRtcCarrierEnabled:()=>r.getBrowserCarrier().isWebRtcCarrierAdvertisable(),isMoqCarrierEnabled:()=>r.getBrowserCarrier().isMoqCarrierAdvertisable(),observeIrohCarrierHandshake:(t,n,i)=>r.getBrowserCarrier().observeHandshake(t,n,i),isBleTransportEnabled:()=>Ir(e.getOptions(),e.capabilities()),getConnectionChannelId:t=>e.getConnectionChannelId(t),getPendingSessionToken:t=>e.getPendingSessionToken(t),getPendingSessionTokenPayload:t=>e.getPendingSessionTokenPayload(t),buildLocalTransportTrustPayload:(t,n)=>e.buildLocalTransportTrustPayload(t,n),requiresManagedTransportTrust:()=>e.requiresManagedTransportTrust(e.getDiscoveryMode()),initializeConnectionTrust:t=>e.initializeConnectionTrust(t),getConnections:()=>e.getConnections(),usesTicketOnlySignalingMode:()=>e.usesTicketOnlySignalingMode(),isSessionTokenApproved:(t,n)=>e.isSessionTokenApproved(t,n),getLocalNodeId:()=>e.getLocalNodeId()||null,maxRecoveryAttempts:15,attemptTimeoutMs:1e3,recoveryBackoffMs:io,registerDisposer:t=>e.registerDisposer(t)})}function br(r){let{host:e$1}=r;return new kt({getOptions:()=>e$1.getOptions(),getWasmClient:()=>e$1.getWasmClient(),getConnection:(t,n)=>e$1.getConnectionForPeer(t,n),getRTCConfig:()=>e$3(e$1.getOptions(),t=>e(t)),sendControl:(t,n)=>r.getHandshake().sendConnectionControlEnvelope(t,n,{preferNativeSignalRoute:true}),registerDisposer:t=>e$1.registerDisposer(t)})}function wr(r){return new fn(r.getContext(),{getRuntimeSafetyProfile:()=>r.getRuntimeSafetyProfile(),usesTicketOnlySignalingMode:()=>r.usesTicketOnlySignalingMode(),isTransportOnlyConnectionId:e=>r.isTransportOnlyConnectionId(e),notifyDisconnectRequested:e=>r.notifyDisconnectRequested(e),isConnected:e=>r.isBackendConnected(e),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>r.schedulePeerReconciliation(e)})}function Tr(r,e$1){return new yn({getOptions:()=>r.getOptions(),getRuntimeSafetyProfile:()=>r.getRuntimeSafetyProfile(),rankRoutes:(t,n)=>{let i=r.getWasmClient(),o=i?.rankRoutes??i?.rank_routes;if(typeof o!="function")return [...n];try{let s=o.call(i,t,n);return Array.isArray(s)?s:[...n]}catch(s){return e("[OpenRTC][route-policy] Rust ranking unavailable; preserving candidate order",{error:s instanceof Error?s.message:String(s)}),[...n]}},requestIrohCarrier:e$1,sendIrohApplicationFrame:(t,n)=>r.sendIrohApplicationFrame(t,n)})}function Rr(r){return new vn(r.getContext(),{getPeerState:e=>r.getPeerState(e),listPeerStates:()=>r.listPeerStates(),hasAnyIncomingChannelListeners:()=>r.hasAnyIncomingChannelListeners(),hasIncomingStreamListeners:()=>r.hasIncomingStreamListeners()})}function kr(r){return new li({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getRuntimeSafetyProfile:()=>r.runtimeSafetyProfile,capabilities:()=>r.signalingBackendController.capabilities(),getWasmClient:()=>r.wasmClient,registerDisposer:e=>r.lifecycleScope.register(e),getLocalNodeId:()=>r.localNodeId,getDiscoveryMode:()=>r.discoveryMode,hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),getPeerState:e=>r.peerServices.getPeerState(e),listPeerStates:()=>r.peerServices.listPeerStates(),getConnectionForPeer:(e,t)=>r.registry.getForPeer(e,t),getConnections:()=>r.registry.values(),getConnectionChannelId:e=>r.connectionChannelPolicy.getConnectionChannelId(e),isTransportOnlyConnectionId:e=>r.connectionChannelPolicy.isTransportOnlyConnectionId(e),getConnectionTrustState:e=>r.connectionTrust.getStateByConnectionId(e),buildLocalTransportTrustPayload:(e,t)=>r.connectionTrust.buildLocalTransportTrustPayload(e,t),initializeConnectionTrust:e=>r.connectionTrust.initialize(e),resolveApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.resolveForPeer(e,t),resolveExistingApplicationCryptoForPeer:(e,t)=>r.securityServices.resolveExistingApplicationCryptoForPeer(e,t),getConfiguredApplicationCrypto:()=>r.options?.applicationCrypto,shouldNegotiateApplicationKeyAgreement:()=>r.applicationCrypto.shouldNegotiateKeyAgreement(),hasRustApplicationCryptoOwner:()=>r.applicationCrypto.hasRustKeyAgreementOwner(),ensureRustApplicationCrypto:(e,t,n)=>r.applicationCrypto.ensureRustOwnedConnection(e,t,n),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),announceConnectionWhenStable:e=>r.connectionLifecycle.announceConnectionWhenStable(e),isConnectionAnnounced:e=>r.connectionLifecycle.isConnectionAnnounced(e),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),sendIrohApplicationFrame:(e,t)=>r.applicationStreams.sendFrame(e,t),getPendingSessionToken:e=>r.sessionTokens.getRouteRepairTokenForNode(e)??void 0,getPendingSessionTokenPayload:e=>r.sessionTokens.getRouteRepairTokenPayloadForNode(e)??void 0,requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),isSessionTokenApproved:(e,t)=>r.sessionTokens.isApproved(e,t),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode(),notifyDisconnectRequested:e=>r.signalingBackendController.notifyDisconnectRequested(e),isBackendConnected:e=>r.signalingBackendController.isConnected(e),hasAnyIncomingChannelListeners:()=>r.incomingStreamRouter.hasAnyIncomingChannelListeners(),hasIncomingStreamListeners:()=>r.incomingStreamRouter.hasIncomingStreamListeners()})}var li=class{constructor(e){this.host=e;}get factoryHost(){return {host:this.host,getHandshake:()=>this.handshake,getHealth:()=>this.health,getRTCConfig:()=>this.getRTCConfig(),getBrowserCarrier:()=>this.browserCarrier}}get applicationRoute(){return this._applicationRoute??(this._applicationRoute=Sr(this.factoryHost))}get handshake(){return this._handshake??(this._handshake=Pr(this.factoryHost))}get health(){return this._health??(this._health=wr(this.host))}get contexts(){return this._contexts??(this._contexts=Tr(this.host,e$1=>{let t=this.host.getConnectionForPeer(void 0,e$1);t&&this.handshake.ensureCurrentTransportCapabilityAdvertisement(t,"iroh-carrier-revisit").then(()=>this.browserCarrier.revisit(t)).catch(n=>{e("[OpenRTC][Iroh carrier] admission revisit failed",{connectionId:t.id,error:n instanceof Error?n.message:String(n)});});}))}get peerIdentity(){return this._peerIdentity??(this._peerIdentity=Rr(this.host))}get browserCarrier(){return this._browserCarrier??(this._browserCarrier=br(this.factoryHost))}retireBrowserCarrierConnection(e$1,t){let n=this._browserCarrier;n&&n.retireConnection(e$1,t).catch(i=>{e("[OpenRTC][Iroh WebRTC carrier] logical retirement failed",{connectionId:e$1,terminalReason:t??null,error:i instanceof Error?i.message:String(i)});});}getRTCConfig(){return e$3(this.host.getOptions(),e$1=>e(e$1))}hasApplicationRouteForConnectionSnapshot(e,t,n){return hn(e,(i,o)=>this.host.getConfiguredApplicationCrypto()??this.host.resolveExistingApplicationCryptoForPeer(i,o),t,n,tn(this.host.getWasmClient()))}hasApplicationRouteForPeer(e,t){return this.hasApplicationRouteForConnectionSnapshot(this.host.getConnectionForPeer(e,t),e,t)}isApplicationRouteReady(e){return this.hasApplicationRouteForConnectionSnapshot(e,e?.id,e?.remoteNodeId)}};var In=class{constructor(e){this.deps=e;this.channelIds=new Map;this.disposed=false;this.deps.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.channelIds.clear());}isChannelPromotionEligible(e){let t=this.deps.getRegisteredChannel(e);return t?t.promotionPolicy!=="never":true}isTransportOnlyChannel(e){return Mt(this.deps.getRegisteredChannel(e))}getConnectionChannelId(e){if(this.disposed)return null;let t=typeof e=="string"?e.trim():"";return t?this.channelIds.get(t)??null:null}isTransportOnlyConnectionId(e){return this.isTransportOnlyChannel(this.getConnectionChannelId(e))}allowsTransportOnlyStability(e){let t=this.getConnectionChannelId(e.id);return t?this.isTransportOnlyChannel(t):this.deps.usesTicketOnlySignalingMode()}resolvePromotionEligibility(e){if(this.disposed)return false;let t=this.getConnectionChannelId(e.connectionId);if(t)return this.isChannelPromotionEligible(t);let n=typeof e.nodeId=="string"?e.nodeId.trim():"";for(let i of this.deps.getConnections()){if(e.connectionId&&i.id===e.connectionId)return this.isChannelPromotionEligible(this.getConnectionChannelId(i.id));if(n&&i.remoteNodeId===n)return this.isChannelPromotionEligible(this.getConnectionChannelId(i.id))}return true}assign(e,t){if(this.disposed)return;let n=typeof t=="string"?t.trim():"";if(!n)return;this.channelIds.set(e.id,n);let i=this.deps.getConnectionTrustState(e.id);if(i&&!this.isChannelPromotionEligible(n)&&(i.required=false,i.verified=true,i.failed=false,i.failureReason=void 0,i.issuedChallenge=null,i.verifiedDeviceId||(i.verifiedDeviceId=i.expectedDeviceId||this.deps.getKnownDeviceIdByNodeId(e.remoteNodeId)||null)),this.deps.hasRustPeerLifecycleProjection())this.schedulePeerReconciliationBestEffort("session-token-trust-approved");else for(let o of this.deps.getConnections())if(o.id===e.id){this.deps.applyConnectionTrustProjection(o);break}}forget(e){if(this.disposed)return;let t=typeof e=="string"?e.trim():"";t&&this.channelIds.delete(t);}schedulePeerReconciliationBestEffort(e){if(!this.disposed)try{Promise.resolve(this.deps.schedulePeerReconciliation(e)).catch(()=>{});}catch{}}};var Sn=class{constructor(e,t){this.ctx=e;this.deps=t;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed=true;}bindConnectionDeviceIdInRust(e$1,t){if(this.disposed)return;let n=t.trim();if(!n)return;let i=this.deps.getSessionTokenApprovedScope(e$1.id);if(i&&!this.deps.sessionTokenScopeAllowsDeviceBinding(i)){e("[Client][BIND] skipped transient session device binding",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,scope:i});return}let o=this.ctx.wasmClient,s=!!o&&typeof o.bind_connection_device_id=="function";e("[Client][BIND] bindConnectionDeviceIdInRust entered",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,deviceId:n,hasWasmClient:!!o,hasMethod:s}),this.deps.rememberKnownDeviceForNode(e$1.remoteNodeId,n);let a=this.deps.getApplicationCryptoForConnectionOrPeer(e$1.id,e$1.remoteNodeId);if(a&&this.deps.indexApplicationCryptoForPeer(n,a),!!s)try{Promise.resolve(o.bind_connection_device_id(e$1.id,n)).then(()=>{this.disposed||e("[Client][BIND] bind_connection_device_id resolved",{connectionId:e$1.id,deviceId:n});}).catch(c=>{this.disposed||console.warn("[Client][TRUST] Failed to bind deviceId on Rust connection record",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,deviceId:n,error:c});});}catch(c){if(this.disposed)return;console.warn("[Client][TRUST] Failed to bind deviceId on Rust connection record",{connectionId:e$1.id,remoteNodeId:e$1.remoteNodeId,deviceId:n,error:c});}}async rejectConnectionInRust(e,t){if(this.disposed)return;let n=this.ctx.wasmClient;if(!(!n||typeof n.reject_connection_admission!="function"))try{await n.reject_connection_admission(e.id,t);}catch(i){if(this.disposed)return;console.warn("[Client][TRUST] Failed to reject connection on Rust admission authority",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t,error:i});}}retireSupersededConnections(e$1,t,n){if(this.disposed)return;let i=t.trim();if(i)for(let o of this.ctx.registry.values())o.id===e$1.id||o.isClosed||this.deps.getLogicalDeviceIdForConnection(o.id)===i&&(e("[Client][CONNECTION] Retiring superseded connection for logical device",{keptConnectionId:e$1.id,retiredConnectionId:o.id,logicalDeviceId:i,reason:n}),this.disconnectBestEffort(o));}disconnectBestEffort(e){try{Promise.resolve(e.disconnect()).catch(()=>{});}catch{}}};var Pn=class{constructor(e,t){this.ctx=e;this.deps=t;this.states=new Map;this.failureCooldowns=new Map;this.disposed=false;this.ctx.registerDisposer(()=>this.dispose());}dispose(){this.disposed||(this.disposed=true,this.states.clear(),this.failureCooldowns.clear());}initialize(e,t){if(this.disposed)return {required:false,verified:false,failed:true,failureReason:"connection-trust-manager-disposed",expectedDeviceId:t??null,verifiedDeviceId:null,issuedChallenge:null};let n=this.states.get(e.id);if(n)return t&&!n.expectedDeviceId&&(n.expectedDeviceId=t),n;let i$1=this.deps.resolvePromotionEligibility({connectionId:e.id,nodeId:e.remoteNodeId,deviceId:t??void 0}),o=this.deps.consumePendingSessionTokenTrustApproval(e.id),s=this.deps.getSessionTokenApprovedScope(e.id),a=o.scope??s,c=o.approved||!!s,d=this.deps.getKnownDeviceIdForNode(e.remoteNodeId),l=!c&&i$1&&this.deps.requiresManagedTransportTrust(),p={required:l,verified:!l,failed:false,expectedDeviceId:t||d||null,verifiedDeviceId:l?null:t||d||null,issuedChallenge:l?i():null};return this.states.set(e.id,p),a&&this.deps.addPeerScope(e.id,a),p}sessionTokenScopeAllowsDeviceBinding(e){let t=typeof e=="string"?e.trim():"";return t==="user-device"||t==="persistent"||t==="trusted-device"||t.startsWith("trusted-device:")}resolveExpectedDeviceIdForSessionTokenScope(e,t,n,i){let o=typeof e=="string"?e.trim():"";if(!o)return null;if(!n)return o;let s=new Set,a=c=>{let d=typeof c=="string"?c.trim():"";d&&s.add(d);};if(a(t),i){a(this.deps.getSessionTokenApprovedScope(i.id));for(let c of this.deps.getPeerScopes(i.id))a(c);for(let c of this.deps.getPeerScopes(i.remoteNodeId))a(c);}return Array.from(s).some(c=>this.sessionTokenScopeAllowsDeviceBinding(c))?o:null}getState(e){if(this.disposed)return null;let t=typeof e.connectionId=="string"?e.connectionId.trim():"";if(t)return this.states.get(t)??null;for(let[n,i]of this.states.entries())if(i.verifiedDeviceId&&(i.verifiedDeviceId===e.deviceId||i.verifiedDeviceId===e.deviceIdHint)||i.expectedDeviceId&&(i.expectedDeviceId===e.deviceId||i.expectedDeviceId===e.deviceIdHint))return this.states.get(n)??null;return null}getProjection(e){if(this.disposed)return null;let t=this.getState(e);if(!t)return null;let n=t.verified&&!t.failed,i=typeof e.connectionId=="string"&&e.connectionId.trim()||Array.from(this.states.entries()).find(([,a])=>a===t)?.[0]||"",o=i?this.deps.getSessionTokenApprovedScope(i):null,s=!o||this.sessionTokenScopeAllowsDeviceBinding(o);return n?{routable:true,protocolState:"routable",health:"healthy",deviceId:s?t.verifiedDeviceId??t.expectedDeviceId??e.deviceId??null:null}:t.required?{routable:false,protocolState:"unverified",health:t.failed?"stale":"unknown",error:t.failureReason??"trusted-device-proof-pending",deviceId:s?t.expectedDeviceId??e.deviceId??e.deviceIdHint??null:null}:null}async buildLocalTransportTrustPayload(e,t){if(this.disposed)return null;let n=await n$1().catch(()=>null),i=await this.deps.getLocalDeviceId().catch(()=>null)||this.ctx.deviceId||this.deps.getFallbackLocalDeviceId()||null;if(!n||!i)return null;let o=this.initialize(e),s={version:1,deviceId:i,identityFingerprint:n.fingerprint,challenge:o.issuedChallenge??void 0};if(t&&(s.signedChallenge=await n.signChallenge(t),s.signedChallengeFor=t,!await j(t,s.signedChallenge,k(n.publicKey))))throw new Error("local-transport-trust-signature-self-check-failed");return s}async verifyRemoteTransportTrust(e,t){if(this.disposed)return {verified:false,reason:"connection-trust-manager-disposed"};let n=this.initialize(e);if(!n.required)return {verified:true,deviceId:t?.deviceId??n.expectedDeviceId??null};if(!t)return {verified:false,reason:"missing-transport-trust-payload"};let i=typeof t.deviceId=="string"?t.deviceId.trim():"";if(!i)return {verified:false,reason:"missing-remote-device-id"};if(n.expectedDeviceId&&n.expectedDeviceId!==i)return {verified:false,reason:`expected-device-mismatch:${n.expectedDeviceId}:${i}`};let o=this.deps.getKnownDevice(i,e.remoteNodeId);if(!o){if(await this.deps.refreshKnownDeviceCache(),this.disposed)return {verified:false,reason:"connection-trust-manager-disposed"};o=this.deps.getKnownDevice(i,e.remoteNodeId);}if(!o)return {verified:false,reason:`unknown-trusted-device:${i}`};let s=l$1(o.metadata);if(!s)return {verified:false,reason:`missing-trusted-device-metadata:${i}`};if(t.identityFingerprint&&s.identityFingerprint!==t.identityFingerprint)return {verified:false,reason:`trusted-device-fingerprint-mismatch:${i}`};let a=n.issuedChallenge;return !a||!t.signedChallenge?{verified:false,reason:"missing-signed-transport-challenge"}:typeof t.signedChallengeFor!="string"?{verified:false,reason:"unbound-transport-trust-response"}:t.signedChallengeFor!==a?{verified:false,stale:true,reason:"stale-transport-trust-response"}:await j(a,t.signedChallenge,s.identityPublicKey)?{verified:true,deviceId:i}:{verified:false,reason:`invalid-transport-proof-bound:${i}`}}async enforceFailure(e,t){if(this.disposed)return;let n=this.initialize(e);n.failed=true,n.verified=false,n.failureReason=t,await this.deps.rejectConnectionInRust(e,t),!this.disposed&&(this.deps.applyConnectionTrustProjection(e),console.warn("[Client][TRUST] Disconnecting unverified connection",{connectionId:e.id,remoteNodeId:e.remoteNodeId,reason:t}),this.failureCooldowns.set(e.remoteNodeId,Date.now()),await Promise.allSettled([this.disconnectConnectionBestEffort(e),this.disconnectNodeBestEffort(e.remoteNodeId)]));}markVerified(e,t){if(this.disposed)return;this.failureCooldowns.delete(e.remoteNodeId);let n=this.deps.getSessionTokenApprovedScope(e.id),i=!n||this.sessionTokenScopeAllowsDeviceBinding(n),o=i?t:null,s=this.initialize(e,o);s.verified=true,s.failed=false,s.failureReason=void 0,i?(s.verifiedDeviceId=o||s.verifiedDeviceId||s.expectedDeviceId||null,o&&!s.expectedDeviceId&&(s.expectedDeviceId=o)):(s.verifiedDeviceId=null,s.expectedDeviceId=null),this.deps.applyConnectionTrustProjection(e);let a=s.verifiedDeviceId??s.expectedDeviceId??o??null;a&&(this.deps.bindConnectionDeviceIdInRust(e,a),this.deps.retireSupersededConnections(e,a,"trusted-device-replacement"));}clearForConnection(e){this.disposed||this.states.delete(e);}getStateByConnectionId(e){if(!this.disposed)return this.states.get(e)}getLogicalDeviceIdForConnection(e){let t=this.states.get(e);return t?.verifiedDeviceId??t?.expectedDeviceId??null}clearFailureCooldown(e){this.disposed||this.failureCooldowns.delete(e);}getFailureCooldown(e){if(!this.disposed)return this.failureCooldowns.get(e)}shouldSuppressConnectionRebuild(e,t,n,i=Date.now()){if(this.disposed)return {suppress:false,remainingMs:0};let o=this.failureCooldowns.get(e);return o===void 0||i-o>=t||n?{suppress:false,remainingMs:0}:{suppress:true,remainingMs:t-(i-o)}}logConnectionRebuildSuppressed(e$1,t){this.disposed||e("[Client][TRUST] Skipping connection rebuild for node in trust-failure cooldown",{remoteNodeId:e$1,cooldownRemainingMs:t});}disconnectConnectionBestEffort(e){try{return Promise.resolve(e.disconnect()).catch(()=>{})}catch{return Promise.resolve()}}disconnectNodeBestEffort(e){try{return Promise.resolve(this.deps.disconnectNode(e)).catch(()=>{})}catch{return Promise.resolve()}}};function Ar(r){return new pi({getContext:()=>r.getClientContext(),getOptions:()=>r.options,getDeviceId:()=>r.deviceId,getDiscoveryMode:()=>r.discoveryMode,registerDisposer:e=>r.lifecycleScope.register(e),getRegisteredChannel:e=>r.incomingStreamRouter.getRegisteredChannel(e),getConnections:()=>r.registry.values(),requiresManagedTransportTrust:e=>r.runtimeStatus.requiresManagedTransportTrust(e??r.discoveryMode),consumePendingSessionTokenTrustApproval:e=>r.sessionTokens.consumePendingTrustApproval(e),getSessionTokenApprovedScope:e=>r.sessionTokens.getApprovedScope(e),addPeerScope:(e,t)=>r.peerServices.addPeerScope(e,t),getPeerScopes:e=>r.peerServices.getPeerScopes(e),getKnownDeviceIdForNode:e=>r.deviceDirectory.getKnownDeviceIdForNode(e),getKnownDevice:(e,t)=>r.deviceDirectory.getKnownDevice(e,t),refreshKnownDeviceCache:()=>r.deviceDirectory.refreshKnownDeviceCache(),getLocalDeviceId:()=>r.signalingBackendController.getLocalDeviceId(),applyConnectionTrustProjection:e=>r.peerProjection.applyConnectionTrustProjection(e),disconnectRuntimeNode:e=>r.runtimeConnections.disconnectNode(e),rememberKnownDeviceForNode:(e,t)=>r.deviceDirectory.rememberKnownDeviceForNode(e,t),getApplicationCryptoForConnectionOrPeer:(e,t)=>r.applicationCrypto.getForConnectionOrPeer(e,t),indexApplicationCryptoForPeer:(e,t)=>r.applicationCrypto.indexPeer(e,t),hasRustPeerLifecycleProjection:()=>r.hasRustPeerLifecycleProjection(),schedulePeerReconciliation:e=>r.peerProjection.schedule(e),usesTicketOnlySignalingMode:()=>r.runtimeStatus.usesTicketOnlySignalingMode()})}var pi=class{constructor(e){this.host=e;}get trust(){return this._trust||(this._trust=new Pn(this.host.getContext(),{requiresManagedTransportTrust:()=>this.host.requiresManagedTransportTrust(this.host.getDiscoveryMode()),resolvePromotionEligibility:e=>this.channelPolicy.resolvePromotionEligibility(e),consumePendingSessionTokenTrustApproval:e=>this.host.consumePendingSessionTokenTrustApproval(e),getSessionTokenApprovedScope:e=>this.host.getSessionTokenApprovedScope(e),addPeerScope:(e,t)=>this.host.addPeerScope(e,t),getPeerScopes:e=>this.host.getPeerScopes(e),getKnownDeviceIdForNode:e=>this.host.getKnownDeviceIdForNode(e),getKnownDevice:(e,t)=>this.host.getKnownDevice(e,t),refreshKnownDeviceCache:()=>this.host.refreshKnownDeviceCache(),getLocalDeviceId:()=>this.host.getLocalDeviceId(),getFallbackLocalDeviceId:()=>this.host.getDeviceId()??this.host.getOptions()?.localDeviceId??null,applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),bindConnectionDeviceIdInRust:(e,t)=>this.deviceBinder.bindConnectionDeviceIdInRust(e,t),rejectConnectionInRust:(e,t)=>this.deviceBinder.rejectConnectionInRust(e,t),retireSupersededConnections:(e,t,n)=>this.deviceBinder.retireSupersededConnections(e,t,n),disconnectNode:e=>this.host.disconnectRuntimeNode(e)})),this._trust}get deviceBinder(){return this._deviceBinder||(this._deviceBinder=new Sn(this.host.getContext(),{rememberKnownDeviceForNode:(e,t)=>this.host.rememberKnownDeviceForNode(e,t),getApplicationCryptoForConnectionOrPeer:(e,t)=>this.host.getApplicationCryptoForConnectionOrPeer(e,t),indexApplicationCryptoForPeer:(e,t)=>{this.host.indexApplicationCryptoForPeer(e,t);},getLogicalDeviceIdForConnection:e=>this.trust.getLogicalDeviceIdForConnection(e),getSessionTokenApprovedScope:e=>this.host.getSessionTokenApprovedScope(e),sessionTokenScopeAllowsDeviceBinding:e=>this.trust.sessionTokenScopeAllowsDeviceBinding(e)})),this._deviceBinder}get channelPolicy(){return this._channelPolicy||(this._channelPolicy=new In({registerDisposer:e=>this.host.registerDisposer(e),getRegisteredChannel:e=>this.host.getRegisteredChannel(e),getConnections:()=>this.host.getConnections(),getConnectionTrustState:e=>this.trust.getStateByConnectionId(e),getKnownDeviceIdByNodeId:e=>this.host.getKnownDeviceIdForNode(e),hasRustPeerLifecycleProjection:()=>this.host.hasRustPeerLifecycleProjection(),applyConnectionTrustProjection:e=>this.host.applyConnectionTrustProjection(e),schedulePeerReconciliation:e=>this.host.schedulePeerReconciliation(e),usesTicketOnlySignalingMode:()=>this.host.usesTicketOnlySignalingMode()})),this._channelPolicy}};var bn=class{constructor(e){this.host=e;this.kernelHandles=new At;this.lifecycleScope=new Nt;}get wasmClient(){return this.kernelHandles.wasmClient}set wasmClient(e){this.kernelHandles.wasmClient=e;}get node(){return this.kernelHandles.node}set node(e){this.kernelHandles.node=e;}get localNodeId(){return this.kernelHandles.localNodeId}set localNodeId(e){this.kernelHandles.localNodeId=e;}get deviceId(){return this.kernelHandles.deviceId}set deviceId(e){this.kernelHandles.deviceId=e;}get runtimeServices(){return this._runtimeServices??(this._runtimeServices=rr(this))}get runtimeBootstrap(){return this.runtimeServices.bootstrap}get runtimeConnections(){return this.runtimeServices.connections}get managedTransportDialer(){return this.runtimeServices.managedDialer}get runtimeIdentity(){return this.runtimeServices.identity}get runtimeReadiness(){return this.runtimeServices.readiness}get runtimeStatus(){return this.runtimeServices.status}get connectionServices(){return this._connectionServices??(this._connectionServices=Bo(this))}get transportServices(){return this._transportServices??(this._transportServices=kr(this))}get trustServices(){return this._trustServices??(this._trustServices=Ar(this))}get registry(){return this.connectionServices.registry}get connectionDialer(){return this.connectionServices.dialer}get connectionMessageHandler(){return this.connectionServices.messageHandler}get incomingConnectionAcceptor(){return this.connectionServices.incomingAcceptor}get appLifecycle(){return this.runtimeServices.appLifecycle}get roomClientHost(){return this._roomClientHost??(this._roomClientHost=Yo(this))}get accessServices(){return this._accessServices??(this._accessServices=Io(this))}get auth(){return this.accessServices.auth}get signalingBackendController(){return this.accessServices.backend}get peerServices(){return this._peerServices??(this._peerServices=$o(this))}get peerProjection(){return this.peerServices.projection}get connectionLifecycle(){return this.connectionServices.lifecycle}get streamServices(){return this._streamServices??(this._streamServices=yr(this))}get incomingStreamRouter(){return this.streamServices.router}get incomingListen(){return this.streamServices.listen}get incomingDiagnostics(){return this.streamServices.diagnostics}get incomingStreamNormalizer(){return this.streamServices.normalizer}get applicationIncomingStreams(){return this.streamServices.applicationIncoming}get applicationStreams(){return this.streamServices.applicationStreams}get deviceDirectory(){return this.accessServices.devices}get connectionTrust(){return this.trustServices.trust}get connectionDeviceBinder(){return this.trustServices.deviceBinder}get connectionChannelPolicy(){return this.trustServices.channelPolicy}get nativeMainServices(){return this._nativeMainServices??(this._nativeMainServices=Oo(this))}get nativeMain(){return this.nativeMainServices.controller}get presence(){return this.accessServices.presence}retirePendingReciprocalAdmissionsIfExists(e){this._nativeMainServices?.controller.retirePendingReciprocalAdmissions(e);}get securityServices(){return this._securityServices??(this._securityServices=sr(this))}get sessionTokens(){return this.securityServices.sessionTokens}get applicationCrypto(){return this.securityServices.applicationCrypto}get applicationRoute(){return this.transportServices.applicationRoute}get transportHandshake(){return this.transportServices.handshake}get browserCarrier(){return this.transportServices.browserCarrier}get transportHealth(){return this.transportServices.health}get transportContexts(){return this.transportServices.contexts}get peerIdentity(){return this.transportServices.peerIdentity}get options(){return this.host.getOptions()}get runtimeSafetyProfile(){return this.host.getRuntimeSafetyProfile()}get discoveryMode(){return this.options.discoveryMode??"space"}get signaling(){return this.host.getSignaling()}get rooms(){return this.host.getRooms()}getRoomCreationMode(){return this.host.getRoomCreationMode()}getAppLimits(){return this.host.getAppLimits()}setSignaling(e){this.host.setSignaling(e);}setRooms(e){this.host.setRooms(e);}setAppLimits(e){this.host.setAppLimits(e);}setRoomCreationMode(e){this.host.setRoomCreationMode(e);}prepareStreamListenForSignOutIfExists(){this._streamServices?.prepareListenForSignOut();}getEffectiveRoomBackendTag(){return this.host.getEffectiveRoomBackendTag()}setEffectiveRoomBackendTag(e){this.host.setEffectiveRoomBackendTag(e);}getExistingPeerReconciliationStats(){return this._peerServices?.getProjectionStats()}hasRustPeerLifecycleProjection(){return ii(this.signaling,this.wasmClient)}getClientContext(){return this._clientContext||(this._clientContext=Co({getRegistry:()=>this.registry,getWasmClient:()=>this.wasmClient,getNode:()=>this.node,getDiscoveryMode:()=>this.discoveryMode,getLocalNodeId:()=>this.localNodeId,getDeviceId:()=>this.deviceId,registerDisposer:e=>this.lifecycleScope.register(e)})),this._clientContext}getApplicationCrypto(e){return this.securityServices.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.securityServices.resolveApplicationCryptoForPeer(e,t)}clearApplicationCryptoForConnection(e){this._securityServices?.clearApplicationCryptoForConnection(e);}releaseApplicationKeyAgreementReply(e,t,n){this._securityServices?.releaseApplicationKeyAgreementReply(e,t,n);}waitForApplicationCryptoForPeer(e,t=0){return this.securityServices.waitForApplicationCryptoForPeer(e,t)}stopListenIfExists(){this._streamServices?.stopListenIfExists();}hasApplicationRouteForPeer(e,t){return this.transportServices.hasApplicationRouteForPeer(e,t)}ensureManagedApplicationRoute(e){return this.connectionServices.ensureManagedApplicationRoute(e)}};function ui(){return new Proxy({},{get(){}})}function Es(){let r=globalThis,e=r.process?.env;return e?.NODE_ENV==="test"||e?.VITEST==="true"||typeof e?.VITEST_WORKER_ID=="string"||typeof r.__vitest_worker__<"u"||typeof r.__vitest_index__<"u"}function w(r){return r.services}var Nr={localNodeId:{get(){return w(this).localNodeId},set(r){w(this).localNodeId=r;}},deviceId:{get(){return w(this).deviceId},set(r){w(this).deviceId=r;}},registry:{get(){return w(this).registry}},__registry:{get(){return w(this).registry}},runtimeBootstrap:{get(){return w(this).runtimeBootstrap}},runtimeConnections:{get(){return w(this).runtimeConnections}},runtimeIdentity:{get(){return w(this).runtimeIdentity}},runtimeReadiness:{get(){return w(this).runtimeReadiness}},runtimeStatus:{get(){return w(this).runtimeStatus}},connectionDialer:{get(){return w(this).connectionDialer}},connectionMessageHandler:{get(){return w(this).connectionMessageHandler},set(r){w(this).connectionServices._messageHandler=r;}},connectionLifecycle:{get(){return w(this).connectionLifecycle}},applicationRoute:{get(){return w(this).applicationRoute}},transportHandshake:{get(){return w(this).transportHandshake}},transportHealth:{get(){return w(this).transportHealth}},transportContexts:{get(){return w(this).transportContexts}},peerIdentity:{get(){return w(this).peerIdentity}},peerProjection:{get(){return w(this).peerProjection}},peerLifecycle:{get(){return w(this).peerServices.store},set(r){w(this).peerServices.store=r;}},peerLifecycleClient:{get(){return w(this).peerServices.client}},connectionTrust:{get(){return w(this).connectionTrust}},connectionDeviceBinder:{get(){return w(this).connectionDeviceBinder}},connectionChannelPolicy:{get(){return w(this).connectionChannelPolicy}},incomingListen:{get(){return w(this).incomingListen}},incomingStreamRouter:{get(){return w(this).incomingStreamRouter}},incomingDiagnostics:{get(){return w(this).incomingDiagnostics}},incomingStreamNormalizer:{get(){return w(this).incomingStreamNormalizer}},applicationIncomingStreams:{get(){return w(this).applicationIncomingStreams}},applicationCrypto:{get(){return w(this).applicationCrypto}},sessionTokens:{get(){return w(this).sessionTokens}},nativeMain:{get(){return w(this).nativeMain}},auth:{get(){return w(this).auth}},deviceDirectory:{get(){return w(this).deviceDirectory}},presence:{get(){return w(this).presence}},appLifecycle:{get(){return w(this).appLifecycle}},_runtimeBootstrap:{get(){return w(this)._runtimeServices?._bootstrap}},_auth:{get(){return w(this)._accessServices?._auth}},_presence:{get(){return w(this)._accessServices?._presence}},_peerProjection:{get(){return w(this)._peerServices?._projection},set(r){w(this).peerServices._projection=r;}},_peerLifecycleClient:{get(){return w(this)._peerServices?._client}},_incomingListen:{get(){return w(this)._streamServices?._listen}},_connectionDialer:{get(){return w(this)._connectionServices?._dialer}},_connectionMessageHandler:{get(){return w(this)._connectionServices?._messageHandler},set(r){w(this).connectionServices._messageHandler=r;}},_applicationRoute:{get(){return w(this)._transportServices?._applicationRoute}},_applicationCrypto:{get(){return w(this)._securityServices?._applicationCrypto},set(r){w(this).securityServices._applicationCrypto=r;}},_transportContexts:{set(r){w(this).transportServices._contexts=r;}}};function Dr(r){if(Es()){for(let e of Object.values(Nr))e.configurable=true;Object.defineProperties(r.prototype,Nr);}}var $e=class{constructor(e){this.appLimits={...g};this.roomCreationMode="client-open";let t=m(e);this.options=t.options,this.runtimeSafetyProfile=je(this.options),this.effectiveRoomBackendTag=t.appTag,this.roomCreationMode=t.roomCreationMode,this.signaling=new he(n(t),ui()),this._services=this.createServiceGraph(),this.rooms=new Te(this.services.roomClientHost,this.signaling),this.services.signalingBackendController;}get services(){return this._services??(this._services=this.createServiceGraph())}createServiceGraph(){let e=()=>({...this.options??{},apiKey:this.options?.apiKey??"test"});return new bn({getOptions:()=>this.options??e(),getRuntimeSafetyProfile:()=>this.runtimeSafetyProfile??je(e()),getSignaling:()=>this.signaling??(this.signaling=new he(n(e()),ui())),setSignaling:t=>{this.signaling=t;},getRooms:()=>this.rooms,setRooms:t=>{this.rooms=t;},getAppLimits:()=>this.appLimits??(this.appLimits={...g}),setAppLimits:t=>{this.appLimits=t;},getRoomCreationMode:()=>this.roomCreationMode??"client-open",setRoomCreationMode:t=>{this.roomCreationMode=t;},getEffectiveRoomBackendTag:()=>this.effectiveRoomBackendTag??"openrtc",setEffectiveRoomBackendTag:t=>{this.effectiveRoomBackendTag=t;}})}get wasmClient(){return this.services.wasmClient}set wasmClient(e){this.services.wasmClient=e;}get node(){return this.services.node}set node(e){this.services.node=e;}attachIncomingStreamSource(e,t){this.services.wasmClient=e,this.services.localNodeId=t;}getApplicationCrypto(e){return this.services.getApplicationCrypto(e)}resolveApplicationCryptoForPeer(e,t){return this.services.resolveApplicationCryptoForPeer(e,t)}releaseApplicationKeyAgreementReply(e,t,n){this.services.releaseApplicationKeyAgreementReply(e,t,n);}waitForApplicationCryptoForPeer(e,t=1500){return this.services.waitForApplicationCryptoForPeer(e,t)}destroy(){this.services.lifecycleScope.destroy();}dispose(){this.destroy();}get apiKey(){return this.options.apiKey}get discoveryMode(){return this.options.discoveryMode??"space"}getRoomBackendTag(){return this.services.runtimeStatus.getRoomBackendTag()}async refreshHostedAppSettings(e=false){return this.services.signalingBackendController.refreshHostedAppSettings(e)}setSignalingBackend(e){this.services.signalingBackendController.setSignalingBackend(e);}get currentUser(){return this.services.signalingBackendController.getCurrentUser()??null}onAuthChange(e){return this.services.auth.onAuthChange(e)}async signInAnonymously(){return this.services.auth.signInAnonymously()}async signInWithPluto(){return this.services.auth.signInWithPluto()}async signOut(){return this.services.auth.signOut()}getSignalingTelemetry(){return this.services.runtimeStatus.getSignalingTelemetry()}reconciliationStats(){return this.services.runtimeStatus.reconciliationStats()}getProtocolCapabilities(){return this.services.runtimeStatus.getProtocolCapabilities()}async getRuntimeStatus(){return this.services.runtimeStatus.getRuntimeStatus()}async searchDevices(){return this.services.deviceDirectory.searchDevices()}async updateDevice(e,t){return this.services.deviceDirectory.updateDevice(e,t)}async deleteDevice(e){return this.services.deviceDirectory.deleteDevice(e)}async cleanupStaleDevices(){return this.services.deviceDirectory.cleanupStaleDevices()}onDevicesChange(e){return this.services.deviceDirectory.onDevicesChange(e)}async subscribeSessions(e,t){return this.services.deviceDirectory.subscribeSessions(e,t)}async startScanningLoop(e){return this.services.deviceDirectory.startScanningLoop(e)}async bootstrapRuntime(e){return this.services.runtimeBootstrap.bootstrapRuntime(e)}async updateTransportConfig(e){o$1(this.options,e),await this.services.transportServices.browserCarrier.applyConfiguredPolicy(),await this.services.transportHandshake.broadcastTransportCapabilityUpdate("transport-policy-updated");}async init(){return this.services.runtimeBootstrap.init()}async ensureAuthenticated(e){return this.services.auth.ensureAuthenticated(e)}async refreshRuntimeAuthToken(e="runtime-start"){return this.services.auth.refreshRuntimeAuthToken(e)}refreshTransportCapabilities(e="client-request"){return this.services.transportHandshake.broadcastTransportCapabilityUpdate(e)}async connect(e,t=2e4,n,i,o){return this.services.connectionDialer.connect(e,t,n,i,o)}async connectRaw(e,t=2e4){return this.services.runtimeConnections.connectRaw(e,t)}async startAutoConnect(e){return this.services.runtimeConnections.startAutoConnect(e)}async openBi(e){return this.services.applicationStreams.openBi(e)}async openUni(e){return this.services.applicationStreams.openUni(e)}getConnections(){return this.services.registry.all()}readyConnections(e={}){return this.services.registry.applicationReady(e)}getConnectionForPeer(e,t){return this.services.registry.getForPeer(e,t)}hasApplicationRouteForPeer(e,t){return this.services.hasApplicationRouteForPeer(e,t)}ensureManagedApplicationRoute(e){return this.services.ensureManagedApplicationRoute(e)}watchPeerStates(e){return this.services.peerServices.watchPeerStates(e)}getPeerState(e){return this.services.peerServices.getPeerState(e)}listConnectedPeers(){return this.services.peerServices.listConnectedPeers()}isPeerPromotionEligible(e){return this.services.peerServices.isPeerPromotionEligible(e)}addPeerScope(e,t="persistent"){return this.services.peerServices.addPeerScope(e,t)}releasePeerScope(e,t){return this.services.peerServices.releasePeerScope(e,t)}getPeerScopes(e){return this.services.peerServices.getPeerScopes(e)}isSamePeer(e,t){return this.services.peerServices.isSamePeer(e,t)}async refreshPeerSnapshot(){return this.services.peerProjection.schedule("refresh")}async connectPeer(e){return this.services.connectionDialer.connectPeer(e)}clearManualDisconnectProjection(e){this.services.peerServices.clearManualDisconnectProjection(e);}async disconnectPeer(e,t="persistent"){await this.services.peerServices.disconnectPeer(e,t);}async forceDisconnectPeer(e){await this.services.peerServices.forceDisconnectPeer(e);}async getPeerHealth(e){return this.services.peerServices.getPeerHealth(e)}async getTicket(){return this.services.runtimeIdentity.getTicket()}async getNodeId(){return this.services.runtimeIdentity.getNodeId()}async getNodeIdFromTicket(e){return this.services.runtimeIdentity.getNodeIdFromTicket(e)}async getTicketWithToken(e,t=0){return this.services.sessionTokens.getTicketWithToken(e,t)}buildCompoundTicketWithToken(e,t,n=0){return this.services.sessionTokens.buildCompoundTicketWithToken(e,t,n)}setManagedPresenceTicket(e){this.services.presence.setManagedPresenceTicket(e);}clearManagedPresenceTicket(){this.services.presence.clearManagedPresenceTicket();}registerSessionToken(e,t,n,i){this.services.sessionTokens.registerSessionToken(e,t,n,i);}revokeSessionToken(e){this.services.sessionTokens.revokeSessionToken(e);}async revokeTokensByScope(e){return this.services.sessionTokens.revokeTokensByScope(e)}async clearSessionTokens(){return this.services.sessionTokens.clearSessionTokens()}async startPresenceLoop(e){return this.services.presence.startPresenceLoop(e)}async setOffline(){return this.services.presence.setOffline()}async isConnected(e){return this.services.runtimeConnections.isConnected(e)}async disconnectNode(e){return this.services.runtimeConnections.disconnectNode(e)}async getLocalDeviceId(){return this.services.signalingBackendController.getLocalDeviceId()}async acceptNativeMessage(e,t,n){return this.services.nativeMain.acceptNativeMessage(e,t,n)}async startListening(e){return this.services.incomingListen.start(e)}stopListening(){this.services.stopListenIfExists();}forceReconnect(){this.services.signalingBackendController.forceReconnect();}wrapChannelWritable(e,t,n){return no(e,t,n)}async updatePresence(e=true,t=3e5,n,i){return this.services.presence.updatePresence(e,t,n,i)}onConnection(e){return this.services.connectionLifecycle.onConnection(e)}onDisconnection(e){return this.services.connectionLifecycle.onDisconnection(e)}onMessage(e){return this.services.incomingStreamRouter.onMessage(e)}onIncomingStream(e){return this.services.incomingStreamRouter.onIncomingStream(e)}registerChannel(e){this.services.incomingStreamRouter.registerChannel(e);}unregisterChannel(e){this.services.incomingStreamRouter.unregisterChannel(e);}listChannels(){return this.services.incomingStreamRouter.listChannels()}onChannelStream(e,t){return this.services.incomingStreamRouter.onChannelStream(e,t)}onRoomJoinRequest(e){return this.services.incomingStreamRouter.onRoomJoinRequest(e)}};Dr($e);var wn=class{constructor(e,t){this._disposed=false;this.cleanups=[];this.runtime=e,this.scope=t.scope,this.allowAllPeers=t.allowAllPeers??false,this.allowedPeerIds=new Set(t.allowPeers??[]);}get disposed(){return this._disposed}matchesPeer(e){if(this.allowAllPeers||e.scopes?.includes(this.scope))return true;if(this.allowedPeerIds.size>0){let t=[e.peerId,e.deviceId,e.deviceIdHint,e.connectionId];for(let n of t)if(n&&this.allowedPeerIds.has(n))return true}return false}matchesConnectionState(e){if(this.allowAllPeers)return true;let t=e.scopes;if(Array.isArray(t)&&t.includes(this.scope))return true;if(this.allowedPeerIds.size>0){let n=[e.connectionId,e.deviceId,e.deviceIdHint,e.remoteNodeId];for(let i of n)if(i&&this.allowedPeerIds.has(i))return true}return false}matchesStream(e){if(this.allowAllPeers)return true;let t=e.scopes;return !!(Array.isArray(t)&&t.includes(this.scope)||this.allowedPeerIds.size>0&&this.allowedPeerIds.has(e.remoteNodeId))}watchPeerStates(e){this.assertNotDisposed();let t=this.runtime.watchPeerStates(n=>{if(this._disposed)return;let i=this.allowAllPeers?n:n.filter(o=>this.matchesPeer(o));e(i);});return this.cleanups.push(t),t}onStateChange(e){this.assertNotDisposed();let t=o=>{this._disposed||this.matchesConnectionState(o)&&e(o);},n=this.runtime.onStateChange(t);return typeof n=="function"?(this.cleanups.push(n),n):n.then(o=>this._disposed?(o(),()=>{}):(this.cleanups.push(o),o))}listConnectedPeers(){this.assertNotDisposed();let e=this.runtime.listConnectedPeers();return this.allowAllPeers?e:e.filter(t=>this.matchesPeer(t))}async getPeerReadiness(e){return this.assertNotDisposed(),this.runtime.getPeerReadiness(e)}connectPeer(e){return this.assertNotDisposed(),this.runtime.connectPeer({...e,scope:e.scope??this.scope})}async disconnectPeer(e){return this.assertNotDisposed(),this.runtime.disconnectPeer(e,this.scope)}onIncomingStream(e){this.assertNotDisposed();let t=this.runtime.onIncomingStream(n=>{this._disposed||this.matchesStream(n)&&e(n);});return this.cleanups.push(t),t}dispose(){if(!this._disposed){this._disposed=true;for(let e of this.cleanups)try{e();}catch{}this.cleanups.length=0,this.releaseScopedPeersOnDispose();}}releaseScopedPeersOnDispose(){let e;try{e=this.runtime.listConnectedPeers();}catch{return}for(let t of e){if(!t.scopes?.includes(this.scope))continue;let n=t.peerId||t.connectionId||t.deviceId||t.deviceIdHint;n&&this.runtime.disconnectPeer(n,this.scope).catch(()=>{});}}assertNotDisposed(){if(this._disposed)throw new Error(`[Session] Session '${this.scope}' has been disposed.`)}};var Ye=class Ye{constructor(e){this.locallyDeletedDeviceIds=new Set;this.deviceStatusRefreshWakeups=new Set;this.client=e.client,this.backend=e.backend,this.peerApi=e.peerApi,this.connectToDevice=e.connectToDevice,this.startManagedReconciliation=e.startManagedReconciliation,this.deviceStatusRefreshDebounceMs=e.deviceStatusRefreshDebounceMs;}deviceStatusSnapshotKey(e){return JSON.stringify([...e].map(t=>({deviceId:t.deviceId,deviceName:t.deviceName??null,platformType:t.platformType??null,online:!!t.online,presenceStatus:t.presenceStatus??null,presenceUpdatedAt:t.presenceUpdatedAt??null,presenceExpiresAt:t.presenceExpiresAt??null,connectable:t.connectable??null,connectionStatus:t.connectionStatus??null,settledReady:!!t.settledReady,readinessState:t.readinessState??null,readinessReason:t.readinessReason??null,peerHealth:t.peerHealth??null,peerId:t.peerId??null,promotionEligible:t.promotionEligible??true,connectionId:t.connectionId??null,deviceIdHint:t.deviceIdHint??null,nodeId:t.nodeId??null,ticket:t.ticket??null,transportStableId:t.transportStableId??null,transportGeneration:t.transportGeneration??null,routeGeneration:t.routeGeneration??null,activeTransport:t.activeTransport??null,parallelTransport:t.parallelTransport??null,latencyMs:t.latencyMs??null,latencyByTransport:t.latencyByTransport??null,scopes:[...t.scopes??[]].sort()})).sort((t,n)=>t.deviceId.localeCompare(n.deviceId)))}normalizeLookupKey(e){return typeof e=="string"?e.trim().toLowerCase():""}isLocallyDeletedDevice(e){let t=this.normalizeLookupKey(e);return !!t&&this.locallyDeletedDeviceIds.has(t)}filterLocallyDeletedDevices(e){return (e??[]).filter(t=>!this.isLocallyDeletedDevice(t.deviceId))}isDurableUserDevicePeer(e){return (e.scopes??[]).some(t=>t==="user-device")}matchItem(e,t){let n=this.normalizeLookupKey(t.deviceId),i=this.normalizeLookupKey(t.nodeId),o=this.normalizeLookupKey(t.connectionId),s=new Set([n,this.normalizeLookupKey(t.deviceIdHint),i,o,this.normalizeLookupKey(t.peerId)].filter(Boolean)),a=null,c=null;for(let d of e){let l=this.normalizeLookupKey(d.deviceId),p=this.normalizeLookupKey(d.deviceIdHint),u=this.normalizeLookupKey(d.nodeId),h=this.normalizeLookupKey(d.peerId),f=this.normalizeLookupKey(d.activeConnectionId??d.connectionId);if(![l,p,u,h,f].filter(Boolean).some(M=>s.has(M))||i&&u&&u!==i)continue;let v=i&&u===i?5:n&&l===n?4:n&&h===n?3:n&&p===n?2:o&&f===o?1:0,y=String(d.status??"").trim().toLowerCase(),S=y==="closed"||y==="disconnected"||y==="failed",P=(d.settledReady===true||d.routable===true||String(d.readinessState??d.protocolState??"").trim().toLowerCase()==="routable")&&!S?4:y==="connected"&&d.health==="healthy"?3:!S&&y==="connected"?2:S?0:1,k=d.replacementPending===true?0:1,A=d.transportGeneration??d.generation??0,R=d.routeGeneration??0,L=d.lastSeenAtMs??d.lastAuthoritativeEventAt??0,N=[v,P,k,A,R,L],b=c,T=b===null;if(b){for(let M=0;M<N.length;M+=1)if(N[M]!==b[M]){T=N[M]>b[M];break}}T&&(a=d,c=N);}return a}peerIsCompatibleWithSession(e,t){let n=this.normalizeLookupKey(t.nodeId),i=this.normalizeLookupKey(e.nodeId);if(n&&i&&n!==i)return false;let o=this.normalizeLookupKey(t.activeConnectionId),s=[e.connectionId,...e.connectionIds??[]].map(a=>this.normalizeLookupKey(a)).filter(Boolean);return !(o&&s.length>0&&!s.includes(o))}shouldIgnoreTerminalPeerForRoutableSession(e,t){if(!e||!t)return false;let n=String(e.status??"").trim().toLowerCase(),i=n==="closed"||n==="disconnected"||n==="failed",o=t.settledReady===true||String(t.readinessState??"").trim().toLowerCase()==="routable",s=this.isManualDisconnectPeer(e);return i&&!s&&o&&!!t.activeConnectionId}latencyForTransport(e,t){let n=l(e);return n==="webrtc"?t.webrtc??null:n==="iroh-lan"?t.irohLan??null:n==="iroh-relay"?t.irohRelay??null:n==="iroh"||n==="iroh-quic"?t.iroh??null:n==="ble"?t.ble??null:n==="moq"?t.moq??null:null}applyLocalTransportLatency(e){if(!this.isRoutableDeviceStatus(e))return {...e,latencyMs:null,latencyByTransport:void 0};let t=this.client.getConnectionForPeer,i=(typeof t=="function"?t.call(this.client,e.connectionId,e.nodeId??e.peerId):null)?.getLatencySnapshot()??{},o={...e.latencyByTransport??{},...Object.fromEntries(Object.entries(i).filter(([,d])=>d!=null))},s=Object.values(o).some(d=>d!=null)?o:void 0,c=(s?this.latencyForTransport(e.activeTransport,s)??this.latencyForTransport(e.parallelTransport,s):null)??e.latencyMs??null;return {...e,latencyMs:c,latencyByTransport:s}}isManualDisconnectPeer(e){let t=String(e?.error??"").trim().toLowerCase();return t.includes("manual disconnect")||e?.manualDisconnect===true&&t.length>0}buildFinalDeviceStatusSnapshots(e,t,n,i={}){let o=this.filterLocallyDeletedDevices(e).map(c=>{let d=this.matchItem(t,c),l=this.matchItem(n,c),p=(c.connectionStatus==="closed"||c.connectionStatus==="disconnected"||c.connectionStatus==="failed")&&String(c.readinessReason??"").trim().toLowerCase().includes("manual disconnect"),u=d?.settledReady===true||String(d?.readinessState??"").trim().toLowerCase()==="routable",h=this.isManualDisconnectPeer(l)&&!this.isRoutableDeviceStatus(c)&&!u;return A({device:c,session:p||h?null:d,peer:h?l:null,isPromotionEligible:v=>this.client.isPeerPromotionEligible(v)})}),s=new Set(o.map(c=>this.normalizeLookupKey(c.deviceId))),a=new Set(o.flatMap(c=>[c.deviceId,c.deviceIdHint,c.nodeId,c.peerId,c.connectionId].map(d=>this.normalizeLookupKey(d)).filter(Boolean)));for(let c of n){if(!this.isDurableUserDevicePeer(c))continue;let d=this.statusDeviceFromPeer(c),l=this.normalizeLookupKey(d?.deviceId),p=[c.deviceId,c.deviceIdHint,c.nodeId,c.peerId,c.connectionId].map(u=>this.normalizeLookupKey(u)).filter(Boolean);if(!(!d||!l||s.has(l)||p.some(u=>a.has(u))||this.isLocallyDeletedDevice(l))){s.add(l);for(let u of p)a.add(u);o.push(A({device:d,session:this.matchItem(t,d),peer:c,isPromotionEligible:u=>this.client.isPeerPromotionEligible(u)}));}}return o.map(c=>this.applyLocalTransportLatency(c))}applyTerminalPeerTransportState(e,t){if(this.isRoutableDeviceStatus(e))return e;let n=String(t?.status??"").trim().toLowerCase();return n!=="closed"&&n!=="disconnected"&&n!=="failed"?e:{...e,transportStableId:null,activeTransport:void 0,parallelTransport:void 0}}statusDeviceFromPeer(e){let t=e.deviceId?.trim()||e.deviceIdHint?.trim(),n=String(e.status??"").trim().toLowerCase();return !t||n==="closed"||n==="disconnected"||n==="failed"?null:{deviceId:t,deviceName:e.deviceName?.trim()||"Unknown Device",online:e.online??true,ticket:e.ticket??"",nodeId:e.nodeId,platformType:e.platformType,presenceStatus:e.online===false?"offline":"online",connectable:!!e.ticket,connectionStatus:e.status,settledReady:e.routable===true||e.protocolState==="routable",readinessState:e.protocolState,peerHealth:e.health,peerId:e.peerId,scopes:[...e.scopes??[]],connectionId:e.connectionId,deviceIdHint:e.deviceIdHint,transportStableId:e.transportStableId,transportGeneration:e.transportGeneration,routeGeneration:e.routeGeneration,activeTransport:e.activeTransport,parallelTransport:e.parallelTransport}}runtimeDeviceToStatusSnapshot(e){return A({device:e})}isRoutableDeviceStatus(e){return e.settledReady===true||String(e.readinessState??"").trim().toLowerCase()==="routable"}mergeWatchedDevicesIntoStatusSnapshots(e,t){if(!e)return t;let n=new Map(t.map(c=>[c.deviceId,c])),i=this.filterLocallyDeletedDevices(e),o=new Set(i.map(c=>this.normalizeLookupKey(c.deviceId))),s=this.filterLocallyDeletedDevices(t.filter(c=>!o.has(this.normalizeLookupKey(c.deviceId))));return [...i.map(c=>{let d=this.runtimeDeviceToStatusSnapshot(c),l=n.get(c.deviceId);if(!l)return d;let{connectionStatus:p,settledReady:u,readinessState:h,readinessReason:f,peerHealth:m,peerId:v,promotionEligible:y,connectionId:S,transportStableId:C,transportGeneration:P,routeGeneration:k,activeTransport:A$1,parallelTransport:R,presenceStatus:L,presenceUpdatedAt:N,presenceExpiresAt:b,connectable:T,...M}=l,{connectionStatus:j,settledReady:J,readinessState:Me,readinessReason:Nn,peerHealth:Je,peerId:Dn,promotionEligible:_e,connectionId:Mn,transportStableId:Ee,transportGeneration:_n,routeGeneration:En,activeTransport:Bn,parallelTransport:Ln,presenceStatus:ye,presenceUpdatedAt:Qe,presenceExpiresAt:I,connectable:D,latencyMs:O,latencyByTransport:E,deviceIdHint:q,scopes:Ce,...V}=d,Ie=l.presenceUpdatedAt,Se=Qe,Or=Se!==void 0&&Ie!==void 0&&Se===Ie&&ye==="online"&&l.presenceStatus!=="online",Be=ye!==void 0&&Se!==void 0&&(Ie===void 0||Se>Ie||Or);return A({device:{...M,...V,connectionStatus:l.connectionStatus,settledReady:l.settledReady,readinessState:l.readinessState,readinessReason:l.readinessReason,peerHealth:l.peerHealth,peerId:l.peerId,promotionEligible:l.promotionEligible,connectionId:l.connectionId,transportStableId:l.transportStableId,transportGeneration:l.transportGeneration,routeGeneration:l.routeGeneration,activeTransport:l.activeTransport,parallelTransport:l.parallelTransport,latencyMs:l.latencyMs,latencyByTransport:l.latencyByTransport,online:Be?d.online:l.online,presenceStatus:Be?ye:l.presenceStatus,presenceUpdatedAt:Be?Qe:l.presenceUpdatedAt,presenceExpiresAt:Be?I:l.presenceExpiresAt,connectable:Be?D:l.connectable,platformType:l.platformType??d.platformType,deviceIdHint:q??l.deviceIdHint,scopes:l.scopes}})}),...s]}async listDevices(){return this.filterLocallyDeletedDevices(await this.client.searchDevices())}async listDeviceStatus(){let e=this.backend;if(e&&typeof e.listDeviceStatus=="function"){let t=await e.listDeviceStatus(),[n,i]=await Promise.allSettled([typeof e.listPeerSessions=="function"?e.listPeerSessions():Promise.resolve([]),this.peerApi.refreshPeerSnapshot().catch(d=>{let l=this.peerApi.listConnectedPeers();return console.warn(`[RuntimeClient] refreshPeerSnapshot failed during listDeviceStatus(); using ${l.length} cached connected peers`,d),l})]),o=n.status==="fulfilled"?n.value:[],s=i.status==="fulfilled"?i.value:[],a=this.filterLocallyDeletedDevices(this.buildFinalDeviceStatusSnapshots(t,o,s,{preserveRoutableInputLifecycle:true}));return (a.some(d=>o$2(d.activeTransport))||o.some(d=>o$2(d.activeTransport))||s.some(d=>o$2(d.activeTransport)))&&d$2("[RuntimeClient] device status snapshot with transport labels",{devices:a.map(d=>({deviceId:d.deviceId,connectionStatus:d.connectionStatus,settledReady:!!d.settledReady,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null,connectionId:d.connectionId??null})),peerSessions:o.map(d=>({peerId:d.peerId,deviceId:d.deviceId??null,activeConnectionId:d.activeConnectionId??null,status:d.status,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null})),peers:s.map(d=>({peerId:d.peerId,deviceId:d.deviceId??null,connectionId:d.connectionId??null,status:d.status,activeTransport:d.activeTransport??null,parallelTransport:d.parallelTransport??null}))}),a}throw new Error("[pluto-rtc] listDeviceStatus() requires a Rust-backed runtime adapter that implements listDeviceStatus().")}async updateDevice(e,t){await this.client.updateDevice(e,t);}async deleteDevice(e){let t=this.normalizeLookupKey(e);await this.client.deleteDevice(e),t&&this.locallyDeletedDeviceIds.add(t);}watchDevices(e){return this.client.onDevicesChange(t=>e(this.filterLocallyDeletedDevices(t)))}watchDeviceStatus(e){let t=this.backend;if(!t||typeof t.listDeviceStatus!="function")throw new Error("[pluto-rtc] watchDeviceStatus() requires a Rust-backed runtime adapter that implements listDeviceStatus().");let n=true,i=null,o=null,s=null,a=null,c=false,d=false,l=C=>{let P=this.filterLocallyDeletedDevices(C);u(P);let k=this.deviceStatusSnapshotKey(P);k!==i&&(i=k,e(P));},p=()=>{a&&(clearTimeout(a),a=null);},u=C=>{if(p(),!n)return;let P=Date.now(),k=C.filter(R=>R.presenceStatus==="online").map(R=>typeof R.presenceUpdatedAt=="number"?R.presenceUpdatedAt+3e5:null).filter(R=>typeof R=="number"&&Number.isFinite(R)).sort((R,L)=>R-L)[0];if(k===void 0)return;let A=Math.max(25,k-P+5);a=setTimeout(()=>{a=null,m();},A);},h=()=>{c=false,!(!n||!d)&&(d=false,m());},f=()=>{if(n){if(c){d=true;return}c=true,this.listDeviceStatus().then(C=>{n&&l(this.mergeWatchedDevicesIntoStatusSnapshots(o,C));}).catch(C=>{console.warn("[RuntimeDeviceManager] device-status refresh failed",C);}).finally(()=>h());}},m=()=>{!n||s||(s=setTimeout(()=>{s=null,f();},this.deviceStatusRefreshDebounceMs));};this.deviceStatusRefreshWakeups.add(m);let v=this.client.onDevicesChange(C=>{Array.isArray(C)&&(o=this.filterLocallyDeletedDevices(C)),m();}),y=this.peerApi.watchPeerStates(()=>{m();}),S=this.startManagedReconciliation(()=>m());return f(),()=>{n=false,s&&clearTimeout(s),p(),this.deviceStatusRefreshWakeups.delete(m),S(),v(),y();}}notifyLifecycleMutation(){for(let e of this.deviceStatusRefreshWakeups)e();}async connectWithRetry(e,t,n){return this.connectDevice(e,{localDeviceId:n.localDeviceId,targetUserId:n.targetUserId,onConnected:t.onConnected})}async connectDevice(e,t){let n=e,i=typeof e.ticket=="string"?e.ticket.trim():"";if(!i){let u=(await this.listDeviceStatus().catch(()=>this.listDevices().catch(()=>[]))).find(h=>h.deviceId===e.deviceId);u&&(n={...e,...u},i=typeof u.ticket=="string"?u.ticket.trim():"");}if(!i){let p=`Cannot connect to ${e.deviceId}: missing endpoint ticket`,u=c$3(p);return {success:false,error:p,errorCode:u.errorCode,retryable:u.retryable,errorPlane:u.errorPlane,attempts:1}}let o=this.peerApi.getPeerState(e.deviceId),s=o?.status,a=this.client.hasApplicationRouteForPeer?.(o?.connectionId??void 0)??false;if(s==="connected"&&a)return {success:true,skipped:"already-connecting",attempts:0};this.client.clearManualDisconnectProjection?.(n.deviceId);let c=this.backend;await c.excludeAutoConnect?.(n.deviceId,false);let d=Date.now(),l=()=>Math.max(1,Ye.EXPLICIT_CONNECT_SETTLE_TIMEOUT_MS-(Date.now()-d));try{let p=await this.connectToDevice({deviceId:n.deviceId,endpointTicket:i,timeoutMs:Ye.EXPLICIT_CONNECT_SETTLE_TIMEOUT_MS});if(c&&typeof c.waitForSettledPeer=="function"){let u=l();if(!(await c.waitForSettledPeer(p.deviceId??n.deviceId??p.remoteNodeId??p.connectionId,u))?.settledReady)throw new Error(`Connection to ${n.deviceId} did not become application-routable`)}return await this.peerApi.refreshPeerSnapshot().catch(()=>{}),this.notifyLifecycleMutation(),await t.onConnected?.(n),{success:!0,attempts:1}}catch(p){let u=p instanceof Error?p.message:`Cannot connect to ${e.deviceId}`,h=e$1(p);return {success:false,error:u,errorCode:h.code,retryable:h.retryable,errorPlane:h.plane,attempts:1}}}};Ye.EXPLICIT_CONNECT_SETTLE_TIMEOUT_MS=3e4;var Tn=Ye;var Rn=class{constructor(e,t){this.client=e;this.backend=t;}normalizeUiConnectionStatus(e){switch((e||"disconnected").trim().toLowerCase()){case "connected":return "connected";case "connecting":return "connecting";case "failed":return "failed";default:return "disconnected"}}buildLookup(e,t){let n=new Map,i=(o,s)=>{let a=typeof o=="string"?o.trim():"";!a||n.has(a)||n.set(a,s);};for(let o of e)for(let s of t(o))i(s,o);return n}uniqueLookupIds(...e){let t=new Set,n=[];for(let i of e){let o=typeof i=="string"?i.trim():"";!o||t.has(o)||(t.add(o),n.push(o));}return n}matchSessionByLookupId(e,t){if(!e.length||!t.length)return null;let n=this.buildLookup(e,i=>[i.peerId,i.deviceId,i.deviceIdHint,i.nodeId,i.activeConnectionId]);for(let i of t){let o=n.get(i);if(o)return o}return null}matchLocalPeerState(e,t){let n=this.uniqueLookupIds(...e,t.peerId,t.deviceId,t.deviceIdHint,t.nodeId,t.activeConnectionId);for(let o of n){let s=this.client.getPeerState(o);if(s)return s}let i=this.buildLookup(this.client.listConnectedPeers(),o=>[o.peerId,o.deviceId,o.deviceIdHint,o.nodeId,o.connectionId,...o.connectionIds??[]]);for(let o of n){let s=i.get(o);if(s)return s}return null}async resolvePeerLookupIds(e,t){let n=typeof t.resolvePeerIdentity=="function"?await t.resolvePeerIdentity(e).catch(()=>null):null,i=this.uniqueLookupIds(e,n?.peerId,n?.deviceId,n?.deviceIdHint,n?.nodeId);if(typeof t.listPeerSessions!="function")return i;let o=this.matchSessionByLookupId(await t.listPeerSessions().catch(()=>[]),i);return this.uniqueLookupIds(...i,o?.peerId,o?.deviceId,o?.deviceIdHint,o?.nodeId,o?.activeConnectionId)}async resolvePeerRecords(e){let t=this.backend;if(!t||typeof t.resolvePeerRecords!="function")throw new Error("[pluto-rtc] resolvePeerRecords() requires a Rust-backed runtime adapter that implements resolvePeerRecords().");return t.resolvePeerRecords(e)}async getPeerSession(e){let t=this.backend;if(!t||typeof t.getPeerSession!="function")throw new Error("[pluto-rtc] getPeerSession() requires a Rust-backed runtime adapter that implements getPeerSession().");let n=await this.resolvePeerLookupIds(e,t);for(let i of n){let o=await t.getPeerSession(i);if(o)return o}return typeof t.listPeerSessions=="function"?this.matchSessionByLookupId(await t.listPeerSessions(),n):null}async listPeerSessions(){let e=this.backend;if(!e||typeof e.listPeerSessions!="function")throw new Error("[pluto-rtc] listPeerSessions() requires a Rust-backed runtime adapter that implements listPeerSessions().");return e.listPeerSessions()}async waitForConnectedPeer(e,t){let n=this.backend;if(!n||typeof n.waitForSettledPeer!="function")throw new Error("[pluto-rtc] waitForConnectedPeer() requires a Rust-backed runtime adapter that implements waitForSettledPeer().");let i=typeof n.resolvePeerIdentity=="function"?await n.resolvePeerIdentity(e).catch(()=>null):null,o=this.uniqueLookupIds(i?.peerId,i?.deviceId,i?.deviceIdHint,i?.nodeId,e),s=o[0]??e,a=Date.now(),c=await n.waitForSettledPeer(s,t);if(!c?.settledReady)return c;let d=typeof t=="number"?Math.max(0,t):5e3;for(;;){let l=this.matchLocalPeerState(o,c);if(!l||l.routable===true||l.protocolState==="routable")return c;if(Date.now()-a>=d)return {...c,settledReady:false,readinessState:l.protocolState??"transport-only",readinessReason:l.error??"application-route-not-ready"};await new Promise(p=>setTimeout(p,50));}}async waitForConnectedScope(e,t){let n=this.backend;if(!n||typeof n.waitForSettledScope!="function")throw new Error("[pluto-rtc] waitForConnectedScope() requires a Rust-backed runtime adapter that implements waitForSettledScope().");return n.waitForSettledScope(e,t)}async getPeerReadiness(e,t){let n=this.client.getPeerState(e)??null,i=typeof t=="number"?await this.waitForConnectedPeer(e,t).catch(()=>null):await this.getPeerSession(e).catch(()=>null),o=this.normalizeUiConnectionStatus(i?.status??n?.status??"disconnected"),s=n?.routable===false&&n?.protocolState==="unverified";return {requestedId:e,connected:o==="connected",settledReady:s?false:!!i?.settledReady,status:o,health:i?.health??n?.health??"unknown",deviceId:i?.deviceId??n?.deviceId??null,deviceIdHint:i?.deviceIdHint??n?.deviceIdHint??null,activeConnectionId:i?.activeConnectionId??n?.connectionId??null,readinessState:s?n?.protocolState:i?.readinessState??n?.protocolState,readinessReason:s?n?.error:i?.readinessReason??n?.error,scopes:[...i?.scopes??n?.scopes??[]]}}async resolvePeerIdentity(e){let t=this.backend;if(!t||typeof t.resolvePeerIdentity!="function")throw new Error("[pluto-rtc] resolvePeerIdentity() requires a Rust-backed runtime adapter that implements resolvePeerIdentity().");return t.resolvePeerIdentity(e)}async resolveStreamPeer(e){return this.resolvePeerIdentity(e)}addPeerScope(e,t){return this.client.addPeerScope(e,t)}releasePeerScope(e,t){return this.client.releasePeerScope(e,t)}getPeerScopes(e){return this.client.getPeerScopes(e)}isSamePeer(e,t){return this.client.isSamePeer(e,t)}};function Mr(r){return ["closed","failed","disconnected"].includes(r.state.trim().toLowerCase())}function _r(r){return Mr(r)||r.replacementInProgress===true?false:r.routable===true||r.protocolState==="routable"||r.readinessState==="routable"}function Bs(r){return r instanceof Uint8Array?r:r instanceof ArrayBuffer?new Uint8Array(r):new TextEncoder().encode(typeof r=="string"?r:JSON.stringify(r))}function Ls(r){try{let e=new TextDecoder("utf-8",{fatal:!0}).decode(r),t=new TextEncoder().encode(e);if(t.byteLength!==r.byteLength||!t.every((n,i)=>n===r[i]))return r;try{return JSON.parse(e)}catch{return e}}catch{return r}}var gi=class{constructor(e,t,n){this.backend=t;this.localNodeIdProvider=n;this.closed=false;this.messageListeners=new Set;this.closeListeners=new Set;this.state=e,this.id=e.connectionId,this.remoteNodeId=e.remoteNodeId?.trim()||e.deviceId?.trim()||e.connectionId,this.deviceId=e.deviceId?.trim()||this.remoteNodeId;}get isClosed(){return this.closed}get localNodeId(){return this.localNodeIdProvider()}get transportType(){return this.state.activeTransport??"iroh-relay"}update(e){this.state=e;}isPayloadReady(e={}){if(this.closed||!_r(this.state))return false;let t=e.preferredTransports??[];return t.length===0||t.includes(this.transportType)||t.includes("iroh")}payloadTransports(e={}){return this.isPayloadReady(e)?[this.transportType]:[]}getAvailableTransports(){return this.closed?[]:[this.transportType]}getTransportStatus(){return {activeTransport:this.transportType,parallelTransport:this.state.parallelTransport??null}}async getTransportDiagnostics(){return {...this.getTransportStatus(),transportStableId:this.state.transportStableId??null,transportGeneration:this.state.transportGeneration??null,routeGeneration:this.state.routeGeneration??null,lifecycleOwner:"rust-logical-peer",projectionAdapter:"openrtc-tauri-ipc"}}async send(e){if(this.closed||!this.isPayloadReady())throw new Error("[Connection] Native logical peer route is not ready.");if(typeof this.backend.sendPeerMessage!="function")throw new Error("[Connection] Native logical peer message IPC is unavailable.");await this.backend.sendPeerMessage(this.remoteNodeId,Bs(e));}onMessage(e){this.messageListeners.add(e);}onDisconnect(e){this.closeListeners.add(e);}receive(e){if(this.closed||Number.isSafeInteger(this.state.transportGeneration)&&e.transportGeneration<Number(this.state.transportGeneration))return null;let t=Ls(Uint8Array.from(e.payload));for(let n of this.messageListeners)n(t);return {message:t}}close(){if(!this.closed){this.closed=true;for(let e of this.closeListeners)e();this.messageListeners.clear(),this.closeListeners.clear();}}},kn=class{constructor(e,t){this.backend=e;this.localNodeId=t;this.connections=new Map;this.connectionListeners=new Set;this.disconnectionListeners=new Set;this.messageListeners=new Set;this.stopState=null;this.stopMessages=null;this.startEpoch=0;}start(){let e=++this.startEpoch;typeof this.backend.onStateChange=="function"&&Promise.resolve(this.backend.onStateChange(t=>this.observeState(t))).then(t=>{if(e!==this.startEpoch)return void t();this.stopState=t;}).catch(t=>{console.error("[OpenRTC] Native connection-state projection unavailable:",t);}),typeof this.backend.onPeerMessage=="function"&&Promise.resolve(this.backend.onPeerMessage(t=>this.observeMessage(t))).then(t=>{if(e!==this.startEpoch)return void t();this.stopMessages=t;}).catch(t=>{console.error("[OpenRTC] Native peer-message projection unavailable:",t);});}list(){return [...this.connections.values()].filter(e=>!e.isClosed).map(e=>e)}ready(e={}){return [...this.connections.values()].filter(t=>t.isPayloadReady(e)).map(t=>t)}onConnection(e){this.connectionListeners.add(e);for(let t of this.list())e(t);return ()=>this.connectionListeners.delete(e)}onDisconnection(e){return this.disconnectionListeners.add(e),()=>this.disconnectionListeners.delete(e)}onMessage(e){return this.messageListeners.add(e),()=>this.messageListeners.delete(e)}close(){this.startEpoch+=1,this.stopState?.(),this.stopMessages?.(),this.stopState=null,this.stopMessages=null;for(let e of this.connections.values())e.close();this.connections.clear(),this.connectionListeners.clear(),this.disconnectionListeners.clear(),this.messageListeners.clear();}observeState(e){let t=this.connections.get(e.connectionId);if(Mr(e)){if(!t)return;this.connections.delete(e.connectionId),t.close();let o=t;for(let s of this.disconnectionListeners)s(o);return}if(!_r(e)){t?.update(e);return}if(t){t.update(e);return}let n=new gi(e,this.backend,this.localNodeId);this.connections.set(e.connectionId,n);let i=n;for(let o of this.connectionListeners)o(i);}observeMessage(e){let t=this.connections.get(e.connectionId)??[...this.connections.values()].find(o=>o.remoteNodeId===e.remoteNodeId);if(!t)return;let n=t.receive(e);if(!n)return;let i=t;for(let o of this.messageListeners)o(i,n.message);}};var xr="drive-view.",hi=[68,86,67,72],xs=new TextDecoder;function mi(r){if(r.byteLength>=hi.length){let e=true;for(let t=0;t<hi.length;t+=1)if(r[t]!==hi[t]){e=false;break}if(e)return true}try{let e=JSON.parse(xs.decode(r));return typeof e.t=="string"&&e.t.startsWith(xr)}catch{return false}}function Er(r){return !!r&&!r.isClosed&&typeof r.send=="function"&&(typeof r.isPayloadReady!="function"||r.isPayloadReady())}var Br=new WeakMap;function Fs(r){if(r instanceof Uint8Array)return mi(r)?r:null;if(r instanceof ArrayBuffer){let e=new Uint8Array(r);return mi(e)?e:null}return r&&typeof r=="object"&&typeof r.t=="string"&&r.t.startsWith(xr)?new TextEncoder().encode(JSON.stringify(r)):null}function Os(r,e$1){let t=Br.get(r);if(!t){t={receivers:new Set([e$1])},Br.set(r,t);let n=i=>{let o=false;for(let s of [...t.receivers])try{o=s(i)||o;}catch(a){e("[RuntimeClient][connectScopedChannel] route-scoped receiver failed",{connectionId:r.id,error:String(a)});}return o};return typeof r.onMessage=="function"&&r.onMessage(i=>{let o=Fs(i);o&&n(o);}),()=>t?.receivers.delete(e$1)}return t.receivers.add(e$1),()=>t?.receivers.delete(e$1)}var H=class H{constructor(e,t){this.nativeProjectionLocalNodeId="";this.managedSessionKey=null;this.managedSessionUserId=null;this.managedSessionOptions=null;this.managedSessionTransition=Promise.resolve();this.managedSessionStartInFlight=new Map;this.browserInitialization=null;this.terminalShutdown=null;this.managedReconciliationTasks=new Set;this.managedReconciliationFollowupTimers=new Set;this.scopedConnectionActorRegistry=null;this.client=new $e(e),this.backend=t??null,t&&this.client.setSignalingBackend(t),this.peerManager=new Rn(this.client,this.backend),this.connectionController=new at(this.client,this.backend,()=>this.deviceManager.notifyLifecycleMutation()),this.deviceManager=new Tn({client:this.client,backend:this.backend,peerApi:{watchPeerStates:i=>this.client.watchPeerStates(i),refreshPeerSnapshot:()=>this.client.refreshPeerSnapshot(),listConnectedPeers:()=>this.client.listConnectedPeers(),getPeerState:i=>this.client.getPeerState(i)},connectToDevice:i=>this.connectionController.connectToDevice(i),startManagedReconciliation:i=>this.startManagedReconciliation(i),deviceStatusRefreshDebounceMs:H.DEVICE_STATUS_REFRESH_DEBOUNCE_MS});let n=t?.capabilities?.().adapter;this.nativeConnectionProjection=n==="native-ipc"||n==="tauri-ipc"?new kn(t,()=>this.nativeProjectionLocalNodeId):null,this.nativeConnectionProjection?.start();}static describeTicketForLogs(e){let t=typeof e=="string"?e.trim():"";if(!t)return {hasTicket:false,isCompound:false,scope:null};let n=t.indexOf(".");if(n<0)return {hasTicket:true,isCompound:false,scope:null};try{let i=t.slice(n+1).replace(/-/g,"+").replace(/_/g,"/"),o=(4-i.length%4)%4,s=JSON.parse(atob(i+"=".repeat(o)));return {hasTicket:!0,isCompound:!0,scope:typeof s?.s=="string"?s.s:null}}catch{return {hasTicket:true,isCompound:true,scope:null}}}async serializeManagedSessionOperation(e,t){let n=Date.now(),i=this.managedSessionTransition,o,s=new Promise(c=>{o=c;});this.managedSessionTransition=s,console.info("[RuntimeClient][managed-session][operation-queued]",{label:e,managedSessionUserId:this.managedSessionUserId,hasManagedSession:this.managedSessionKey!==null}),await i.catch(()=>{});let a=Date.now();console.info("[RuntimeClient][managed-session][operation-started]",{label:e,queueWaitMs:a-n,managedSessionUserId:this.managedSessionUserId,hasManagedSession:this.managedSessionKey!==null});try{return await t()}finally{console.info("[RuntimeClient][managed-session][operation-finished]",{label:e,queueWaitMs:a-n,operationMs:Date.now()-a,managedSessionUserId:this.managedSessionUserId,hasManagedSession:this.managedSessionKey!==null}),o(),this.managedSessionTransition===s&&(this.managedSessionTransition=Promise.resolve());}}get identity(){return this.client.currentUser}resolveManagedSessionUserId(e,t){let n=this.identity?.id??null;return n?(t&&t!==n&&console.warn("[RuntimeClient][managed-session][user-id-override]",{requestedUserId:t,runtimeIdentityUserId:n}),n):t??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}resolveManagedTicketScope(e){if(e?.platform!=="web"||e.sessionKind!=="scoped-guest")return H.MANAGED_USER_DEVICE_SCOPE;let t=e.scope?.trim();if(!t||t===H.MANAGED_USER_DEVICE_SCOPE)throw new Error("Managed browser session requires a non-device guest scope.");return t}getEffectiveRuntimeUserId(){return this.identity?.id??this.managedSessionUserId??this.managedSessionOptions?.userId??null}async fetchAndApplyAppLimits(){try{await this.client.refreshHostedAppSettings();}catch(e){console.warn("[pluto-rtc] Could not fetch app limits, using technical safety defaults.",e);}}async resolvePeerStreamTarget(e){let t=this.client.getPeerState(e)??null,n=await this.getPeerSession(e).catch(()=>null),i=n?.activeConnectionId?.trim()||null,o=(i?this.client.getConnections().find(a=>!a.isClosed&&a.id===i):void 0)??null,s=n?.nodeId?.trim()||o?.remoteNodeId?.trim()||t?.nodeId?.trim()||null;return {peer:t,session:n,connection:o,remoteNodeId:s}}compatPeerConnectionFromTarget(e,t){let n=e.session?.activeConnectionId?.trim()||`peer-stream:${t}`,i=e.remoteNodeId||t;return {id:n,deviceId:i,remoteNodeId:i,isClosed:false}}isTransportOnlyStreamChannel(e){let t=typeof e=="string"?e.trim():"";if(!t)return false;let n=this.client.listChannels().find(i=>i.id.trim()===t);return Mt(n??null)}nextNativeStartRetryDelayMs(e){return d$1(e,H.NATIVE_START_RETRY_MIN_DELAY_MS,H.NATIVE_START_RETRY_MAX_DELAY_MS)}hasManagedSession(){return !!(this.managedSessionKey||this.managedSessionUserId)}usesNativeIpcBackend(){let t=this.backend?.capabilities?.();return t?.adapter==="native-ipc"||t?.adapter==="tauri-ipc"||t?.signaling.nativeIpc===true}startManagedReconciliation(e){return this.managedReconciliationTasks.add(e),()=>{this.managedReconciliationTasks.delete(e);}}scheduleManagedReconciliationFollowups(){this.notifyManagedReconciliation();for(let e of this.managedReconciliationFollowupTimers)clearTimeout(e);this.managedReconciliationFollowupTimers.clear();for(let e of [1500,5e3]){let t=setTimeout(()=>{this.managedReconciliationFollowupTimers.delete(t),this.notifyManagedReconciliation();},e);this.managedReconciliationFollowupTimers.add(t);}}stopManagedReconciliation(){for(let e of this.managedReconciliationFollowupTimers)clearTimeout(e);this.managedReconciliationFollowupTimers.clear(),this.managedReconciliationTasks.clear();}notifyManagedReconciliation(){this.hasManagedSession()&&this.managedReconciliationTasks.forEach(e=>{if(this.hasManagedSession())try{e();}catch{}});}async syncNativeSession(e="frontend"){let t=this.backend;t&&typeof t.syncNativeSession=="function"&&await t.syncNativeSession({reason:e}),await this.refreshPeerSnapshot().catch(()=>[]),this.scheduleManagedReconciliationFollowups();}async notifyNetworkChange(e="host"){let t=this.backend;typeof t.notifyNetworkChange=="function"&&await t.notifyNetworkChange({reason:e});}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,logicalSessionTerminal:e.logicalSessionTerminal===true,readinessState:e.readinessState??null,readinessReason:e.readinessReason??null,transportGeneration:e.transportGeneration??null,routeGeneration:e.routeGeneration??null,activeTransport:e.activeTransport??null,parallelTransport:e.parallelTransport??null,replacementInProgress:e.replacementInProgress??null,error:e.error??null,updatedAt:e.updatedAt??null})}async runNativeStartLoop(e$1){let t=Date.now(),n=0;for(;Date.now()-t<=H.NATIVE_START_RETRY_WINDOW_MS;){n+=1;try{await e$1.start(),n>1&&e(`[RuntimeClient] ${e$1.label} recovered after ${n} attempts`);return}catch(i){if(this.isUnsupportedRuntimeAdapterError(i,e$1.label))throw i;let o=this.nextNativeStartRetryDelayMs(n);console.warn(`[RuntimeClient] ${e$1.label} failed attempt=${n} retry_in_ms=${o}:`,i),await a(o);}}throw new Error(e$1.exhaustedMessage)}isUnsupportedRuntimeAdapterError(e,t){if(!(e instanceof Error))return false;let n=e.message||"",i=t==="startPresenceLoop"?"startPresence":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().");let n=typeof e?.userId=="string"&&e.userId.trim()||null,i=this.managedSessionUserId;i&&i!==n&&(console.info("[RuntimeClient][auth-context][managed-session-replace]",{previousUserId:i,nextUserId:n}),await this.stopManagedSession()),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}if(!this.browserInitialization){let e=this.client.init();this.browserInitialization=e,e.catch(()=>{this.browserInitialization===e&&(this.browserInitialization=null);});}await this.browserInitialization;}async getRuntimeStatus(){return this.client.getRuntimeStatus()}async setTransportPriority(e){let t=[...e],n=this.backend;if(typeof n?.setTransportPriority=="function"){await n.setTransportPriority(t);return}if(this.usesNativeIpcBackend())throw new Error("Native transport priority control is unavailable from the IPC host.");await this.client.updateTransportConfig({priority:t});}reconciliationStats(){return this.client.reconciliationStats()}getRuntimePolicy(){return o}capabilities(){let e=this.backend;return typeof e?.capabilities=="function"?e.capabilities():t()}getCapabilityProfile(){return v(this.capabilities())}async attachNativeIncomingProjection(e){let t=this.backend;if(!t)throw new Error("Native incoming-stream projection requires the IPC backend.");if(typeof t.incoming_projected_streams!="function")throw new Error("Native IPC requires incoming_projected_streams(); it must not attach a second admitted-stream receiver.");let n=typeof t.projectedIncomingStreamSource=="function"?t.projectedIncomingStreamSource():{incoming_streams:()=>t.incoming_projected_streams(),isCurrentTransport:t.isCurrentTransport?.bind(t)};this.client.attachIncomingStreamSource(n,e),await this.client.startListening({startPresence:false});}async start(e){if(this.usesNativeIpcBackend()){let t=await this.getManagedNodeId({initializeIfMissing:true});if(!t)throw new Error("Native runtime started without a node id for the admitted application-stream queue.");console.info("[RuntimeClient][native] Rust host owns the admitted application-stream queue",{nativeNodeId:t}),await this.attachNativeIncomingProjection(t);return}e?.clearSessionTokens!==false&&await this.client.clearSessionTokens().catch(()=>{}),await this.client.refreshRuntimeAuthToken("runtime-start"),await this.client.startListening();}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 localDeviceProfile(e){let t=await this.getLocalDeviceInfo().catch(()=>null),n=e?.localDeviceId??t?.deviceId??await this.getLocalDeviceId().catch(()=>null)??null,i=await this.getRuntimeStatus().catch(()=>({runtime:"unknown",wasmLoaded:false,localNodeId:void 0,userId:void 0})),o=e?.platform??(i.runtime==="tauri"?"native":"web");return {deviceId:n,deviceName:e?.deviceName||t?.deviceName||"Unknown Device",platformType:t?.platformType||(o==="native"?"desktop":"web"),userId:e?.userId??this.identity?.id??i.userId??null,capabilities:t?.capabilities??{can_host:o==="native",can_sync:o==="native",read_only:o!=="native"},lastSeenAt:t?.lastSeenAt||new Date().toISOString(),localNodeId:i.localNodeId||null}}async updateDeviceName(e){let t=this.backend;return !t||typeof t.updateDeviceName!="function"?null:t.updateDeviceName(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 initIrohProtocols(e){await this.persistentIrohProtocolBackend().initializePersistentIrohProtocols(e);}async createIrohNamespace(e={}){let t=e.generation??0,n=e.shareRevision??0;return this.assertProtocolCounter(t,"generation"),this.assertProtocolCounter(n,"shareRevision"),this.persistentIrohProtocolBackend().createPersistentIrohNamespace(t,n)}async importIrohTicket(e,t={}){let n=t.generation??0,i=t.shareRevision??0;if(this.assertProtocolCounter(n,"generation"),this.assertProtocolCounter(i,"shareRevision"),!e.trim())throw new Error("Iroh document ticket is required.");return this.persistentIrohProtocolBackend().importPersistentIrohTicket(e,n,i)}async shareIrohNamespace(e,t){return this.persistentIrohProtocolBackend().sharePersistentIrohNamespace(e,t?.writable===true)}async removeIrohNamespace(e,t={}){let n=t.generation??0,i=t.shareRevision??0;this.assertProtocolCounter(n,"generation"),this.assertProtocolCounter(i,"shareRevision"),await this.persistentIrohProtocolBackend().removePersistentIrohNamespace(e,n,i);}async putIrohBytes(e,t,n){return this.persistentIrohProtocolBackend().putPersistentIrohBytes(e,t,n)}async setIrohHash(e,t,n,i){return this.assertProtocolCounter(i,"contentLength"),this.persistentIrohProtocolBackend().setPersistentIrohHash(e,t,n,i)}async deleteIrohPrefix(e,t){return this.persistentIrohProtocolBackend().deletePersistentIrohPrefix(e,t)}async queryIrohNamespace(e,t=new Uint8Array){return this.persistentIrohProtocolBackend().queryPersistentIrohNamespace(e,t)}async hydrateIrohBlob(e){await this.persistentIrohProtocolBackend().hydratePersistentIrohBlob(e);}async acknowledgeOutbox(e){await this.persistentIrohProtocolBackend().acknowledgePersistentIrohOutbox(e);}async flushIrohProtocols(){await this.persistentIrohProtocolBackend().flushPersistentIrohProtocols();}persistentIrohProtocolBackend(){let e=this.backend;if(!e||typeof e.initializePersistentIrohProtocols!="function")throw new Error("Persistent Iroh protocols require the browser WASM runtime.");return e}assertProtocolCounter(e,t){if(!Number.isSafeInteger(e)||e<0)throw new Error(`${t} must be a non-negative safe integer.`)}async getTicket(){return this.usesNativeIpcBackend()?this.getEndpointTicket():this.client.getTicket()}async getTicketWithToken(e,t=0){let n=this.backend;if(n?.getTicketWithToken)try{let i=await n.getTicketWithToken(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.getTicketWithToken(e,t)}async registerToken(e){let t=e.token.trim(),n=e.scope.trim(),i=e.maxConnections??0;if(!t)throw new Error("Admission token is required.");if(!n)throw new Error("Admission scope is required.");if(!Number.isSafeInteger(i)||i<0)throw new Error("maxConnections must be a non-negative safe integer.");if(e.expiresAtMs!==void 0&&(!Number.isSafeInteger(e.expiresAtMs)||e.expiresAtMs<=Date.now()))throw new Error("Admission token expiry must be a future epoch millisecond.");let o=this.backend;if(o?.registerSessionToken){await o.registerSessionToken(t,n,i,e.expiresAtMs);return}if(this.usesNativeIpcBackend())throw new Error("Native admission-token registration is unavailable from the IPC backend.");this.client.registerSessionToken(t,n,i,e.expiresAtMs);}async revokeTokensByScope(e){return this.revokeTokensByScopeInternal(e,{rotateManagedScopeIfActive:true})}async revokeTokensByScopeInternal(e,t){h("revokeTokensByScopeInternal",{grantScope:e,rotateManagedScopeIfActive:t?.rotateManagedScopeIfActive!==false,hasManagedSessionOptions:!!this.managedSessionOptions});let n=this.usesNativeIpcBackend(),i=n?[]:await this.client.revokeTokensByScope(e),o=this.backend,s=[];if(o?.revokeTokens)s=await o.revokeTokens(e).catch(()=>[]);else if(n)throw new Error("Native token revoke requires revokeTokens() on the IPC backend.");let a=Array.from(new Set([...i,...s]));return t?.rotateManagedScopeIfActive!==false&&this.managedSessionOptions&&e===this.resolveManagedTicketScope(this.managedSessionOptions)&&this.managedSessionOptions.presence!==false&&await this.rotateManagedGrant(),a}revokeSessionToken(e){this.client.revokeSessionToken(e);}watchFriendDevices(e,t){let n=this.backend;return n?.watchFriendDevices?n.watchFriendDevices(e,t):()=>{}}async getFriendTicket(e=0){return this.getTicketWithToken(H.MANAGED_FRIEND_SCOPE,e)}async revokeFriendTokens(){return this.revokeTokensByScope(H.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.resolveManagedTicketScope(e),n=this.resolveManagedSessionUserId(e.platform,e.userId??null),i=JSON.stringify({platform:e.platform,sessionKind:e.sessionKind??"app-user-device",scope:e.scope??null,userId:n,autoConnect:this.resolveManagedAutoConnectEnabled(e),autoConnectPolicy:e.autoConnectPolicy??null,presence:this.resolveManagedPresenceEnabled(e),presencePolicy:e.presencePolicy??null}),o=this.managedSessionStartInFlight.get(i);if(o)return o;let s=this.serializeManagedSessionOperation("start",async()=>{if(this.managedSessionKey===i){if(e.platform==="native"&&n){let l=this.backend;if(l&&typeof l.startNativeSession=="function")try{let p=await l.startNativeSession({userId:n,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:n,localNodeId:p.localNodeId,presenceStarted:p.presenceStarted,autoConnectStarted:p.autoConnectStarted,localDeviceId:p.localDevice?.deviceId??null});}catch(p){console.warn("[RuntimeClient][managed-session][native-replay-failed]",{userId:n,message:p instanceof Error?p.message:String(p)});}}let d=await this.localDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:n});return {mode:e.platform,device:d,stop:async()=>this.stopManagedSession()}}h("managed-session-replace",{previousSessionKey:this.managedSessionKey,nextSessionKey:i}),await this.stopManagedSessionInternal(),this.managedSessionKey=i,this.managedSessionUserId=n,this.managedSessionOptions={...e,userId:n};let a=null,c=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(()=>{}),a=await this.getTicketWithToken(t,0),this.client.setManagedPresenceTicket(a),await this.start({clearSessionTokens:!1})):(this.client.clearManagedPresenceTicket(),await this.start());else {if(!this.managedSessionUserId)throw new Error("Native managed session startup requires an authenticated user id.");await this.client.ensureAuthenticated("discovery");let l=this.backend;if(!l||typeof l.startNativeSession!="function")throw new Error("Native managed session startup requires a native backend-owned startNativeSession() surface.");c=await l.startNativeSession({userId:this.managedSessionUserId,deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,metadata:e.metadata,autoConnect:this.resolveManagedAutoConnectEnabled(e),presence:this.resolveManagedPresenceEnabled(e)}),this.nativeProjectionLocalNodeId=c.localNodeId??"",console.info("[RuntimeClient][managed-session][native-started]",{userId:this.managedSessionUserId,localNodeId:c.localNodeId,ticketScope:c.ticketScope??null,presenceStarted:c.presenceStarted,autoConnectStarted:c.autoConnectStarted,localDeviceId:c.localDevice?.deviceId??null});let p=c.localNodeId??await this.getManagedNodeId({initializeIfMissing:!1});if(!p)throw new Error("Native managed session started without a node id for the admitted application-stream queue.");console.info("[RuntimeClient][managed-session] Rust host owns the admitted application-stream queue",{nativeNodeId:p}),await this.attachNativeIncomingProjection(p);}this.fetchAndApplyAppLimits();let d=await this.localDeviceProfile({deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,platform:e.platform,userId:this.managedSessionUserId});return e.platform==="native"?(this.resolveManagedPresenceEnabled(e)&&!c?.presenceStarted&&console.warn("[RuntimeClient][managed-session][native-presence-missing]",{userId:this.managedSessionUserId,deviceId:d.deviceId}),this.resolveManagedAutoConnectEnabled(e)&&d.deviceId&&!c?.autoConnectStarted&&console.warn("[RuntimeClient][managed-session][native-auto-connect-missing]",{userId:this.managedSessionUserId,deviceId:d.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:d.deviceId,deviceName:d.deviceName,ticketScope:H.describeTicketForLogs(a).scope}),await this.startPresenceLoop({deviceName:d.deviceName,ticket:a,metadata:e.metadata}),console.info("[RuntimeClient][managed-session][presence-started]",{platform:e.platform,userId:this.managedSessionUserId,deviceId:d.deviceId})),e.platform!=="native"&&this.resolveManagedAutoConnectEnabled(e)&&d.deviceId&&(await this.startAutoConnect(d.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:d.deviceId})),await this.refreshPeerSnapshot().catch(()=>[]),this.scheduleManagedReconciliationFollowups(),{mode:e.platform,device:d,stop:async()=>this.stopManagedSession()}}catch(d){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:d instanceof Error?d.message:String(d)}),await this.stopManagedSessionInternal().catch(()=>{}),d}});this.managedSessionStartInFlight.set(i,s);try{return await s}finally{this.managedSessionStartInFlight.delete(i);}}async stopManagedSession(e){return this.serializeManagedSessionOperation(e?.preserveBackendSession?"stop-preserve-backend":"stop",()=>this.stopManagedSessionInternal(e))}async stopManagedSessionInternal(e){if(!this.managedSessionKey&&!this.managedSessionUserId)return;let t=!!e?.preserveBackendSession;h("stopManagedSessionInternal",{preserveBackendSession:t,managedSessionKey:this.managedSessionKey,managedSessionUserId:this.managedSessionUserId??null});let n=this.backend,i=this.managedSessionOptions,o=i?.platform==="native"&&typeof n?.releaseNativeCapability=="function",s=Date.now();if(console.info("[RuntimeClient][managed-session][stop-stage]",{stage:"local-invalidate",elapsedMs:0,managedSessionUserId:this.managedSessionUserId,preserveBackendSession:t}),this.client.clearManagedPresenceTicket(),t?console.info("[RuntimeClient] Preserving native backend-managed session across frontend teardown",{userId:this.managedSessionUserId??this.identity?.id??null,scope:H.MANAGED_USER_DEVICE_SCOPE}):(this.stop(),o?(console.info("[RuntimeClient][managed-session][stop-stage]",{stage:"release-native-capability",elapsedMs:Date.now()-s,managedSessionUserId:this.managedSessionUserId}),await n.releaseNativeCapability()):(console.info("[RuntimeClient][managed-session][stop-stage]",{stage:"revoke-managed-grants",elapsedMs:Date.now()-s,managedSessionUserId:this.managedSessionUserId}),await this.revokeTokensByScopeInternal(this.resolveManagedTicketScope(i),{rotateManagedScopeIfActive:false}).catch(()=>[])),!o&&n&&typeof n.stopAuthActivity=="function"?(console.info("[RuntimeClient][managed-session][stop-stage]",{stage:"stop-backend-auth-scope",elapsedMs:Date.now()-s,managedSessionUserId:this.managedSessionUserId}),await n.stopAuthActivity({userId:this.managedSessionUserId??this.identity?.id??null})):o||await this.setOffline().catch(()=>{})),t){this.notifyManagedReconciliation();return}await this.scopedConnectionActorRegistry?.shutdownAll().catch(a=>{console.warn("[RuntimeClient] scoped connection actor shutdown failed",a);}),this.scopedConnectionActorRegistry=null,this.managedSessionKey=null,this.managedSessionUserId=null,this.managedSessionOptions=null,console.info("[RuntimeClient][managed-session][stop-stage]",{stage:"complete",elapsedMs:Date.now()-s,managedSessionUserId:null});}async rotateManagedGrant(){let e=this.managedSessionOptions;if(!e||!this.resolveManagedPresenceEnabled(e))return;if(e.platform==="native"){let o=this.backend;if(!o||typeof o.startNativeSession!="function")throw new Error("Native managed ticket rotation requires a native backend-owned startNativeSession() surface.");let s=this.managedSessionUserId??e.userId??this.identity?.id??null;if(!s)throw new Error("Native managed ticket rotation requires an authenticated user id.");await o.startNativeSession({userId:s,deviceName:e.deviceName,localDeviceId:e.localDeviceId??null,metadata:e.metadata,autoConnect:this.resolveManagedAutoConnectEnabled(e),presence:this.resolveManagedPresenceEnabled(e)}),console.info("[RuntimeClient][managed-ticket][rotate]",{scope:H.MANAGED_USER_DEVICE_SCOPE,platform:e.platform,userId:s});return}let t=await this.getTicketWithToken(this.resolveManagedTicketScope(e),0),n=this.managedSessionUserId??e.userId??this.identity?.id??null;this.client.setManagedPresenceTicket(t);let i=await this.localDeviceProfile({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:this.resolveManagedTicketScope(e),platform:e.platform,userId:n});}async listDevices(){return this.deviceManager.listDevices()}async listDeviceStatus(){return this.deviceManager.listDeviceStatus()}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)}watchDeviceStatus(e){return this.deviceManager.watchDeviceStatus(e)}async connectWithRetry(e,t,n){return this.deviceManager.connectWithRetry(e,t,n)}async connectDevice(e,t){return this.deviceManager.connectDevice(e,t)}watchPeerStates(e){return this.client.watchPeerStates(e)}watchPeerLifecycle(e){return this.watchPeerStates(e)}getPeerState(e){return this.client.getPeerState(e)}async resolvePeerRecords(e){return this.peerManager.resolvePeerRecords(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 waitForConnectedScope(e,t){return this.peerManager.waitForConnectedScope(e,t)}async getPeerReadiness(e,t){return this.peerManager.getPeerReadiness(e,t)}async resolvePeerIdentity(e){return this.peerManager.resolvePeerIdentity(e)}async resolveStreamPeer(e){return this.peerManager.resolveStreamPeer(e)}listConnectedPeers(){return this.client.listConnectedPeers()}addPeerScope(e,t){return this.peerManager.addPeerScope(e,t)}releasePeerScope(e,t){return this.peerManager.releasePeerScope(e,t)}getPeerScopes(e){return this.peerManager.getPeerScopes(e)}isSamePeer(e,t){return this.peerManager.isSamePeer(e,t)}async refreshPeerSnapshot(){return this.client.refreshPeerSnapshot()}async subscribeSessions(e,t){return this.client.subscribeSessions(e,t)}getAppLimits(){return this.client.appLimits}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)}async connectScopedChannel(e$1){let t=e$1.timeoutMs===void 0?void 0:Math.max(1,e$1.timeoutMs),n=t===void 0?void 0:Date.now()+t,i=I=>{if(n===void 0||t===void 0)return;let D=n-Date.now();if(D<=0)throw new Error(`connectScopedChannel timeout after ${t}ms during ${I}`);return Math.max(1,D)},o=e$1.scope,s=e$1.channelId.trim();if(!s)throw new Error("connectScopedChannel requires a channelId");let a$2=e$1.peerId??e$1.peerNodeId??e$1.deviceId??(e$1.ticket?await this.getNodeIdFromTicket(e$1.ticket).catch(()=>null):null);if(!a$2)throw new Error("connectScopedChannel requires peerId, peerNodeId, deviceId, or a ticket with an embedded node id");let c=this.client.getConnections().find(I=>!I.isClosed&&(I.remoteNodeId===a$2||I.deviceId===a$2))??null,d=c?[c.id,c.remoteNodeId,c.deviceId,a$2,e$1.deviceId].map(I=>typeof I=="string"?I.trim():"").filter(Boolean).map(I=>this.client.getPeerState(I)).find(I=>I!==void 0):void 0,l=c?await this.resolvePeerRecords(e$1.deviceId??a$2).catch(()=>[]):[],p=this.usesNativeIpcBackend()?await this.getPeerSession(e$1.deviceId??a$2).catch(()=>null):null,u=l.some(I=>I.state.toLowerCase()==="connected"&&I.transportStableId!==null&&I.transportStableId!==void 0),h=d?.status==="connected"&&d.lifecycleStage!=="closed"&&d.baseTransportState!=="closed"&&d.routable!==false,f=c!==null&&(typeof c.isPayloadReady!="function"||c.isPayloadReady()),m=e$1.existingRouteOnly===true?f:(l.length>0?u:h)&&d?.scopes.includes(o)===true,v=p?.status==="connected"&&p.settledReady===true&&p.scopes.includes(o);e("[RuntimeClient][connectScopedChannel] existing route decision",{peerId:a$2,scope:o,hasWrapper:c!==null,projectedStatus:d?.status??null,projectedScopes:d?.scopes??[],managedRecords:l.map(I=>({connectionId:I.connectionId,state:I.state,transportStableId:I.transportStableId??null})),nativeSession:p?{peerId:p.peerId,deviceId:p.deviceId??null,nodeId:p.nodeId??null,status:p.status,settledReady:p.settledReady===true,scopes:p.scopes}:null,reuse:m||v,existingRouteOnly:e$1.existingRouteOnly===true});let y=m?c:null,S=null,C=v?p?.nodeId??a$2:null;if(!y){if(e$1.existingRouteOnly===true)throw new Error(`Capability-owned channel '${s}' has no application-ready route for '${a$2}'`);if(this.usesNativeIpcBackend()||e$1.admissionToken){if(!v){if(!e$1.ticket&&!e$1.admissionToken)throw new Error("Rust-owned connectScopedChannel requires an endpoint ticket or known-device admission token when no scoped connection exists");{let I=o===H.MANAGED_USER_DEVICE_SCOPE?e$1.deviceId:null,D=i("native peer dial"),O=e$1.ticket?{endpointTicket:e$1.ticket,deviceId:I}:{deviceId:e$1.deviceId,admissionToken:e$1.admissionToken,admissionScope:o,admissionPeerUserId:e$1.admissionPeerUserId,admissionMaxConnections:e$1.admissionMaxConnections??0,admissionExpiresAtMs:e$1.admissionExpiresAtMs};D!==void 0&&(O.timeoutMs=D);let E=await this.connectToDevice(O),q=E.remoteNodeId??E.deviceId??E.deviceIdHint??a$2,Ce=e$1.admissionToken?await this.waitForConnectedScope(o,i("native scoped peer settle")):await this.waitForConnectedPeer(q,i("native scoped peer settle"));if(!Ce?.settledReady||!Ce.scopes.includes(o))throw new Error(`native scoped peer '${q}' did not admit '${o}' before channel open`);C=Ce.nodeId??q,y=this.client.getConnections().find(V=>!V.isClosed&&(V.id===E.connectionId||V.remoteNodeId===q||V.deviceId===q||V.deviceId===e$1.deviceId))??null;}}}else {S=this.connectionActor({scope:o,peerNodeId:a$2},{ticket:e$1.ticket,timeoutMs:i("scoped peer actor"),channelId:s,dial:async()=>{y=await this.connectPeer({ticket:e$1.ticket,deviceId:e$1.deviceId??a$2,scope:o,channelId:s,timeoutMs:i("browser peer dial"),keepManualDisconnect:e$1.keepManualDisconnect??true});}});try{await S.ensureReady();}catch(I){throw await this.scopedConnectionActorRegistry?.retireIfCurrent(dt(o,a$2),S).catch(()=>{}),I}}}y||(this.usesNativeIpcBackend()||e$1.admissionToken?y=this.client.getConnections().find(I=>!I.isClosed&&(I.remoteNodeId===(C??a$2)||I.deviceId===a$2))??null:y=await this.connectPeer({ticket:e$1.ticket,deviceId:e$1.deviceId??a$2,scope:o,channelId:s,timeoutMs:i("peer dial fallback"),keepManualDisconnect:e$1.keepManualDisconnect??true}));let P=y?.remoteNodeId??C??a$2,k=y,A=e$1.framing??"raw",R=async I=>{let D=await this.openPeerBi(P,{timeoutMs:I,scope:o,channelId:s});return {connection:D.connection,readable:D.readable,writer:D.writable.getWriter()}},L=await R(i("scoped stream open"));y=k??L.connection;let N=L.writer,b=new Set,T=false,M=false,j=0,J=null,Me=null,Nn=Promise.resolve(),Je=null,Dn=null,_e=null,Mn=I=>{s!=="drive-view"||!I||I===Dn||typeof I.onMessage=="function"&&(_e?.(),_e=Os(I,D=>{if(T||!mi(D))return false;for(let O of [...b])O(D);return true}),Dn=I);},Ee=()=>{let I=new Set([y?.id,y?.remoteNodeId,y?.deviceId,P,a$2,e$1.deviceId,e$1.peerId,e$1.peerNodeId].map(E=>typeof E=="string"?E.trim():"").filter(Boolean)),D=this.client.getConnections().filter(E=>!E.isClosed&&(I.has(E.id)||I.has(E.remoteNodeId)||I.has(E.deviceId??""))),O=D.find(E=>Er(E))??D[0]??null;if(O&&O!==y&&(y=O),!y)throw new Error(`Scoped channel '${s}' has no active connection`);return Mn(y),y};Mn(y);let _n=I=>{let D=I.getReader(),O=++j,E=new Uint8Array(0);J=D,M=false,(async()=>{try{for(;!T&&O===j;){let{value:q,done:Ce}=await D.read();if(Ce)break;if(!(!q||q.byteLength===0)){if(A==="raw"){for(let V of [...b])V(q);continue}for(E=jn(E,q);E.byteLength>=4;){let V=qn(E,0);if(E.byteLength<4+V)break;let Ie=E.slice(4,4+V);E=E.slice(4+V);for(let Se of [...b])Se(Ie);}}}}catch(q){!T&&O===j&&e("[RuntimeClient][connectScopedChannel] physical stream read loop ended with error",{peerId:P,channelId:s,error:String(q)});}finally{O===j&&(M=true,J===D&&(J=null));try{D.releaseLock();}catch{}}})();};_n(L.readable);let En=async()=>{M&&(Me||(Me=(async()=>{let I=N,D=await R(t);if(T){try{await D.readable.cancel("scoped channel closed during physical stream reopen");}catch{}try{await D.writer.abort("scoped channel closed during physical stream reopen");}catch{}try{D.writer.releaseLock();}catch{}throw new Error(`Scoped channel '${s}' is closed`)}y=D.connection??y,N=D.writer,_n(D.readable);try{await I.abort("scoped channel physical stream replaced");}catch{}try{I.releaseLock();}catch{}})().finally(()=>{Me=null;})),await Me);},Bn=async I=>{let D=Nn.then(async()=>{if(T)throw new Error(`Scoped channel '${s}' is closed`);let O=Ee();if(!M&&s==="drive-view"&&Er(O))try{await O.send(I),Je=O.lastPayloadTransport?.()??O.getTransportStatus?.().activeTransport??null;return}catch(q){e("[RuntimeClient][connectScopedChannel] current-route scoped-channel send failed; falling back to stream",{peerId:P,channelId:s,error:String(q)});}let E=A==="u32be"?Wn(I):I;await En();try{await N.write(E);}catch(q){if(T)throw q;M=true,await En(),await N.write(E);}Je="stream";});Nn=D.catch(()=>{}),await D;},Ln=this.client.listChannels().find(I=>I.id===s)?.delivery??"reliable",ye=Ln==="latest-state"?new a$1(Bn):null,Qe=I=>ye?.send(I)??Bn(I);if(!this.usesNativeIpcBackend()){let I=Math.max(1,Math.min(i("application route settlement")??5e3,5e3)),D=Date.now();for(;;){let O=Ee();if(typeof O.isPayloadReady!="function"||O.isPayloadReady())break;if(Date.now()-D>=I){T=true,j+=1;let E=J;try{await E?.cancel("scoped channel application route timeout");}catch{}try{await N.abort("scoped channel application route timeout");}catch{}try{N.releaseLock();}catch{}throw await S?.shutdown().catch(()=>{}),new Error(`Scoped channel '${s}' timed out waiting for an application payload route`)}await a(20);}}return {channelId:s,peerId:P,get connection(){return Ee()},send:Qe,onMessage(I){return b.add(I),()=>b.delete(I)},async close(){if(!T){T=true,ye?.close(new Error(`Scoped channel '${s}' is closed`)),j+=1,b.clear(),_e?.(),_e=null;try{await J?.cancel("scoped channel closed");}catch{}try{await N.abort("scoped channel closed");}catch{}try{N.releaseLock();}catch{}await S?.shutdown().catch(()=>{});}},diagnostics:()=>{let I=Ee();return {connectionId:I.id??null,remoteNodeId:I.remoteNodeId??null,transports:I.getAvailableTransports?.()??[],lastSendTransport:Je,framing:A,delivery:Ln}}}}connectionActor(e,t){let n=a=>{let c=t?.ticket,d=t?.channelId,l=t?.dial;return new Ue({key:a,dial:async p=>{if(this.assertScopedDialAllowed(p),l){await l(p);return}await this.connectPeer({deviceId:p.peerNodeId,ticket:c,scope:p.scope,channelId:d,keepManualDisconnect:true});},close:async()=>{}})};this.scopedConnectionActorRegistry||(this.scopedConnectionActorRegistry=new We(n));let i=dt(e.scope,e.peerNodeId),o=this.scopedConnectionActorRegistry.get(i),s=this.scopedConnectionActorRegistry.getOrSpawn(i,n);return (o===null||o!==null&&o!==s)&&$("[runtime-client][scoped-connection-actor]",He(i.scope,{peerNodeId:i.peerNodeId}),"spawn"),s}assertScopedDialAllowed(e){let t=this.scopedDialCandidateIds(e).find(n=>this.hasManualDisconnectSuppression(n));if(t)throw $("[runtime-client][scoped-connection-actor]",He(e.scope,{peerNodeId:e.peerNodeId}),"dial_suppressed_manual_disconnect peerId={}",t),new Error(`scoped connection dial suppressed by manual disconnect for peer ${t}`)}scopedDialCandidateIds(e){let t=new Set,n=e.peerNodeId.trim();n&&t.add(n);let i=e.scope.trim();if(i.startsWith("trusted-device:")){let o=i.slice(15).split(":")[0]?.trim();o&&t.add(o);}return [...t]}hasManualDisconnectSuppression(e){let t=this.client.getPeerState(e);if(!t)return false;if(t.manualDisconnect===true)return true;let n=t,i=[t.error,n.lastDisconnectReason].filter(o=>typeof o=="string"&&o.length>0).join(" ");return /manual disconnect/i.test(i)}async shutdownActors(){if(!this.scopedConnectionActorRegistry)return;let e=this.scopedConnectionActorRegistry.size();$("[runtime-client][scoped-connection-actor]",{sessionKind:"drive-grant-guest"},"shutdown_all count={}",e),await this.scopedConnectionActorRegistry.shutdownAll();}async openPeerBi(e,t){let n=this.backend;if(n&&typeof n.openPeerBi=="function"){await this.waitForBrowserApplicationCrypto(e,t?.timeoutMs);let i=await n.openPeerBi(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),readable:i.readable,writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId,t.channelMetadata):i.writable}}throw new Error("[pluto-rtc] openPeerBi() requires a Rust-backed runtime adapter that implements openPeerBi().")}async openPeerBiRaw(e,t){let n=this.backend;if(n&&typeof n.openPeerBiRaw=="function"){let i=await n.openPeerBiRaw(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),readable:i.readable,writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId,t.channelMetadata):i.writable}}throw new Error("[pluto-rtc] this runtime does not support the restricted transport-only diagnostic stream.")}async openPeerUni(e,t){let n=this.backend;if(n&&typeof n.openPeerUni=="function"){await this.waitForBrowserApplicationCrypto(e,t?.timeoutMs);let i=await n.openPeerUni(e,t?.timeoutMs),o=await this.resolvePeerStreamTarget(e);return {connection:o.connection??this.compatPeerConnectionFromTarget(o,e),writable:t?.channelId?this.client.wrapChannelWritable(i.writable,t.channelId,t.channelMetadata):i.writable}}throw new Error("[pluto-rtc] openPeerUni() requires a Rust-backed runtime adapter that implements openPeerUni().")}async beginOpenRtcMediaPublication(e){let t=this.backend;if(!t?.beginOpenRtcMediaPublication)throw new Error("[OpenRTC] The active runtime does not expose Rust-owned media sessions.");return t.beginOpenRtcMediaPublication(e)}async encodeOpenRtcMediaSample(e){let t=this.backend;if(!t?.encodeOpenRtcMediaSample)throw new Error("[OpenRTC] The active runtime does not expose Rust-owned media sessions.");return t.encodeOpenRtcMediaSample(e)}async pauseOpenRtcMediaPublication(e){let t=this.backend;if(!t?.pauseOpenRtcMediaPublication)throw new Error("[OpenRTC] The active runtime does not expose Rust-owned media sessions.");await t.pauseOpenRtcMediaPublication(e);}async retireOpenRtcMediaPublication(e){let t=this.backend;if(!t?.retireOpenRtcMediaPublication)throw new Error("[OpenRTC] The active runtime does not expose Rust-owned media sessions.");await t.retireOpenRtcMediaPublication(e);}async retireOpenRtcMediaReceiver(e,t){let n=this.backend;if(!n?.retireOpenRtcMediaReceiver)throw new Error("[OpenRTC] The active runtime does not expose Rust-owned media sessions.");await n.retireOpenRtcMediaReceiver(e,t);}async decodeOpenRtcMediaChunk(e){let t=this.backend;if(!t?.decodeOpenRtcMediaChunk)throw new Error("[OpenRTC] The active runtime does not expose the shared media protocol.");return t.decodeOpenRtcMediaChunk(e)}async decodeOpenRtcMediaControl(e){let t=this.backend;if(!t?.decodeOpenRtcMediaControl)throw new Error("[OpenRTC] The active runtime does not expose the shared media protocol.");return t.decodeOpenRtcMediaControl(e)}async sendPeerDatagram(e,t,n){let i=this.backend;if(!i?.sendPeerDatagram)throw new Error("[OpenRTC] Protected peer datagrams are unavailable in this runtime.");return await i.sendPeerDatagram(e,t,n)!==false}async receivePeerDatagram(e){let t=this.backend;if(!t?.receivePeerDatagram)throw new Error("[OpenRTC] Protected peer datagrams are unavailable in this runtime.");return t.receivePeerDatagram(e)}peerDatagramMaxSize(){return this.backend?.peerDatagramMaxSize?.()??1024}createPeerDatagramPolicy(){let e=this.backend;if(!e?.createPeerDatagramPolicy)throw new Error("[OpenRTC] The active runtime does not expose shared datagram policy.");return e.createPeerDatagramPolicy()}async waitForBrowserApplicationCrypto(e,t){if(this.usesNativeIpcBackend())return;let n=Math.max(1,t??1e4);if(!await this.client.waitForApplicationCryptoForPeer(e,n))throw new Error(`[OpenRTC] protected application stream to '${e}' timed out waiting for application crypto`)}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()}onChannelStream(e,t){return this.client.onChannelStream(e,t)}async sendExplicitFilePath(e,t,n){let i=this.backend;if(!i||typeof i.sendExplicitFilePath!="function")throw new Error("Selected runtime adapter does not support sendExplicitFilePath().");return i.sendExplicitFilePath(e,t,n)}async sendExplicitFileData(e){let t=this.backend;if(!t||typeof t.sendExplicitFileData!="function")throw new Error("Selected runtime adapter does not support sendExplicitFileData().");let n=this.client.getConnectionForPeer(e.connectionId,e.remoteNodeId),i=e.requireApplicationCrypto??(typeof n?.isApplicationCryptoRequired=="function"?n.isApplicationCryptoRequired():void 0),o=e.remoteNodeId??n?.remoteNodeId??e.connectionId??n?.deviceId,s=e.applicationCrypto??this.client.getApplicationCrypto(n??void 0)??this.client.resolveApplicationCryptoForPeer(o,n??void 0)??(i?await this.client.waitForApplicationCryptoForPeer(o):void 0),a=e.receiverPlatformType;if(a===void 0){let d=new Set([e.remoteNodeId,n?.remoteNodeId,n?.deviceId,e.connectionId].map(l=>typeof l=="string"?l.trim():"").filter(l=>l.length>0));if(d.size>0){let p=(await this.listDeviceStatus().catch(()=>[])).find(u=>d.has(String(u.deviceId??""))||d.has(String(u.peerId??""))||d.has(String(u.nodeId??""))||d.has(String(u.connectionId??"")));a=typeof p?.platformType=="string"&&p.platformType.trim().length>0?p.platformType:null;}}let c={...e,connection:e.connection??n,remoteNodeId:e.remoteNodeId??n?.remoteNodeId,receiverPlatformType:a,applicationCrypto:s,requireApplicationCrypto:i};return t.sendExplicitFileData(c)}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(this.usesNativeIpcBackend()&&t&&typeof t.startPresence=="function"){let n=this.getEffectiveRuntimeUserId();if(!n){await this.client.startPresenceLoop(e);return}let i=await this.getManagedNodeId({initializeIfMissing:true}).catch(()=>null),o=i||await this.getNodeId(),s=e?.ticket||await this.getEndpointTicket(),a=await this.localDeviceProfile({deviceName:e?.deviceName,platform:"native",userId:n}),c=H.describeTicketForLogs(s);console.info("[RuntimeClient][native-presence][start]",{userId:n,localNodeId:o,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:a.deviceId,deviceName:e?.deviceName||a.deviceName,ticketScope:c.scope,isCompoundTicket:c.isCompound});try{await this.runNativeStartLoop({label:"startPresenceLoop",exhaustedMessage:`[RuntimeClient] startPresenceLoop exhausted retries user_id=${n} local_node_id=${o}`,start:()=>t.startPresence(n,o,e?.deviceName||a.deviceName,s,e?.metadata)});}catch(d){if(!this.isUnsupportedRuntimeAdapterError(d,"startPresenceLoop"))throw d;await this.client.startPresenceLoop(e);return}console.info("[RuntimeClient][native-presence][started]",{userId:n,localNodeId:o,nodeSource:i?"native-managed":"client-getNodeId-fallback",deviceId:a.deviceId});return}await this.client.startPresenceLoop(e);}async updatePresence(e){await this.client.updatePresence(e?.isOnline,e?.ttlMs,e?.metadata,e?.ticket);}async refreshLivePresence(e){let t=this.backend;if(!t||typeof t.refreshLivePresence!="function"){await this.updatePresence(e);return}let n=await this.getNodeId(),i=e?.ticket||await this.getEndpointTicket();await t.refreshLivePresence(n,i,e?.metadata);}async setOffline(){await this.client.setOffline();}async cleanupStaleDevices(){await this.client.cleanupStaleDevices();}async startAutoConnect(e){await this.client.refreshRuntimeAuthToken("runtime-start");let t=this.backend;if(t&&typeof t.startAutoConnectOnce=="function"){this.usesNativeIpcBackend()||await this.initialize();let n=this.getEffectiveRuntimeUserId();if(!n)throw new Error("startAutoConnect requires an authenticated user");let i=e||await this.getLocalDeviceId();if(!i)throw new Error("startAutoConnect requires a local device id");try{await this.runNativeStartLoop({label:"startAutoConnect",exhaustedMessage:`[RuntimeClient] startAutoConnect exhausted retries user_id=${n} local_device_id=${i}`,start:()=>t.startAutoConnectOnce(n,i)});}catch(o){if(!this.isUnsupportedRuntimeAdapterError(o,"startAutoConnect"))throw o;await this.client.startAutoConnect(e);return}return}await this.client.startAutoConnect(e);}async isConnected(e){return this.connectionController.isConnected(e)}async disconnectNode(e){await this.connectionController.disconnectNode(e);}async encodeSparseFanoutMessage(e,t){if(!this.backend?.encodeSparseFanoutMessage)throw new Error("[OpenRTC] Sparse fanout is unavailable in this runtime.");return this.backend.encodeSparseFanoutMessage(e,t)}async acceptSparseFanoutMessage(e,t,n){if(!this.backend?.acceptSparseFanoutMessage)throw new Error("[OpenRTC] Sparse fanout is unavailable in this runtime.");return this.backend.acceptSparseFanoutMessage(e,t,n)}async recordSparseFanoutForwardQueueDrop(e,t){await this.backend?.recordSparseFanoutForwardQueueDrop?.(e,t);}async disconnectDevice(e){return this.connectionController.disconnectDevice(e)}onRoomArchitectureChange(e){return this.backend?.onRoomArchitectureChange?.(e)??(()=>{})}onRoomAuthorityAssignmentChange(e){return this.backend?.onRoomAuthorityAssignmentChange?.(e)??(()=>{})}async publishAuthorityAssignment(e){if(!this.backend?.publishAuthorityAssignment)throw new Error("[OpenRTC] Authority assignment publication is unavailable.");await this.backend.publishAuthorityAssignment(e);}async publishManagedRoomMessage(e){if(!this.backend?.publishManagedRoomMessage)throw new Error("[OpenRTC] Managed room fanout is unavailable in this runtime.");await this.backend.publishManagedRoomMessage(e);}onManagedRoomMessage(e){return this.backend?.onManagedRoomMessage?.(e)??(()=>{})}async excludeAutoConnect(e,t){await this.connectionController.excludeAutoConnect(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()}onStateChange(e){let t=true,n=new Map,i=c=>{if(!t)return;let d=this.connectionStateSnapshotKey(c);n.get(c.connectionId)!==d&&(n.set(c.connectionId,d),e(c));},o=()=>{t&&this.getConnectionStates().then(c=>{c.forEach(d=>i(d));}).catch(()=>{});},s=c=>()=>{t=false,c?.();},a=this.client.signaling.onStateChange(c=>i(c));return o(),typeof a=="function"?s(a):Promise.resolve(a).then(c=>s(typeof c=="function"?c:null))}getConnections(){return this.nativeConnectionProjection?.list()??this.client.getConnections()}readyConnections(e={}){return this.nativeConnectionProjection?.ready(e)??this.client.readyConnections(e)}onConnection(e){return this.nativeConnectionProjection?.onConnection(e)??this.client.onConnection(e)}onDisconnection(e){return this.nativeConnectionProjection?.onDisconnection(e)??this.client.onDisconnection(e)}onMessage(e){return this.nativeConnectionProjection?.onMessage(e)??this.client.onMessage(e)}onConnectionEvent(e){let t=this.onConnection(i=>{let{activeTransport:o}=i.getTransportStatus();e({type:"connected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:o});}),n=this.onDisconnection(i=>{let{activeTransport:o}=i.getTransportStatus();e({type:"disconnected",connectionId:i.id,localNodeId:i.localNodeId,remoteNodeId:i.remoteNodeId,transport:o});});return ()=>{t(),n();}}forceReconnect(){this.client.forceReconnect();}async connect(){await this.initialize(),await this.start();}disconnect(){this.stop();}async shutdown(){return this.terminalShutdown?this.terminalShutdown:(this.terminalShutdown=(async()=>{if(this.stopManagedReconciliation(),this.nativeConnectionProjection?.close(),this.hasManagedSession())await this.stopManagedSession();else {this.stop();let t=this.backend;typeof t?.releaseNativeCapability=="function"?await t.releaseNativeCapability():await this.backend?.stopAuthActivity?.(),await this.scopedConnectionActorRegistry?.shutdownAll(),this.scopedConnectionActorRegistry=null;}await this.backend?.shutdownPersistentIrohProtocols?.(),this.destroy();})(),this.terminalShutdown)}destroy(){this.stopManagedReconciliation(),this.stop();let e=this.client;e&&typeof e.destroy=="function"&&e.destroy();}dispose(){this.destroy();}onAuthChange(e){return this.onIdentityChange(e)}async setAuth(e){return this.setAuthContext(e)}async signIn(){return this.signInWithPluto()}async getDevices(){return this.listDevices()}onDevices(e,t){return t?.status?this.watchDeviceStatus(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){if(t?.direction==="send")return this.openPeerUni(e,t);if(this.isTransportOnlyStreamChannel(t?.channelId))try{return await this.openPeerBiRaw(e,t)}catch(n){let i=n instanceof Error?n.message:String(n);if(!/application crypto/i.test(i))throw n;return this.openPeerBi(e,t)}return this.openPeerBi(e,t)}async openChannelStream(e,t,n){return this.openStream(t,{...n,channelId:e})}onStream(e){return this.onIncomingStream(e)}onRoomChange(e,t){return this.watchRoom(e,t)}createSession(e){return new wn(this,e)}};H.NATIVE_START_RETRY_WINDOW_MS=o.managedSession.nativeStartRetryWindowMs,H.NATIVE_START_RETRY_MIN_DELAY_MS=o.managedSession.nativeStartRetryMinDelayMs,H.NATIVE_START_RETRY_MAX_DELAY_MS=o.managedSession.nativeStartRetryMaxDelayMs,H.DEVICE_STATUS_REFRESH_DEBOUNCE_MS=o.managedSession.deviceStatusRefreshDebounceMs,H.MANAGED_USER_DEVICE_SCOPE="user-device",H.MANAGED_FRIEND_SCOPE="friend";var Lr=H;var K=class K{constructor(e){this.subscriptionNonce=0;this.activeNativeProjectionRequestId=null;this.lastSyncedAuthToken=null;this.cachedLocalDeviceId=null;this.cachedLocalDeviceName=null;this.tauriCoreAvailability=null;this.tauriCoreAvailabilityValue=null;this.tauriCoreAvailabilityCheckedAtMs=0;this.authSyncInFlight=null;this.nativeTrustTokenUnsubscribe=null;this.nativeTrustRelayQueue=Promise.resolve();this.nativeTrustRelayError=null;this.nativeRuntimeCapabilitiesSyncInFlight=null;this.gatewayDesiredPeersCleanup=null;this.gatewayDesiredPeerRelayKey=null;this.gatewayDesiredPeerRelayGeneration=0;this.gatewayDesiredPeerRevision=0;this.gatewayDesiredPeerSubmission=Promise.resolve();this.gatewayDesiredPeerLifecycle=Promise.resolve();this.gatewayExcludedPeers=new Set;this.lastNativeAuthSyncAtMs=0;this.authContext=null;this.authListeners=[];this.injectedBrowserAuthSessionActive=false;this.lastObservedFirebaseUserId=null;this.spaceNamespaceIdPromise=null;this.cachedSpaceNamespaceId=null;this.nativeCapabilityRegistration=null;this.nativeCapabilityReleased=false;this.nativeProjectionSource=null;this.nativeIdentityId=null;this.runtimeCapabilities=u(null,false);if(e.allowWasmFallback===true)throw new Error("[OpenRTC] NativeIpcBridge is IPC-only; WASM fallback is supported only by browser runtimes.");this.appTag=c$4(e),this.options={...e,appTag:this.appTag,authMode:d$3(e),projectId:e$2(e),coordinationPlatformType:e.coordinationPlatformType??"desktop"},this.initialGatewayExcludedPeers=[...new Set((e.initialAutoConnectExcludedDeviceIds??[]).map(i=>i.trim().toLowerCase()).filter(Boolean))].sort();for(let i of this.initialGatewayExcludedPeers)this.gatewayExcludedPeers.add(i);let n=!this.isTicketOnlyMode()&&!this.usesProviderNeutralGrant()?a$3():null;this.app=n?.getApp()??null,this.auth=n?.getAuth()??null,this.coordinationHost=new b({appTag:this.appTag,projectId:this.options.projectId,discoveryMode:this.options.discoveryMode,signalingMode:this.options.signalingMode,gateway:this.options.coordinationGateway,avenueOverride:this.options.coordinationAvenueOverride,initialExcludedPeers:this.initialGatewayExcludedPeers,resolveSpaceNamespaceId:()=>this.ensureSpaceNamespaceIdPromise(),getCurrentUserId:()=>this.getCurrentUserIdForCoordination(),getAuthToken:async(i=false)=>this.currentUser?.getToken?.(i)??null,getAppCheckToken:async(i=false)=>{let o=this.authContext?.appCheckTokenProvider??this.options.attestationTokenProvider;return o?o(i):a$3().getAppCheckToken(i)},getLocalDeviceId:()=>this.cachedLocalDeviceId??this.options.localDeviceId?.trim()??"",getDefaultDeviceName:()=>this.cachedLocalDeviceName??this.defaultDeviceNameFallback(),getPlatformType:()=>this.options.coordinationPlatformType??"desktop",normalizeDevice:(i,o)=>z(i,o)}),n&&n.onAuthStateChanged(i=>{if(this.authContext)return;let o=i?.uid??null,s=this.lastObservedFirebaseUserId;this.lastObservedFirebaseUserId=o,s&&s!==o&&this.stopAuthActivity({userId:s}),this.coordinationHost.handleScopeChange(),this.authListeners.forEach(a=>a(this.toRuntimeIdentity(i)));}),this.turnCredentialsProvider=e.turnCredentialsProvider,this.nativeCapability=c$2(e.coordinationAvenueOverride),this.ipcBridge=c$1(e.ipcBridge??d$4(),"NativeIpcBridge"),this.coordinationHost.setManagedRoomRuntime(this.nativeManagedRoomRuntime(),this.nativeManagedRoomStateProvider()),this.runtimeCapabilities=u(null,false),this.syncNativeRuntimeCapabilities("constructor");}attachNativeProjectionSource(e){if(this.nativeProjectionSource&&this.nativeProjectionSource!==e)throw new Error("[OpenRTC] Native projection source is already attached.");this.nativeProjectionSource=e;}requireNativeProjectionSource(){if(!this.nativeProjectionSource)throw new Error("[OpenRTC] Native capability projection source is unavailable.");return this.nativeProjectionSource}get currentUser(){if(this.authContext?.userId){let e=this.authContext.token??null,t=this.authContext.tokenProvider;return {id:this.authContext.userId,getToken:async(n=false)=>{if(e&&(!n||!t))return e;if(t)try{let o=await t(n);if(o)return o}catch{}let i=this.isTicketOnlyMode()?null:this.auth?.currentUser;if(i?.uid!==this.authContext?.userId)return null;try{return await i.getIdToken(n)}catch{return null}}}}return this.isTicketOnlyMode()?null:this.toRuntimeIdentity(this.auth?.currentUser??null)}get tag(){return this.appTag}isTicketOnlyMode(){return this.options.signalingMode==="ticket-only"}usesProviderNeutralGrant(){return typeof this.options.coordinationGateway?.grantProvider=="function"}isSpaceMode(){return x(this.options)}getCurrentUserIdForCoordination(){return this.authContext?.userId?this.authContext.userId:this.isTicketOnlyMode()?null:this.auth?.currentUser?.uid??null}toRuntimeIdentity(e){return e?{id:e.uid,email:e.email,displayName:e.displayName,isAnonymous:e.isAnonymous,getToken:async(t=false)=>{try{return await e.getIdToken(t)}catch{return null}}}:null}async ensureBrowserPlatformAuth(e,t){if(this.auth?.currentUser?.uid===e){this.injectedBrowserAuthSessionActive=true;return}await a$3().signInWithCustomTokenValue(t),this.injectedBrowserAuthSessionActive=true;}async applyCoordinationAuthContext(e){let t=this.injectedBrowserAuthSessionActive,n=this.authContext?.userId??null,i=e?.userId??null;if(this.authContext=e,!this.isTicketOnlyMode()&&!this.usesProviderNeutralGrant()&&e?.customToken?.trim()&&!(g$1()&&this.options.authMode==="external"&&typeof e.tokenProvider=="function"))try{await this.ensureBrowserPlatformAuth(e.userId,e.customToken.trim());}catch(o){console.warn("[NativeIpcBridge] host platform auth projection failed:",o);}else if(!this.isTicketOnlyMode()&&!this.usesProviderNeutralGrant()&&!e&&t)try{await this.auth?.signOut();}finally{this.injectedBrowserAuthSessionActive=false;}!this.isTicketOnlyMode()&&n!==i&&await this.coordinationHost.handleScopeChange(),this.authListeners.forEach(o=>o(this.currentUser));}ensureSpaceNamespaceIdPromise(){if(this.cachedSpaceNamespaceId)return Promise.resolve(this.cachedSpaceNamespaceId);if(!this.spaceNamespaceIdPromise){let e=this.options.apiKey?.trim()??"",t=this.options.spaceKey?.trim()??"";if(!e||!t)return Promise.resolve(null);this.spaceNamespaceIdPromise=b$1(e,t).then(n=>(this.cachedSpaceNamespaceId=n,n)).catch(()=>null);}return this.spaceNamespaceIdPromise}ensureNativeCapabilityRegistered(){return this.nativeCapabilityReleased?Promise.reject(new Error(`[OpenRTC] Native capability '${this.nativeCapability.key}' is already released.`)):this.nativeCapabilityRegistration??(this.nativeCapabilityRegistration=this.invokeIpc("register_rtc_capability",{capabilityKey:this.nativeCapability.key,avenueKind:this.nativeCapability.kind,avenueId:this.nativeCapability.id,sparseFanout:this.options.coordinationRoomGossipFanout===true,architecture:this.nativeCapability.kind==="room"?this.options.coordinationRoomArchitecture??(this.options.coordinationRoomGossipFanout===true?"sparse":void 0):void 0},{timeoutMs:null}).catch(e=>{throw this.nativeCapabilityRegistration=null,e}))}usesRustNativeDevices(){return this.nativeCapability.kind==="devices"&&this.options.nativeIdentityProvider!==void 0}async ensureRustNativeDevicesIdentity(e){let t=this.options.nativeIdentityProvider;if(!t)throw new Error("[OpenRTC] Native device identity provider is unavailable.");let n=(await t.getSessionKey())?.trim()??"";if(!n)throw new Error("[OpenRTC] Native device startup requires an active auth principal.");let i="",o=await this.createIpcChannel(d=>{let l=d.requestId??d.request_id??"",p=d.deviceId??d.device_id??"",u=d.forceRefresh??d.force_refresh??false,h=d.recoveryReason??d.recovery_reason;!i||!l||!p||(async()=>{let f=null,m=null;try{f=(await t.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:u,deviceId:p,recoveryReason:h}))?.trim()||null,f||(m="Native assertion provider returned no assertion.");}catch(v){m=v instanceof Error?v.message:String(v);}await this.invokeIpc("openrtc_complete_native_assertion",{identityId:i,requestId:l,token:f,providerId:t.providerId??null,error:m},{timeoutMs:null}).catch(()=>{});})();});i=await this.invokeIpc("openrtc_configure_native_identity",{sessionKey:n,requests:o},{timeoutMs:null}),this.nativeIdentityId=i;let s=await this.invokeIpc("openrtc_start_native_devices",{identityId:i,deviceName:e?.trim()||null},{timeoutMs:null}),a=s.principalId??s.principal_id??"",c=s.deviceId??s.device_id??"";if(!a||!c)throw new Error("[OpenRTC] Native device enrollment returned an invalid identity.");return {identityId:i,principalId:a,deviceId:c}}async listRustNativeDevices(e){let t=this.nativeIdentityId;if(!t)return [];let n=await this.invokeIpc("openrtc_list_native_devices",{identityId:t});return this.filterNativeRosterByTag(Array.isArray(n)?n:[],"native identity roster").map(i=>this.normalizeDevice(w$1(i))).filter(i=>!e||i.nodeId!==e&&i.deviceId!==e)}nativeManagedRoomRuntime(){let e=(n,i)=>{if(n<0n||n>BigInt(Number.MAX_SAFE_INTEGER))throw new RangeError(`[OpenRTC] ${i} exceeds the native IPC integer range.`);return Number(n)},t=async()=>(await this.ensureNativeCapabilityRegistered(),this.nativeCapability.key);return {__initManagedRoomGroup:async(n,i)=>this.invokeIpc("openrtc_init_managed_room_group",{capabilityKey:await t(),deviceId:i},{timeoutMs:null}),__handleManagedRoomPreparePage:async(n,i)=>this.invokeIpc("openrtc_handle_managed_room_prepare_page",{capabilityKey:await t(),deviceId:await this.resolveLocalDeviceId(),page:i},{timeoutMs:null}),__handleManagedRoomArtifactChunk:async(n,i)=>this.invokeIpc("openrtc_handle_managed_room_artifact_chunk",{capabilityKey:await t(),deviceId:await this.resolveLocalDeviceId(),chunk:i},{timeoutMs:null}),__sealManagedRoomPayload:async(n,i,o,s,a,c,d,l)=>this.invokeIpc("openrtc_seal_managed_room_payload",{capabilityKey:await t(),deviceId:await this.resolveLocalDeviceId(),architectureEpoch:e(i,"architecture epoch"),encryptionEpoch:e(o,"encryption epoch"),messageId:s,channel:a,priority:c,zoneId:d,payload:Array.from(l)},{timeoutMs:null}),__openManagedRoomPayload:async(n,i,o,s,a,c,d,l)=>this.invokeIpc("openrtc_open_managed_room_payload",{capabilityKey:await t(),deviceId:await this.resolveLocalDeviceId(),architectureEpoch:e(i,"architecture epoch"),encryptionEpoch:e(o,"encryption epoch"),messageId:s,channel:a,priority:c,zoneId:d,ciphertext:Array.from(l)},{timeoutMs:null}),__forgetManagedRoomGroup:async()=>{await this.invokeIpc("openrtc_forget_managed_room_group",{capabilityKey:this.nativeCapability.key},{timeoutMs:null});}}}nativeManagedRoomStateProvider(){return async()=>({wrappingKey:new Uint8Array(32),persist:async()=>{},close:()=>{}})}async releaseNativeCapability(){this.nativeCapabilityReleased||(this.nativeCapabilityReleased=true,await this.clearGatewayDesiredPeerRelay(),this.coordinationHost.stopAuthActivity(),await this.invokeIpc("unregister_rtc_capability",{capabilityKey:this.nativeCapability.key},{timeoutMs:null}).catch(e=>{console.warn("[OpenRTC] Failed to unregister native capability projection:",{capabilityKey:this.nativeCapability.key,error:e});}));}capabilities(){let e=s(this.runtimeCapabilities);return e.fallback.wasm=false,e}usesCoordinationGateway(){return this.coordinationHost.usesGateway()}setCoordinationHostAvailability(e){this.coordinationHost.setHostAvailability(e);}assertManagedCoordinationGateway(){if(!this.usesCoordinationGateway())throw new Error("[OpenRTC] Native managed coordination requires coordinationGateway; the legacy native Firebase data plane has been removed.")}async joinCoordinationRoom(e,t,n){await this.syncCoordinationDeviceIdentity();let i=this.coordinationHost.getSignaling();if(!i.joinCoordinationRoom)throw new Error("The active coordination provider does not support rooms.");await i.joinCoordinationRoom(e,t,n);}leaveCoordinationRoom(e){return this.coordinationHost.getSignaling().leaveCoordinationRoom?.(e)??Promise.resolve()}getCoordinationRoomMembers(e){let t=this.coordinationHost.getSignaling();if(!t.getCoordinationRoomMembers)throw new Error("The active coordination provider does not support rooms.");return t.getCoordinationRoomMembers(e)}watchCoordinationRoomMembers(e,t){let n=this.coordinationHost.getSignaling();if(!n.watchCoordinationRoomMembers)throw new Error("The active coordination provider does not support rooms.");return n.watchCoordinationRoomMembers(e,t)}async syncCoordinationDeviceIdentity(){if(!this.usesCoordinationGateway())return;let e=await this.getLocalDeviceInfo().catch(()=>null),t=e?.deviceId||await this.resolveLocalDeviceId();this.options.localDeviceId=t,this.options.coordinationPlatformType=this.normalizeNativeCoordinationPlatform(e?.platformType);}setWasmClient(e){let t="[NativeIpcBridge][NATIVE-GUARD] Native hosts cannot attach WasmClient; use Rust IPC or select the browser runtime.";throw console.error(t,{capabilities:this.capabilities()}),new Error(t)}onAuthChange(e){return this.authListeners.push(e),e(this.currentUser),()=>{this.authListeners=this.authListeners.filter(t=>t!==e);}}checkForSSOToken(){return this.isTicketOnlyMode()||this.usesProviderNeutralGrant()?Promise.resolve():a$3().checkForSSOToken()}async waitForAuth(){this.isTicketOnlyMode()||this.usesProviderNeutralGrant()||this.isSpaceMode()||this.authContext?.userId||this.auth?.currentUser||await a$3().waitForAuth();}async signInAnonymously(){if(!this.isTicketOnlyMode()){if(this.options.authMode!=="anonymous")throw new Error(`[openrtc] Anonymous sign-in is disabled when authMode=${this.options.authMode}.`);await a$3().signInAnonymously();}}async getTurnCredentials(){return this.isTicketOnlyMode()||!this.auth?.currentUser?null:typeof this.turnCredentialsProvider=="function"?await this.turnCredentialsProvider()??null:null}cleanupStaleDevices(){return this.coordinationHost.getSignaling().cleanupStaleDevices()}sendMessage(e,t,n,i){return this.coordinationHost.getSignaling().sendMessage(e,t,n,i)}pollMessages(e){return this.coordinationHost.getSignaling().pollMessages(e)}watchFriendDevices(e,t){return this.assertManagedCoordinationGateway(),this.coordinationHost.getSignaling().watchFriendDevices(e,t)}async updateFriendTicket(e){this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity(),await this.coordinationHost.getSignaling().updateFriendTicket(e);}createSession(e){let t=this.getCurrentUserIdForCoordination();return this.coordinationHost.getSignaling().createSession({...e,appTag:e.appTag??this.appTag,initiator:e.initiator??t??void 0,target:e.target??t??void 0})}updateSession(e,t){return this.coordinationHost.getSignaling().updateSession(e,t)}async openPeerBi(e,t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("openPeerBi");return this.openPeerBiViaIpc("open_peer_bi_stream",{peerId:e,timeoutMs:t??null})}async openPeerBiRaw(e,t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("openPeerBiRaw");return this.openPeerBiViaIpc("open_peer_bi_transport_only_stream",{peerId:e,timeoutMs:t??null})}async incoming_projected_streams(){return this.projectedIncomingStreamsViaChannel()}async releaseNativeProjectionSubscription(){let e=this.activeNativeProjectionRequestId;e&&(this.activeNativeProjectionRequestId=null,await this.canUseTauriIpc()&&await this.invokeIpc("stop_rtc_subscription",{requestId:e},{timeoutMs:null}).catch(()=>{}));}async projectedIncomingStreamsViaChannel(){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("incoming_projected_streams");await this.ensureNativeCapabilityRegistered();let e=this.activeNativeProjectionRequestId;e&&(this.activeNativeProjectionRequestId=null,await this.invokeIpc("stop_rtc_subscription",{requestId:e},{timeoutMs:null}).catch(()=>{}));let t=`native-projected-${Date.now()}-${++this.subscriptionNonce}`,n=false,i=async()=>{n||(n=true,this.activeNativeProjectionRequestId===t&&(this.activeNativeProjectionRequestId=null),await this.invokeIpc("stop_rtc_subscription",{requestId:t},{timeoutMs:null}).catch(()=>{}));};return new ReadableStream({start:async o=>{try{let s=await this.createIpcChannel(a=>{n||this.enqueueNativeProjection(o,a,t);});await this.invokeIpc("start_native_projection",{requestId:t,channel:s},{timeoutMs:null}),n||(this.activeNativeProjectionRequestId=t);}catch(s){o.error(s),await i();}},cancel:i})}enqueueNativeProjection(e,t,n){if((typeof t?.requestId=="string"?t.requestId:typeof t?.request_id=="string"?t.request_id:"")!==n)return;let o=t.capabilityKeys??t.capability_keys,s=Array.isArray(o)?[...new Set(o.filter(c=>typeof c=="string").map(c=>c.trim()).filter(Boolean))]:[];if(s.length===0)return;if(t.kind==="stream"){let c=this.projectIncomingPeerBi(t.payload,n);c&&e.enqueue({kind:"stream",capabilityKeys:s,payload:c});return}if(t.kind==="connection-state"){let c=G(t.payload);c&&e.enqueue({kind:"connection-state",capabilityKeys:s,payload:c});return}if(t.kind==="devices"&&t.payload&&typeof t.payload=="object"){let c=t.payload;if(typeof c.identityId!="string"||c.identityId!==this.nativeIdentityId||!Array.isArray(c.devices))return;let d=this.filterNativeRosterByTag(c.devices,"native device projection").map(l=>this.normalizeDevice(w$1(l)));e.enqueue({kind:"devices",capabilityKeys:s,payload:{identityId:c.identityId,devices:d}});return}if(t.kind!=="peer-data"||!t.payload||typeof t.payload!="object")return;let a=t.payload;typeof a.connectionId!="string"||!Array.isArray(a.payload)||!Number.isSafeInteger(a.transportStableId)||!Number.isSafeInteger(a.transportGeneration)||!Number.isSafeInteger(a.routeGeneration)||e.enqueue({kind:"peer-data",capabilityKeys:s,payload:a});}projectIncomingPeerBi(e$1,t){let n=typeof e$1?.requestId=="string"?e$1.requestId:typeof e$1?.request_id=="string"?e$1.request_id:"";if(n!==t)return e("[NativeIpcBridge][incoming-application-stream] ignored request id",{expectedRequestId:t,eventRequestId:n}),null;let i=typeof e$1?.streamId=="string"?e$1.streamId.trim():typeof e$1?.stream_id=="string"?e$1.stream_id.trim():"",o=typeof e$1?.connectionId=="string"?e$1.connectionId.trim():typeof e$1?.connection_id=="string"?e$1.connection_id.trim():"",s=typeof e$1?.remoteNodeId=="string"?e$1.remoteNodeId.trim():typeof e$1?.remote_node_id=="string"?e$1.remote_node_id.trim():"",a=Number.isSafeInteger(e$1?.transportStableId)?Number(e$1.transportStableId):Number.isSafeInteger(e$1?.transport_stable_id)?Number(e$1.transport_stable_id):0,c=typeof e$1?.capabilityKey=="string"?e$1.capabilityKey.trim():typeof e$1?.capability_key=="string"?e$1.capability_key.trim():"";if(!i||!s||a<=0)return e("[NativeIpcBridge][incoming-application-stream] ignored invalid projection",{requestId:t,streamId:i,remoteNodeId:s,transportStableId:a}),null;let d=this.peerBiStreamFromId(i),l=e$1?.channel,p=typeof l?.channelId=="string"?l.channelId.trim():typeof l?.channel_id=="string"?l.channel_id.trim():"",u={send:d.writable,recv:d.readable,endpoint_id:s,transport_stable_id:a};return Object.defineProperty(u,"applicationCryptoWrapped",{value:true,enumerable:true}),{type:"bi",stream:u,...o?{connectionId:o}:{},endpointId:s,transportStableId:a,...c?{capabilityKey:c}:{},protocolHint:"unknown",channel:p?{channelId:p,metadata:l?.metadata??null}:null,applicationAuthorized:e$1?.applicationAuthorized===true||e$1?.application_authorized===true}}async isCurrentTransport(e,t){return !await this.canUseTauriIpc()||!e.trim()||t<=0n||t>BigInt(Number.MAX_SAFE_INTEGER)?false:this.invokeIpc("is_current_transport_stable_id",{endpointId:e.trim(),transportStableId:Number(t)})}async openPeerUni(e,t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("openPeerUni");let n=await this.invokeIpc("open_peer_uni_stream",{peerId:e,timeoutMs:t??null}),i=typeof n?.streamId=="string"?n.streamId.trim():typeof n?.stream_id=="string"?n.stream_id.trim():"";if(!i)throw new Error("open_peer_uni_stream returned no streamId");let o=this,s=async()=>{await o.invokeIpc("close_peer_uni_stream",{streamId:i},{timeoutMs:null}).catch(()=>{});};return {writable:new WritableStream({write:async a=>{await o.invokeRawIpc("write_peer_uni_stream",a,{"x-openrtc-stream-id":i});},close:s,abort:s})}}async isConnected(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("isConnected");return this.invokeIpc("is_peer_connected",{nodeId:e})}async beginOpenRtcMediaPublication(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("beginOpenRtcMediaPublication");let t=await this.invokeIpc("begin_openrtc_media_publication",{publicationId:e.publicationId||null,kind:e.kind,codec:e.codec,clockRate:e.clockRate,codedWidth:e.codedWidth??null,codedHeight:e.codedHeight??null,channels:e.channels??null});return {...t,control:Uint8Array.from(t.control)}}async encodeOpenRtcMediaSample(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("encodeOpenRtcMediaSample");let t=await this.invokeRawIpc("encode_openrtc_media_sample",e.payload,{"x-openrtc-publication-id":e.publicationId,"x-openrtc-timestamp-us":String(e.timestampUs),"x-openrtc-duration-us":String(e.durationUs),"x-openrtc-keyframe":String(e.keyframe),"x-openrtc-discardable":String(e.discardable)});return this.binaryIpcBytes(t,"encode_openrtc_media_sample")}async pauseOpenRtcMediaPublication(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("pauseOpenRtcMediaPublication");await this.invokeIpc("pause_openrtc_media_publication",{publicationId:e});}async retireOpenRtcMediaPublication(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("retireOpenRtcMediaPublication");await this.invokeIpc("retire_openrtc_media_publication",{publicationId:e});}async retireOpenRtcMediaReceiver(e,t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("retireOpenRtcMediaReceiver");await this.invokeIpc("retire_openrtc_media_receiver",{publicationId:e,mediaGeneration:t});}async decodeOpenRtcMediaChunk(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("decodeOpenRtcMediaChunk");let t=await this.invokeRawIpc("decode_openrtc_media_chunk",e,{}),n=this.binaryIpcBytes(t,"decode_openrtc_media_chunk");if(n.byteLength<4)throw new Error("[OpenRTC] decode_openrtc_media_chunk returned a truncated response.");let o=4+new DataView(n.buffer,n.byteOffset,4).getUint32(0,false);if(o>n.byteLength)throw new Error("[OpenRTC] decode_openrtc_media_chunk returned invalid metadata.");let s;try{s=JSON.parse(new TextDecoder().decode(n.subarray(4,o)));}catch(a){throw new Error(`[OpenRTC] decode_openrtc_media_chunk returned malformed metadata: ${String(a)}`)}return {...s,payload:n.slice(o)}}async decodeOpenRtcMediaControl(e){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("decodeOpenRtcMediaControl");return this.invokeRawIpc("decode_openrtc_media_control",e,{})}getAuthContext(){return this.authContext}resolveNativeAuthScopedUserId(e){return this.currentUser?.id??this.getAuthContext()?.userId??e??null}resolveConfiguredSpaceKey(){let e=this.options.spaceKey??this.options.space;return typeof e=="string"?e.trim():""}usesAnonymousSpaceMode(){return this.options.authMode==="anonymous"&&this.resolveConfiguredSpaceKey().length>0}requiresNativeAuthToken(){return !this.usesProviderNeutralGrant()&&(!this.usesAnonymousSpaceMode()||typeof this.options.spaceTokenProvider=="function")}async nativeAuthTokenMatchesExpectedScope(e){if(!this.usesAnonymousSpaceMode())return true;let t=typeof this.options.apiKey=="string"?this.options.apiKey.trim():"",n=this.resolveConfiguredSpaceKey();if(!t||!n)return true;let i=await b$1(t,n).catch(()=>null);return i?lt(we(e),i):true}resolveNativeSignalingUserId(e){return this.usesAnonymousSpaceMode()?(typeof e=="string"?e.trim():"")||this.resolveConfiguredSpaceKey()||null:this.resolveNativeAuthScopedUserId(e)}getCurrentUserId(){return this.resolveNativeSignalingUserId(this.getCurrentUserIdForCoordination())}nativeAuthWaitMs(){return this.requiresNativeAuthToken()?K.AUTH_REQUIRED_WAIT_MS:0}normalizeDevice(e,t){return z(e,t)}matchesTag(e){return y(e,this.appTag,this.isSpaceMode())}nativeRosterTagDisposition(e){let t=w$1(e);if(this.matchesTag(t))return {keep:true,classification:"match"};let n=typeof t.appTag=="string"&&t.appTag.trim().length>0?t.appTag.trim():typeof t.tag=="string"&&t.tag.trim().length>0?t.tag.trim():void 0;return n===void 0?{keep:true,classification:"untagged"}:{keep:false,classification:"foreign",foreignTag:n}}filterNativeRosterByTag(e$1,t){let n=new Set,i=e$1.filter(o=>{let s=this.nativeRosterTagDisposition(o);return !s.keep&&s.foreignTag&&n.add(s.foreignTag),s.keep});return e$1.length>0&&i.length===0&&n.size>0?console.warn(`[NativeIpcBridge] ${t}: dropped ALL ${e$1.length} native device(s) as foreign-app \u2014 this is the app-tag drift signature (empty native device list). The native Rust OpenRTC app tag does not match the SDK app tag; check that the desktop binary and the web bundle use the same VITE_PLUTO_OPENRTC_API_KEY / VITE_PLUTO_OPENRTC_APP_TAG for this environment lane.`,{sdkAppTag:this.appTag,foreignTags:Array.from(n),droppedCount:e$1.length}):n.size>0&&e(`[NativeIpcBridge] ${t}: filtered ${e$1.length-i.length} foreign-app device(s) from the native roster`,{sdkAppTag:this.appTag,foreignTags:Array.from(n)}),i}isTauriEnv(){return g$1()}async clearNativeAuthRelay(e$1){if(await this.canUseTauriIpc())try{typeof this.options.coordinationGateway?.grantProvider=="function"?await this.invokeIpc("openrtc_set_identity_credential",{identityCredential:null}):await this.invokeIpc("desktop_set_pluto_auth_token",{authToken:null,refreshToken:null}),this.lastSyncedAuthToken=null,this.lastNativeAuthSyncAtMs=0,e(`[NativeIpcBridge] cleared native auth relay (${e$1})`);}catch(t){console.warn(`[NativeIpcBridge] failed clearing native auth relay (${e$1}):`,t);}}async clearNativeTrustRelay(e$1){if(this.nativeTrustTokenUnsubscribe?.(),this.nativeTrustTokenUnsubscribe=null,this.nativeTrustRelayError=null,this.coordinationHost.invalidateNativeTrustToken(),typeof this.options.coordinationGateway?.grantProvider!="function"&&await this.canUseTauriIpc())try{await this.invokeIpc("openrtc_set_native_trust_token",{trustToken:null,expiresAtMs:null}),e(`[NativeIpcBridge] cleared native trust relay (${e$1})`);}catch(t){b$2(t)||console.warn(`[NativeIpcBridge] failed clearing native trust relay (${e$1}):`,t);}}relayNativeTrustToken(e$1,t){let n=async()=>{await this.canUseTauriIpc()&&(await this.invokeIpc("openrtc_set_native_trust_token",{trustToken:e$1?.token??null,expiresAtMs:e$1?.expiresAtMs??null}),e(`[NativeIpcBridge] native trust token ${e$1?"relayed":"cleared"} (${t})`));},i=this.nativeTrustRelayQueue.then(n,n);return this.nativeTrustRelayQueue=i.catch(()=>{}),i}async ensureNativeTrustRelay(e=false){if(!this.usesCoordinationGateway()||typeof this.options.coordinationGateway?.grantProvider=="function")return true;if(typeof this.options.coordinationGateway?.nativeTrustTokenProvider!="function")return false;if(!await this.canUseTauriIpc())return true;try{let t=await this.coordinationHost.getNativeTrustToken(e);return await this.relayNativeTrustToken(t,"auth-ready"),this.nativeTrustRelayError=null,this.nativeTrustTokenUnsubscribe||(this.nativeTrustTokenUnsubscribe=this.coordinationHost.subscribeNativeTrustToken(n=>{this.relayNativeTrustToken(n,"provider-refresh").catch(i=>{console.warn("[NativeIpcBridge] native trust token refresh relay failed:",i);});},{emitCurrent:!1})),!0}catch(t){return this.nativeTrustRelayError=(t instanceof Error?t.message:String(t)).trim().slice(0,300)||"unknown provider failure",console.warn("[NativeIpcBridge] native trust token unavailable:",t),false}}async relayNativeAuthToken(e$1,t,n,i){if(!await this.canUseTauriIpc())return true;if(!await this.nativeAuthTokenMatchesExpectedScope(e$1))return e(`[NativeIpcBridge] auth sync deferred (${n}): token claims do not match configured space`),false;if(e$1===this.lastSyncedAuthToken)return true;try{typeof this.options.coordinationGateway?.grantProvider=="function"?await this.invokeIpc("openrtc_set_identity_credential",{identityCredential:e$1}):await this.invokeIpc("desktop_set_pluto_auth_token",{authToken:e$1,refreshToken:t??null});}catch(o){return b$2(o)?console.warn(`[NativeIpcBridge] desktop auth relay unavailable (${n}); install/register openrtc-tauri-plugin and include its default permission set.`,o):console.warn(`[NativeIpcBridge] desktop auth relay failed (${n}):`,o),false}return this.lastSyncedAuthToken=e$1,this.lastNativeAuthSyncAtMs=Date.now(),e(`[NativeIpcBridge] auth token relayed to native runtime (${n}) user_id=${i??this.currentUser?.id??"unknown"}`),true}async relayExplicitNativeAuthContext(e){let t=this.authSyncInFlight,n=(async()=>(await t?.catch(()=>{}),this.relayNativeAuthToken(e.token,e.refreshToken,"setAuthContext",e.userId)))();this.authSyncInFlight=n;try{return await n}finally{this.authSyncInFlight===n&&(this.authSyncInFlight=null);}}applyNativeRuntimeStatus(e){this.runtimeCapabilities=u(e,false);}syncNativeRuntimeCapabilities(e$1){return this.ipcBridge?this.nativeRuntimeCapabilitiesSyncInFlight?this.nativeRuntimeCapabilitiesSyncInFlight:(this.nativeRuntimeCapabilitiesSyncInFlight=(async()=>{try{let t=await this.invokeIpc("rtc_native_status",void 0,{timeoutMs:K.NATIVE_STATUS_IPC_TIMEOUT_MS});this.applyNativeRuntimeStatus(t),e(`[NativeIpcBridge] refreshed native runtime capabilities (${e$1})`);}catch(t){d$2("[NativeIpcBridge] native runtime capability refresh skipped",t);}})().finally(()=>{this.nativeRuntimeCapabilitiesSyncInFlight=null;}),this.nativeRuntimeCapabilitiesSyncInFlight):Promise.resolve()}async canUseTauriIpc(){if(this.ipcBridge){let e=typeof this.ipcBridge.isAvailable=="function"?!!await this.ipcBridge.isAvailable():true;return e&&this.syncNativeRuntimeCapabilities("ipc-available"),e}return typeof window>"u"?false:this.tauriCoreAvailabilityValue===true?true:this.tauriCoreAvailabilityValue===false&&Date.now()-this.tauriCoreAvailabilityCheckedAtMs<K.TAURI_IPC_NEGATIVE_CACHE_MS?false:(this.tauriCoreAvailability||(this.tauriCoreAvailability=(async()=>{try{if(this.isTauriEnv())return this.tauriCoreAvailabilityValue=!0,this.tauriCoreAvailabilityCheckedAtMs=Date.now(),this.syncNativeRuntimeCapabilities("tauri-env"),!0;try{let e$1=await this.invokeIpc("rtc_native_status");return this.applyNativeRuntimeStatus(e$1),e("[NativeIpcBridge] Resolved Tauri IPC via rtc_native_status probe"),this.tauriCoreAvailabilityValue=!0,this.tauriCoreAvailabilityCheckedAtMs=Date.now(),!0}catch(e$1){let t=String(e$1?.message??e$1??"");return t.includes("__TAURI_INTERNALS__")||t.includes("Cannot read properties of undefined")||t.includes("window is not defined")?(this.tauriCoreAvailabilityValue=!1,this.tauriCoreAvailabilityCheckedAtMs=Date.now(),!1):(e("[NativeIpcBridge] Tauri IPC probe reached native layer (command-level error acceptable)"),this.tauriCoreAvailabilityValue=!0,this.tauriCoreAvailabilityCheckedAtMs=Date.now(),!0)}}catch{return this.tauriCoreAvailabilityValue=false,this.tauriCoreAvailabilityCheckedAtMs=Date.now(),false}})().finally(()=>{this.tauriCoreAvailability=null;})),this.tauriCoreAvailability)}async invokeIpc(e,t,n){let i=this.ipcBridge.invoke(e,t),o=n&&Object.prototype.hasOwnProperty.call(n,"timeoutMs")?n.timeoutMs:K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS;return o==null||o<=0?i:b$3(i,o,()=>new Error(`${e} timeout after ${o}ms`))}async invokeRawIpc(e,t,n){if(typeof this.ipcBridge?.invokeRaw!="function")throw new Error("[OpenRTC] Native stream binary IPC is unavailable.");return this.ipcBridge.invokeRaw(e,t,n)}binaryIpcBytes(e,t){if(e instanceof ArrayBuffer||Object.prototype.toString.call(e)==="[object ArrayBuffer]")return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);if(Array.isArray(e))return Uint8Array.from(e);throw new Error(`[OpenRTC] ${t} returned no binary IPC response.`)}async createIpcChannel(e){if(typeof this.ipcBridge?.createChannel!="function")throw new Error("[OpenRTC] Native ordered stream IPC is unavailable.");return this.ipcBridge.createChannel(e)}async listenIpc(e,t){return this.ipcBridge.listen(e,n=>{t({payload:n});})}async openPeerBiViaIpc(e,t,n){let i=await this.invokePeerBiOpen(e,t,n),o=typeof i?.streamId=="string"?i.streamId.trim():typeof i?.stream_id=="string"?i.stream_id.trim():"";if(!o)throw new Error(`${e} returned no streamId`);return this.peerBiStreamFromId(o)}peerBiStreamFromId(e){let t=this,n=null,i=false,o=null,s=null,a=(async()=>{n=await this.createIpcChannel(u=>{if(i||!o)return;if(u instanceof ArrayBuffer||Object.prototype.toString.call(u)==="[object ArrayBuffer]"){o.enqueue(new Uint8Array(u));return}if(ArrayBuffer.isView(u)){o.enqueue(new Uint8Array(u.buffer,u.byteOffset,u.byteLength));return}let h=u;if(h?.type!=="closed")return;i=true,n=null;let f=typeof h.error=="string"?h.error.trim():"";f?o.error(new Error(f)):o.close();}),await this.invokeIpc("start_peer_bi_stream_read",{streamId:e,channel:n},{timeoutMs:null});})().catch(u=>{s=u,n=null,o&&!i&&(i=true,o.error(u));}),c=async()=>{await this.invokeIpc("close_peer_bi_stream",{streamId:e},{timeoutMs:null}).catch(()=>{}),n=null;},d=async()=>{await this.invokeIpc("cancel_peer_bi_stream_read",{streamId:e},{timeoutMs:null}).catch(()=>{}),n=null;},l=new ReadableStream({async start(u){o=u,await a,s&&!i&&(i=true,u.error(s));},async cancel(){i=true,await d();}}),p=new WritableStream({write:async u=>{await t.invokeRawIpc("write_peer_bi_stream",u,{"x-openrtc-stream-id":e});},close:c,abort:c});return {readable:l,writable:p}}async invokePeerBiOpen(e,t,n){try{return await this.invokeIpc(e,t)}catch(i){if(!n?.fallbackCommand||!this.isMissingNativeCommandError(i))throw i;return this.invokeIpc(n.fallbackCommand,n.fallbackArgs??t)}}isMissingNativeCommandError(e){let t=e instanceof Error?e.message:String(e??"");return t.includes("Command")&&t.includes("not found")}nativeIpcRequired(e){return new Error(`[OpenRTC] ${e} requires the native Rust IPC runtime; native hosts never fall back to WASM.`)}async shouldUseTauriSignaling(){if(await this.canUseTauriIpc())return true;throw this.nativeIpcRequired("managed signaling")}async signInWithPluto(){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("signInWithPluto");let e=await this.invokeIpc("rtc_sign_in_with_pluto"),t=typeof e?.customToken=="string"?e.customToken.trim():"";if(!t)throw new Error("[pluto-rtc] Native Pluto SSO did not return a custom token.");await a$3().signInWithCustomTokenValue(t),await this.ensureNativeAuth("pluto-sso",{requireToken:true,maxWaitMs:1e4});}async setAuthContext(e){let t=this.getAuthContext()?.userId??null,n=typeof e?.userId=="string"&&e.userId.trim()||null,i=this.applyCoordinationAuthContext(e);if(t&&n&&t!==n&&await this.stopNativeAuthScopedActivity(t),await i,!e?.token)await this.clearNativeAuthRelay("setAuthContext"),await this.clearNativeTrustRelay("setAuthContext");else {if(!await this.relayExplicitNativeAuthContext(e))throw new Error("Native auth token unavailable for setAuthContext");if(!await this.ensureNativeTrustRelay())throw new Error(`Native trust token unavailable for setAuthContext: ${this.nativeTrustRelayError??"unknown provider failure"}`)}}async signOut(){let e=this.getCurrentUserId();await this.stopAuthActivity({userId:e}),await this.applyCoordinationAuthContext(null),this.isTicketOnlyMode()||await this.auth?.signOut(),await Promise.all([this.clearNativeAuthRelay("signOut"),this.clearNativeTrustRelay("signOut")]);}async stopAuthActivity(e){let t=this.resolveNativeSignalingUserId(e?.userId??null);await this.stopNativeAuthScopedActivity(t);}async stopNativeAuthScopedActivity(e){await this.stopGatewayDesiredPeerRelay(),this.gatewayExcludedPeers.clear();let t=await this.shouldUseTauriSignaling();if(h("NativeIpcBridge.stopAuthActivity",{userId:e,useTauri:t}),t)try{let n=this.nativeIdentityId;this.nativeIdentityId=null,await Promise.allSettled([this.revokeTokens("user-device"),this.invokeIpc("stop_rtc_presence_loop"),this.invokeIpc("stop_rtc_auto_connect"),...n?[this.invokeIpc("openrtc_clear_native_identity",{identityId:n},{timeoutMs:null})]:[]]);}catch(n){console.warn("[NativeIpcBridge] Failed to stop native auth-scoped RTC activity:",n);}this.coordinationHost.stopAuthActivity();}async ensureNativeAuthOnce(e$1,t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired(`auth relay (${e$1})`);if(this.authSyncInFlight)return this.authSyncInFlight;let n=(async()=>{try{if(!this.currentUser)return e(`[NativeIpcBridge] auth sync deferred (${e$1}): no current user`),!t;let i=Date.now()-this.lastNativeAuthSyncAtMs>=480*1e3,o=this.currentUser?.getToken?await this.currentUser.getToken(i):null,a=this.getAuthContext()?.refreshToken??this.auth?.currentUser?.refreshToken??null;return o?this.relayNativeAuthToken(o,a,e$1,this.currentUser?.id):(e(`[NativeIpcBridge] auth sync deferred (${e$1}): missing token for user ${this.currentUser?.id}`),!t)}catch(i){return console.error("[NativeIpcBridge] auth sync failed:",i),false}})();this.authSyncInFlight=n;try{return await n}finally{this.authSyncInFlight===n&&(this.authSyncInFlight=null);}}async ensureNativeAuth(e="runtime",t){if(!await this.canUseTauriIpc())throw this.nativeIpcRequired(`auth readiness (${e})`);let n=t?.requireToken??false,i=t?.maxWaitMs??(n?K.AUTH_REQUIRED_WAIT_MS:0),o=t?.pollMs??250,s=Date.now()+Math.max(0,i);for(;;){if(await this.ensureNativeAuthOnce(e,n))return true;if(!n||Date.now()>=s)return false;await a(o);}}decodeNativeDeviceIdentity(e){let t=e?.systemInfo??e?.system_info??null,n=typeof e?.deviceId=="string"?e.deviceId.trim():typeof e?.device_id=="string"?e.device_id.trim():"",i=typeof e?.deviceName=="string"?e.deviceName.trim():typeof e?.device_name=="string"?e.device_name.trim():"",o=typeof e?.platformType=="string"?e.platformType.trim():typeof e?.platform_type=="string"?e.platform_type.trim():typeof t?.platformType=="string"?t.platformType.trim():typeof t?.platform_type=="string"?t.platform_type.trim():"";return {deviceId:n,deviceName:i,platformType:o}}async resolveLocalDeviceId(){if(this.cachedLocalDeviceId)return this.cachedLocalDeviceId;if(!await this.canUseTauriIpc())throw this.nativeIpcRequired("local device identity");let e=await this.invokeIpc("get_rtc_local_device_info"),{deviceId:t,deviceName:n}=this.decodeNativeDeviceIdentity(e);if(!t)throw new Error("[OpenRTC] Native Rust runtime returned no local device identity.");return this.cachedLocalDeviceId=t,this.options.localDeviceId=t,n&&(this.cachedLocalDeviceName=n),t}async resolveLocalDeviceName(){if(this.cachedLocalDeviceName)return this.cachedLocalDeviceName;if(await this.canUseTauriIpc())try{let e=await this.invokeIpc("get_rtc_local_device_info"),{deviceName:t}=this.decodeNativeDeviceIdentity(e);if(t){let n=this.normalizeNativeDeviceName(t);return this.cachedLocalDeviceName=n,n}}catch(e){console.warn("[NativeIpcBridge] get_rtc_local_device_info failed:",e);}return this.defaultDeviceNameFallback()}normalizeNativeDeviceName(e){let t=e.trim();if(!t)return this.defaultDeviceNameFallback();if(t==="Desktop Device"){let n=this.defaultDeviceNameFallback();if(n!=="Desktop Device")return n}return t}defaultDeviceNameFallback(){if(typeof window>"u"||typeof navigator>"u")return "Desktop Device";let e=navigator.userAgent||"";return /iPhone|iPad|iPod/i.test(e)?"iPhone":/Android/i.test(e)?"Android":"Desktop Device"}inferNativePlatformTypeFallback(){if(typeof window>"u"||typeof navigator>"u")return "desktop";if(!this.isTauriEnv())return "web";let e=navigator.userAgent||"";return /iPhone|iPad|iPod|Android|Mobile/i.test(e)?"mobile":"desktop"}normalizeNativeCoordinationPlatform(e){let t=this.options.coordinationPlatformType?.trim().toLowerCase()??"";if(t&&t!=="desktop"&&t!=="mobile"&&t!=="web")return t;let n=e?.trim().toLowerCase()??"";return n||(t==="mobile"||t==="desktop"?t:this.inferNativePlatformTypeFallback()==="mobile"?"mobile":"desktop")}withPresenceMetadata(e,t){try{let n=e?JSON.parse(e):{};return JSON.stringify({...n,deviceId:t,plutoVersion:"0.1.0-desktop"})}catch{return JSON.stringify({deviceId:t,plutoVersion:"0.1.0-desktop",rawMetadata:e})}}async searchDevices(e){return this.assertManagedCoordinationGateway(),this.usesRustNativeDevices()?this.listRustNativeDevices(e):this.coordinationHost.getSignaling().searchDevices(e)}async listDeviceStatus(){return this.assertManagedCoordinationGateway(),(this.usesRustNativeDevices()?await this.listRustNativeDevices():await this.coordinationHost.getSignaling().searchDevices()).map(t=>B(t))}async getPeerSession(e){await this.shouldUseTauriSignaling();let t=await this.invokeIpc("get_rtc_peer_session",{id:e});return !t||typeof t!="object"?null:C(t)}async listPeerSessions(){await this.shouldUseTauriSignaling();let e=await this.invokeIpc("list_rtc_peer_sessions");return (Array.isArray(e)?e:[]).map(t=>C(t))}async waitForSettledPeer(e,t){await this.shouldUseTauriSignaling();let n=typeof t=="number"?Math.max(K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS,t+1e3):K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS,i=await this.invokeIpc("wait_for_rtc_settled_peer",{id:e,timeoutMs:t},{timeoutMs:n});return !i||typeof i!="object"?null:C(i)}async waitForSettledScope(e,t){await this.shouldUseTauriSignaling();let n=typeof t=="number"?Math.max(K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS,t+1e3):K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS,i=await this.invokeIpc("wait_for_rtc_settled_scope",{scope:e,timeoutMs:t},{timeoutMs:n});return !i||typeof i!="object"?null:C(i)}async resolvePeerRecords(e){await this.shouldUseTauriSignaling();let t=await this.invokeIpc("resolve_rtc_peer_connection_records",{id:e});return (Array.isArray(t)?t:[]).map(n=>D(n))}async resolvePeerIdentity(e){await this.shouldUseTauriSignaling();let t=await this.invokeIpc("resolve_rtc_peer_identity",{id:e});return E(t)}async setOffline(e){if(this.assertManagedCoordinationGateway(),this.usesRustNativeDevices()){let t=this.nativeIdentityId;this.nativeIdentityId=null,t&&await this.invokeIpc("openrtc_clear_native_identity",{identityId:t},{timeoutMs:null});return}return this.coordinationHost.getSignaling().setOffline(e)}async updateDevice(e,t){return this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity(),this.coordinationHost.getSignaling().updateDevice(e,t)}async deleteDevice(e){return this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity(),this.coordinationHost.getSignaling().deleteDevice(e)}async getLocalDeviceInfo(){if(!await this.canUseTauriIpc()){let e=await this.getLocalDeviceId?.();return e?{deviceId:e,deviceName:this.defaultDeviceNameFallback(),platformType:this.inferNativePlatformTypeFallback()}:null}try{let e=await this.invokeIpc("get_rtc_local_device_info"),t=this.decodeNativeDeviceIdentity(e),{deviceId:n}=t;return n?{deviceId:n,deviceName:this.normalizeNativeDeviceName(t.deviceName),platformType:t.platformType||this.inferNativePlatformTypeFallback(),capabilities:e?.capabilities??void 0,lastSeenAt:typeof e?.last_seen_at=="string"?e.last_seen_at:void 0}:null}catch(e){return console.warn("[NativeIpcBridge] getLocalDeviceInfo failed:",e),null}}async updateDeviceName(e){if(!await this.canUseTauriIpc())return null;try{let t=await this.invokeIpc("update_rtc_local_device_name",{deviceName:e}),n=this.decodeNativeDeviceIdentity(t),{deviceId:i}=n;return i?(this.cachedLocalDeviceName=this.normalizeNativeDeviceName(e),{deviceId:i,deviceName:this.cachedLocalDeviceName,platformType:n.platformType||this.inferNativePlatformTypeFallback(),capabilities:t?.capabilities??void 0,lastSeenAt:typeof t?.last_seen_at=="string"?t.last_seen_at:void 0}):null}catch(t){return console.warn("[NativeIpcBridge] updateDeviceName failed:",t),null}}async startNativeSession(e){if(this.assertManagedCoordinationGateway(),!await this.shouldUseTauriSignaling())throw new Error("[pluto-rtc] Native IPC unavailable for startNativeSession().");if(await this.ensureNativeCapabilityRegistered(),!await this.ensureNativeAuth("startNativeSession",{requireToken:this.requiresNativeAuthToken(),maxWaitMs:this.nativeAuthWaitMs()}))throw new Error("Native auth token unavailable for startNativeSession");let n=this.resolveNativeSignalingUserId(e.userId);if(!n)throw new Error("Native managed session startup requires a runtime auth-scoped user id.");let i=this.usesRustNativeDevices()?await this.ensureRustNativeDevicesIdentity(e.deviceName):null;if(i&&i.principalId!==n)throw new Error("[OpenRTC] Native device enrollment principal does not match the active capability.");if(i&&e.localDeviceId?.trim()&&i.deviceId!==e.localDeviceId.trim())throw new Error("[OpenRTC] Native device enrollment returned a different durable device identity.");n!==e.userId&&console.info("[NativeIpcBridge][managed-session][user-id-remap]",{requestedUserId:e.userId,runtimeUserId:this.currentUser?.id??this.getAuthContext()?.userId??null,effectiveUserId:n}),console.info("[NativeIpcBridge][managed-session][start-request]",{requestedUserId:e.userId,runtimeUserId:this.currentUser?.id??this.getAuthContext()?.userId??null,effectiveUserId:n,deviceName:e.deviceName??null,localDeviceId:e.localDeviceId??null,presence:e.presence!==false,autoConnect:e.autoConnect!==false,hasMetadata:typeof e.metadata=="string"&&e.metadata.trim().length>0});let o={userId:n,deviceName:e.deviceName??null,localDeviceId:i?.deviceId??e.localDeviceId??null,metadata:e.metadata??null,autoConnect:false,presence:false},s=await this.invokeIpc("start_rtc_managed_session",o,{timeoutMs:null});this.syncNativeRuntimeCapabilities("managed-session-started");let a=typeof s?.ticket=="string"&&s.ticket.trim().length>0?s.ticket.trim():null,c=s?.localDevice&&typeof s.localDevice=="object"?s.localDevice:s?.local_device&&typeof s.local_device=="object"?s.local_device:null,d=c?{deviceId:typeof c.deviceId=="string"?c.deviceId:typeof c.device_id=="string"?c.device_id:"",deviceName:this.normalizeNativeDeviceName(typeof c.deviceName=="string"?c.deviceName:typeof c.device_name=="string"?c.device_name:""),platformType:typeof c.platformType=="string"?c.platformType:typeof c.platform_type=="string"?c.platform_type:"desktop",capabilities:c.capabilities??void 0,lastSeenAt:typeof c.lastSeenAt=="string"?c.lastSeenAt:typeof c.last_seen_at=="string"?c.last_seen_at:void 0}:null,l={localNodeId:typeof s?.localNodeId=="string"?s.localNodeId:typeof s?.local_node_id=="string"?s.local_node_id:null,ticket:a,ticketScope:typeof s?.ticketScope=="string"?s.ticketScope:typeof s?.ticket_scope=="string"?s.ticket_scope:null,presenceStarted:typeof s?.presenceStarted=="boolean"?s.presenceStarted:!!s?.presence_started,autoConnectStarted:typeof s?.autoConnectStarted=="boolean"?s.autoConnectStarted:!!s?.auto_connect_started,localDevice:d?.deviceId?d:null};if(i)e.presence!==false&&(await this.invokeIpc("openrtc_publish_native_devices",{identityId:i.identityId,capabilityKey:this.nativeCapability.key,deviceName:e.deviceName?.trim()||l.localDevice?.deviceName||this.defaultDeviceNameFallback(),metadata:e.metadata??null,excludedPeers:[...this.gatewayExcludedPeers].sort(),autoConnect:e.autoConnect!==false},{timeoutMs:null}),l.localNodeId&&l.ticket&&this.coordinationHost.getSignaling().setFriendObservationIdentity?.({localNodeId:l.localNodeId,ticket:l.ticket,ttlMs:3e5,metadata:this.withPresenceMetadata(e.metadata,i.deviceId),deviceName:e.deviceName?.trim()||l.localDevice?.deviceName||this.defaultDeviceNameFallback()})),l.presenceStarted=e.presence!==false,l.autoConnectStarted=e.presence!==false&&e.autoConnect!==false;else if(this.usesCoordinationGateway()){await this.installInitialGatewayAutoConnectExclusions(),e.presence!==false&&!l.ticket&&(l.ticket=await this.getTicketWithToken("user-device",0),l.ticketScope=l.ticket?"user-device":null);let p=l.localDevice?.deviceId||e.localDeviceId?.trim()||await this.resolveLocalDeviceId();if(p&&(this.options.localDeviceId=p),this.options.coordinationPlatformType=this.normalizeNativeCoordinationPlatform(l.localDevice?.platformType),e.presence!==false){if(!l.localNodeId||!l.ticket)throw new Error("Native managed session did not return the node identity required for gateway presence.");await this.coordinationHost.getSignaling().updatePresence(l.localNodeId,l.ticket,true,3e5,this.withPresenceMetadata(e.metadata,p),l.localDevice?.deviceName||e.deviceName),l.presenceStarted=true;}else l.presenceStarted=false;e.autoConnect!==false&&p?(await this.startGatewayAutoConnect(n,p),l.autoConnectStarted=true):l.autoConnectStarted=false;}return console.info("[NativeIpcBridge][managed-session][ipc-started]",{requestedUserId:e.userId,runtimeUserId:this.currentUser?.id??this.getAuthContext()?.userId??null,effectiveUserId:n,localNodeId:l.localNodeId,ticketScope:l.ticketScope,presenceStarted:l.presenceStarted,autoConnectStarted:l.autoConnectStarted,localDeviceId:l.localDevice?.deviceId??null}),l}async installInitialGatewayAutoConnectExclusions(){for(let e of this.initialGatewayExcludedPeers)this.gatewayExcludedPeers.add(e),await this.invokeIpc("set_rtc_external_auto_connect_excluded",{deviceId:e,excluded:true});}async syncNativeSession(e){return this.assertManagedCoordinationGateway(),await this.coordinationHost.reconnectAfterHostResume(),console.info("[NativeIpcBridge] reattached gateway coordination after host resume.",{reason:e?.reason??"frontend"}),null}async notifyNetworkChange(e$1){return await this.canUseTauriIpc()?(e("[NativeIpcBridge] forwarding host network-change hint",{reason:e$1?.reason??"host"}),this.invokeIpc("notify_rtc_network_change")):null}async setTransportPriority(e){if(!await this.canUseTauriIpc())throw new Error("[pluto-rtc] Native IPC unavailable for setTransportPriority().");await this.invokeIpc("set_rtc_transport_priority",{priority:e}),this.syncNativeRuntimeCapabilities("transport-priority-updated");}async getManagedNodeId(e){let t=e?.initializeIfMissing??true;console.info("[NativeIpcBridge][getManagedNodeId] enter",{initializeIfMissing:t});let n=await this.canUseTauriIpc();if(console.info("[NativeIpcBridge][getManagedNodeId] canUseTauriIpc",{canUse:n}),!n)return null;try{console.info("[NativeIpcBridge][getManagedNodeId] invoking get_iroh_node_id");let i=await this.invokeIpc("get_iroh_node_id");if(console.info("[NativeIpcBridge][getManagedNodeId] get_iroh_node_id returned",{existing:i}),i||!t)return i;console.info("[NativeIpcBridge][getManagedNodeId] invoking start_iroh_node");let o=await this.invokeIpc("start_iroh_node");return console.info("[NativeIpcBridge][getManagedNodeId] start_iroh_node returned",{started:o}),o}catch(i){if(console.warn("[NativeIpcBridge] getManagedNodeId failed:",i),!t)return null;throw i}}async getEndpointTicket(){if(!await this.canUseTauriIpc())throw new Error("[pluto-rtc] getEndpointTicket requires native IPC in Tauri runtime.");return se(()=>this.invokeIpc("get_iroh_endpoint_ticket"))}async connectToDevice(e$1){if(!await this.canUseTauriIpc())throw new Error("[pluto-rtc] connectToDevice requires native IPC in Tauri runtime.");this.options.authMode!=="anonymous"?await this.ensureNativeAuth("connectToDevice",{requireToken:true,maxWaitMs:K.AUTH_REQUIRED_WAIT_MS}):e("[NativeIpcBridge] connectToDevice using anonymous native ticket path");let t=Math.max(1,Math.floor(e$1.timeoutMs??K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS)),n=e$1.endpointTicket?.trim()??"",i=e$1.admissionToken?.trim()??"",o=e$1.admissionScope?.trim()??"";if(!n&&(!e$1.deviceId||!i||!o))throw new Error("[pluto-rtc] connectToDevice requires an endpoint ticket or known-device admission intent.");if(!n){let s=Date.now(),a=()=>Math.max(1,t-(Date.now()-s)),c=e$1.admissionPeerUserId?.trim()??"";if(c){let p=(await this.coordinationHost.getSignaling().waitForFriendDevice(c,e$1.deviceId,Math.min(1e4,a()))).ticket?.trim()??"";if(!p)throw new Error(`[pluto-rtc] authorized device ${e$1.deviceId} did not publish an endpoint ticket.`);await this.invokeIpc("observe_known_device_endpoint",{deviceId:e$1.deviceId,endpointTicket:p},{timeoutMs:a()});}let d=a();return this.invokeIpc("connect_to_known_device_with_token",{deviceId:e$1.deviceId,token:i,scope:o,maxConnections:e$1.admissionMaxConnections??0,expiresAtMs:e$1.admissionExpiresAtMs??null,timeoutMs:d},{timeoutMs:d+1e3})}return this.invokeIpc("connect_to_device",{deviceId:e$1.deviceId??null,endpointTicket:n,timeoutMs:t},{timeoutMs:t+1e3})}async registerSessionToken(e,t,n,i){await this.canUseTauriIpc()&&await this.invokeIpc("register_session_token",{token:e,scope:t,maxConnections:n,expiresAtMs:i??null});}async getTicketWithToken(e,t){if(!await this.canUseTauriIpc())return null;try{return await se(()=>this.invokeIpc("get_endpoint_ticket_with_token",{scope:e,maxConnections:t}))}catch{return null}}async validateSessionToken(e,t){if(!await this.canUseTauriIpc())return null;try{return await this.invokeIpc("validate_session_token",{token:e,connectionId:t??null})}catch{return null}}async revokeTokens(e){if(h("NativeIpcBridge.revokeTokens",{grantScope:e}),!await this.canUseTauriIpc())return [];try{return await this.invokeIpc("revoke_session_tokens_by_scope",{scope:e})}catch{return []}}async disconnectDevice(e){if(!await this.canUseTauriIpc())throw new Error("[pluto-rtc] disconnectDevice requires native IPC in Tauri runtime.");await this.invokeIpc("disconnect_device",{deviceId:e});}async excludeAutoConnect(e,t){if(!await this.canUseTauriIpc())return;let n=e.trim().toLowerCase();if(n&&(this.usesCoordinationGateway()&&(t?this.gatewayExcludedPeers.add(n):this.gatewayExcludedPeers.delete(n)),await this.invokeIpc(this.usesCoordinationGateway()?"set_rtc_external_auto_connect_excluded":"set_auto_connect_excluded",{deviceId:e,excluded:t}),this.usesCoordinationGateway()&&!this.usesRustNativeDevices())){let i=await this.resolveLocalDeviceId();await this.coordinationHost.getSignaling().updateDevice(i,{excludedPeers:[...this.gatewayExcludedPeers].sort()});}}onDevicesChange(e,t){return this.assertManagedCoordinationGateway(),this.usesRustNativeDevices()?this.requireNativeProjectionSource().onDevices(i=>e(i.filter(o=>!t||o.nodeId!==t&&o.deviceId!==t))):this.coordinationHost.getSignaling().onDevicesChange(e,t)}onRoomArchitectureChange(e){return this.coordinationHost.getSignaling().onRoomArchitectureChange?.(e)??(()=>{})}onRoomAuthorityAssignmentChange(e){return this.coordinationHost.getSignaling().onRoomAuthorityAssignmentChange?.(e)??(()=>{})}async publishAuthorityAssignment(e){let t=this.coordinationHost.getSignaling();if(!t.publishAuthorityAssignment)throw new Error("[OpenRTC] Authority assignment publication is unavailable.");await t.publishAuthorityAssignment(e);}async subscribeDevices(e){return this.assertManagedCoordinationGateway(),this.coordinationHost.getSignaling().subscribeDevices()}async subscribeSessions(e){return this.assertManagedCoordinationGateway(),this.coordinationHost.getSignaling().subscribeSessions(e)}async getLocalDeviceId(){return this.resolveLocalDeviceId()}async updatePresence(e,t,n=true,i=3e5,o){this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity();let s=await this.resolveLocalDeviceId();return this.coordinationHost.getSignaling().updatePresence(e,t,n,i,this.withPresenceMetadata(o,s))}startAutoConnect(e,t){this.assertManagedCoordinationGateway(),this.startGatewayAutoConnect(e,t).catch(n=>{console.warn("[NativeIpcBridge] gateway auto-connect failed:",n);});}forceReconnect(){this.notifyNetworkChange({reason:"frontend-force-reconnect-hint"}).catch(e=>{console.warn("[NativeIpcBridge] native reconnect hint failed:",e);});}async startPresenceLoop(e,t,n,i,o){this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity(),await this.coordinationHost.getSignaling().updatePresence(t,i,true,3e5,this.withPresenceMetadata(o,await this.resolveLocalDeviceId()),n);}async startAutoConnectOnce(e,t){this.assertManagedCoordinationGateway(),await this.startGatewayAutoConnect(e,t);}async clearGatewayDesiredPeerRelay(){let e=this.gatewayDesiredPeerSubmission;this.gatewayDesiredPeerRelayGeneration+=1,this.gatewayDesiredPeersCleanup?.(),this.gatewayDesiredPeersCleanup=null,this.gatewayDesiredPeerRelayKey=null,this.gatewayDesiredPeerRevision=0,this.gatewayDesiredPeerSubmission=Promise.resolve(),await e;}serializeGatewayDesiredPeerLifecycle(e){let t=this.gatewayDesiredPeerLifecycle.then(e);return this.gatewayDesiredPeerLifecycle=t.catch(()=>{}),t}stopGatewayDesiredPeerRelay(){return this.serializeGatewayDesiredPeerLifecycle(async()=>{await this.clearGatewayDesiredPeerRelay();})}startGatewayAutoConnect(e,t){return this.serializeGatewayDesiredPeerLifecycle(()=>this.startGatewayAutoConnectSerialized(e,t))}async startGatewayAutoConnectSerialized(e,t){if(!await this.shouldUseTauriSignaling())throw new Error("[openrtc] Native IPC unavailable for coordination gateway auto-connect.");if(!await this.ensureNativeAuth("startGatewayAutoConnect",{requireToken:this.requiresNativeAuthToken(),maxWaitMs:this.nativeAuthWaitMs()}))throw new Error("Native auth token unavailable for coordination gateway auto-connect");let i=this.resolveNativeSignalingUserId(e);if(!i)throw new Error("Coordination gateway auto-connect requires an authenticated user id.");let o=await this.resolveLocalDeviceId()||t.trim();if(!o)throw new Error("Coordination gateway auto-connect requires a local device id.");let s=JSON.stringify([i,o]);this.options.localDeviceId=o;let a=this.gatewayDesiredPeerRelayKey===s&&this.gatewayDesiredPeersCleanup;if(a||(await this.clearGatewayDesiredPeerRelay(),this.gatewayDesiredPeerRelayKey=s),await this.invokeIpc("start_rtc_external_auto_connect",{userId:i,localDeviceId:o,capabilityKey:this.nativeCapability.key}),a)return;let c=this.gatewayDesiredPeerRelayGeneration;this.gatewayDesiredPeersCleanup=this.coordinationHost.getSignaling().onDevicesChange(d=>{let p=d.map(h=>({deviceId:String(h.deviceId??"").trim(),nodeId:typeof h.nodeId=="string"&&h.nodeId.trim()||null,ticket:typeof h.ticket=="string"&&h.ticket.trim()||null,online:h.online===true,sessionId:typeof h.sessionId=="string"&&h.sessionId.trim()||null,excludedPeers:Array.isArray(h.excludedPeers)?[...new Set(h.excludedPeers.map(f=>String(f??"").trim().toLowerCase()).filter(Boolean))].sort():[],devicePublicKeyJwk:h.devicePublicKeyJwk,topologyRole:h.topologyRole,topologyRevision:h.topologyRevision})).filter(h=>h.deviceId.length>0&&h.deviceId!==o).sort((h,f)=>h.deviceId.localeCompare(f.deviceId)),u=++this.gatewayDesiredPeerRevision;this.gatewayDesiredPeerSubmission=this.gatewayDesiredPeerSubmission.then(async()=>{this.gatewayDesiredPeerRelayGeneration!==c||this.gatewayDesiredPeerRelayKey!==s||await this.invokeIpc("submit_rtc_desired_peers",{revision:u,peersJson:JSON.stringify(p),capabilityKey:this.nativeCapability.key,localDeviceId:o,appTag:this.appTag});}).catch(h=>{console.warn("[NativeIpcBridge] failed to relay gateway desired peers to Rust:",{revision:u,error:h});});},o);}async startPresence(e,t,n,i,o){this.assertManagedCoordinationGateway(),await this.syncCoordinationDeviceIdentity();let s=await this.resolveLocalDeviceId();await this.coordinationHost.getSignaling().updatePresence(t,i,true,3e5,this.withPresenceMetadata(o,s),n);}shouldUseResolvedDeviceName(e){let t=e.trim();return t.length===0||t==="Unknown Device"||t==="Desktop Device"}async sendExplicitFilePath(e$1,t,n=""){if(e("[NativeIpcBridge] sendExplicitFilePath start",{connectionId:e$1,filePath:t,transferId:n||null,authMode:this.options.authMode}),await this.canUseTauriIpc()){this.options.authMode!=="anonymous"?await this.ensureNativeAuth("sendExplicitFilePath"):e("[NativeIpcBridge] sendExplicitFilePath using anonymous native path");let i=await this.invokeIpc("send_file",{connectionId:e$1,filePath:t,transferId:n});return e("[NativeIpcBridge] sendExplicitFilePath completed",{connectionId:e$1,transferId:n||null,result:i}),i}throw this.nativeIpcRequired("sendExplicitFilePath")}async sendExplicitFileData(e$1){if(e("[NativeIpcBridge] sendExplicitFileData start",{connectionId:e$1.connectionId??null,connectionRemoteNodeId:e$1.connection?.remoteNodeId??null,remoteNodeId:e$1.remoteNodeId??null,transferId:e$1.transferId??null,fileName:e$1.file.name,fileSize:e$1.file.size,authMode:this.options.authMode}),await this.canUseTauriIpc()){this.options.authMode!=="anonymous"?await this.ensureNativeAuth("sendExplicitFileData"):e("[NativeIpcBridge] sendExplicitFileData using anonymous native path");let t=e$1.connectionId||e$1.connection?.deviceId||e$1.connection?.remoteNodeId||e$1.remoteNodeId||"";if(!t)throw new Error("sendExplicitFileData requires a settled peer identifier in native runtime");let n=new Uint8Array(await e$1.file.arrayBuffer());await this.invokeIpc("send_file_data",{connectionId:t,filename:e$1.file.name,data:Array.from(n),transferId:e$1.transferId}),e("[NativeIpcBridge] sendExplicitFileData completed",{connectionId:t,transferId:e$1.transferId??null,fileName:e$1.file.name,fileSize:e$1.file.size});return}throw this.nativeIpcRequired("sendExplicitFileData")}async getConnectionStates(){if(await this.canUseTauriIpc())try{await this.ensureNativeCapabilityRegistered(),this.options.authMode!=="anonymous"&&await this.ensureNativeAuth("getConnectionStates");let e=await this.invokeIpc("list_rtc_connection_states",{capabilityKey:this.nativeCapability.key});return (Array.isArray(e)?e:[]).map(t=>G(t)).filter(t=>!!t)}catch(e$1){return b$2(e$1)?e("[NativeIpcBridge] native connection-state replay unavailable; continuing without replay. Install/register openrtc-tauri-plugin default permissions to enable it."):console.warn("[NativeIpcBridge] Failed to fetch native connection states:",e$1),[]}return []}async getConnectionState(e){let t=e.trim();if(!t||!await this.canUseTauriIpc())return null;try{return await this.ensureNativeCapabilityRegistered(),this.options.authMode!=="anonymous"&&await this.ensureNativeAuth("getConnectionState"),G(await this.invokeIpc("get_rtc_connection_state",{connectionId:t,capabilityKey:this.nativeCapability.key}))}catch(n){return console.warn("[NativeIpcBridge] Failed to fetch native connection state:",{connectionId:t,error:n}),null}}async onStateChange(e){await this.ensureNativeCapabilityRegistered();let t=false,n=this.requireNativeProjectionSource().onStateChange(i=>{t||e(i);});try{let i=await this.getConnectionStates();t||i.forEach(o=>e(o));}catch(i){console.warn("[NativeIpcBridge] Failed to replay native connection states:",i);}return ()=>{t=true,n();}}async sendPeerMessage(e,t){await this.invokeRawIpc("send_peer_message",t,{"x-openrtc-peer-id":e});}async encodeSparseFanoutMessage(e,t){let n=await this.invokeRawIpc("encode_sparse_fanout_message",t,{"x-openrtc-fanout-capability":e,"x-openrtc-fanout-app-tag":this.appTag});return this.binaryIpcBytes(n,"encode_sparse_fanout_message")}async acceptSparseFanoutMessage(e,t,n){let i=await this.invokeRawIpc("accept_sparse_fanout_message",n,{"x-openrtc-fanout-capability":e,"x-openrtc-fanout-source-peer":t});return {payload:this.binaryIpcBytes(i.payload,"accept_sparse_fanout_message.payload"),authorDeviceId:String(i.authorDeviceId??""),authorPeerId:String(i.authorPeerId??""),topologyRevision:Number(i.topologyRevision),hop:Number(i.hop),forwardPeerIds:Array.isArray(i.forwardPeerIds)?i.forwardPeerIds.map(String):[],forwardPeerLimit:Number(i.forwardPeerLimit),forwardQueueCapacity:Number(i.forwardQueueCapacity),...i.forward==null?{}:{forward:this.binaryIpcBytes(i.forward,"accept_sparse_fanout_message.forward")}}}async recordSparseFanoutForwardQueueDrop(e,t){await this.invokeIpc("record_sparse_fanout_forward_queue_drop",{capabilityKey:e,count:t});}async onPeerMessage(e){return await this.ensureNativeCapabilityRegistered(),this.requireNativeProjectionSource().onPeerMessage(e)}async onIncomingNativeMessage(e){if(!await this.canUseTauriIpc())return ()=>{};let t=await this.listenIpc("iroh://message",n=>{if(n?.payload?.data&&n.payload.streamId==="main")try{let i=new Uint8Array(n.payload.data);if(i.length<2||i[0]!==0)return;let s=i.slice(1),a=new TextDecoder().decode(s),c=JSON.parse(a);e(n.payload.connectionId,n.payload.remoteNodeId??null,c);}catch{}});return typeof t=="function"?t:()=>{}}async getTransferHistory(e=50){return await this.canUseTauriIpc()?this.invokeIpc("get_transfer_history",{limit:e}):[]}async deleteTransferJob(e){await this.canUseTauriIpc()&&await this.invokeIpc("delete_transfer_job",{jobId:e});}};K.AUTH_REQUIRED_WAIT_MS=o.nativeIpc.authRequiredWaitMs,K.DEFAULT_BOUNDED_IPC_TIMEOUT_MS=o.nativeIpc.defaultBoundedCommandTimeoutMs,K.TAURI_IPC_NEGATIVE_CACHE_MS=o.nativeIpc.tauriIpcNegativeCacheMs,K.NATIVE_STATUS_IPC_TIMEOUT_MS=2500;var An=K;var Fr=class extends a$2{constructor(e){let t=c$1(e.bridge,"IpcRuntimeAdapter"),{projectionBroker:n,...i}=e,o=new An({...i,ipcBridge:t});super(o),this.projectionBroker=n,this.capabilityKey=c$2(i.coordinationAvenueOverride).key,this.projectedSource=n.register(this.capabilityKey,o),o.attachNativeProjectionSource(this.projectedSource);}projectedIncomingStreamSource(){return this.projectedSource}async releaseNativeCapability(){this.projectionBroker.unregister(this.capabilityKey),await this.backend.releaseNativeCapability();}};
2
+ export{at as a,Ur as b,He as c,$ as d,ce as e,dt as f,ct as g,Ue as h,We as i,Wn as j,Kr as k,zr as l,Vr as m,zs as n,Vs as o,jn as p,qn as q,Lr as r,Fr as s};