@robota-sdk/agent-transport-webrtc 3.0.0-beta.94 → 3.0.0-beta.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/session-attachment-app-view.test.ts +66 -0
- package/src/__tests__/webrtc-transport.test.ts +41 -2
- package/src/session-attachment.ts +4 -0
- package/src/webrtc-transport.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @robota-sdk/agent-transport-webrtc
|
|
2
2
|
|
|
3
|
+
## 3.0.0-beta.95
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- Updated dependencies [c967c57]
|
|
7
|
+
- Updated dependencies [60f3965]
|
|
8
|
+
- Updated dependencies [115e104]
|
|
9
|
+
- Updated dependencies [04719a9]
|
|
10
|
+
- Updated dependencies [04a6de4]
|
|
11
|
+
- Updated dependencies [0ba247b]
|
|
12
|
+
- @robota-sdk/agent-transport@3.0.0-beta.95
|
|
13
|
+
- @robota-sdk/agent-interface-session@3.0.0-beta.95
|
|
14
|
+
- @robota-sdk/agent-interface-session-mobility@3.0.0-beta.95
|
|
15
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.95
|
|
16
|
+
- @robota-sdk/agent-remote-pairing@3.0.0-beta.95
|
|
17
|
+
|
|
3
18
|
## 3.0.0-beta.94
|
|
4
19
|
### Patch Changes
|
|
5
20
|
|
package/dist/node/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("@robota-sdk/agent-transport"),l=require("@robota-sdk/agent-transport/node"),u=require("@robota-sdk/agent-remote-pairing"),d=require("node:module"),f=require("ws");f=s(f,1);let ee=require("@robota-sdk/agent-interface-session-mobility"),p=require("node:crypto"),te=require("node:dgram"),m=require("node:net"),h=require("node:os"),ne=require("nostr-tools/pool"),g=require("nostr-tools/pure");function re(e,t){return(0,c.createOutboundDelivery)(t=>e.send(JSON.stringify(t)),(e,n)=>t(e,n),()=>e.bufferedAmount)}const ie=/^[0-9A-F]{2}(?::[0-9A-F]{2})+$/;function _(e,t,n,r){let i=!1,a=()=>{if(i)return;i=!0;let a=e.remoteFingerprint();if(a===void 0){r(`the DTLS layer exposed no remote certificate`);return}let o=a.value.toUpperCase();if(a.algorithm.toLowerCase()!==t.toLowerCase()){r(`the remote certificate was checked with ${a.algorithm}, not ${t}`);return}if(!ie.test(o)){r(`the remote certificate fingerprint is malformed`);return}n(o)},o=e=>{i||(i=!0,r(`the connection ended ${e} before DTLS completed`))};if(e.state===`connected`)return a(),()=>void 0;if(e.state===`failed`||e.state===`closed`)return o(e.state),()=>void 0;let s=e.onStateChange(e=>{if(e===`connected`)a();else if(e===`failed`||e===`closed`)o(e);else return;s()});return s}const ae=e=>(0,d.createRequire)(require("url").pathToFileURL(__filename).href)(e);function oe(e=ae){try{let t=e(`node-datachannel`);if(typeof t?.PeerConnection!=`function`)throw Error(`no PeerConnection export`);return t}catch{throw Error(`WebRTC transport unavailable — the optional dependency "node-datachannel" is not installed or has no prebuilt binary for this platform (${process.platform}-${process.arch}).`)}}function v(e){try{return e?.()}catch{return}}function se(e){return e instanceof Error?e.message:String(e)}const ce={stun:3478,turn:3478,turns:5349};function le(e){let t=/^(stuns?|turns?):([^:?]+|\[[^\]]+\])(?::(\d{1,5}))?(?:\?transport=(udp|tcp))?$/i.exec(e.urls);if(!t)throw Error(`unsupported ICE server url: ${e.urls}`);let n=t[1].toLowerCase(),r=t[2].replace(/^\[|\]$/g,``),i=t[3]===void 0?ce[n]??3478:Number(t[3]);return n===`stun`||n===`stuns`?`stun:${r}:${i}`:{hostname:r,port:i,...e.username===void 0?{}:{username:e.username},...e.credential===void 0?{}:{password:e.credential},relayType:n===`turns`?`TurnTls`:t[4]?.toLowerCase()===`tcp`?`TurnTcp`:`TurnUdp`}}function ue(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}var y=class{native;fault;stateValue;closeCauseValue;closedLocally=!1;messageHandlers=new Set;stateHandlers=new Set;constructor(e,t){this.native=e,this.fault=t,this.stateValue=e.isOpen()?`open`:`connecting`,e.onOpen(()=>this.guard(()=>this.setState(`open`))),e.onClosed(()=>this.guard(()=>this.closedWith(`closed by the peer or the transport`))),e.onError(e=>this.guard(()=>this.closedWith(`error: ${e}`))),e.onMessage(e=>this.guard(()=>{if(this.closedLocally)return;let t=ue(e);for(let e of this.messageHandlers)e(t)}))}guard(e){try{e()}catch(e){this.closeCauseValue??=`handler error: ${se(e)}`,this.fault(e)}}closedWith(e){this.closeCauseValue??=e,this.setState(`closed`)}get closeCause(){return this.closeCauseValue}setState(e){if(this.stateValue!==e&&this.stateValue!==`closed`){this.stateValue=e;for(let t of this.stateHandlers)t(e)}}get readyState(){return this.stateValue}get label(){try{return this.native.getLabel?.()??``}catch{return``}}get bufferedAmount(){try{return this.native.bufferedAmount()}catch{return 0}}send(e){if(this.stateValue!==`open`)throw Error(`data channel is not open`);this.native.sendMessage(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}close(){if(this.stateValue===`closed`)return;this.closedLocally=!0;let e=this.native;setTimeout(()=>{try{e.close()}catch{}},250).unref?.(),this.closedWith(`closed by this side`)}},b=class{native;stateValue=`new`;stateHandlers=new Set;candidateHandlers=new Set;channelHandlers=new Set;descriptionWaiters=[];hasRemoteDescription=!1;history=[];closedBy;handlerError;localCandidateCount=0;remoteCandidateCount=0;heldLocalCandidates=[];earlyCandidates=[];closed=!1;constructor(e={}){let t=(e.loadDataChannel??oe)();this.native=new t.PeerConnection(`agent`,{iceServers:(e.iceServers??[]).map(le),...e.forceTurn===!0?{iceTransportPolicy:`relay`}:{},disableAutoNegotiation:!0}),this.native.onStateChange(e=>this.guard(()=>{if(e!==this.stateValue&&this.stateValue!==`closed`){this.stateValue=e,this.remember(this.stateValue);for(let e of this.stateHandlers)e(this.stateValue)}})),this.native.onLocalCandidate((e,t)=>this.guard(()=>{let n=e.startsWith(`a=`)?e.slice(2):e;if(n.length!==0){if(!this.hasRemoteDescription){this.heldLocalCandidates.push({candidate:n,mid:t});return}this.handOut({candidate:n,mid:t})}})),this.native.onLocalDescription(e=>this.guard(()=>{for(let t of this.descriptionWaiters.splice(0))t(e)})),this.native.onDataChannel(e=>this.guard(()=>{let t=new y(e,e=>this.fault(e));for(let e of this.channelHandlers)e(t)}))}guard(e){try{e()}catch(e){this.fault(e)}}fault(e){this.closed||(this.closedBy=`handler-error`,this.handlerError=se(e),this.close())}remember(e){this.history.length<16&&this.history.push(e)}diagnostics(){let e=v(this.native.iceState?.bind(this.native)),t=v(this.native.gatheringState?.bind(this.native)),n=v(this.native.signalingState?.bind(this.native));return{state:this.stateValue,...e===void 0?{}:{ice:e},...t===void 0?{}:{gathering:t},...n===void 0?{}:{signaling:n},history:[...this.history],...this.closedBy===void 0?{}:{closedBy:this.closedBy},...this.handlerError===void 0?{}:{handlerError:this.handlerError},localCandidates:this.localCandidateCount,remoteCandidates:this.remoteCandidateCount}}get state(){return this.stateValue}createDataChannel(e){return new y(this.native.createDataChannel(e),e=>this.fault(e))}localDescription(e){return new Promise((t,n)=>{this.descriptionWaiters.push(t);try{this.native.setLocalDescription(e)}catch(e){let r=this.descriptionWaiters.indexOf(t);r>=0&&this.descriptionWaiters.splice(r,1),n(e instanceof Error?e:Error(String(e)))}})}createOffer(){return this.localDescription(`offer`)}async acceptOffer(e){return this.native.setRemoteDescription(e,`offer`),this.remoteDescriptionApplied(),this.localDescription(`answer`)}acceptAnswer(e){this.native.setRemoteDescription(e,`answer`),this.remoteDescriptionApplied()}remoteDescriptionApplied(){this.hasRemoteDescription=!0;for(let e of this.earlyCandidates.splice(0))this.addRemoteCandidate(e);let e=this.heldLocalCandidates.splice(0);this.guard(()=>{for(let t of e)this.handOut(t)})}handOut(e){if(!this.closed){this.localCandidateCount+=1;for(let t of this.candidateHandlers)t(e)}}addRemoteCandidate(e){if(!this.closed){if(!this.hasRemoteDescription){this.earlyCandidates.length<64&&this.earlyCandidates.push(e);return}try{this.native.addRemoteCandidate(e.candidate,e.mid),this.remoteCandidateCount+=1}catch{}}}remoteFingerprint(){if(this.stateValue===`connected`)try{let e=this.native.remoteFingerprint();return e.value.length>0?e:void 0}catch{return}}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}onLocalCandidate(e){return this.candidateHandlers.add(e),()=>this.candidateHandlers.delete(e)}onDataChannel(e){return this.channelHandlers.add(e),()=>this.channelHandlers.delete(e)}close(){if(!this.closed){this.closed=!0,this.closedBy??=`local`;try{this.native.close()}catch{}if(this.stateValue!==`closed`){this.stateValue=`closed`,this.remember(`closed`);for(let e of this.stateHandlers)e(`closed`)}}}};function de(e,t){let n=t===`operator-approval`;return e.localPeer!==void 0&&t!==`local-proof`&&t!==`handoff-grant`&&!n?`local-proof`:e.handoffGrant!==void 0&&t!==`handoff-grant`&&!n?`handoff-grant`:e.connectionApproval!==void 0&&!n?`operator-approval`:null}function fe(e){return typeof e==`object`&&!!e&&e.t===`handoff-grant`&&e.grant!==void 0}function x(e){return{admitted:!1,trust:`unproven`,reason:e}}async function pe(e,t){if(t===void 0)return x(`no hand-off grant verifier is configured for this channel`);if(!fe(e))return x(`expected a handoff-grant frame carrying the signed grant`);try{let n=await t.verify(e.grant);return n.admitted&&n.trust===`same-user-same-host`?x(`the grant verifier returned same-user-same-host. A cross-device grant proves the user, not the machine — see SEC-010 for what same-host requires.`):!n.admitted||t.consent===void 0||await t.consent(n)?n:x(`the person at this machine declined the transfer`)}catch(e){return x(`the grant verifier could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function me(e){return{t:`handoff-grant`,grant:e}}function he(e){return typeof e==`object`&&!!e&&e.t===`local-proof`&&typeof e.nonce==`string`}function S(e){return{admitted:!1,trust:`unproven`,reason:e}}function ge(e,t){if(t===void 0)return S(`no local-peer proof is configured for this channel`);if(!he(e))return S(`expected a local-proof frame carrying the rendezvous nonce`);try{return t.redeem(e.nonce)}catch(e){return S(`the rendezvous ledger could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function _e(e){return{t:`local-proof`,nonce:e}}function ve(e,t){try{e.send(t)}catch{}}function ye(e){try{e.close()}catch{}}function be(e,t,n){try{e?.(t,n)}catch{}}const C=Object.freeze({send:ve,close:ye,reportDeliveryError:be});function xe(e,t,n,r,i,a=u.startPairingHandshake){let o=a(e.cryptoContext,{secret:t,role:n,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,send:t=>C.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return o.result.then(r,i),o}function Se(e,t,n,r){let i=(0,u.startHostReconnect)(e.cryptoContext,{hostIdentityId:t.hostIdentityId,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,hostPrivateKey:t.hostPrivateKey,resolveDevicePublicKey:t.resolveDevicePublicKey,send:t=>C.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return i.result.then(n,r),i}function Ce(e){return(0,u.decodePairingFrame)(e).ok}function we(e){return(0,u.decodeReconnectFrame)(e).ok}function Te(e){return(0,u.decodeEnrollFrame)(e).ok}function Ee(e,t,n){let r=e.resumeBridge;if(r)return r.attach(t=>e.channel.send(t),{awaitResume:t,onDeliveryError:n,pendingBytes:()=>e.channel.bufferedAmount}),{onSessionMessage:e=>r.onClientMessage(e),cleanup:()=>r.detach()};let{onMessage:i,cleanup:a}=(e.createHandler??c.createSessionMessageHandler)({session:e.session,deliver:re(e.channel,n),...e.personalUsageReporter?{personalUsageReporter:e.personalUsageReporter}:{},...e.usageReporter?{usageReporter:e.usageReporter}:{},...e.storedSessionUsageReporter?{storedSessionUsageReporter:e.storedSessionUsageReporter}:{},...e.surface?{surface:e.surface}:{},...e.commandSurfaceLocality?{commandSurfaceLocality:e.commandSurfaceLocality}:{}});return{onSessionMessage:i,cleanup:a}}var De=class{options;state;onSessionMessage;handlerCleanup;pairingController;reconnectController;pendingResult;pendingViaReconnect=!1;pendingDeviceId;pendingEnrollment;heldFrames=[];heldChars=0;approvalAbort;constructor(e){this.options=e,e.reconnect?this.state=`awaiting-mode`:(this.state=`pairing`,this.startFirstPair())}onInbound(e){if(this.state===`closed`)return;if(this.state===`accepted`){this.onSessionMessage?.(e);return}if(this.state===`operator-approval`){this.hold(e);return}let t;try{t=JSON.parse(e)}catch{return}if(this.state===`awaiting-mode`){we(t)&&t.t===`rc-hello`?(this.state=`reconnecting`,this.startReconnect(),this.reconnectController?.onFrame(t)):Ce(t)&&t.t===`pair-nonce`&&(this.state=`pairing`,this.startFirstPair(),this.pairingController?.onFrame(t));return}if(this.state===`pairing`){Ce(t)?this.pairingController?.onFrame(t):this.hold(e);return}if(this.state===`reconnecting`){we(t)?this.reconnectController?.onFrame(t):this.hold(e);return}if(this.state===`local-proof`){let e=ge(t,this.options.localPeer);this.options.localPeer?.onAdmission?.(e),e.admitted?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose();return}if(this.state===`handoff-grant`){this.judgeGrantFrame(t);return}if(this.state===`enrolling`){Te(t)?this.completeEnrollment(t.spki):this.hold(e);return}}cleanup(){this.state=`closed`,this.withdrawApproval(),this.handlerCleanup?.(),this.handlerCleanup=void 0,this.onSessionMessage=void 0}onChannelClosed(){this.state!==`accepted`&&this.state!==`closed`&&this.rejectAndClose()}withdrawApproval(){this.heldFrames=[],this.heldChars=0,this.approvalAbort?.abort(),this.approvalAbort=void 0}startFirstPair(){this.pairingController=xe(this.options,this.options.secret,this.options.role,e=>this.onFirstPairAccepted(e),()=>this.rejectAndClose(),this.options.startHandshake??u.startPairingHandshake)}startReconnect(){let e=this.options.reconnect;if(!e){this.rejectAndClose();return}this.reconnectController=Se(this.options,e,e=>{this.pendingDeviceId=e.deviceId,this.accept(void 0,!0)},()=>this.rejectAndClose())}onFirstPairAccepted(e){if(this.state!==`pairing`)return;this.pendingResult=e;let t=this.options.reconnect;if(!t){this.accept(e);return}this.state=`enrolling`,C.send(this.options.channel,JSON.stringify({t:`enroll-key`,spki:t.hostPublicSpki})),this.replayHeld()}completeEnrollment(e){if(this.state===`enrolling`){if(!this.options.reconnect){this.rejectAndClose();return}(async()=>{try{await(0,u.importPublicKey)(e);let t=await(0,u.deriveIdentityId)(e);if(this.state!==`enrolling`)return;this.pendingDeviceId=t,this.pendingEnrollment={deviceId:t,spki:e},this.accept(this.pendingResult)}catch{this.rejectAndClose()}})()}}accept(e,t=!1){if(this.state===`closed`||this.state===`accepted`)return;let n=de(this.options,this.state);if(n!==null){this.pendingResult=e??this.pendingResult,this.pendingViaReconnect=t,this.state=n,n===`operator-approval`&&this.askOperator(),this.replayHeld();return}let r=this.pendingEnrollment;if(this.pendingEnrollment=void 0,r!==void 0)try{this.options.reconnect?.onEnroll(r.deviceId,r.spki)}catch{this.rejectAndClose();return}let i=Ee(this.options,t,(e,t)=>this.handleSessionDeliveryError(e,t));this.onSessionMessage=i.onSessionMessage,this.handlerCleanup=i.cleanup,this.state=`accepted`,this.options.onAccept?.(e);let a=this.heldFrames;this.heldFrames=[],this.heldChars=0;for(let e of a){if(this.state!==`accepted`)return;this.onSessionMessage?.(e)}}replayHeld(){let e=this.heldFrames;this.heldFrames=[],this.heldChars=0;for(let t of e){if(this.state===`closed`)return;this.onInbound(t)}}hold(e){this.heldChars+=e.length,this.heldFrames.push(e),(this.heldFrames.length>32||this.heldChars>262144)&&this.rejectAndClose()}async askOperator(){let e=new AbortController;this.approvalAbort=e;let t={...this.pendingDeviceId===void 0?{}:{deviceId:this.pendingDeviceId},viaReconnect:this.pendingViaReconnect,signal:e.signal},n=!1;try{n=await this.options.connectionApproval?.approve(t)===!0}catch{n=!1}this.state!==`operator-approval`||e.signal.aborted||(this.approvalAbort=void 0,n?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose())}async judgeGrantFrame(e){let t=await pe(e,this.options.handoffGrant);this.state===`handoff-grant`&&(this.options.handoffGrant?.onAdmission?.(t),t.admitted?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose())}rejectAndClose(){this.state!==`closed`&&(this.state=`closed`,this.withdrawApproval(),C.close(this.options.channel),this.options.onReject?.())}handleSessionDeliveryError(e,t){this.state!==`closed`&&(this.state=`closed`,this.handlerCleanup?.(),this.handlerCleanup=void 0,this.onSessionMessage=void 0,C.reportDeliveryError(this.options.onDeliveryError,e,t),C.close(this.options.channel))}};function Oe(e){return Object.assign(Error(`WebRtcTransport ${e}.`),{name:`TransportLifecycleError`,code:e,transportName:`webrtc`})}var ke=class{options;generation=0;paired=!1;dropped=!1;constructor(e){this.options=e}reset(e){this.generation=e,this.paired=!1,this.dropped=!1}accept(e){e===this.generation&&(this.paired=!0)}handleDrop(e){e!==this.generation||!this.paired||this.dropped||(this.dropped=!0,this.options.cleanup(),this.options.onDropped())}handleFailure(e,t,n,r){if(t!==this.generation||this.dropped)return;let i=this.paired;i&&(this.dropped=!0);try{this.options.onDeliveryError(n,r)}catch{}this.options.cleanup();try{e.close()}catch{}i&&this.options.onDropped()}},Ae=class{options;name=`webrtc`;lifecycle=Object.freeze({kind:`service`});defaultEnabled=!1;optionsSchema={};session;peer;unsubscribeSignal;cleanupHandler;generation=0;localFingerprint;pairingGate;offerSent=!1;localCandidates=[];answered=!1;pendingFrames=[];stopAwaitingCertificate;deliveryLifecycle;constructor(e){if(this.options=e,this.deliveryLifecycle=new ke({cleanup:()=>{this.cleanupHandler?.(),this.pairingGate?.cleanup()},onDropped:()=>this.options.onDropped?.(),onDeliveryError:(e,t)=>this.options.onDeliveryError?.(e,t)}),this.options.secret&&this.options.open===!0)throw Error("WebRtcTransport: `secret` and `open: true` are contradictory. A pairing secret gates the data channel; `open` runs without a gate. Pass one.");if(this.options.secret===void 0||this.options.secret===``){if(this.options.open!==!0)throw Error('WebRtcTransport: no pairing `secret` and no explicit `open`. Pass a `secret` to gate the data channel, or `{ open: true, openReason: "…" }` to run without pairing on purpose.');(0,l.resolveAdmission)({open:!0,...this.options.openReason===void 0?{}:{openReason:this.options.openReason}})}}validateOptions(){return!0}attach(e){this.session=e}createPeer(){return new b({...this.options.iceServers?{iceServers:this.options.iceServers}:{},...this.options.forceTurn?{forceTurn:!0}:{},...this.options.loadDataChannel?{loadDataChannel:this.options.loadDataChannel}:{}})}wireSignaling(e,t,n,r){let i=this.options.signaling;e.onLocalCandidate(t=>{r===this.generation&&e===this.peer&&(this.offerSent?this.sendCandidate(t):this.localCandidates.length<64&&this.localCandidates.push(t))});let a=Promise.resolve();this.unsubscribeSignal=i.onSignal(i=>{r===this.generation&&(a=a.then(async()=>{if(r===this.generation&&e===this.peer){if(i.kind===`answer`){if(this.answered)return;this.answered=!0;let a=this.remoteFingerprintAlgorithm(t,i.data);if(this.options.secret&&a===void 0)return;let o=i.data?.sdp;if(typeof o!=`string`)return;e.acceptAnswer(o),a!==void 0&&this.awaitVerifiedCertificate(e,t,n,a,r)}else if(i.kind===`ice`){let t=je(i.data);t!==void 0&&e.addRemoteCandidate(t)}}}).catch(()=>{r===this.generation&&this.failPairing(t)}))})}sendCandidate(e){this.options.signaling.send({kind:`ice`,data:{candidate:e.candidate,sdpMid:e.mid,sdpMLineIndex:0}})}requireCurrentPeer(e,t){if(t!==this.generation||this.peer!==e)throw e.close(),Error(`WebRtcTransport startup was stopped.`)}async start(){let e=this.session;if(!e)throw Oe(`not-attached`);if(this.peer)throw Oe(`already-started`);let t=++this.generation;this.deliveryLifecycle.reset(t),this.answered=!1,this.offerSent=!1,this.localCandidates=[],this.pendingFrames=[];let n=this.createPeer();this.peer=n;let r=this.options.signaling,i=n.createDataChannel(`agent-session`);this.wireChannel(i,e,t),this.wireSignaling(n,i,e,t);let a=await n.createOffer();this.requireCurrentPeer(n,t),this.options.secret&&(this.localFingerprint=(0,u.extractDtlsFingerprint)(a)),r.send({kind:`offer`,data:{type:`offer`,sdp:a}}),this.offerSent=!0;for(let e of this.localCandidates.splice(0))this.sendCandidate(e)}remoteFingerprintAlgorithm(e,t){if(!this.options.secret)return;let n=t.sdp;try{if(typeof n!=`string`)throw Error(`answer carries no SDP`);return(0,u.extractDtlsFingerprintAttribute)(n).algorithm}catch{this.failPairing(e);return}}failPairing(e){e.close(),this.options.onPairingFailed?.()}awaitVerifiedCertificate(e,t,n,r,i){this.stopAwaitingCertificate=_(e,r,e=>{if(i!==this.generation)return;if(t.readyState===`open`){this.startPairing(t,n,e,i);return}let r=t.onStateChange(a=>{a===`open`&&i===this.generation&&(r(),this.startPairing(t,n,e,i))})},()=>{i===this.generation&&this.failPairing(t)})}startPairing(e,t,n,r){let i=this.options.secret;if(!i||!this.localFingerprint)return;this.pairingGate=new De({cryptoContext:this.options.cryptoContext,channel:{send:t=>e.send(t),close:()=>e.close()},session:t,secret:i,role:`initiator`,localFingerprint:this.localFingerprint,remoteFingerprint:n,onAccept:e=>{r===this.generation&&(this.deliveryLifecycle.accept(r),this.options.onPaired?.(e))},...this.options.onPairingFailed?{onReject:this.options.onPairingFailed}:{},...this.options.reconnect?{reconnect:this.options.reconnect}:{},...this.options.localPeer?{localPeer:this.options.localPeer}:{},...this.options.connectionApproval?{connectionApproval:this.options.connectionApproval}:{},...this.options.resumeBridge?{resumeBridge:this.options.resumeBridge}:{},...this.options.personalUsageReporter?{personalUsageReporter:this.options.personalUsageReporter}:{},...this.options.usageReporter?{usageReporter:this.options.usageReporter}:{},...this.options.storedSessionUsageReporter?{storedSessionUsageReporter:this.options.storedSessionUsageReporter}:{},surface:`remote`,commandSurfaceLocality:`remote`,onDeliveryError:(t,n)=>this.deliveryLifecycle.handleFailure(e,r,t,n)});let a=this.pairingGate;for(let e of this.pendingFrames.splice(0))a.onInbound(e)}wireChannel(e,t,n){if(this.options.secret){e.onMessage(e=>{n===this.generation&&(this.pairingGate?this.pairingGate.onInbound(e):this.pendingFrames.length<16&&this.pendingFrames.push(e))}),e.onStateChange(e=>{n===this.generation&&e===`closed`&&(this.pairingGate?.onChannelClosed(),this.deliveryLifecycle.handleDrop(n))}),this.cleanupHandler=()=>this.pairingGate?.cleanup();return}let{onMessage:r,cleanup:i}=(0,c.createSessionMessageHandler)({session:t,deliver:re(e,(t,r)=>this.deliveryLifecycle.handleFailure(e,n,t,r)),...this.options.personalUsageReporter?{personalUsageReporter:this.options.personalUsageReporter}:{},...this.options.usageReporter?{usageReporter:this.options.usageReporter}:{},...this.options.storedSessionUsageReporter?{storedSessionUsageReporter:this.options.storedSessionUsageReporter}:{},surface:`remote`,commandSurfaceLocality:`remote`});this.cleanupHandler=i,e.onMessage(e=>{n===this.generation&&r(e)})}async stop(){this.generation+=1,this.cleanupHandler?.(),this.unsubscribeSignal?.(),this.cleanupHandler=void 0,this.unsubscribeSignal=void 0,this.pairingGate=void 0,this.localFingerprint=void 0,this.answered=!1,this.offerSent=!1,this.localCandidates=[],this.pendingFrames=[],this.stopAwaitingCertificate?.(),this.stopAwaitingCertificate=void 0,this.deliveryLifecycle.reset(this.generation),this.peer&&=(this.peer.close(),void 0),this.session=void 0}};function je(e){if(typeof e!=`object`||!e)return;let t=e;if(typeof t.candidate!=`string`||t.candidate.length===0)return;let n=typeof t.sdpMid==`string`?t.sdpMid:typeof t.sdpMLineIndex==`number`?String(t.sdpMLineIndex):`0`;return{candidate:t.candidate,mid:n}}function Me(){let e=[],t=[],n=!0;function r(e,t){return{send(e){n&&queueMicrotask(()=>{for(let n of t)n(e)})},onSignal(t){return e.push(t),()=>{let n=e.indexOf(t);n>=0&&e.splice(n,1)}},close(){n=!1,e.length=0}}}return[r(e,t),r(t,e)]}const Ne=new Set([`offer`,`answer`,`ice`]);function Pe(e){return new f.default(e)}var Fe=class{options;socket;handlers=[];outbox=[];joined=!1;closed=!1;constructor(e){this.options=e;let t=e.createSocket??Pe;this.socket=t(e.url),this.socket.on(`open`,()=>this.handleOpen()),this.socket.on(`message`,e=>this.handleMessage(e)),this.socket.on(`error`,e=>this.fail(e instanceof Error?e:Error(String(e)))),this.socket.on(`close`,()=>this.handleClose())}handleOpen(){this.socket.send(JSON.stringify({type:`join`,rendezvous:this.options.rendezvous}));for(let e of this.outbox)this.writeSignal(e);this.outbox.length=0}handleMessage(e){let t;try{t=JSON.parse(typeof e==`string`?e:String(e))}catch{return}if(typeof t!=`object`||!t)return;let n=t;if(n.type===`joined`){this.joined=!0,this.options.onReady?.();return}if(n.type===`error`){this.fail(Error(`signaling relay rejected the connection: ${String(n.reason)}`));return}if(n.type===`signal`&&typeof n.kind==`string`&&Ne.has(n.kind)){let e={kind:n.kind,data:n.data};for(let t of this.handlers)t(e)}}handleClose(){this.closed||this.joined||this.fail(Error(`signaling socket closed before the rendezvous was joined`))}fail(e){this.options.onError?.(e)}writeSignal(e){this.socket.send(JSON.stringify({type:`signal`,kind:e.kind,data:e.data}))}send(e){this.closed||(this.socket.readyState===1?this.writeSignal(e):this.outbox.push(e))}onSignal(e){return this.handlers.push(e),()=>{let t=this.handlers.indexOf(e);t>=0&&this.handlers.splice(t,1)}}close(){this.closed=!0,this.handlers.length=0,this.outbox.length=0,this.socket.close()}};const Ie=/^[A-Za-z0-9_-]{22}$/,Le=6e4;function w(e){return typeof e==`string`&&Ie.test(e)}function T(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function Re(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(!(t.v!==1||!w(t.from))){if(t.kind===`hello`)return{v:1,kind:`hello`,from:t.from};if(!(!w(t.to)||!w(t.cid))){if(t.kind===`offer`||t.kind===`answer`)return T(t.sdp,49152)?{v:1,kind:t.kind,from:t.from,to:t.to,cid:t.cid,sdp:t.sdp}:void 0;if(t.kind===`ice`){let e=t.candidate;if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e;return!T(n.candidate,2048)||n.sdpMid!==void 0&&!T(n.sdpMid,64)||n.sdpMLineIndex!==void 0&&!(typeof n.sdpMLineIndex==`number`&&Number.isInteger(n.sdpMLineIndex)&&n.sdpMLineIndex>=0&&n.sdpMLineIndex<64)?void 0:{v:1,kind:`ice`,from:t.from,to:t.to,cid:t.cid,candidate:{candidate:n.candidate,...n.sdpMid===void 0?{}:{sdpMid:n.sdpMid},...n.sdpMLineIndex===void 0?{}:{sdpMLineIndex:n.sdpMLineIndex}}}}}}}function ze(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(!(t.t!==`mesh-msg`||typeof t.body!=`string`||t.body.length>6e4))return{t:`mesh-msg`,body:t.body}}var Be=class extends Error{end;stage;role;peer;channelClose;cause;constructor(e){let t=[`mesh link ended (${e.end}) during ${e.stage} as ${e.role}`];e.detail!==void 0&&t.push(e.detail),e.cause!==void 0&&t.push(e.cause instanceof Error?e.cause.message:String(e.cause));let n=e.peer;n!==void 0&&t.push(`connection ${n.state} [${n.history.join(` > `)}], ice ${n.ice??`?`}, gathering ${n.gathering??`?`}, candidates ${n.localCandidates} sent / ${n.remoteCandidates} applied, closed by ${n.closedBy??`the peer or the network`}${n.handlerError===void 0?``:` (${n.handlerError})`}`),e.channelClose!==void 0&&t.push(`channel ${e.channelClose}`),super(t.join(`; `)),this.name=`MeshLinkEndedError`,this.end=e.end,this.stage=e.stage,this.role=e.role,n!==void 0&&(this.peer=n),e.channelClose!==void 0&&(this.channelClose=e.channelClose),e.cause!==void 0&&(this.cause=e.cause)}};const Ve=`agent-file`,He=JSON.stringify({t:`mesh-admitted`});var Ue=class{options;state=`connecting`;peer;channel;localFingerprint;remoteFingerprint;tookRemoteDescription=!1;creatingPeer=!1;sentDescription=!1;localCandidates=[];remoteCandidates=0;handshake;fedProof=!1;held=[];handlers=new Set;endHandlers=new Set;fileChannels=new Set;fileHandlers=new Set;signalChain=Promise.resolve();stopAwaitingCertificate;timer;admissionResult;constructor(e){this.options=e,this.timer=setTimeout(()=>this.end(`timeout`),e.connectTimeoutMs)}get role(){return this.options.role}get admitted(){return this.state===`admitted`}get ended(){return this.isEnded()}isEnded(){return this.state===`ended`}get admission(){return this.state===`admitted`?this.admissionResult:void 0}get channelBinding(){if(this.state===`admitted`&&this.localFingerprint!==void 0&&this.remoteFingerprint!==void 0)return{localFingerprint:this.localFingerprint,remoteFingerprint:this.remoteFingerprint}}async offer(){if(!(this.options.role!==`offerer`||this.creatingPeer||this.isEnded())){this.creatingPeer=!0;try{let e=await this.createPeer();if(e===void 0)return;this.adoptChannel(e.createDataChannel(`agent-mesh`));let t=await e.createOffer();if(this.isEnded())return;this.localFingerprint=(0,u.extractDtlsFingerprint)(t),this.sendDescription({kind:`offer`,sdp:t})}catch(e){this.end(`signaling`,e)}}}onSignal(e){this.isEnded()||(this.signalChain=this.signalChain.then(()=>this.applySignal(e)).catch(e=>this.end(`signaling`,e)))}async applySignal(e){if(this.isEnded())return;if(e.kind===`ice`){if(!this.tookRemoteDescription||!this.peer||++this.remoteCandidates>64)return;this.peer.addRemoteCandidate({candidate:e.candidate.candidate,mid:e.candidate.sdpMid??String(e.candidate.sdpMLineIndex??0)});return}let t=this.options.role===`offerer`?`answer`:`offer`;if(e.kind!==t||this.tookRemoteDescription)return;this.tookRemoteDescription=!0;let n;try{n=(0,u.extractDtlsFingerprintAttribute)(e.sdp).algorithm}catch(e){this.end(`channel-binding`,e);return}if(this.options.role===`offerer`){let t=this.peer;if(!t)return;t.acceptAnswer(e.sdp),this.awaitCertificate(t,n);return}let r=await this.createPeer();if(r===void 0)return;let i=await r.acceptOffer(e.sdp);this.isEnded()||(this.localFingerprint=(0,u.extractDtlsFingerprint)(i),this.sendDescription({kind:`answer`,sdp:i}),this.awaitCertificate(r,n))}async createPeer(){let e=await this.options.createPeer();if(this.isEnded()){e.close();return}return this.peer=e,e.onLocalCandidate(e=>{if(this.isEnded())return;let t={kind:`ice`,candidate:{candidate:e.candidate,sdpMid:e.mid}};this.sentDescription?this.options.sendSignal(t):this.localCandidates.length<64&&this.localCandidates.push(t)}),e.onStateChange(e=>{(e===`failed`||e===`closed`)&&this.end(`closed`,void 0,`connection ${e}`)}),e.onDataChannel(e=>this.incomingChannel(e)),e}incomingChannel(e){if(this.options.role===`answerer`&&this.channel===void 0&&!this.isEnded()){this.adoptChannel(e);return}if(this.state!==`admitted`||e.label!==Ve||this.fileHandlers.size===0||this.fileChannels.size>=4){e.close();return}this.trackFileChannel(e);for(let t of this.fileHandlers)t(e)}trackFileChannel(e){this.fileChannels.add(e),e.onStateChange(t=>{t===`closed`&&this.fileChannels.delete(e)})}openFileChannel(){let e=this.peer;if(this.state!==`admitted`||e===void 0)return Promise.reject(Error(`mesh link is not admitted`));if(this.fileChannels.size>=4)return Promise.reject(Error(`too many file transfers are open on this link`));let t=e.createDataChannel(Ve);return this.trackFileChannel(t),new Promise((e,n)=>{if(t.readyState===`open`){e(t);return}let r=setTimeout(()=>{i(),t.close(),n(Error(`the file channel did not open`))},1e4),i=t.onStateChange(a=>{a!==`connecting`&&(clearTimeout(r),i(),a===`open`?e(t):n(Error(`the file channel closed before it opened`)))})})}onFileChannel(e){return this.fileHandlers.add(e),()=>this.fileHandlers.delete(e)}sendDescription(e){this.options.sendSignal(e),this.sentDescription=!0;for(let e of this.localCandidates.splice(0))this.options.sendSignal(e)}awaitCertificate(e,t){this.stopAwaitingCertificate=_(e,t,e=>{this.isEnded()||(this.remoteFingerprint=e,this.maybeStartHandshake())},e=>this.end(`channel-binding`,Error(e)))}adoptChannel(e){this.channel=e,e.onMessage(e=>this.inbound(e)),e.onStateChange(e=>{e===`open`?this.maybeStartHandshake():e===`closed`&&this.end(`closed`,void 0,`data channel closed`)}),e.readyState===`open`&&this.maybeStartHandshake()}maybeStartHandshake(){let e=this.channel;if(this.state!==`connecting`||this.handshake!==void 0||e===void 0||this.localFingerprint===void 0||this.remoteFingerprint===void 0||e.readyState!==`open`)return;let t;try{t=this.options.startHandshake({localFingerprint:this.localFingerprint,remoteFingerprint:this.remoteFingerprint,send:e=>this.write(JSON.stringify(e))})}catch(e){this.end(`handshake`,e);return}this.handshake=t,t.result.then(e=>this.confirm(e),e=>this.end(`handshake`,e));let n=this.held.splice(0);for(let e of n)this.feed(e)}inbound(e){if(!this.isEnded()){if(this.state===`admitted`){this.deliver(e);return}if(this.state===`confirming`){this.confirmed(e);return}if(this.handshake===void 0){this.hold(e);return}this.feed(e)}}hold(e){if(this.held.length>=16){this.end(`protocol`);return}this.held.push(e)}feed(e){if(this.fedProof){this.hold(e);return}let t;try{t=JSON.parse(e)}catch{t=e}typeof t==`object`&&t&&t.t===`dh-prove`&&(this.fedProof=!0),this.handshake?.onFrame(t)}confirm(e){if(this.state!==`connecting`)return;if(this.options.accepts!==void 0&&!this.options.accepts(e)){this.end(`handshake`,Error(`the admitted device is not the one this link is for`));return}this.state=`confirming`,this.admissionResult=e,this.write(He);let t=this.held.splice(0);for(let e of t)this.inbound(e)}confirmed(e){let t;try{t=JSON.parse(e)}catch{t=void 0}let n=this.admissionResult;if(n===void 0||typeof t!=`object`||!t||t.t!==`mesh-admitted`){this.end(`protocol`);return}clearTimeout(this.timer),this.state=`admitted`,this.options.onAdmitted(n)}deliver(e){let t;try{t=JSON.parse(e)}catch{t=void 0}let n=ze(t);if(n===void 0){this.end(`protocol`);return}for(let e of this.handlers)e(n.body)}write(e){try{this.channel?.send(e)}catch(e){this.end(`closed`,e)}}send(e){if(this.state!==`admitted`)throw Error(`mesh link is not admitted`);if(e.length>6e4)throw Error(`mesh message exceeds ${Le} characters`);this.write(JSON.stringify({t:`mesh-msg`,body:e}))}onMessage(e){return this.handlers.add(e),()=>this.handlers.delete(e)}onEnd(e){return this.endHandlers.add(e),()=>this.endHandlers.delete(e)}close(){this.end(`closed`,void 0,`closed by this side`)}get stage(){return this.state===`admitted`||this.state===`confirming`?this.state:this.handshake===void 0?this.remoteFingerprint===void 0?this.tookRemoteDescription?`connecting`:`signaling`:`awaiting-channel`:`handshake`}end(e,t,n){if(this.isEnded())return;let r=new Be({end:e,stage:this.stage,role:this.options.role,...n===void 0?{}:{detail:n},...this.peer===void 0?{}:{peer:this.peer.diagnostics()},...this.channel?.closeCause===void 0?{}:{channelClose:this.channel.closeCause},...t===void 0?{}:{cause:t}});this.state=`ended`,clearTimeout(this.timer),this.stopAwaitingCertificate?.(),this.held.length=0,this.handshake?.onFrame(void 0),this.channel?.close();for(let e of this.fileChannels)e.close();this.fileChannels.clear(),this.fileHandlers.clear();let i=this.peer;i&&setTimeout(()=>i.close(),250).unref?.(),this.options.onEnded(e,r);for(let t of this.endHandlers)t(e);this.endHandlers.clear(),this.handlers.clear()}};const E=554869826,D={Binding:1,Allocate:3,Refresh:4,Send:6,Data:7,CreatePermission:8,ChannelBind:9},O={Request:0,Indication:1,Success:2,Error:3},k={MappedAddress:1,Username:6,MessageIntegrity:8,ErrorCode:9,UnknownAttributes:10,ChannelNumber:12,Lifetime:13,XorPeerAddress:18,Data:19,Realm:20,Nonce:21,XorRelayedAddress:22,RequestedAddressFamily:23,EvenPort:24,RequestedTransport:25,DontFragment:26,MessageIntegritySha256:28,PasswordAlgorithm:29,Userhash:30,XorMappedAddress:32,ReservationToken:34,Priority:36,UseCandidate:37,Fingerprint:32808};function We(e,t){return e&15|(e&112)<<1|(e&3968)<<2|(t&1)<<4|(t&2)<<7}function Ge(e){return e.length>=20&&(e[0]&192)==0&&e.readUInt32BE(4)===554869826}function Ke(e){if(!Ge(e))return;let t=e.readUInt16BE(0),n=e.readUInt16BE(2);if(n%4!=0||20+n>e.length)return;let r=t&15|(t&224)>>1|(t&15872)>>2,i=(t&16)>>4|(t&256)>>7,a=[],o=20,s=20+n;for(;o<s;){if(o+4>s)return;let t=e.readUInt16BE(o),n=e.readUInt16BE(o+2);if(o+4+n>s)return;a.push({type:t,value:e.subarray(o+4,o+4+n),offset:o}),o+=4+n+(4-n%4)%4}if(o===s)return{method:r,cls:i,transactionId:Buffer.from(e.subarray(8,20)),attributes:a,raw:e.subarray(0,s)}}function A(e,t){return e.attributes.find(e=>e.type===t)?.value}function qe(e,t){return e.attributes.filter(e=>e.type===t).map(e=>e.value)}function Je(e){let t=e.attributes.findIndex(e=>e.type===k.MessageIntegrity);return t<0?e:{...e,attributes:e.attributes.slice(0,t+1)}}function Ye(e,t){if(e.length<8)return;let n=e[1],r=e.readUInt16BE(2)^E>>>16;if(n===1&&e.length===8){let t=e.readUInt32BE(4)^E;return{address:[t>>>24,t>>>16&255,t>>>8&255,t&255].join(`.`),port:r}}if(n===2&&e.length===20){let n=Buffer.alloc(16);n.writeUInt32BE(E,0),t.copy(n,4);let i=[];for(let t=0;t<16;t+=2)i.push(((e.readUInt16BE(4+t)^n.readUInt16BE(t))&65535).toString(16));return{address:i.join(`:`),port:r}}}function Xe(e){let[t=``,n=``]=e.split(`::`),r=t.length>0?t.split(`:`):[],i=e.includes(`::`)&&n.length>0?n.split(`:`):[],a=e.includes(`::`)?[...r,...Array(8-r.length-i.length).fill(`0`),...i]:r,o=Buffer.alloc(16);return a.forEach((e,t)=>o.writeUInt16BE(parseInt(e,16)&65535,t*2)),o}function j(e,t){let n=(e.port^E>>>16)&65535;if((0,m.isIPv4)(e.address)){let t=Buffer.alloc(8);t[1]=1,t.writeUInt16BE(n,2);let r=e.address.split(`.`).reduce((e,t)=>e<<8|Number(t),0);return t.writeUInt32BE((r^E)>>>0,4),t}if(!(0,m.isIPv6)(e.address))throw Error(`not an IP address: ${e.address}`);let r=Buffer.alloc(20);r[1]=2,r.writeUInt16BE(n,2);let i=Buffer.alloc(16);i.writeUInt32BE(E,0),t.copy(i,4);let a=Xe(e.address);for(let e=0;e<16;e+=1)r[4+e]=a[e]^i[e];return r}function Ze(e,t,n){return(0,p.createHash)(`md5`).update(`${e}:${t}:${n}`,`utf8`).digest()}function Qe(e,t){let n=e.attributes.find(e=>e.type===k.MessageIntegrity);if(n===void 0||n.value.length!==20)return!1;let r=Buffer.from(e.raw.subarray(0,n.offset));return r.writeUInt16BE(n.offset-20+24,2),(0,p.timingSafeEqual)((0,p.createHmac)(`sha1`,t).update(r).digest(),n.value)}const $e=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t+=1){let n=t;for(let e=0;e<8;e+=1)n=n&1?3988292384^n>>>1:n>>>1;e[t]=n>>>0}return e})();function et(e){let t=4294967295;for(let n of e)t=$e[(t^n)&255]^t>>>8;return(t^4294967295)>>>0}function M(e,t,n,r,i={}){let a=[],o=Buffer.alloc(20);o.writeUInt16BE(We(e,t),0),o.writeUInt32BE(E,4),n.copy(o,8,0,12),a.push(o);let s=(e,t)=>{let n=Buffer.alloc(4);n.writeUInt16BE(e,0),n.writeUInt16BE(t.length,2),a.push(n,t,Buffer.alloc((4-t.length%4)%4))};for(let e of r)s(e.type,e.value);let c=()=>Buffer.concat(a);if(i.integrityKey!==void 0){let e=c();e.writeUInt16BE(e.length-20+24,2),s(k.MessageIntegrity,(0,p.createHmac)(`sha1`,i.integrityKey).update(e).digest())}if(i.fingerprint!==!1){let e=c();e.writeUInt16BE(e.length-20+8,2);let t=Buffer.alloc(4);t.writeUInt32BE((et(e)^1398035790)>>>0,0),s(k.Fingerprint,t)}let l=c();if(l.writeUInt16BE(l.length-20,2),l.length>65535)throw Error(`STUN message too large`);return l}function tt(e,t){let n=Buffer.from(t,`utf8`),r=Buffer.alloc(4+n.length);return r[2]=Math.floor(e/100),r[3]=e%100,n.copy(r,4),r}function N(e){let t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),t}function nt(e){return e.length>=4&&(e[0]&192)==64}function rt(e){if(!nt(e))return;let t=e.readUInt16BE(0),n=e.readUInt16BE(2);if(!(4+n>e.length))return{channel:t,payload:e.subarray(4,4+n)}}function it(e,t){let n=Buffer.alloc(4);return n.writeUInt16BE(e,0),n.writeUInt16BE(t.length,2),Buffer.concat([n,t,Buffer.alloc((4-t.length%4)%4)])}const at={allocationsPerOwner:8,totalAllocations:64,bytesPerSecondPerOwner:1024*1024,maxLifetimeSeconds:3600,maxAllocationAgeMs:720*60*1e3,permissionsPerAllocation:32,channelsPerAllocation:32},ot={perSourcePerSecond:10,totalPerSecond:2e3},st=3e5,ct=new Set([k.MappedAddress,k.Username,k.MessageIntegrity,k.ErrorCode,k.ChannelNumber,k.Lifetime,k.XorPeerAddress,k.Data,k.Realm,k.Nonce,k.RequestedAddressFamily,k.RequestedTransport,k.MessageIntegritySha256,k.PasswordAlgorithm,k.XorMappedAddress,k.Priority,k.UseCandidate]);function P(e){return`${e.address}:${e.port}`}function lt(){for(let e of Object.values((0,h.networkInterfaces)()))for(let t of e??[])if(t.family===`IPv4`&&!t.internal)return t.address;return`127.0.0.1`}function ut(e){return e.startsWith(`127.`)||e===`::1`}function dt(e){let[t=0,n=0]=e.split(`.`).map(Number);return t===10||t===172&&n>=16&&n<=31||t===192&&n===168||t===169&&n===254||t===100&&n>=64&&n<=127}function ft(e,t){return n=>{if(!(0,m.isIPv4)(n))return!1;let r=Number(n.split(`.`)[0]);return r===0||r>=224?!1:r===127?e:t||!dt(n)}}async function pt(e,t){let n=(0,te.createSocket)(`udp4`);try{return await new Promise((r,i)=>{n.once(`error`,i),n.bind(e,t,()=>{n.off(`error`,i),r()})}),n}catch(e){try{n.close()}catch{}throw e}}async function F(e,t){try{return await pt(e,t)}catch{return}}function mt(e,t,n){let r=e instanceof Error?e.code:void 0,i=r===`EADDRINUSE`?`the port is taken`:r===`EADDRNOTAVAIL`?`${t} is not an address of this machine`:r===`EACCES`?`port ${n} needs privileges this process does not have`:gt(e).message;return Error(`the TURN relay cannot listen on UDP ${t}:${n}: ${i}`,{cause:e})}function ht(){let e=new Set;for(let t of Object.values((0,h.networkInterfaces)()))for(let n of t??[])e.add(n.address);return e}function I(e,t,n,r=1){let i=Math.max(0,n-e.at);return e.tokens=Math.min(Math.max(t,r),e.tokens+i/1e3*t),e.at=n,e.tokens>=r}function gt(e){return e instanceof Error?e:Error(String(e))}var _t=class e{socket;options;bindHost;relayAddress;allocations=new Map;buckets=new Map;quotas;realm;limits;answerBuckets=new Map;answerBudget;nonceSecret=(0,p.randomBytes)(32);ownAddresses=ht();allowPeer;sweeper;retained;closed=!1;constructor(e,t,n,r){this.socket=e,this.options=t,this.bindHost=n,this.relayAddress=r,this.quotas={...at,...t.quotas},this.realm=t.realm??`r`,this.limits={...ot,...t.unauthenticatedLimits},this.allowPeer=t.allowPeer??ft(ut(r),t.allowPrivatePeers??!0),e.on(`message`,(e,t)=>this.receive(e,t)),e.on(`error`,e=>t.onError?.(e)),this.sweeper=setInterval(()=>this.sweep(),5e3),this.sweeper.unref?.()}static async start(t){let n=Buffer.byteLength(t.realm??`r`);if(n===0||n>4)throw Error(`TURN realm must be 1 to 4 bytes`);let r=t.host??`0.0.0.0`,i=t.port??3478,a;try{a=await pt(i,r)}catch(e){throw mt(e,r,i)}let o=t.relayAddress??(r===`0.0.0.0`?lt():r);return new e(a,t,r,o)}get address(){let e=this.socket.address();return{address:this.bindHost===`0.0.0.0`?this.relayAddress:e.address,port:e.port}}allocationCount(e){if(e===void 0)return this.allocations.size;let t=0;for(let n of this.allocations.values())n.owner===e&&(t+=1);return t}retain(e){this.retained=new Set(e);for(let t of[...this.allocations.values()])e.has(t.owner)||this.remove(t);for(let t of[...this.buckets.keys()])e.has(t)||this.buckets.delete(t)}close(){if(this.closed)return Promise.resolve();this.closed=!0,clearInterval(this.sweeper);for(let e of[...this.allocations.values()])this.remove(e);return new Promise(e=>this.socket.close(()=>e()))}now(){return(this.options.now??Date.now)()}receive(e,t){if(this.closed)return;if(nt(e)){this.fromClientChannel(e,t);return}let n=Ke(e);if(n!==void 0){if(n.cls===O.Indication){n.method===D.Send&&this.fromClientSend(n,t);return}n.cls===O.Request&&this.request(n,t).catch(e=>this.options.onError?.(gt(e)))}}send(e,t){this.closed||this.socket.send(e,t.port,t.address,e=>{e&&this.options.onError?.(e)})}reply(e,t,n,r){let i=M(e.method,O.Success,e.transactionId,n,{...r===void 0?{}:{integrityKey:r}});return this.send(i,t),i}fail(e,t,n,r,i=[],a){let o=M(e.method,O.Error,e.transactionId,[{type:k.ErrorCode,value:tt(n,r)},...i],{...a===void 0?{}:{integrityKey:a}});this.send(o,t)}nonce(e){let t=Buffer.alloc(4);return t.writeUInt32BE(Math.floor(this.now()/1e3)>>>0,0),Buffer.concat([t,this.nonceMac(t,e)]).toString(`base64url`)}nonceMac(e,t){return(0,p.createHmac)(`sha256`,this.nonceSecret).update(e).update(P(t)).digest().subarray(0,8)}nonceValid(e,t){if(!/^[A-Za-z0-9_-]{16}$/.test(e))return!1;let n=Buffer.from(e,`base64url`),r=n.subarray(0,4);if(!(0,p.timingSafeEqual)(n.subarray(4),this.nonceMac(r,t)))return!1;let i=this.now()-r.readUInt32BE(0)*1e3;return i>=-6e4&&i<=6e5}answerUnauthenticated(e,t,n,r){let i=this.now(),a=this.answerBudget??={tokens:this.limits.totalPerSecond,at:i},o=this.answerBuckets.get(t.address)??{tokens:this.limits.perSourcePerSecond,at:i};if(this.answerBuckets.set(t.address,o),e.raw.length<28||!I(o,this.limits.perSourcePerSecond,i)||!I(a,this.limits.totalPerSecond,i))return;let s=M(e.method,n,e.transactionId,r(),{fingerprint:!1});s.length>e.raw.length||(--o.tokens,--a.tokens,this.send(s,t))}refuseUnauthenticated(e,t,n,r=()=>[]){this.answerUnauthenticated(e,t,O.Error,()=>[{type:k.ErrorCode,value:tt(n,``)},...r()])}challenge(e,t,n){this.refuseUnauthenticated(e,t,n,()=>[{type:k.Realm,value:Buffer.from(this.realm)},{type:k.Nonce,value:Buffer.from(this.nonce(t))}])}async authenticate(e,t,n){if(A(e,k.MessageIntegrity)===void 0){this.challenge(e,t,401);return}let r=A(e,k.Username)?.toString(`utf8`),i=A(e,k.Realm)?.toString(`utf8`),a=A(e,k.Nonce)?.toString(`utf8`);if(r===void 0||i===void 0||a===void 0){this.refuseUnauthenticated(e,t,400);return}if(i!==this.realm){this.challenge(e,t,401);return}if(!this.nonceValid(a,t)){this.challenge(e,t,438);return}if(n!==void 0){if(r!==n.username){this.refuseUnauthenticated(e,t,441);return}if(!Qe(e,n.integrityKey)){this.challenge(e,t,401);return}return{auth:{owner:n.owner,password:``},key:n.integrityKey,username:r}}let o;try{o=await this.options.authorize(r)}catch{o=void 0}if(this.closed)return;let s=o===void 0?void 0:Ze(r,this.realm,o.password);if(o===void 0||s===void 0||!Qe(e,s)){this.challenge(e,t,401);return}return{auth:o,key:s,username:r}}unknownAttributes(e){return e.attributes.map(e=>e.type).filter(e=>e<32768&&!ct.has(e))}async request(e,t){let n={address:t.address,port:t.port};if(e.method===D.Binding){this.answerUnauthenticated(e,n,O.Success,()=>[{type:k.XorMappedAddress,value:j(n,e.transactionId)}]);return}if(![D.Allocate,D.Refresh,D.CreatePermission,D.ChannelBind].includes(e.method)){this.refuseUnauthenticated(e,n,400);return}let r=this.allocations.get(P(n)),i=this.live(r)?r:void 0;if(e.method===D.Allocate&&i!==void 0&&i.transactionId.equals(e.transactionId)){i.response.length<=e.raw.length&&this.send(i.response,n);return}let a=await this.authenticate(e,n,i);a!==void 0&&await this.authenticatedRequest(Je(e),n,a)}async authenticatedRequest(e,t,n){let{key:r}=n,i=this.unknownAttributes(e);if(i.length>0){let n=Buffer.alloc(i.length*2);i.forEach((e,t)=>n.writeUInt16BE(e,t*2)),this.fail(e,t,420,`Unknown Attribute`,[{type:k.UnknownAttributes,value:n}],r);return}let a=this.allocations.get(P(t)),o=this.live(a)?a:void 0;if(e.method===D.Allocate){await this.allocate(e,t,n,o);return}if(o===void 0||o.owner!==n.auth.owner){this.fail(e,t,437,`Allocation Mismatch`,[],r);return}e.method===D.Refresh?this.refresh(e,t,o):e.method===D.CreatePermission?this.permit(e,t,o):this.bindChannel(e,t,o)}async allocate(e,t,n,r){let{auth:i,key:a,username:o}=n;if(r!==void 0){this.fail(e,t,437,`Allocation Mismatch`,[],a);return}let s=A(e,k.RequestedTransport);if(s===void 0||s.length!==4){this.fail(e,t,400,`Bad Request`,[],a);return}if(s[0]!==17){this.fail(e,t,442,`Unsupported Transport Protocol`,[],a);return}let c=A(e,k.RequestedAddressFamily);if(c!==void 0&&c[0]!==1){this.fail(e,t,440,`Address Family not Supported`,[],a);return}if(this.retained!==void 0&&!this.retained.has(i.owner)){this.fail(e,t,403,`Forbidden`,[],a);return}if(this.allocations.size>=this.quotas.totalAllocations){this.fail(e,t,508,`Insufficient Capacity`,[],a);return}if(this.allocationCount(i.owner)>=this.quotas.allocationsPerOwner){this.fail(e,t,486,`Allocation Quota Reached`,[],a);return}let l=await this.relayedSocket();if(l===void 0){this.fail(e,t,508,`Insufficient Capacity`,[],a);return}if(!this.closed&&this.retained!==void 0&&!this.retained.has(i.owner)){l.close(),this.fail(e,t,403,`Forbidden`,[],a);return}if(this.closed||this.allocations.has(P(t))||this.allocationCount(i.owner)>=this.quotas.allocationsPerOwner||this.allocations.size>=this.quotas.totalAllocations){l.close(),this.closed||this.fail(e,t,486,`Allocation Quota Reached`,[],a);return}let u=this.now(),d=this.grantedLifetime(e,u,u),f={key:P(t),client:t,owner:i.owner,username:o,integrityKey:a,transactionId:Buffer.from(e.transactionId),socket:l,relayed:{address:this.relayAddress,port:l.address().port},createdAt:u,expiresAt:u+d*1e3,permissions:new Map,channelsByNumber:new Map,channelsByPeer:new Map,response:Buffer.alloc(0)};l.on(`message`,(e,t)=>this.fromPeer(f,e,t)),l.on(`error`,e=>this.options.onError?.(e)),this.allocations.set(f.key,f),f.response=this.reply(e,t,[{type:k.XorRelayedAddress,value:j(f.relayed,e.transactionId)},{type:k.Lifetime,value:N(d)},{type:k.XorMappedAddress,value:j(t,e.transactionId)}],a)}async relayedSocket(){let e=this.options.relayPorts;if(e===void 0)return F(0,this.bindHost);let t=e.max-e.min+1;for(let n=0;n<Math.min(t,8);n+=1){let t=await F((0,p.randomInt)(e.min,e.max+1),this.bindHost);if(t!==void 0)return t}let n=new Set(this.allocationPorts());for(let t=e.min;t<=e.max;t+=1){if(n.has(t))continue;let e=await F(t,this.bindHost);if(e!==void 0)return e}}allocationPorts(){return[...this.allocations.values()].map(e=>e.relayed.port)}isServerItself(e){return e.port===this.socket.address().port&&(ut(e.address)||e.address===this.relayAddress||e.address===this.bindHost||this.bindHost===`0.0.0.0`&&this.ownAddresses.has(e.address))}grantedLifetime(e,t,n){let r=A(e,k.Lifetime),i=r!==void 0&&r.length===4?r.readUInt32BE(0):600,a=Math.floor((t+this.quotas.maxAllocationAgeMs-n)/1e3);return Math.max(0,Math.min(i,this.quotas.maxLifetimeSeconds,a))}refresh(e,t,n){let r=this.now(),i=this.grantedLifetime(e,n.createdAt,r);if(i===0){this.remove(n),this.reply(e,t,[{type:k.Lifetime,value:N(0)}],n.integrityKey);return}n.expiresAt=r+i*1e3,this.reply(e,t,[{type:k.Lifetime,value:N(i)}],n.integrityKey)}peerAddresses(e){let t=[];for(let n of qe(e,k.XorPeerAddress)){let r=Ye(n,e.transactionId);if(r===void 0)return;t.push(r)}return t.length>0?t:void 0}permit(e,t,n){let r=n.integrityKey,i=this.peerAddresses(e);if(i===void 0){this.fail(e,t,400,`Bad Request`,[],r);return}if(i.some(e=>!(0,m.isIPv4)(e.address))){this.fail(e,t,443,`Peer Address Family Mismatch`,[],r);return}if(i.some(e=>!this.allowPeer(e.address))){this.fail(e,t,403,`Forbidden`,[],r);return}let a=new Set(i.map(e=>e.address).filter(e=>!n.permissions.has(e)));if(n.permissions.size+a.size>this.quotas.permissionsPerAllocation){this.fail(e,t,508,`Insufficient Capacity`,[],r);return}let o=this.now()+st;for(let e of i)n.permissions.set(e.address,o);this.reply(e,t,[],r)}bindChannel(e,t,n){let r=n.integrityKey,i=A(e,k.ChannelNumber),a=this.peerAddresses(e),o=i!==void 0&&i.length===4?i.readUInt16BE(0):-1;if(o<16384||o>20479||a===void 0||a.length!==1){this.fail(e,t,400,`Bad Request`,[],r);return}let s=a[0];if(!(0,m.isIPv4)(s.address)){this.fail(e,t,443,`Peer Address Family Mismatch`,[],r);return}if(!this.allowPeer(s.address)){this.fail(e,t,403,`Forbidden`,[],r);return}let c=n.channelsByNumber.get(o),l=n.channelsByPeer.get(P(s));if(c!==void 0&&P(c.peer)!==P(s)||l!==void 0&&l.number!==o){this.fail(e,t,400,`Bad Request`,[],r);return}if(c===void 0&&n.channelsByNumber.size>=this.quotas.channelsPerAllocation||!n.permissions.has(s.address)&&n.permissions.size>=this.quotas.permissionsPerAllocation){this.fail(e,t,508,`Insufficient Capacity`,[],r);return}let u=this.now(),d=c??{number:o,peer:s,expiresAt:0};d.expiresAt=u+6e5,n.channelsByNumber.set(o,d),n.channelsByPeer.set(P(s),d),n.permissions.set(s.address,u+st),this.reply(e,t,[],r)}permitted(e,t){let n=e.permissions.get(t);return n!==void 0&&n>this.now()}spend(e,t){let n=this.now(),r=this.quotas.bytesPerSecondPerOwner,i=this.buckets.get(e)??{tokens:r,at:n};return this.buckets.set(e,i),I(i,r,n,t)?(i.tokens-=t,!0):!1}live(e){return e===void 0?!1:e.expiresAt>this.now()?!0:(this.remove(e),!1)}fromClientSend(e,t){let n=this.allocations.get(P(t));if(!this.live(n))return;let r=A(e,k.XorPeerAddress),i=A(e,k.Data);if(r===void 0||i===void 0)return;let a=Ye(r,e.transactionId);a===void 0||!this.permitted(n,a.address)||this.isServerItself(a)||this.spend(n.owner,i.length)&&n.socket.send(i,a.port,a.address)}fromClientChannel(e,t){let n=this.allocations.get(P(t));if(!this.live(n))return;let r=rt(e);if(r===void 0)return;let i=n.channelsByNumber.get(r.channel);i===void 0||i.expiresAt<=this.now()||this.permitted(n,i.peer.address)&&(this.isServerItself(i.peer)||this.spend(n.owner,r.payload.length)&&n.socket.send(r.payload,i.peer.port,i.peer.address))}fromPeer(e,t,n){if(this.allocations.get(e.key)!==e||!this.live(e)||!this.permitted(e,n.address)||!this.spend(e.owner,t.length))return;let r=e.channelsByPeer.get(P(n));if(r!==void 0&&r.expiresAt>this.now()){this.send(it(r.number,t),e.client);return}let i=(0,p.randomBytes)(12);this.send(M(D.Data,O.Indication,i,[{type:k.XorPeerAddress,value:j({address:n.address,port:n.port},i)},{type:k.Data,value:t}]),e.client)}remove(e){this.allocations.get(e.key)===e&&this.allocations.delete(e.key);try{e.socket.close()}catch{}}sweep(){let e=this.now();for(let[t,n]of this.answerBuckets)Math.abs(e-n.at)>=1e3&&this.answerBuckets.delete(t);for(let t of[...this.allocations.values()]){if(t.expiresAt<=e){this.remove(t);continue}for(let[n,r]of t.permissions)r<=e&&t.permissions.delete(n);for(let[n,r]of t.channelsByNumber)r.expiresAt>e||(t.channelsByNumber.delete(n),t.channelsByPeer.delete(P(r.peer)))}}};const vt=600*1e3,yt=3600*1e3,bt=/^(\d{1,12}):([A-Za-z0-9_-]{22})$/;function xt(e){return Buffer.from(e).toString(`base64url`)}async function St(e,t,n=vt){let r=Math.min(Math.max(n,1e3),yt),i=(await e.tag(`relay-user`,`outbound`,(0,u.rendezvousEpoch)(t))).slice(0,16),a=`${Math.floor((t+r)/1e3)}:${xt(i)}`;return{username:a,credential:await e.relayPassword(`outbound`,a)}}function Ct(e){return`turn:${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}?transport=udp`}async function wt(e,t,n,r){if(t.length===0)return[];let{username:i,credential:a}=await St(e,n,r);return t.map(e=>({urls:Ct(e),username:i,credential:a}))}var L=class extends Error{deviceId;need;constructor(e,t,n){let r=t===`relay-only`?`only relayed connections are allowed`:`no direct path was found (${n?.cause instanceof Error?n.cause.message:String(n?.cause)})`;super(`a relay device is needed to reach device ${e}: ${r}, and no paired device advertises a relay and no TURN server is configured. Run the relay on an always-on device, or configure a TURN server.`,n?.cause===void 0?void 0:{cause:n.cause}),this.name=`MeshRelayNeededError`,this.deviceId=e,this.need=t}},Tt=class e{server;now;peers=[];owners;constructor(e,t){this.server=e,this.now=t}static async start(t={}){let n=t.now??Date.now,r,i=await _t.start({...t.host===void 0?{}:{host:t.host},...t.port===void 0?{}:{port:t.port},...t.relayAddress===void 0?{}:{relayAddress:t.relayAddress},...t.relayPorts===void 0?{}:{relayPorts:t.relayPorts},...t.quotas===void 0?{}:{quotas:t.quotas},...t.allowPeer===void 0?{}:{allowPeer:t.allowPeer},...t.allowPrivatePeers===void 0?{}:{allowPrivatePeers:t.allowPrivatePeers},...t.onError===void 0?{}:{onError:t.onError},now:n,authorize:e=>r===void 0?Promise.resolve(void 0):r.authorize(e)});return r=new e(i,n),r}get endpoint(){let{address:e,port:t}=this.server.address;return{host:e,port:t}}allocationCount(e){return this.server.allocationCount(e)}declarePeers(e){this.peers=[...e],this.server.retain(new Set(e.map(e=>e.deviceId)))}async authorize(e){let t=bt.exec(e);if(t===null)return;let n=this.now(),r=Number(t[1])*1e3;if(r<=n||r-n>366e4)return;let i=(await this.tagOwners((0,u.rendezvousEpoch)(n))).get(t[2]);if(!(i===void 0||!this.peers.some(e=>e.deviceId===i.deviceId)))return{owner:i.deviceId,password:await i.rendezvous.relayPassword(`inbound`,e)}}tagOwners(e){let t=this.owners;if(t!==void 0&&t.epoch===e&&t.peers===this.peers)return t.byTag;let n=this.peers,r=(async()=>{let t=new Map;for(let r of n)for(let n of await r.rendezvous.lookupTags(`relay-user`,e))t.set(xt(n.slice(0,16)),r);return t})();return r.catch(()=>{this.owners?.byTag===r&&(this.owners=void 0)}),this.owners={epoch:e,peers:n,byTag:r},r}close(){return this.peers=[],this.server.close()}};const Et=2e4,Dt=1e3,Ot=3e3,kt=`mesh-lists`,At=`{"t":"${kt}"`;function jt(e){return{send:t=>e.send(t),onFrame:t=>e.onMessage(t),onClose:t=>e.readyState===`closed`?(queueMicrotask(t),()=>void 0):e.onStateChange(e=>{e===`closed`&&t()}),close:()=>e.close()}}var Mt=class{last;waiting;timer;run(e){let t=Date.now();if(this.last===void 0||t-this.last>=Dt){this.last=t,e();return}this.waiting=e,this.timer===void 0&&(this.timer=setTimeout(()=>{this.timer=void 0;let e=this.waiting;this.waiting=void 0,e!==void 0&&this.run(e)},Dt-(t-this.last)),this.timer.unref?.())}cancel(){this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0,this.waiting=void 0}};function Nt(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function R(e,t){return t!==void 0&&t.seq>e.seq&&t.signingKeyId===e.signingKeyId}function Pt(e,t){return e===void 0?t:t===void 0?e:Math.max(e,t)}function Ft(e,t){let n=new Map;for(let r of[e.bySigningKey??{},t.bySigningKey??{}])for(let[e,t]of Object.entries(r)){let r=n.get(e)??{},i=Pt(r.rosterSeq,t.rosterSeq),a=Pt(r.revocationSeq,t.revocationSeq);n.set(e,{...i===void 0?{}:{rosterSeq:i},...a===void 0?{}:{revocationSeq:a}})}let r=Object.fromEntries(n),i=Pt(e.signingKeyRevocationSeq,t.signingKeyRevocationSeq);return{...i===void 0?{}:{signingKeyRevocationSeq:i},bySigningKey:r}}function It(e,t){let n=t.signingKeyCertificate.signingKeyId===e.signingKeyCertificate.signingKeyId;return{...t,...n&&R(t.roster,e.roster)?{roster:e.roster}:{},...n&&R(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Ft(e.marks,t.marks)}}function Lt(e,t){return t.signingKeyCertificate.signingKeyId===e.signingKeyCertificate.signingKeyId?t.roster.seq>e.roster.seq||t.revocation.seq>e.revocation.seq||t.signingKeyRevocation.seq>e.signingKeyRevocation.seq:!1}function Rt(e){if(e.startsWith(At))try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:void 0}catch{return{}}}var zt=class{options;instance=Nt();identity;sessionDescriptor;peers=new Map;byInbound=new Map;linkHandlers=new Set;refusalHandlers=new Set;waiters=new Set;unsubscribes=[];started=!1;stopped=!1;sync=Promise.resolve();constructor(e){this.options=e,this.identity=e.identity,this.sessionDescriptor=e.sessionDescriptor}get deviceId(){return this.identity.deviceCertificate.deviceId}async start(){if(this.started)throw Error(`DeviceMeshNode already started`);this.started=!0,this.unsubscribes.push(this.options.relay.onMessage((e,t)=>this.receive(e,t))),await this.syncPeers()}refresh(e){if(e.sessionDescriptor!==void 0&&(this.sessionDescriptor=e.sessionDescriptor),e.identity===void 0)return Promise.resolve();let t=this.identity;this.identity=It(t,e.identity);let n=this.syncPeers();return Lt(t,this.identity)&&n.then(()=>this.pushLists(),()=>void 0),n}pushLists(){if(this.stopped)return;let{roster:e,revocation:t,signingKeyRevocation:n}=this.identity,r=JSON.stringify({t:kt,roster:e,revocation:t,signingKeyRevocation:n});for(let e of this.peers.values())try{e.admitted?.exposed?.send(r)}catch{}}async receiveLists(e){let t=this.identity,n=(0,u.decodeDeviceRoster)(this.options.cryptoContext,e.roster),r=(0,u.decodeDeviceRevocationList)(this.options.cryptoContext,e.revocation),i=(0,u.decodeSigningKeyRevocation)(this.options.cryptoContext,e.signingKeyRevocation),a={...n.ok&&R(t.roster,n.value)?{roster:n.value}:{},...r.ok&&R(t.revocation,r.value)?{revocation:r.value}:{},...i.ok&&i.value.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:i.value}:{}};if(Object.keys(a).length===0)return;let o=await(0,u.verifyDeviceChain)(this.options.cryptoContext,{masterPublicKey:t.masterPublicKey,signingKeyCert:t.signingKeyCertificate,deviceCert:t.deviceCertificate,roster:a.roster??t.roster,revocation:a.revocation??t.revocation,signingKeyRevocation:a.signingKeyRevocation??t.signingKeyRevocation,now:(this.options.now??Date.now)(),lastSeen:t.marks,required:{roster:!0,revocation:!0,signingKeyRevocation:!0},listExpiryGraceMs:1/0});if(!o.ok||this.stopped)return;let{rosterSeq:s,revocationSeq:c,signingKeyRevocationSeq:l}=o.accepted;this.adoptLists({...a,marks:{...a.signingKeyRevocation!==void 0&&l!==void 0?{signingKeyRevocationSeq:l}:{},bySigningKey:{[o.signingKeyId]:{...a.roster!==void 0&&s!==void 0?{rosterSeq:s}:{},...a.revocation!==void 0&&c!==void 0?{revocationSeq:c}:{}}}}})}syncPeers(){this.sync=this.sync.then(async()=>{if(this.stopped)return;let e=this.identity,t=e.deviceCertificate,n=new Set(e.revocation.revokedDeviceIds),r=new Map;for(let i of e.roster.devices)i.deviceId!==t.deviceId&&!n.has(i.deviceId)&&r.set(i.deviceId,i);for(let[e,t]of this.peers){let n=r.get(e);(n===void 0||n.kaKey!==t.device.kaKey||n.kaEpoch!==t.device.kaEpoch)&&this.drop(t)}let i=[];for(let[n,a]of r){if(this.peers.has(n))continue;let r,o;try{r=await(0,u.derivePairRendezvous)(this.options.cryptoContext,{ownKaPrivateKey:e.kaPrivateKey,own:t,peerDeviceId:n,lists:e}),o=await r.relayInbox()}catch{continue}let s={device:a,role:t.deviceId<a.deviceId?`offerer`:`answerer`,rendezvous:r,inbound:o.inbound,outbound:o.outbound,attempts:new Mt,replies:new Mt,relayFailures:0};this.peers.set(n,s),this.byInbound.set(o.inbound,s),i.push(s)}if(this.stopped)return;this.options.relayServer?.declarePeers([...this.peers.values()].map(e=>({deviceId:e.device.deviceId,rendezvous:e.rendezvous}))),this.options.relay.declarePresence([...this.byInbound.keys()]);let a=this.peerRoutes();this.options.relay.declarePeers?.(a),this.options.relays?.advertised?.(a,AbortSignal.timeout(Ot)).catch(()=>void 0);for(let e of i)this.hello(e)});let e=this.sync;return this.sync=e.catch(()=>void 0),e}drop(e){this.peers.delete(e.device.deviceId),this.byInbound.delete(e.inbound),e.attempts.cancel(),e.replies.cancel();let{pending:t,admitted:n}=e;if(e.pending=void 0,e.admitted=void 0,t?.link.close(),n?.link.close(),t!==void 0&&!this.stopped){let t={deviceId:e.device.deviceId,end:`closed`,error:Error(`peer device was revoked or is no longer in the roster`)};for(let e of this.refusalHandlers)e(t)}}roleFor(e){return this.peers.get(e)?.role}link(e){return this.peers.get(e)?.admitted?.exposed}connect(e,t=Et){if(this.stopped)return Promise.reject(Error(`device mesh node stopped`));let n=this.peers.get(e);if(n===void 0)return Promise.reject(Error(`not a rostered, unrevoked peer device`));let r=n.admitted?.exposed;return r===void 0?new Promise((r,i)=>{let a=()=>{clearTimeout(s),c(),l(),this.waiters.delete(o)},o=e=>{a(),i(e)},s=setTimeout(()=>o(Error(`peer device did not connect in time`)),t);s.unref?.();let c=this.onLink(t=>{t.admission.deviceId===e&&(a(),r(t))}),l=this.onRefusal(t=>{t.deviceId===e&&o(t.error instanceof Error?t.error:Error(`connection ${t.end}`))});this.waiters.add(o),this.hello(n)}):Promise.resolve(r)}onLink(e){return this.linkHandlers.add(e),()=>this.linkHandlers.delete(e)}onRefusal(e){return this.refusalHandlers.add(e),()=>this.refusalHandlers.delete(e)}stop(){if(!this.stopped){this.stopped=!0;for(let e of this.unsubscribes.splice(0))e();for(let e of[...this.peers.values()])this.drop(e);for(let e of[...this.waiters])e(Error(`device mesh node stopped`));this.linkHandlers.clear(),this.refusalHandlers.clear()}}hello(e){this.stopped||this.options.relay.send(e.outbound,{v:1,kind:`hello`,from:this.instance})}receive(e,t){if(this.stopped)return;let n=this.byInbound.get(e);if(n===void 0)return;let r=Re(t);if(r===void 0)return;if(r.kind===`hello`){this.onHello(n,r.from);return}if(r.to!==this.instance)return;if(r.kind===`offer`){this.onOffer(n,r);return}for(let e of[n.pending,n.admitted])if(e?.cid===r.cid&&e.remoteInstance===r.from){e.link.onSignal(z(r));return}let i=n.waitingOffer;r.kind===`ice`&&i?.cid===r.cid&&i.from===r.from&&i.ice.length<64&&i.ice.push(z(r))}serves(e,t){return e.admitted?.remoteInstance===t||e.pending?.remoteInstance===t}onHello(e,t){if(!this.serves(e,t)){if(e.role===`answerer`){e.replies.run(()=>this.hello(e));return}e.attempts.run(()=>{this.stopped||this.peers.get(e.device.deviceId)!==e||this.serves(e,t)||this.startAttempt(e,t,Nt()).link.offer()})}}onOffer(e,t){if(e.role!==`answerer`||e.admitted?.cid===t.cid||e.pending?.cid===t.cid)return;let n={cid:t.cid,from:t.from,ice:[]};e.waitingOffer=n,e.attempts.run(()=>{if(e.waitingOffer===n&&(e.waitingOffer=void 0),this.stopped||this.peers.get(e.device.deviceId)!==e||e.admitted?.cid===t.cid||e.pending?.cid===t.cid)return;let{link:r}=this.startAttempt(e,t.from,t.cid);r.onSignal(z(t));for(let e of n.ice)r.onSignal(e)})}startAttempt(e,t,n){let r=e.pending;e.pending=void 0,r?.link.close();let i=r=>{this.stopped||this.options.relay.send(e.outbound,{v:1,from:this.instance,to:t,cid:n,...r})},a,o=new Ue({role:e.role,createPeer:async()=>{let{stage:t,servers:n}=await this.relayStage(e);return a!==void 0&&(a.relayStage=t),this.createPeer(n)},sendSignal:i,startHandshake:t=>(0,u.startDeviceHandshake)(this.options.cryptoContext,{role:e.role===`offerer`?`initiator`:`responder`,identity:this.identity,sessionDescriptor:this.sessionDescriptor,...e.role===`offerer`?{expectedPeerDeviceId:e.device.deviceId}:{},localFingerprint:t.localFingerprint,remoteFingerprint:t.remoteFingerprint,locality:`another-host`,localPolicy:this.options.localPolicy,send:t.send,...this.options.fetchLatestLists===void 0?{}:{fetchLatestLists:this.options.fetchLatestLists},onListsAdopted:e=>this.adoptLists(e),...this.options.now===void 0?{}:{now:this.options.now},...this.options.handshakeTimeoutMs===void 0?{}:{timeoutMs:this.options.handshakeTimeoutMs}}),connectTimeoutMs:this.options.connectTimeoutMs??Et,accepts:t=>t.admission.deviceId===e.device.deviceId,onAdmitted:t=>this.admitted(e,o,t),onEnded:(t,n)=>this.ended(e,o,t,n)});return a={cid:n,remoteInstance:t,link:o},e.pending=a,a}adoptLists(e){let t=this.identity,n={...t,...R(t.roster,e.roster)?{roster:e.roster}:{},...R(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation!==void 0&&e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Ft(t.marks,e.marks)};this.refresh({identity:n}).catch(()=>void 0),this.options.onListsAdopted?.(e)}admitted(e,t,n){let r=e.pending;if(r===void 0||r.link!==t)return;if(n.admission.deviceId!==e.device.deviceId){t.close();return}let i=n.admission,a=t.channelBinding;if(a===void 0){t.close();return}let o=new ee.ConnectionAuthority({deviceId:i.deviceId,sessionId:i.sessionId,locality:i.locality,capabilities:i.capabilities},this.options.operatorApprover);t.onEnd(()=>o.close());let s=o.authorize(`message`);t.onMessage(e=>{let t=Rt(e);t!==void 0&&this.receiveLists(t).catch(()=>void 0)});let c={admission:i,result:n,channelBinding:a,authority:o,send:e=>t.send(e),onMessage:e=>t.onMessage(n=>{Rt(n)===void 0&&s.then(r=>{r.allowed&&!t.ended?e(n):t.close()})}),openFileChannel:async()=>jt(await t.openFileChannel()),onFileChannel:e=>t.onFileChannel(t=>e(jt(t))),onClose:e=>t.onEnd(()=>e()),close:()=>t.close()};r.exposed=c,e.relayFailures=0;let l=e.admitted;e.admitted=r,e.pending=void 0,l?.link.close(),this.options.relay.confirmPeer?.(i.deviceId);for(let e of this.linkHandlers)e(c)}ended(e,t,n,r){if(e.admitted?.link===t){e.admitted=void 0;return}if(e.pending?.link!==t)return;let i=e.pending.relayStage;e.pending=void 0;let a=r.stage===`connecting`&&(n===`timeout`||r.peer?.state===`failed`)&&r.peer?.history.includes(`connected`)!==!0,o=r;r.cause instanceof L?o=r.cause:a&&i===`direct`?o=new L(e.device.deviceId,`no-direct-path`,{cause:r}):a&&(e.relayFailures+=1);let s={deviceId:e.device.deviceId,end:n,error:o};for(let e of this.refusalHandlers)e(s)}async relayStage(e){let t=this.options.relays,n=[],r=await this.embeddedRelays(e);if(r.length>0&&n.push({stage:`embedded`,servers:r}),t?.configured!==void 0&&t.configured.length>0&&n.push({stage:`configured`,servers:t.configured}),n.length===0){if(t?.relayOnly===!0)throw new L(e.device.deviceId,`relay-only`);return{stage:`direct`,servers:[]}}return n[e.relayFailures%n.length]}peerRoutes(e){let t=[...this.peers.values()];return(e===void 0?t:[e,...t.filter(t=>t!==e)]).map(e=>({deviceId:e.device.deviceId,inbound:e.inbound,outbound:e.outbound,rendezvous:e.rendezvous}))}async embeddedRelays(e){let t=this.options.relays?.advertised;if(t===void 0)return[];let n;try{n=await t(this.peerRoutes(e),AbortSignal.timeout(Ot))}catch{return[]}let r=e.device.deviceId,i=[r,...[...n.keys()].filter(e=>e!==r)],a=(this.options.now??Date.now)(),o=[],s=0;for(let e of i){if(s>=2)break;let t=n.get(e),r=this.peers.get(e);t!==void 0&&t.length!==0&&r!==void 0&&(s+=1,o.push(...await wt(r.rendezvous,t.slice(0,3),a,this.options.relays?.credentialTtlMs)))}return o}createPeer(e){let t=[...this.options.iceServers??[],...e];return new b({...t.length>0?{iceServers:t}:{},...this.options.relays?.relayOnly===!0?{forceTurn:!0}:{},...this.options.loadDataChannel===void 0?{}:{loadDataChannel:this.options.loadDataChannel}})}};function z(e){return e.kind===`ice`?{kind:`ice`,candidate:{...e.candidate}}:{kind:e.kind,sdp:e.sdp}}function Bt(){let e=new Map;return{connect(){let t={messages:new Set,absents:new Set,topics:new Set,open:!0},n=()=>{for(let n of t.topics)e.get(n)===t&&e.delete(n);t.topics=new Set};return{declarePresence(r){if(t.open){n(),t.topics=new Set(r);for(let n of r)e.set(n,t)}},send(n,r){if(!t.open)return;let i=JSON.parse(JSON.stringify(r));queueMicrotask(()=>{let r=e.get(n);if(r===void 0||r===t||!r.open){for(let e of t.absents)e(n);return}for(let e of r.messages)e(n,i)})},onMessage(e){return t.messages.add(e),()=>t.messages.delete(e)},onAbsent(e){return t.absents.add(e),()=>t.absents.delete(e)},close(){t.open=!1,n(),t.messages.clear(),t.absents.clear()}}}}}var Vt=class{options;socket;messages=new Set;absents=new Set;outbox=[];topics;closed=!1;constructor(e){this.options=e;let t=e.createSocket??(e=>new f.default(e));this.socket=t(e.url),this.socket.on(`open`,()=>this.flush()),this.socket.on(`message`,e=>this.receive(e)),this.socket.on(`error`,e=>this.options.onError?.(e instanceof Error?e:Error(String(e)))),this.socket.on(`close`,()=>{this.closed||this.options.onError?.(Error(`signaling relay connection closed`))})}flush(){this.topics!==void 0&&this.write({type:`presence`,topics:this.topics});for(let e of this.outbox.splice(0))this.socket.send(e)}write(e){this.socket.send(JSON.stringify(e))}receive(e){let t;try{t=JSON.parse(typeof e==`string`?e:String(e))}catch{return}if(typeof t!=`object`||!t)return;let n=t;if(n.type===`message`&&typeof n.topic==`string`)for(let e of this.messages)e(n.topic,n.data);else if(n.type===`absent`&&typeof n.topic==`string`)for(let e of this.absents)e(n.topic);else n.type===`present`?this.options.onPresent?.():n.type===`error`&&this.options.onError?.(Error(`signaling relay refused a frame: ${String(n.reason)}`))}declarePresence(e){this.closed||(this.topics=[...e],this.socket.readyState===1&&this.write({type:`presence`,topics:this.topics}))}send(e,t){if(this.closed)return;let n=JSON.stringify({type:`message`,topic:e,data:t});this.socket.readyState===1?this.socket.send(n):this.outbox.length<256?this.outbox.push(n):this.options.onError?.(Error(`signaling relay is not reachable; message dropped`))}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){this.closed=!0,this.messages.clear(),this.absents.clear(),this.outbox.length=0,this.socket.close()}};function Ht(e){return{candidates:t=>Promise.resolve(e.recall(t.deviceId))}}function Ut(e,t){return e.host===t.host&&e.port===t.port}function Wt(e,t){return[{host:t.host,port:t.port},...e.filter(e=>!Ut(e,t))].slice(0,3)}function Gt(){let e=new Map,t;return{recall:t=>e.get(t)??[],remember:(t,n)=>{e.set(t,Wt(e.get(t)??[],n))},retain:t=>{let n=new Set(t);for(let t of[...e.keys()])n.has(t)||e.delete(t)},lastListenPort:()=>t,rememberListenPort:e=>{t=e}}}const Kt=/^[A-Za-z0-9_-]{43}$/,qt=/^[A-Za-z0-9_-]{22}$/,Jt=12e4,Yt=1008;function B(e){return(0,p.createHash)(`sha256`).update(`lan-address:${e}`).digest(`base64url`)}function Xt(e,t){return(0,p.createHmac)(`sha256`,e).update(`lan-present:${t}`).digest(`base64url`)}function Zt(e,t,n){if(typeof n!=`string`)return!1;let r=Buffer.from(Xt(e,t)),i=Buffer.from(n);return i.length===r.length&&(0,p.timingSafeEqual)(i,r)}function Qt(e,t){return new Promise((n,r)=>{let i=new f.WebSocketServer({port:e,...t===void 0?{}:{host:t},maxPayload:65536,perMessageDeflate:!1,verifyClient:e=>e.origin===void 0||e.origin===``}),a=e=>{i.close(),r(e)};i.once(`error`,a),i.once(`listening`,()=>{i.off(`error`,a),n(i)})})}function $t(e){let t;try{t=JSON.parse(String(e))}catch{return}if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;if(!(typeof n.type!=`string`||typeof n.to!=`string`||!Kt.test(n.to)))return n.type===`probe`?typeof n.nonce==`string`&&qt.test(n.nonce)?{type:n.type,to:n.to,nonce:n.nonce}:void 0:{type:n.type,to:n.to,data:n.data}}async function en(e={}){let t;try{t=await Qt(e.port??0,e.host)}catch(n){if(e.port===void 0||e.port===0)throw n;t=await Qt(0,e.host)}let n=t.address(),r=typeof n==`object`&&n?n.port:0,i=new Map,a=new Set;return t.on(`connection`,e=>{if(t.clients.size>32){e.close(Yt);return}let n=0,r=Date.now(),o=setTimeout(()=>e.close(),Jt);o.unref?.(),e.on(`close`,()=>clearTimeout(o)),e.on(`error`,()=>e.close()),e.on(`message`,t=>{let s=Date.now();if(s-r>1e4&&(r=s,n=0),n+=1,n>128){e.close(Yt);return}clearTimeout(o),o=setTimeout(()=>e.close(),Jt),o.unref?.();let c=$t(t);if(c===void 0)return;let l=i.get(c.to);if(l===void 0){e.send(JSON.stringify({type:`absent`,to:c.to}));return}if(c.type===`probe`&&c.nonce!==void 0){e.send(JSON.stringify({type:`present`,to:c.to,nonce:c.nonce,proof:Xt(l,c.nonce)}));return}if(c.type===`message`)for(let e of a)e(l,c.data)})}),{port:r,setPresence(e){i=new Map(e.map(e=>[B(e),e]))},onMessage(e){return a.add(e),()=>a.delete(e)},close(){a.clear(),i=new Map;for(let e of t.clients)e.terminate();return new Promise(e=>t.close(()=>e()))}}}const V=`_rdv._tcp.local`;function tn(){return(0,d.createRequire)(require("url").pathToFileURL(__filename).href)(`multicast-dns`)()}function nn(){let e=[];for(let t of Object.values((0,h.networkInterfaces)()))for(let n of t??[])n.internal||(n.family===`IPv4`||n.family===`IPv6`&&!n.address.startsWith(`fe80`))&&e.push(n.address);return e}function rn(e){let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),Buffer.from(t).toString(`hex`)}function an(e){return Buffer.from(e.subarray(0,16)).toString(`hex`)}function on(e){return Math.max(8,Math.ceil(e/8)*8)}function H(e,t){return e.toLowerCase()===t.toLowerCase()}var sn=class{options;transport;routes=[];port;records;instances=new Set;timer;generation=0;closed=!1;epochCover;announced;lastAnswer;answerTimer;constructor(e={}){this.options=e}now(){return(this.options.now??Date.now)()}open(){if(!this.closed){if(this.transport!==void 0)return this.transport;try{let e=(this.options.createTransport??tn)();return e.on(`query`,e=>this.onQuery(e)),e.on(`error`,e=>this.options.onError?.(e)),this.transport=e,e}catch(e){this.closed=!0,this.options.onError?.(e instanceof Error?e:Error(String(e)));return}}}advertise(e,t){return this.routes=e,this.port=t,this.rebuild()}async rebuild(){let e=++this.generation,t=this.port;if(this.closed||t===void 0)return;let n=(0,u.rendezvousEpoch)(this.now()),r=await Promise.all(this.routes.map(e=>e.rendezvous.tag(`mdns`,`outbound`,n)));if(e!==this.generation||this.closed)return;this.epochCover?.epoch!==n&&(this.epochCover={epoch:n,padding:[],target:`${rn(8)}.local`});let{padding:i,target:a}=this.epochCover,o=on(r.length)-r.length;for(;i.length<o;)i.push(rn(16));let s=[...r.map(an),...i.slice(0,o)].sort(),c=JSON.stringify([n,t,s]),l=s.map(e=>({name:V,type:`PTR`,ttl:120,data:`${e}.${V}`})),d=[];for(let e of s){let n=`${e}.${V}`;d.push({name:n,type:`SRV`,ttl:120,data:{priority:0,weight:0,port:t,target:a}},{name:n,type:`TXT`,ttl:120,data:[]})}for(let e of(this.options.addresses??nn)())d.push({name:a,type:e.includes(`:`)?`AAAA`:`A`,ttl:120,data:e});this.records={answers:l,additionals:d},this.instances=new Set(s.map(e=>`${e}.${V}`.toLowerCase())),this.schedule(n),c!==this.announced&&(this.announced=c,this.open()?.respond(this.records))}schedule(e){this.timer!==void 0&&clearTimeout(this.timer);let t=Math.max(0,(e+1)*u.RENDEZVOUS_EPOCH_MS-this.now());this.timer=setTimeout(()=>{this.rebuild().catch(()=>void 0)},t),this.timer.unref?.()}onQuery(e){this.records===void 0||this.closed||(e.questions??[]).some(e=>H(e.name,`_rdv._tcp.local`)&&(e.type===`PTR`||e.type===`ANY`)||this.instances.has(e.name.toLowerCase()))&&this.answer()}answer(){if(this.answerTimer!==void 0)return;let e=this.options.minAnswerIntervalMs??500,t=this.lastAnswer===void 0?0:this.lastAnswer+e-this.now(),n=()=>{this.answerTimer=void 0,!(this.closed||this.records===void 0)&&(this.lastAnswer=this.now(),this.transport?.respond(this.records))};if(t<=0){n();return}this.answerTimer=setTimeout(n,t),this.answerTimer.unref?.()}async candidates(e,t){let n=this.open();if(n===void 0||t.aborted)return[];let r=(0,u.rendezvousEpoch)(this.now()),i=new Set((await e.rendezvous.lookupTags(`mdns`,r)).map(e=>`${an(e)}.${V}`));return t.aborted||this.closed?[]:new Promise(e=>{let r=[],a,o=()=>{clearTimeout(c),clearTimeout(a),t.removeEventListener(`abort`,o),n.removeListener(`response`,s),e(r)},s=(e,t)=>{let n=[...e.answers??[],...e.additionals??[]];for(let e of n){if(e.type!==`PTR`||!H(e.name,`_rdv._tcp.local`)||typeof e.data!=`string`||!i.has(e.data.toLowerCase()))continue;let a=n.find(t=>t.type===`SRV`&&H(t.name,e.data))?.data?.port;if(typeof a!=`number`||!Number.isInteger(a)||a<=0||a>65535)continue;let o=r.filter(e=>e.host===t.address);r.length<8&&o.length<2&&!o.some(e=>e.port===a)&&r.push({host:t.address,port:a})}r.length!==0&&a===void 0&&(a=setTimeout(o,this.options.answerGraceMs??200),a.unref?.())},c=setTimeout(o,this.options.lookupTimeoutMs??1e3);c.unref?.(),t.addEventListener(`abort`,o,{once:!0}),n.on(`response`,s),n.query({questions:[{name:V,type:`PTR`}]})})}close(){this.closed=!0,this.generation+=1,this.timer!==void 0&&clearTimeout(this.timer),this.answerTimer!==void 0&&clearTimeout(this.answerTimer),this.transport?.destroy(),this.transport=void 0}};function cn(){let e=new Set,t=[],n=(t,n,r)=>{let i=JSON.parse(JSON.stringify(n));queueMicrotask(()=>{for(let n of e)for(let e of r(n))e(i,{address:t.address})})};return{responses:t,transport(r){let i={address:r,queries:new Set,responses:new Set};return e.add(i),{on(e,t){e===`query`&&i.queries.add(t),e===`response`&&i.responses.add(t)},removeListener(e,t){i.responses.delete(t)},query(e){n(i,e,e=>e.queries)},respond(e){t.push(JSON.parse(JSON.stringify(e))),n(i,e,e=>e.responses)},destroy(){e.delete(i)}}}}}var ln=class{until=new Map;failures=new Map;has(e,t){let n=this.until.get(e);return n===void 0?!1:n>t?!0:(this.until.delete(e),!1)}fail(e,t,n){let r=(this.failures.get(e)??0)+1;this.failures.delete(e),this.failures.set(e,r);for(let e of this.failures.keys()){if(this.failures.size<=32)break;this.failures.delete(e),this.until.delete(e)}let i=Math.min(2**(r-1),16);this.until.set(e,t+n*i)}clear(){this.until.clear(),this.failures.clear()}};function un(e){if(typeof e!=`object`||!e)return!1;let t=e.kind;return t===`hello`||t===`offer`||t===`answer`}function dn(e){return`${e.host}:${e.port}`}function fn(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function pn(e){return Buffer.from(e).toString(`base64url`)}function mn(e){return`ws://${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}`}function hn(e){try{let t=JSON.parse(String(e));return typeof t==`object`&&t?t:void 0}catch{return}}var gn=class{options;routes=new Map;byDevice=new Map;lanIn=new Map;messages=new Set;absents=new Set;unsubscribes=[];abort=new AbortController;sync=Promise.resolve();pendingPeers=0;waiting=[];timer;closed=!1;constructor(e){this.options=e;for(let e of this.carriers())this.unsubscribes.push(e.onMessage((e,t)=>this.deliver(e,t)),e.onAbsent(e=>this.absent(e)));this.unsubscribes.push(e.listener.onMessage((e,t)=>{let n=this.lanIn.get(e);n!==void 0&&this.deliver(n,t)}))}now(){return(this.options.now??Date.now)()}carriers(){return[...this.options.signaling??[],...this.options.relay===void 0?[]:[this.options.relay]]}deliver(e,t){if(!this.closed)for(let n of this.messages)n(e,t)}absent(e){if(!this.closed)for(let t of this.absents)t(e)}declarePresence(e){for(let t of this.carriers())t.declarePresence(e)}declarePeers(e){for(let t of this.carriers())t.declarePeers?.(e);this.pendingPeers+=1,this.sync=this.sync.then(()=>this.applyPeers(e)).catch(e=>{this.options.onError?.(e instanceof Error?e:Error(String(e)))}).finally(()=>{if(--this.pendingPeers,!(this.pendingPeers>0))for(let{topic:e,data:t}of this.waiting.splice(0))this.send(e,t)})}async applyPeers(e){if(this.closed)return;let t=(0,u.rendezvousEpoch)(this.now()),n=new Map,r=new Map;for(let i of e){let e=pn(await i.rendezvous.tag(`lan-inbox`,`outbound`,t));for(let e of await i.rendezvous.lookupTags(`lan-inbox`,t))n.set(pn(e),i.inbound);let a=this.routes.get(i.outbound),o=a!==void 0&&a.route.deviceId===i.deviceId?a:{route:i,lanOut:e,path:{kind:`unresolved`},avoid:new ln,avoidCarriers:new ln};o.route=i,o.lanOut=e,r.set(i.outbound,o)}if(!this.closed){for(let[e,t]of this.routes)r.get(e)!==t&&this.reset(t);this.routes.clear(),this.byDevice.clear();for(let[e,t]of r)this.routes.set(e,t),this.byDevice.set(t.route.deviceId,t);this.lanIn=n,this.options.listener.setPresence([...n.keys()]),this.cacheWrite(()=>this.options.cache?.retain(e.map(e=>e.deviceId))),await Promise.all((this.options.advertisers??[]).map(t=>t.advertise(e,this.options.listener.port))),!this.closed&&this.scheduleEpoch(t,e)}}scheduleEpoch(e,t){this.timer!==void 0&&clearTimeout(this.timer);let n=Math.max(0,(e+1)*u.RENDEZVOUS_EPOCH_MS-this.now());this.timer=setTimeout(()=>this.declarePeers(t),n),this.timer.unref?.()}confirmPeer(e){let t=this.byDevice.get(e),n=t?.path;if(!(t===void 0||n?.kind!==`direct`&&n?.kind!==`relay`)){if(clearTimeout(n.deadline),n.deadline=void 0,n.kind===`relay`){t.avoidCarriers.clear();return}t.avoid.clear(),this.cacheWrite(()=>this.options.cache?.remember(e,n.candidate))}}cacheWrite(e){try{e()}catch(e){this.options.onError?.(e instanceof Error?e:Error(String(e)))}}send(e,t){if(this.closed)return;if(this.pendingPeers>0){this.waiting.length<256?this.waiting.push({topic:e,data:t}):this.viaRelay(e,t);return}let n=this.routes.get(e);if(n===void 0){this.viaRelay(e,t);return}let r=n.path;if(r.kind===`direct`&&r.socket.readyState===1){this.sendDirect(n,r,t);return}if(r.kind===`relay`&&this.now()<r.until){this.viaCarrier(n,r,t);return}if(r.kind===`resolving`){r.queue.length<256?r.queue.push(t):this.viaRelay(e,t);return}r.kind===`direct`&&this.reset(n);let i=[t];n.path={kind:`resolving`,queue:i},this.resolve(n,i)}sendDirect(e,t,n){un(n)&&this.armDeadline(e,t),t.socket.send(JSON.stringify({type:`message`,to:B(e.lanOut),data:n}))}viaRelay(e,t){let n=this.carriers().at(-1);if(n===void 0){queueMicrotask(()=>this.absent(e));return}n.send(e,t)}viaCarrier(e,t,n){un(n)&&t.carrier!==this.carriers().at(-1)&&this.armDeadline(e,t),t.carrier.send(e.route.outbound,n)}async resolve(e,t){let n=new Set;for(let r of this.options.sources){if(this.closed||e.path.kind!==`resolving`)return;for(let i of await this.look(r,e.route)){let r=dn(i);if(n.size>=8)break;if(n.has(r)||e.avoid.has(r,this.now()))continue;n.add(r);let a=await this.probe(i,e.lanOut);if(a===void 0)continue;if(this.closed||e.path.kind!==`resolving`||this.routes.get(e.route.outbound)!==e){a.close();return}let o=this.useDirect(e,a,i);for(let n of t)this.sendDirect(e,o,n);return}}if(this.closed||e.path.kind!==`resolving`)return;this.fallBack(e);let r=e.path;for(let n of t)r.kind===`relay`?this.viaCarrier(e,r,n):this.viaRelay(e.route.outbound,n)}fallBack(e){let t=this.now(),n=this.carriers(),r=n.find(n=>!e.avoidCarriers.has(n,t))??n.at(-1);e.path=r===void 0?{kind:`unresolved`}:{kind:`relay`,until:t+this.recheckMs(),carrier:r}}recheckMs(){return this.options.relayRecheckMs??3e4}async look(e,t){let n=AbortSignal.timeout(e.timeoutMs??this.options.sourceTimeoutMs??1500),r=AbortSignal.any([n,this.abort.signal]);try{return await Promise.race([e.candidates(t,r),new Promise(e=>r.addEventListener(`abort`,()=>e([]),{once:!0}))])}catch{return[]}}probe(e,t){let n=B(t),r=fn();return new Promise(i=>{let a;try{a=(this.options.connect??(e=>new f.default(mn(e),{maxPayload:4096})))(e)}catch{i(void 0);return}let o=!1,s=e=>{o||(o=!0,clearTimeout(c),e||a.close(),i(e?a:void 0))},c=setTimeout(()=>s(!1),this.options.probeTimeoutMs??1500);c.unref?.(),a.on(`open`,()=>a.send(JSON.stringify({type:`probe`,to:n,nonce:r}))),a.on(`message`,e=>{let i=hn(e);if(i?.to===n){if(i.type===`absent`){s(!1);return}s(Zt(t,r,i.proof))}}),a.on(`error`,()=>s(!1)),a.on(`close`,()=>s(!1))})}armDeadline(e,t){t.deadline===void 0&&(t.deadline=setTimeout(()=>{e.path===t&&(t.kind===`direct`?e.avoid.fail(dn(t.candidate),this.now(),this.recheckMs()):e.avoidCarriers.fail(t.carrier,this.now(),this.recheckMs()),this.reset(e),this.fallBack(e))},this.options.admissionTimeoutMs??2e4),t.deadline.unref?.())}useDirect(e,t,n){let r={kind:`direct`,socket:t,candidate:n};e.path=r;let i=()=>{e.path===r&&this.reset(e)};return t.on(`close`,i),t.on(`error`,i),t.on(`message`,t=>{let n=hn(t);n?.type===`absent`&&n.to===B(e.lanOut)&&i()}),r}reset(e){let t=e.path;e.path={kind:`unresolved`},t.kind===`relay`&&clearTimeout(t.deadline),t.kind===`direct`&&(clearTimeout(t.deadline),t.socket.close())}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){if(!this.closed){this.closed=!0,this.abort.abort(),this.timer!==void 0&&clearTimeout(this.timer);for(let e of this.unsubscribes.splice(0))e();for(let e of this.routes.values())this.reset(e);this.routes.clear(),this.byDevice.clear(),this.messages.clear(),this.absents.clear(),this.waiting=[];for(let e of this.options.advertisers??[])e.close();this.options.listener.close().catch(()=>void 0)}}};async function _n(e={}){let t=e.cache??Gt(),n=t.lastListenPort(),r=await en({...n===void 0?{}:{port:n},...e.host===void 0?{}:{host:e.host}});try{t.rememberListenPort(r.port)}catch(t){e.onError?.(t instanceof Error?t:Error(String(t)))}let i=e.mdns===!1?void 0:new sn({...e.onError===void 0?{}:{onError:e.onError},...e.mdns}),a=e.internet?.dht,o=e.internet?.signaling??[];return new gn({...e.relay===void 0?{}:{relay:e.relay},...o.length>0?{signaling:o}:{},listener:r,sources:[Ht(t),...i===void 0?[]:[i],...a===void 0?[]:[a]],cache:t,advertisers:[...i===void 0?[]:[i],...a===void 0?[]:[a]],...e.onError===void 0?{}:{onError:e.onError}})}const vn=Uint8Array.from([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),U=new TextEncoder,yn=new TextDecoder;function W(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function bn(e){let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),n=new Uint8Array(t.length);for(let e=0;e<t.length;e+=1)n[e]=t.charCodeAt(e);return n}function G(e){let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t}function xn(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r+=1)n|=e[r]^t[r];return n===0}async function Sn(e){if(e.length!==32)throw Error(`an Ed25519 seed is 32 bytes`);let t=await globalThis.crypto.subtle.importKey(`pkcs8`,W(G([vn,e])),{name:`Ed25519`},!0,[`sign`]),n=await globalThis.crypto.subtle.exportKey(`jwk`,t);if(typeof n.x!=`string`)throw Error(`Ed25519 public key unavailable`);return{publicKey:bn(n.x),sign:async e=>new Uint8Array(await globalThis.crypto.subtle.sign({name:`Ed25519`},t,W(e)))}}async function Cn(e,t,n){if(e.length!==32||n.length!==64)return!1;try{let r=await globalThis.crypto.subtle.importKey(`raw`,W(e),{name:`Ed25519`},!1,[`verify`]);return await globalThis.crypto.subtle.verify({name:`Ed25519`},r,W(n),W(t))}catch{return!1}}function K(e,t,n){let r=[];return e!==void 0&&e.length>0&&r.push(U.encode(`4:salt${e.length}:`),e),r.push(U.encode(`3:seqi${t}e1:v${n.length}:`),n),G(r)}async function wn(e,t,n,r){if(r.length>999)throw Error(`record value exceeds 999 bytes`);if(t!==void 0&&t.length>64)throw Error(`salt exceeds 64 bytes`);if(!Number.isSafeInteger(n)||n<0)throw Error(`seq must be a non-negative integer`);let i=await e.sign(K(t,n,r));return{k:e.publicKey,...t===void 0?{}:{salt:t},seq:n,v:r,sig:i}}async function q(e,t,n){return!xn(e.k,t)||!xn(e.salt??new Uint8Array,n??new Uint8Array)||e.v.length>999||!Number.isSafeInteger(e.seq)||e.seq<0?!1:Cn(t,K(n,e.seq,e.v),e.sig)}const Tn={hints:`bep44-salt`,revocation:`bep44-revocation-salt`};async function J(e){return new Uint8Array(await globalThis.crypto.subtle.digest(`SHA-256`,W(G(e))))}async function En(e,t,n,r,i=0){let[a,o]=await Promise.all([e.signingSeed(n,r,t),e.tag(Tn[t],n,r)]);if(i===0)return{key:await Sn(a),salt:o};let s=U.encode(`chunk`),c=Uint8Array.of(i),[l,u]=await Promise.all([J([s,a,c]),J([s,o,c])]);return{key:await Sn(l),salt:u}}async function Dn(e){let t=U.encode(JSON.stringify(e)),n=(await J([t])).subarray(0,8),r=Math.max(1,Math.ceil(t.length/854));if(r>8)throw Error(`device lists too large to publish as records`);return Array.from({length:r},(e,i)=>{let a=new Uint8Array(864).fill(32);return a[0]=r,a[1]=i,a.set(n,2),a.set(t.subarray(i*854,(i+1)*854),10),a})}function On(e){let t=e[0];if(e.length===864&&e[1]===0)return t!==void 0&&t>=1&&t<=8?t:void 0}function kn(e){let t=e.length,n=e[0]?.subarray(2,10),r=[];for(let[i,a]of e.entries()){if(a.length!==864||a[0]!==t||a[1]!==i||!An(a.subarray(2,10),n))return;r.push(a.subarray(10))}return Y(G(r))}function An(e,t){return t!==void 0&&e.length===t.length&&e.every((e,n)=>e===t[n])}function jn(e,t){let n=U.encode(JSON.stringify(e));if(n.length>t)throw Error(`record does not fit its fixed size`);let r=new Uint8Array(t).fill(32);return r.set(n),r}function Y(e){try{return JSON.parse(yn.decode(e))}catch{return}}function Mn(e,t){let n=[];for(let r of e){if(n.length>=t)break;r.host.length===0||r.host.length>64||n.push([r.host,r.port])}return n}function Nn(e,t=[]){let n=Mn(e,8),r=Mn(t,4);for(;;)try{return jn({v:1,c:n,...r.length>0?{t:r}:{}},640)}catch(e){if(n.length>0)n.pop();else if(r.length>0)r.pop();else throw e}}const Pn=/^[0-9A-Za-z.:%_-]{1,64}$/;function Fn(e){return Ln(e,`c`,8)}function In(e){return Ln(e,`t`,4)}function Ln(e,t,n){let r=Y(e);if(typeof r!=`object`||!r)return[];let i=r,a=i[t];if(i.v!==1||!Array.isArray(a))return[];let o=[];for(let e of a.slice(0,n)){if(!Array.isArray(e)||e.length!==2)continue;let[t,n]=e;typeof t!=`string`||!Pn.test(t)||typeof n!=`number`||!Number.isInteger(n)||n<1||n>65535||o.push({host:t,port:n})}return o}function Rn(e,t=Math.random){let n=t();return Math.floor((Number.isFinite(n)?Math.min(Math.max(n,0),1):0)*Math.max(0,e))}function zn(e){if(typeof e!=`object`||!e)return-1;let t=e.seq;return typeof t==`number`&&Number.isSafeInteger(t)?t:-1}function X(e){return e instanceof Error?e:Error(String(e))}var Bn=class{options;timeoutMs;scheduled=new Map;routes=[];listsFound;prefetchedEpoch;relaysFound=new Map;relayLookups=new Map;closed=!1;constructor(e){this.options=e,this.timeoutMs=e.lookupTimeoutMs??6e3}now(){return(this.options.now??Date.now)()}async candidates(e,t){let n=(0,u.rendezvousEpoch)(this.now()),r=await this.lookup(e,`hints`,n,t);t.aborted||this.rememberRelays(e,n,r);let i=[],a=new Set;for(let e of r.sort((e,t)=>t.epoch-e.epoch))for(let t of Fn(e.data)){let e=`${t.host}:${t.port}`;a.has(e)||(a.add(e),i.push(t))}return i}rememberRelays(e,t,n){let r=[...n].sort((e,t)=>t.epoch-e.epoch)[0],i=r===void 0?[]:In(r.data);this.relaysFound.set(e.deviceId,{epoch:t,checkedAt:this.now(),endpoints:i})}async relayAdverts(e,t){let n=this.now(),r=(0,u.rendezvousEpoch)(n),i=e.slice(0,16),a=[];for(let e of i){let t=this.relaysFound.get(e.deviceId);t!==void 0&&t.epoch===r&&(t.endpoints.length>0||n-t.checkedAt<12e4)||a.push(this.lookUpRelay(e,r))}if(a.length>0){let e=new Promise(e=>{t.aborted&&e(),t.addEventListener(`abort`,()=>e(),{once:!0})});await Promise.race([Promise.all(a),e])}let o=new Set(e.map(e=>e.deviceId));for(let e of[...this.relaysFound.keys()])o.has(e)||this.relaysFound.delete(e);let s=new Map;for(let e of i){let t=this.relaysFound.get(e.deviceId)?.endpoints??[];t.length>0&&s.set(e.deviceId,t)}return s}lookUpRelay(e,t){let n=this.relayLookups.get(e.deviceId);if(n!==void 0)return n;let r=AbortSignal.timeout(this.timeoutMs),i=this.lookup(e,`hints`,t,r).then(n=>{!r.aborted&&!this.closed&&this.rememberRelays(e,t,n)}).finally(()=>this.relayLookups.delete(e.deviceId));return this.relayLookups.set(e.deviceId,i),i}async lookup(e,t,n,r){let i=[n-1,n,n+1].flatMap(n=>this.options.stores.map(async i=>{let a=await this.read(i,e,t,n,0,r);return a===void 0?void 0:{epoch:n,data:a}}));return(await Promise.all(i)).filter(e=>e!==void 0)}async read(e,t,n,r,i,a){try{let o=await En(t.rendezvous,n,`inbound`,r,i),s=await e.get(o.key.publicKey,o.salt,a);if(s===void 0)return;let c=await t.rendezvous.openRecord(s,r,n);return c?.epoch===r?c.hints:void 0}catch{return}}async lookupLists(e,t,n){let r=[t-1,t,t+1].flatMap(t=>this.options.stores.map(async r=>{let i=await this.read(r,e,`revocation`,t,0,n),a=i===void 0?void 0:On(i);if(i===void 0||a===void 0)return;let o=await Promise.all(Array.from({length:a-1},(i,a)=>this.read(r,e,`revocation`,t,a+1,n)));if(!o.some(e=>e===void 0))return kn([i,...o])}));return(await Promise.all(r)).filter(e=>e!==void 0)}advertise(e,t){if(this.closed)return Promise.resolve();this.routes=e;let n=(0,u.rendezvousEpoch)(this.now()),r=new Set(e.map(e=>e.outbound));for(let[e,t]of this.scheduled)r.has(e)||(clearTimeout(t.timer),this.scheduled.delete(e));this.prefetchedEpoch!==n&&(this.prefetchedEpoch=n,this.findLists(AbortSignal.timeout(3e4)));let i=this.options.maxPublishJitterMs??9e4;for(let r of e){let e=this.scheduled.get(r.outbound);if(e!==void 0&&e.epoch===n&&e.port===t)continue;e!==void 0&&clearTimeout(e.timer);let a=setTimeout(()=>{this.scheduled.delete(r.outbound),this.publish(r,t)},Rn(i,this.options.random));a.unref?.(),this.scheduled.set(r.outbound,{timer:a,epoch:n,port:t})}return Promise.resolve()}async publish(e,t){if(this.closed)return;let n=this.now(),r=(0,u.rendezvousEpoch)(n),i=[];try{i.push({purpose:`hints`,chunk:0,plaintext:Nn(this.options.addresses().map(e=>({host:e,port:t})),this.options.relayEndpoints?.()??[])});let e=this.options.lists?.();if(e!==void 0){let t=await Dn({r:e.revocation,...e.signingKeyRevocation===void 0?{}:{s:e.signingKeyRevocation}});for(let[e,n]of t.entries())i.push({purpose:`revocation`,chunk:e,plaintext:n})}}catch(e){this.options.onError?.(X(e))}for(let{purpose:t,chunk:a,plaintext:o}of i)try{let i=await e.rendezvous.sealRecord(o,r,t),s=await En(e.rendezvous,t,`outbound`,r,a),c=await Promise.allSettled(this.options.stores.map(e=>e.put(s,i,n)));for(let e of c)e.status===`rejected`&&this.options.onError?.(X(e.reason))}catch(e){this.options.onError?.(X(e))}}async latestLists(e){let t=new Promise(t=>{e.aborted&&t(void 0),e.addEventListener(`abort`,()=>t(void 0),{once:!0})});return await Promise.race([this.findLists(e),t])??this.listsFound}async findLists(e){let t=(0,u.rendezvousEpoch)(this.now()),n=await Promise.all(this.routes.slice(0,16).map(n=>this.lookupLists(n,t,e))),r=[],i=[];for(let e of n){let t=[],n=[];for(let r of e){if(typeof r!=`object`||!r)continue;let e=r;e.r!==void 0&&t.push(e.r),e.s!==void 0&&n.push(e.s)}r.push(t),i.push(n)}let a=Un(r),o=Un(i),s=a.length===0&&o.length===0?void 0:{...a.length>0?{revocation:a}:{},...o.length>0?{signingKeyRevocation:o}:{}};return e.aborted||(this.listsFound=s),s}close(){if(!this.closed){this.closed=!0;for(let{timer:e}of this.scheduled.values())clearTimeout(e);this.scheduled.clear();for(let e of this.options.stores)e.close()}}};function Vn(e){let t=new Set;return e.filter(e=>{let n=JSON.stringify(e);return t.has(n)?!1:(t.add(n),!0)})}function Hn(e){return Vn(e).sort((e,t)=>zn(t)-zn(e))}function Un(e){let t=e.map(e=>Hn(e).slice(0,2)),n=[];for(let e=0;e<2;e+=1)n.push(...Hn(t.flatMap(t=>t.slice(e,e+1))));return Vn(n).slice(0,16)}function Wn(e){let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}function Gn(){let e=new Map,t=e=>e,n=(e,t)=>`${Wn(e)}/${Wn(t??new Uint8Array)}`;return{store:()=>({async put(t,r,i){let a=await wn(t.key,t.salt,Math.floor(i/1e3),r);if(!await q(a,a.k,a.salt))throw Error(`item refused`);let o=n(a.k,a.salt),s=e.get(o);if(s!==void 0&&s.seq>a.seq)throw Error(`item refused: older seq`);e.set(o,a)},async get(r,i){await Promise.resolve();let a=e.get(n(r,i)),o=a===void 0?void 0:t(a);if(o!==void 0)return await q(o,r,i)?o.v:void 0},close:()=>void 0}),items:()=>[...e.values()],serve:e=>{t=e}}}const Kn=`ybndrfg8ejkmcpqxot1uwisza345h769`;function qn(e){let t=``,n=0,r=0;for(let i of e)for(n=n<<8|i,r+=8;r>=5;)t+=Kn[n>>>r-5&31],r-=5;return r>0&&(t+=Kn[n<<5-r&31]),t}function Z(e){return Uint8Array.from([e>>>8&255,e&255])}function Jn(e,t){let n=G([...[`_r`,qn(e)].flatMap(e=>[Uint8Array.of(e.length),new TextEncoder().encode(e)]),Uint8Array.of(0)]),r=[];for(let e=0;e<t.length;e+=255){let n=t.subarray(e,e+255);r.push(Uint8Array.of(n.length),n)}t.length===0&&r.push(Uint8Array.of(0));let i=G(r);return G([Uint8Array.from([0,0,132,0,0,0,0,1,0,0,0,0]),n,Z(16),Z(1),Uint8Array.from([0,0,1,44]),Z(i.length),i])}function Yn(e){let t=t=>(e[t]??0)<<8|(e[t+1]??0);if(e.length<12)return;let n=t(4),r=t(6),i=12,a=()=>{for(let t=0;t<128;t+=1){let t=e[i];if(t===void 0)return!1;if(t===0)return i+=1,!0;if((t&192)==192)return i+=2,!0;i+=1+t}return!1};for(let e=0;e<n;e+=1){if(!a())return;i+=4}for(let n=0;n<r;n+=1){if(!a()||i+10>e.length)return;let n=t(i),r=t(i+8),o=i+10,s=o+r;if(s>e.length)return;if(n===16){let t=[],n=o;for(;n<s;){let r=e[n];if(n+1+r>s)return;t.push(e.subarray(n+1,n+1+r)),n+=1+r}return G(t)}i=s}}function Xn(e){let t=new Uint8Array(8);return new DataView(t.buffer).setBigUint64(0,BigInt(e)),t}function Zn(e){let t=e.length;for(;t>0&&e[t-1]===`/`;)--t;return e.slice(0,t)}function Qn(e){let t=e.fetch??globalThis.fetch.bind(globalThis),n=(e,t)=>`${Zn(e)}/${qn(t)}`;return{async put(r,i,a,o){let s=Jn(r.key.publicKey,i);if(s.length>999)throw Error(`record too large for a pkarr relay`);let c=Math.floor(a)*1e3,l=G([await r.key.sign(K(void 0,c,s)),Xn(c),s]);if(!(await Promise.allSettled(e.relays.map(async e=>{let i=await t(n(e,r.key.publicKey),{method:`PUT`,headers:{"content-type":`application/pkarr.org/relays#payload`},body:l.slice().buffer,...o===void 0?{}:{signal:o}});if(!i.ok)throw Error(`pkarr relay refused (${i.status})`)}))).some(e=>e.status===`fulfilled`))throw Error(`no pkarr relay took the record`)},async get(r,i,a){let o=await Promise.all(e.relays.map(async e=>{try{let i=await t(n(e,r),{signal:a});if(!i.ok)return;let o=new Uint8Array(await i.arrayBuffer());if(o.length<=72||o.length>1200)return;let s=o.subarray(0,64),c=Number(new DataView(o.buffer,o.byteOffset+64,8).getBigUint64(0)),l=o.slice(72);if(!Number.isSafeInteger(c)||!await Cn(r,K(void 0,c,l),s))return;let u=Yn(l);return u===void 0?void 0:{seq:c,value:u}}catch{return}})),s;for(let e of o)e!==void 0&&(s===void 0||e.seq>s.seq)&&(s=e);return s?.value},close:()=>void 0}}const $n=Uint8Array.from([48,42,48,5,6,3,43,101,112,3,33,0]),er=(e,t,n)=>{if(n.length!==32||e.length!==64)return!1;try{return(0,p.verify)(null,t,(0,p.createPublicKey)({key:Buffer.from(G([$n,n])),format:`der`,type:`spki`}),e)}catch{return!1}};async function tr(e){return new(await(import(`bittorrent-dht`))).default({verify:e})}function Q(e){return Buffer.from(e.buffer,e.byteOffset,e.byteLength)}function nr(e){if(e!==void 0)return new Promise((t,n)=>{e.aborted&&n(Error(`aborted`)),e.addEventListener(`abort`,()=>n(Error(`aborted`)),{once:!0})})}async function rr(e={}){let t=await(e.createDht??tr)(er),n=t=>e.onError?.(t);t.on(`error`,n),t.on(`warning`,n);let r=!1;return{async put(e,n,i,a){if(r)throw Error(`DHT store closed`);if(n.length>999)throw Error(`record value exceeds 999 bytes`);let o=await wn(e.key,e.salt,Math.floor(i/1e3),n),s=new Promise((n,r)=>{t.put({k:Q(o.k),salt:Q(e.salt),seq:o.seq,v:Q(o.v),sig:Q(o.sig)},(e,t,i)=>{e===null?i===0?r(Error(`no DHT node took the record`)):n():r(e)})}),c=nr(a);await(c===void 0?s:Promise.race([s,c]))},async get(e,n,i){if(r||i.aborted)return;let a=(0,p.createHash)(`sha1`).update(G([e,n])).digest(),o=new Promise(e=>{t.get(a,{salt:Q(n),cache:!1},(t,n)=>e(t===null?n:null))});try{let t=await Promise.race([o,nr(i)]);if(t?.v===void 0||t.k===void 0||t.sig===void 0)return;let r={k:new Uint8Array(t.k),salt:n,seq:t.seq??0,v:new Uint8Array(t.v),sig:new Uint8Array(t.sig)};return await q(r,e,n)?r.v:void 0}catch{return}},close(){r||(r=!0,t.destroy())}}}const ir=/^[0-9a-f]{64}$/,ar=/^[0-9a-f]{128}$/;function or(e){return 2e4+((e[0]??0)<<8|(e[1]??0))%1e4}function sr(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function cr(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e+=1)n[e]=t.charCodeAt(e);return n}catch{return}}function lr(e){if(typeof e!=`object`||!e)return;let t=e;if(!(typeof t.id!=`string`||!ir.test(t.id))&&!(typeof t.pubkey!=`string`||!ir.test(t.pubkey))&&!(typeof t.sig!=`string`||!ar.test(t.sig))&&!(typeof t.kind!=`number`||!Number.isInteger(t.kind))&&!(typeof t.created_at!=`number`||!Number.isInteger(t.created_at))&&!(typeof t.content!=`string`||t.content.length>49152)&&!(!Array.isArray(t.tags)||t.tags.length!==0))return{id:t.id,pubkey:t.pubkey,sig:t.sig,kind:t.kind,created_at:t.created_at,content:t.content,tags:[]}}var ur=class{options;messages=new Set;absents=new Set;outbound=new Map;inbound=new Map;subscription;chain=Promise.resolve();seen=new Set;routes=[];epoch;timer;closed=!1;constructor(e){this.options=e}now(){return(this.options.now??Date.now)()}report(e){this.options.onError?.(e instanceof Error?e:Error(String(e)))}enqueue(e){this.chain=this.chain.then(e).catch(e=>this.report(e))}whenIdle(){return this.chain}declarePresence(){}declarePeers(e){this.enqueue(()=>this.derive(e))}async derive(e){if(this.closed)return;this.routes=e;let t=(0,u.rendezvousEpoch)(this.now()),n=new Map,r=new Map;for(let i of e){let e=await i.rendezvous.signingSeed(`outbound`,t,`signal`),a=or(await i.rendezvous.tag(`nostr-kind`,`outbound`,t));n.set(i.outbound,{route:i,epoch:t,secretKey:e,kind:a});for(let e of[t-1,t,t+1]){let t=await i.rendezvous.signingSeed(`inbound`,e,`signal`),n=or(await i.rendezvous.tag(`nostr-kind`,`inbound`,e));r.set((0,g.getPublicKey)(t),{route:i,epoch:e,kind:n})}}this.closed||(this.outbound=n,this.inbound=r,this.epoch=t,this.subscription?.close(),this.subscription=r.size===0?void 0:this.options.pool.subscribe({kinds:[...new Set([...r.values()].map(e=>e.kind))],authors:[...r.keys()],since:Math.floor(this.now()/1e3)-(this.options.maxEventAgeS??120)},e=>this.enqueue(()=>this.receive(e))),this.timer!==void 0&&clearTimeout(this.timer),this.timer=setTimeout(()=>this.declarePeers(this.routes),Math.max(0,(t+1)*u.RENDEZVOUS_EPOCH_MS-this.now())),this.timer.unref?.())}send(e,t){this.closed||this.enqueue(async()=>{if(this.closed)return;this.epoch!==void 0&&(0,u.rendezvousEpoch)(this.now())!==this.epoch&&await this.derive(this.routes);let n=this.outbound.get(e);if(n===void 0){for(let t of this.absents)t(e);return}let r=new TextEncoder().encode(JSON.stringify(t)).length;if(r>32768)throw Error(`signal too large for a Nostr event`);let i=jn(t,Math.ceil(r/512)*512),a=await n.route.rendezvous.sealRecord(i,n.epoch,`signal`),o=(0,g.finalizeEvent)({kind:n.kind,created_at:Math.floor(this.now()/1e3),tags:[],content:sr(a)},n.secretKey);if(!await this.options.pool.publish(o))throw Error(`no Nostr relay took the signal`)})}async receive(e){if(this.closed)return;let t=lr(e);if(t===void 0||this.seen.has(t.id))return;let n=this.inbound.get(t.pubkey);if(n===void 0||t.kind!==n.kind||Math.abs(Math.floor(this.now()/1e3)-t.created_at)>(this.options.maxEventAgeS??120)||!(0,g.verifyEvent)(t))return;this.remember(t.id);let r=cr(t.content);if(r===void 0)return;let i=await n.route.rendezvous.openRecord(r,n.epoch,`signal`);if(i?.epoch!==n.epoch)return;let a=Y(i.hints);if(!(a===void 0||this.closed))for(let e of this.messages)e(n.route.inbound,a)}remember(e){if(this.seen.add(e),this.seen.size<=2048)return;let t=this.seen.values().next().value;t!==void 0&&this.seen.delete(t)}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){this.closed||(this.closed=!0,this.timer!==void 0&&clearTimeout(this.timer),this.subscription?.close(),this.messages.clear(),this.absents.clear(),this.options.pool.close())}};function dr(e,t){return e.kinds.includes(t.kind)&&e.authors.includes(t.pubkey)}function fr(){let e=new Set,t=[],n=t=>{let n=JSON.parse(JSON.stringify(t));queueMicrotask(()=>{for(let t of[...e])dr(t.filter,n)&&t.onEvent(n)})};return{pool:()=>{let r=new Set;return{publish:e=>{let r=lr(e);return r===void 0||!(0,g.verifyEvent)(r)?Promise.resolve(!1):(t.push(JSON.parse(JSON.stringify(e))),n(e),Promise.resolve(!0))},subscribe:(t,n)=>{let i={filter:t,onEvent:n};return e.add(i),r.add(i),{close:()=>{e.delete(i),r.delete(i)}}},close:()=>{for(let t of r)e.delete(t);r.clear()}}},events:t,inject:e=>n(e)}}function pr(e){if(e.length===0)throw Error(`a Nostr relay pool needs at least one relay`);let t=new ne.SimplePool,n=[...e];return{publish:async e=>(await Promise.allSettled(t.publish(n,e))).some(e=>e.status===`fulfilled`),subscribe:(e,r)=>t.subscribeMany(n,{kinds:[...e.kinds],authors:[...e.authors],...e.since===void 0?{}:{since:e.since}},{onevent:e=>r(e)}),close:()=>t.destroy()}}const mr=[`wss://relay.damus.io`,`wss://nos.lol`,`wss://relay.primal.net`],hr=[`https://pkarr.pubky.app`,`https://pkarr.pubky.org`,`https://dns.iroh.link/pkarr`],gr=/^[A-Za-z0-9_-]{22}$/;var $=class extends Error{reason;constructor(e,t){super(`enrollment connection failed (${e})${t===void 0?``:`: ${t}`}`),this.name=`EnrollmentLinkError`,this.reason=e}};function _r(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function vr(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(t.v!==1||typeof t.cid!=`string`||!gr.test(t.cid))return;let n=t.cid;if(t.kind===`offer`||t.kind===`answer`)return _r(t.sdp,49152)?{kind:t.kind,cid:n,sdp:t.sdp}:void 0;if(t.kind===`ice`){let e=t.candidate;if(typeof e!=`object`||!e||Array.isArray(e))return;let r=e;return!_r(r.candidate,2048)||!_r(r.mid,64)?void 0:{kind:`ice`,cid:n,candidate:{candidate:r.candidate,mid:r.mid}}}}function yr(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}var br=class{role;cid;options;onBound;onFailed;peer;channel;localFingerprint;remoteFingerprint;tookRemoteDescription=!1;sentDescription=!1;localCandidates=[];remoteCandidates=0;chain=Promise.resolve();stopAwaiting;timer;done=!1;early=[];frameHandlers=new Set;closeHandlers=new Set;constructor(e,t,n,r,i){this.role=e,this.cid=t,this.options=n,this.onBound=r,this.onFailed=i,this.timer=setTimeout(()=>this.fail(new $(`timeout`)),n.connectTimeoutMs??2e4)}async offer(){try{let e=this.createPeer();this.adopt(e.createDataChannel(`agent-enroll`));let t=await e.createOffer();if(this.done)return;this.localFingerprint=(0,u.extractDtlsFingerprint)(t),this.sendDescription({kind:`offer`,cid:this.cid,sdp:t})}catch(e){this.fail(new $(`signaling`,xr(e)))}}onSignal(e){this.done||(this.chain=this.chain.then(()=>this.apply(e)).catch(e=>this.fail(new $(`signaling`,xr(e)))))}async apply(e){if(this.done)return;if(e.kind===`ice`){if(this.peer===void 0||++this.remoteCandidates>64)return;this.peer.addRemoteCandidate(e.candidate);return}let t=this.role===`offerer`?`answer`:`offer`;if(e.kind!==t||this.tookRemoteDescription)return;this.tookRemoteDescription=!0;let n;try{n=(0,u.extractDtlsFingerprintAttribute)(e.sdp).algorithm}catch(e){this.fail(new $(`channel-binding`,xr(e)));return}if(this.role===`offerer`){let t=this.peer;if(t===void 0)return;t.acceptAnswer(e.sdp),this.awaitCertificate(t,n);return}let r=this.createPeer(),i=await r.acceptOffer(e.sdp);this.done||(this.localFingerprint=(0,u.extractDtlsFingerprint)(i),this.sendDescription({kind:`answer`,cid:this.cid,sdp:i}),this.awaitCertificate(r,n))}createPeer(){let e=new b({...this.options.iceServers===void 0?{}:{iceServers:this.options.iceServers},...this.options.loadDataChannel===void 0?{}:{loadDataChannel:this.options.loadDataChannel}});return this.peer=e,e.onLocalCandidate(e=>{if(this.done)return;let t={kind:`ice`,cid:this.cid,candidate:{candidate:e.candidate,mid:e.mid}};this.sentDescription?this.send(t):this.localCandidates.length<64&&this.localCandidates.push(t)}),e.onStateChange(e=>{(e===`failed`||e===`closed`)&&this.fail(new $(`closed`,`connection ${e}`))}),e.onDataChannel(e=>{this.role===`answerer`&&this.channel===void 0&&!this.done?this.adopt(e):e.close()}),e}send(e){this.options.relay.send(this.options.outbound,{v:1,...e})}sendDescription(e){this.send(e),this.sentDescription=!0;for(let e of this.localCandidates.splice(0))this.send(e)}awaitCertificate(e,t){this.stopAwaiting=_(e,t,e=>{this.remoteFingerprint=e,this.maybeBound()},e=>this.fail(new $(`channel-binding`,e)))}adopt(e){this.channel=e,e.onMessage(e=>this.inbound(e)),e.onStateChange(e=>{e===`open`?this.maybeBound():e===`closed`&&this.closed()}),e.readyState===`open`&&this.maybeBound()}inbound(e){if(e.length>262144){this.closeAll();return}if(this.frameHandlers.size===0){if(this.early.length>=16){this.closeAll();return}this.early.push(e);return}this.deliver(e)}deliver(e){let t;try{t=JSON.parse(e)}catch{t=void 0}for(let e of this.frameHandlers)e(t)}maybeBound(){let e=this.channel;if(this.done||e===void 0||e.readyState!==`open`)return;let t=this.localFingerprint,n=this.remoteFingerprint;t!==void 0&&n!==void 0&&(this.done=!0,clearTimeout(this.timer),this.stopAwaiting?.(),this.onBound({localFingerprint:t,remoteFingerprint:n,send:t=>{try{e.send(JSON.stringify(t))}catch{}},onFrame:e=>{this.frameHandlers.add(e);let t=this.early.splice(0);return t.length>0&&queueMicrotask(()=>t.forEach(e=>this.deliver(e))),()=>this.frameHandlers.delete(e)},onClose:t=>e.readyState===`closed`?(queueMicrotask(t),()=>void 0):(this.closeHandlers.add(t),()=>this.closeHandlers.delete(t)),close:()=>this.closeAll()}))}closed(){if(!this.done){this.fail(new $(`closed`,`data channel closed`));return}this.closeAll()}closeAll(){this.channel?.close();let e=this.peer;e!==void 0&&setTimeout(()=>e.close(),250).unref?.();let t=[...this.closeHandlers];this.closeHandlers.clear(),this.frameHandlers.clear();for(let e of t)e()}fail(e){this.done||(this.done=!0,clearTimeout(this.timer),this.stopAwaiting?.(),this.channel?.close(),this.peer?.close(),this.onFailed(e))}};function xr(e){return e instanceof Error?e.message:String(e)}function Sr(e){return new Promise((t,n)=>{let r=[],i=()=>{for(let e of r.splice(0))e()},a=new br(`offerer`,yr(),e,e=>{i(),t(e)},e=>{i(),n(e)});r.push(e.relay.onMessage((t,n)=>{if(t!==e.inbound)return;let r=vr(n);r!==void 0&&r.cid===a.cid&&a.onSignal(r)}),e.relay.onAbsent(t=>{t===e.outbound&&a.fail(new $(`absent`))})),e.relay.declarePresence([e.inbound]),a.offer()})}function Cr(e){let t,n=!1,r=e.relay.onMessage((r,i)=>{if(n||r!==e.inbound)return;let a=vr(i);if(a===void 0)return;if(t!==void 0){a.cid===t.cid&&t.onSignal(a);return}if(a.kind!==`offer`)return;let o=new br(`answerer`,a.cid,e,r=>{if(n){r.close();return}r.onClose(()=>{t===o&&(t=void 0)}),e.onChannel(r)},n=>{t===o&&(t=void 0),e.onAttemptFailed?.(n)});t=o,o.onSignal(a)});return e.relay.declarePresence([e.inbound]),{close:()=>{n||(n=!0,r(),t?.fail(new $(`closed`,`no longer listening`)))}}}exports.DEFAULT_MAX_PUBLISH_JITTER_MS=9e4,exports.DEFAULT_NOSTR_RELAYS=mr,exports.DEFAULT_PKARR_RELAYS=hr,exports.DEFAULT_RELAY_CREDENTIAL_TTL_MS=vt,exports.DEFAULT_TURN_QUOTAS=at,exports.DEFAULT_UNAUTHENTICATED_LIMITS=ot,exports.DeviceMeshNode=zt,exports.DiscoveringMeshRelay=gn,exports.EnrollmentLinkError=$,exports.MAX_CACHED_CANDIDATES=3,exports.MAX_MESH_MESSAGE_CHARS=Le,exports.MAX_RELAY_CREDENTIAL_TTL_MS=yt,exports.MESH_MDNS_SERVICE=V,exports.MeshDht=Bn,exports.MeshLinkEndedError=Be,exports.MeshMdns=sn,exports.MeshRelayNeededError=L,exports.MeshTurnRelay=Tt,exports.NostrMeshRelay=ur,exports.RtcChannel=y,exports.RtcPeer=b,exports.TurnServer=_t,exports.WebRtcTransport=Ae,exports.WsMeshRelayClient=Vt,exports.WsSignalingClient=Fe,exports.addressCacheSource=Ht,exports.createInMemoryItemNetwork=Gn,exports.createInMemoryMdnsBus=cn,exports.createInMemoryMeshAddressCache=Gt,exports.createInMemoryMeshRelayHub=Bt,exports.createInMemoryNostrHub=fr,exports.createInMemorySignalingPair=Me,exports.createNostrRelayPool=pr,exports.createPkarrRelayStore=Qn,exports.dialEnrollment=Sr,exports.handoffGrantFrame=me,exports.judgeHandoffGrant=pe,exports.listenForEnrollment=Cr,exports.loadDataChannel=oe,exports.localInterfaceAddresses=nn,exports.localProofFrame=_e,exports.meshRelayCredential=St,exports.meshRelayIceServers=wt,exports.paddedInstanceCount=on,exports.startLanMeshRelay=_n,exports.startMainlineDhtStore=rr,exports.startMeshLanListener=en;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("@robota-sdk/agent-transport"),l=require("@robota-sdk/agent-transport/node"),u=require("@robota-sdk/agent-remote-pairing"),d=require("node:module"),f=require("ws");f=s(f,1);let ee=require("@robota-sdk/agent-interface-session-mobility"),p=require("node:crypto"),te=require("node:dgram"),m=require("node:net"),h=require("node:os"),ne=require("nostr-tools/pool"),g=require("nostr-tools/pure");function re(e,t){return(0,c.createOutboundDelivery)(t=>e.send(JSON.stringify(t)),(e,n)=>t(e,n),()=>e.bufferedAmount)}const ie=/^[0-9A-F]{2}(?::[0-9A-F]{2})+$/;function _(e,t,n,r){let i=!1,a=()=>{if(i)return;i=!0;let a=e.remoteFingerprint();if(a===void 0){r(`the DTLS layer exposed no remote certificate`);return}let o=a.value.toUpperCase();if(a.algorithm.toLowerCase()!==t.toLowerCase()){r(`the remote certificate was checked with ${a.algorithm}, not ${t}`);return}if(!ie.test(o)){r(`the remote certificate fingerprint is malformed`);return}n(o)},o=e=>{i||(i=!0,r(`the connection ended ${e} before DTLS completed`))};if(e.state===`connected`)return a(),()=>void 0;if(e.state===`failed`||e.state===`closed`)return o(e.state),()=>void 0;let s=e.onStateChange(e=>{if(e===`connected`)a();else if(e===`failed`||e===`closed`)o(e);else return;s()});return s}const ae=e=>(0,d.createRequire)(require("url").pathToFileURL(__filename).href)(e);function oe(e=ae){try{let t=e(`node-datachannel`);if(typeof t?.PeerConnection!=`function`)throw Error(`no PeerConnection export`);return t}catch{throw Error(`WebRTC transport unavailable — the optional dependency "node-datachannel" is not installed or has no prebuilt binary for this platform (${process.platform}-${process.arch}).`)}}function v(e){try{return e?.()}catch{return}}function se(e){return e instanceof Error?e.message:String(e)}const ce={stun:3478,turn:3478,turns:5349};function le(e){let t=/^(stuns?|turns?):([^:?]+|\[[^\]]+\])(?::(\d{1,5}))?(?:\?transport=(udp|tcp))?$/i.exec(e.urls);if(!t)throw Error(`unsupported ICE server url: ${e.urls}`);let n=t[1].toLowerCase(),r=t[2].replace(/^\[|\]$/g,``),i=t[3]===void 0?ce[n]??3478:Number(t[3]);return n===`stun`||n===`stuns`?`stun:${r}:${i}`:{hostname:r,port:i,...e.username===void 0?{}:{username:e.username},...e.credential===void 0?{}:{password:e.credential},relayType:n===`turns`?`TurnTls`:t[4]?.toLowerCase()===`tcp`?`TurnTcp`:`TurnUdp`}}function ue(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}var y=class{native;fault;stateValue;closeCauseValue;closedLocally=!1;messageHandlers=new Set;stateHandlers=new Set;constructor(e,t){this.native=e,this.fault=t,this.stateValue=e.isOpen()?`open`:`connecting`,e.onOpen(()=>this.guard(()=>this.setState(`open`))),e.onClosed(()=>this.guard(()=>this.closedWith(`closed by the peer or the transport`))),e.onError(e=>this.guard(()=>this.closedWith(`error: ${e}`))),e.onMessage(e=>this.guard(()=>{if(this.closedLocally)return;let t=ue(e);for(let e of this.messageHandlers)e(t)}))}guard(e){try{e()}catch(e){this.closeCauseValue??=`handler error: ${se(e)}`,this.fault(e)}}closedWith(e){this.closeCauseValue??=e,this.setState(`closed`)}get closeCause(){return this.closeCauseValue}setState(e){if(this.stateValue!==e&&this.stateValue!==`closed`){this.stateValue=e;for(let t of this.stateHandlers)t(e)}}get readyState(){return this.stateValue}get label(){try{return this.native.getLabel?.()??``}catch{return``}}get bufferedAmount(){try{return this.native.bufferedAmount()}catch{return 0}}send(e){if(this.stateValue!==`open`)throw Error(`data channel is not open`);this.native.sendMessage(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}close(){if(this.stateValue===`closed`)return;this.closedLocally=!0;let e=this.native;setTimeout(()=>{try{e.close()}catch{}},250).unref?.(),this.closedWith(`closed by this side`)}},b=class{native;stateValue=`new`;stateHandlers=new Set;candidateHandlers=new Set;channelHandlers=new Set;descriptionWaiters=[];hasRemoteDescription=!1;history=[];closedBy;handlerError;localCandidateCount=0;remoteCandidateCount=0;heldLocalCandidates=[];earlyCandidates=[];closed=!1;constructor(e={}){let t=(e.loadDataChannel??oe)();this.native=new t.PeerConnection(`agent`,{iceServers:(e.iceServers??[]).map(le),...e.forceTurn===!0?{iceTransportPolicy:`relay`}:{},disableAutoNegotiation:!0}),this.native.onStateChange(e=>this.guard(()=>{if(e!==this.stateValue&&this.stateValue!==`closed`){this.stateValue=e,this.remember(this.stateValue);for(let e of this.stateHandlers)e(this.stateValue)}})),this.native.onLocalCandidate((e,t)=>this.guard(()=>{let n=e.startsWith(`a=`)?e.slice(2):e;if(n.length!==0){if(!this.hasRemoteDescription){this.heldLocalCandidates.push({candidate:n,mid:t});return}this.handOut({candidate:n,mid:t})}})),this.native.onLocalDescription(e=>this.guard(()=>{for(let t of this.descriptionWaiters.splice(0))t(e)})),this.native.onDataChannel(e=>this.guard(()=>{let t=new y(e,e=>this.fault(e));for(let e of this.channelHandlers)e(t)}))}guard(e){try{e()}catch(e){this.fault(e)}}fault(e){this.closed||(this.closedBy=`handler-error`,this.handlerError=se(e),this.close())}remember(e){this.history.length<16&&this.history.push(e)}diagnostics(){let e=v(this.native.iceState?.bind(this.native)),t=v(this.native.gatheringState?.bind(this.native)),n=v(this.native.signalingState?.bind(this.native));return{state:this.stateValue,...e===void 0?{}:{ice:e},...t===void 0?{}:{gathering:t},...n===void 0?{}:{signaling:n},history:[...this.history],...this.closedBy===void 0?{}:{closedBy:this.closedBy},...this.handlerError===void 0?{}:{handlerError:this.handlerError},localCandidates:this.localCandidateCount,remoteCandidates:this.remoteCandidateCount}}get state(){return this.stateValue}createDataChannel(e){return new y(this.native.createDataChannel(e),e=>this.fault(e))}localDescription(e){return new Promise((t,n)=>{this.descriptionWaiters.push(t);try{this.native.setLocalDescription(e)}catch(e){let r=this.descriptionWaiters.indexOf(t);r>=0&&this.descriptionWaiters.splice(r,1),n(e instanceof Error?e:Error(String(e)))}})}createOffer(){return this.localDescription(`offer`)}async acceptOffer(e){return this.native.setRemoteDescription(e,`offer`),this.remoteDescriptionApplied(),this.localDescription(`answer`)}acceptAnswer(e){this.native.setRemoteDescription(e,`answer`),this.remoteDescriptionApplied()}remoteDescriptionApplied(){this.hasRemoteDescription=!0;for(let e of this.earlyCandidates.splice(0))this.addRemoteCandidate(e);let e=this.heldLocalCandidates.splice(0);this.guard(()=>{for(let t of e)this.handOut(t)})}handOut(e){if(!this.closed){this.localCandidateCount+=1;for(let t of this.candidateHandlers)t(e)}}addRemoteCandidate(e){if(!this.closed){if(!this.hasRemoteDescription){this.earlyCandidates.length<64&&this.earlyCandidates.push(e);return}try{this.native.addRemoteCandidate(e.candidate,e.mid),this.remoteCandidateCount+=1}catch{}}}remoteFingerprint(){if(this.stateValue===`connected`)try{let e=this.native.remoteFingerprint();return e.value.length>0?e:void 0}catch{return}}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}onLocalCandidate(e){return this.candidateHandlers.add(e),()=>this.candidateHandlers.delete(e)}onDataChannel(e){return this.channelHandlers.add(e),()=>this.channelHandlers.delete(e)}close(){if(!this.closed){this.closed=!0,this.closedBy??=`local`;try{this.native.close()}catch{}if(this.stateValue!==`closed`){this.stateValue=`closed`,this.remember(`closed`);for(let e of this.stateHandlers)e(`closed`)}}}};function de(e,t){let n=t===`operator-approval`;return e.localPeer!==void 0&&t!==`local-proof`&&t!==`handoff-grant`&&!n?`local-proof`:e.handoffGrant!==void 0&&t!==`handoff-grant`&&!n?`handoff-grant`:e.connectionApproval!==void 0&&!n?`operator-approval`:null}function fe(e){return typeof e==`object`&&!!e&&e.t===`handoff-grant`&&e.grant!==void 0}function x(e){return{admitted:!1,trust:`unproven`,reason:e}}async function pe(e,t){if(t===void 0)return x(`no hand-off grant verifier is configured for this channel`);if(!fe(e))return x(`expected a handoff-grant frame carrying the signed grant`);try{let n=await t.verify(e.grant);return n.admitted&&n.trust===`same-user-same-host`?x(`the grant verifier returned same-user-same-host. A cross-device grant proves the user, not the machine — see SEC-010 for what same-host requires.`):!n.admitted||t.consent===void 0||await t.consent(n)?n:x(`the person at this machine declined the transfer`)}catch(e){return x(`the grant verifier could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function me(e){return{t:`handoff-grant`,grant:e}}function he(e){return typeof e==`object`&&!!e&&e.t===`local-proof`&&typeof e.nonce==`string`}function S(e){return{admitted:!1,trust:`unproven`,reason:e}}function ge(e,t){if(t===void 0)return S(`no local-peer proof is configured for this channel`);if(!he(e))return S(`expected a local-proof frame carrying the rendezvous nonce`);try{return t.redeem(e.nonce)}catch(e){return S(`the rendezvous ledger could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function _e(e){return{t:`local-proof`,nonce:e}}function ve(e,t){try{e.send(t)}catch{}}function ye(e){try{e.close()}catch{}}function be(e,t,n){try{e?.(t,n)}catch{}}const C=Object.freeze({send:ve,close:ye,reportDeliveryError:be});function xe(e,t,n,r,i,a=u.startPairingHandshake){let o=a(e.cryptoContext,{secret:t,role:n,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,send:t=>C.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return o.result.then(r,i),o}function Se(e,t,n,r){let i=(0,u.startHostReconnect)(e.cryptoContext,{hostIdentityId:t.hostIdentityId,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,hostPrivateKey:t.hostPrivateKey,resolveDevicePublicKey:t.resolveDevicePublicKey,send:t=>C.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return i.result.then(n,r),i}function Ce(e){return(0,u.decodePairingFrame)(e).ok}function we(e){return(0,u.decodeReconnectFrame)(e).ok}function Te(e){return(0,u.decodeEnrollFrame)(e).ok}function Ee(e,t,n){let r=e.resumeBridge;if(r)return r.attach(t=>e.channel.send(t),{awaitResume:t,onDeliveryError:n,pendingBytes:()=>e.channel.bufferedAmount}),{onSessionMessage:e=>r.onClientMessage(e),cleanup:()=>r.detach()};let{onMessage:i,cleanup:a}=(e.createHandler??c.createSessionMessageHandler)({session:e.session,deliver:re(e.channel,n),maxFrameBytes:c.HISTORY_PAGE_MAX_BYTES,...e.personalUsageReporter?{personalUsageReporter:e.personalUsageReporter}:{},...e.usageReporter?{usageReporter:e.usageReporter}:{},...e.storedSessionUsageReporter?{storedSessionUsageReporter:e.storedSessionUsageReporter}:{},...e.surface?{surface:e.surface}:{},...e.commandSurfaceLocality?{commandSurfaceLocality:e.commandSurfaceLocality}:{}});return{onSessionMessage:i,cleanup:a}}var De=class{options;state;onSessionMessage;handlerCleanup;pairingController;reconnectController;pendingResult;pendingViaReconnect=!1;pendingDeviceId;pendingEnrollment;heldFrames=[];heldChars=0;approvalAbort;constructor(e){this.options=e,e.reconnect?this.state=`awaiting-mode`:(this.state=`pairing`,this.startFirstPair())}onInbound(e){if(this.state===`closed`)return;if(this.state===`accepted`){this.onSessionMessage?.(e);return}if(this.state===`operator-approval`){this.hold(e);return}let t;try{t=JSON.parse(e)}catch{return}if(this.state===`awaiting-mode`){we(t)&&t.t===`rc-hello`?(this.state=`reconnecting`,this.startReconnect(),this.reconnectController?.onFrame(t)):Ce(t)&&t.t===`pair-nonce`&&(this.state=`pairing`,this.startFirstPair(),this.pairingController?.onFrame(t));return}if(this.state===`pairing`){Ce(t)?this.pairingController?.onFrame(t):this.hold(e);return}if(this.state===`reconnecting`){we(t)?this.reconnectController?.onFrame(t):this.hold(e);return}if(this.state===`local-proof`){let e=ge(t,this.options.localPeer);this.options.localPeer?.onAdmission?.(e),e.admitted?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose();return}if(this.state===`handoff-grant`){this.judgeGrantFrame(t);return}if(this.state===`enrolling`){Te(t)?this.completeEnrollment(t.spki):this.hold(e);return}}cleanup(){this.state=`closed`,this.withdrawApproval(),this.handlerCleanup?.(),this.handlerCleanup=void 0,this.onSessionMessage=void 0}onChannelClosed(){this.state!==`accepted`&&this.state!==`closed`&&this.rejectAndClose()}withdrawApproval(){this.heldFrames=[],this.heldChars=0,this.approvalAbort?.abort(),this.approvalAbort=void 0}startFirstPair(){this.pairingController=xe(this.options,this.options.secret,this.options.role,e=>this.onFirstPairAccepted(e),()=>this.rejectAndClose(),this.options.startHandshake??u.startPairingHandshake)}startReconnect(){let e=this.options.reconnect;if(!e){this.rejectAndClose();return}this.reconnectController=Se(this.options,e,e=>{this.pendingDeviceId=e.deviceId,this.accept(void 0,!0)},()=>this.rejectAndClose())}onFirstPairAccepted(e){if(this.state!==`pairing`)return;this.pendingResult=e;let t=this.options.reconnect;if(!t){this.accept(e);return}this.state=`enrolling`,C.send(this.options.channel,JSON.stringify({t:`enroll-key`,spki:t.hostPublicSpki})),this.replayHeld()}completeEnrollment(e){if(this.state===`enrolling`){if(!this.options.reconnect){this.rejectAndClose();return}(async()=>{try{await(0,u.importPublicKey)(e);let t=await(0,u.deriveIdentityId)(e);if(this.state!==`enrolling`)return;this.pendingDeviceId=t,this.pendingEnrollment={deviceId:t,spki:e},this.accept(this.pendingResult)}catch{this.rejectAndClose()}})()}}accept(e,t=!1){if(this.state===`closed`||this.state===`accepted`)return;let n=de(this.options,this.state);if(n!==null){this.pendingResult=e??this.pendingResult,this.pendingViaReconnect=t,this.state=n,n===`operator-approval`&&this.askOperator(),this.replayHeld();return}let r=this.pendingEnrollment;if(this.pendingEnrollment=void 0,r!==void 0)try{this.options.reconnect?.onEnroll(r.deviceId,r.spki)}catch{this.rejectAndClose();return}let i=Ee(this.options,t,(e,t)=>this.handleSessionDeliveryError(e,t));this.onSessionMessage=i.onSessionMessage,this.handlerCleanup=i.cleanup,this.state=`accepted`,this.options.onAccept?.(e);let a=this.heldFrames;this.heldFrames=[],this.heldChars=0;for(let e of a){if(this.state!==`accepted`)return;this.onSessionMessage?.(e)}}replayHeld(){let e=this.heldFrames;this.heldFrames=[],this.heldChars=0;for(let t of e){if(this.state===`closed`)return;this.onInbound(t)}}hold(e){this.heldChars+=e.length,this.heldFrames.push(e),(this.heldFrames.length>32||this.heldChars>262144)&&this.rejectAndClose()}async askOperator(){let e=new AbortController;this.approvalAbort=e;let t={...this.pendingDeviceId===void 0?{}:{deviceId:this.pendingDeviceId},viaReconnect:this.pendingViaReconnect,signal:e.signal},n=!1;try{n=await this.options.connectionApproval?.approve(t)===!0}catch{n=!1}this.state!==`operator-approval`||e.signal.aborted||(this.approvalAbort=void 0,n?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose())}async judgeGrantFrame(e){let t=await pe(e,this.options.handoffGrant);this.state===`handoff-grant`&&(this.options.handoffGrant?.onAdmission?.(t),t.admitted?this.accept(this.pendingResult,this.pendingViaReconnect):this.rejectAndClose())}rejectAndClose(){this.state!==`closed`&&(this.state=`closed`,this.withdrawApproval(),C.close(this.options.channel),this.options.onReject?.())}handleSessionDeliveryError(e,t){this.state!==`closed`&&(this.state=`closed`,this.handlerCleanup?.(),this.handlerCleanup=void 0,this.onSessionMessage=void 0,C.reportDeliveryError(this.options.onDeliveryError,e,t),C.close(this.options.channel))}};function Oe(e){return Object.assign(Error(`WebRtcTransport ${e}.`),{name:`TransportLifecycleError`,code:e,transportName:`webrtc`})}var ke=class{options;generation=0;paired=!1;dropped=!1;constructor(e){this.options=e}reset(e){this.generation=e,this.paired=!1,this.dropped=!1}accept(e){e===this.generation&&(this.paired=!0)}handleDrop(e){e!==this.generation||!this.paired||this.dropped||(this.dropped=!0,this.options.cleanup(),this.options.onDropped())}handleFailure(e,t,n,r){if(t!==this.generation||this.dropped)return;let i=this.paired;i&&(this.dropped=!0);try{this.options.onDeliveryError(n,r)}catch{}this.options.cleanup();try{e.close()}catch{}i&&this.options.onDropped()}},Ae=class{options;name=`webrtc`;lifecycle=Object.freeze({kind:`service`});defaultEnabled=!1;optionsSchema={};session;peer;unsubscribeSignal;cleanupHandler;generation=0;localFingerprint;pairingGate;offerSent=!1;localCandidates=[];answered=!1;pendingFrames=[];stopAwaitingCertificate;deliveryLifecycle;constructor(e){if(this.options=e,this.deliveryLifecycle=new ke({cleanup:()=>{this.cleanupHandler?.(),this.pairingGate?.cleanup()},onDropped:()=>this.options.onDropped?.(),onDeliveryError:(e,t)=>this.options.onDeliveryError?.(e,t)}),this.options.secret&&this.options.open===!0)throw Error("WebRtcTransport: `secret` and `open: true` are contradictory. A pairing secret gates the data channel; `open` runs without a gate. Pass one.");if(this.options.secret===void 0||this.options.secret===``){if(this.options.open!==!0)throw Error('WebRtcTransport: no pairing `secret` and no explicit `open`. Pass a `secret` to gate the data channel, or `{ open: true, openReason: "…" }` to run without pairing on purpose.');(0,l.resolveAdmission)({open:!0,...this.options.openReason===void 0?{}:{openReason:this.options.openReason}})}}validateOptions(){return!0}attach(e){this.session=e}createPeer(){return new b({...this.options.iceServers?{iceServers:this.options.iceServers}:{},...this.options.forceTurn?{forceTurn:!0}:{},...this.options.loadDataChannel?{loadDataChannel:this.options.loadDataChannel}:{}})}wireSignaling(e,t,n,r){let i=this.options.signaling;e.onLocalCandidate(t=>{r===this.generation&&e===this.peer&&(this.offerSent?this.sendCandidate(t):this.localCandidates.length<64&&this.localCandidates.push(t))});let a=Promise.resolve();this.unsubscribeSignal=i.onSignal(i=>{r===this.generation&&(a=a.then(async()=>{if(r===this.generation&&e===this.peer){if(i.kind===`answer`){if(this.answered)return;this.answered=!0;let a=this.remoteFingerprintAlgorithm(t,i.data);if(this.options.secret&&a===void 0)return;let o=i.data?.sdp;if(typeof o!=`string`)return;e.acceptAnswer(o),a!==void 0&&this.awaitVerifiedCertificate(e,t,n,a,r)}else if(i.kind===`ice`){let t=je(i.data);t!==void 0&&e.addRemoteCandidate(t)}}}).catch(()=>{r===this.generation&&this.failPairing(t)}))})}sendCandidate(e){this.options.signaling.send({kind:`ice`,data:{candidate:e.candidate,sdpMid:e.mid,sdpMLineIndex:0}})}requireCurrentPeer(e,t){if(t!==this.generation||this.peer!==e)throw e.close(),Error(`WebRtcTransport startup was stopped.`)}async start(){let e=this.session;if(!e)throw Oe(`not-attached`);if(this.peer)throw Oe(`already-started`);let t=++this.generation;this.deliveryLifecycle.reset(t),this.answered=!1,this.offerSent=!1,this.localCandidates=[],this.pendingFrames=[];let n=this.createPeer();this.peer=n;let r=this.options.signaling,i=n.createDataChannel(`agent-session`);this.wireChannel(i,e,t),this.wireSignaling(n,i,e,t);let a=await n.createOffer();this.requireCurrentPeer(n,t),this.options.secret&&(this.localFingerprint=(0,u.extractDtlsFingerprint)(a)),r.send({kind:`offer`,data:{type:`offer`,sdp:a}}),this.offerSent=!0;for(let e of this.localCandidates.splice(0))this.sendCandidate(e)}remoteFingerprintAlgorithm(e,t){if(!this.options.secret)return;let n=t.sdp;try{if(typeof n!=`string`)throw Error(`answer carries no SDP`);return(0,u.extractDtlsFingerprintAttribute)(n).algorithm}catch{this.failPairing(e);return}}failPairing(e){e.close(),this.options.onPairingFailed?.()}awaitVerifiedCertificate(e,t,n,r,i){this.stopAwaitingCertificate=_(e,r,e=>{if(i!==this.generation)return;if(t.readyState===`open`){this.startPairing(t,n,e,i);return}let r=t.onStateChange(a=>{a===`open`&&i===this.generation&&(r(),this.startPairing(t,n,e,i))})},()=>{i===this.generation&&this.failPairing(t)})}startPairing(e,t,n,r){let i=this.options.secret;if(!i||!this.localFingerprint)return;this.pairingGate=new De({cryptoContext:this.options.cryptoContext,channel:{send:t=>e.send(t),close:()=>e.close()},session:t,secret:i,role:`initiator`,localFingerprint:this.localFingerprint,remoteFingerprint:n,onAccept:e=>{r===this.generation&&(this.deliveryLifecycle.accept(r),this.options.onPaired?.(e))},...this.options.onPairingFailed?{onReject:this.options.onPairingFailed}:{},...this.options.reconnect?{reconnect:this.options.reconnect}:{},...this.options.localPeer?{localPeer:this.options.localPeer}:{},...this.options.connectionApproval?{connectionApproval:this.options.connectionApproval}:{},...this.options.resumeBridge?{resumeBridge:this.options.resumeBridge}:{},...this.options.personalUsageReporter?{personalUsageReporter:this.options.personalUsageReporter}:{},...this.options.usageReporter?{usageReporter:this.options.usageReporter}:{},...this.options.storedSessionUsageReporter?{storedSessionUsageReporter:this.options.storedSessionUsageReporter}:{},surface:`remote`,commandSurfaceLocality:`remote`,onDeliveryError:(t,n)=>this.deliveryLifecycle.handleFailure(e,r,t,n)});let a=this.pairingGate;for(let e of this.pendingFrames.splice(0))a.onInbound(e)}wireChannel(e,t,n){if(this.options.secret){e.onMessage(e=>{n===this.generation&&(this.pairingGate?this.pairingGate.onInbound(e):this.pendingFrames.length<16&&this.pendingFrames.push(e))}),e.onStateChange(e=>{n===this.generation&&e===`closed`&&(this.pairingGate?.onChannelClosed(),this.deliveryLifecycle.handleDrop(n))}),this.cleanupHandler=()=>this.pairingGate?.cleanup();return}let{onMessage:r,cleanup:i}=(0,c.createSessionMessageHandler)({session:t,deliver:re(e,(t,r)=>this.deliveryLifecycle.handleFailure(e,n,t,r)),...this.options.personalUsageReporter?{personalUsageReporter:this.options.personalUsageReporter}:{},...this.options.usageReporter?{usageReporter:this.options.usageReporter}:{},...this.options.storedSessionUsageReporter?{storedSessionUsageReporter:this.options.storedSessionUsageReporter}:{},surface:`remote`,commandSurfaceLocality:`remote`,maxFrameBytes:c.HISTORY_PAGE_MAX_BYTES});this.cleanupHandler=i,e.onMessage(e=>{n===this.generation&&r(e)})}async stop(){this.generation+=1,this.cleanupHandler?.(),this.unsubscribeSignal?.(),this.cleanupHandler=void 0,this.unsubscribeSignal=void 0,this.pairingGate=void 0,this.localFingerprint=void 0,this.answered=!1,this.offerSent=!1,this.localCandidates=[],this.pendingFrames=[],this.stopAwaitingCertificate?.(),this.stopAwaitingCertificate=void 0,this.deliveryLifecycle.reset(this.generation),this.peer&&=(this.peer.close(),void 0),this.session=void 0}};function je(e){if(typeof e!=`object`||!e)return;let t=e;if(typeof t.candidate!=`string`||t.candidate.length===0)return;let n=typeof t.sdpMid==`string`?t.sdpMid:typeof t.sdpMLineIndex==`number`?String(t.sdpMLineIndex):`0`;return{candidate:t.candidate,mid:n}}function Me(){let e=[],t=[],n=!0;function r(e,t){return{send(e){n&&queueMicrotask(()=>{for(let n of t)n(e)})},onSignal(t){return e.push(t),()=>{let n=e.indexOf(t);n>=0&&e.splice(n,1)}},close(){n=!1,e.length=0}}}return[r(e,t),r(t,e)]}const Ne=new Set([`offer`,`answer`,`ice`]);function Pe(e){return new f.default(e)}var Fe=class{options;socket;handlers=[];outbox=[];joined=!1;closed=!1;constructor(e){this.options=e;let t=e.createSocket??Pe;this.socket=t(e.url),this.socket.on(`open`,()=>this.handleOpen()),this.socket.on(`message`,e=>this.handleMessage(e)),this.socket.on(`error`,e=>this.fail(e instanceof Error?e:Error(String(e)))),this.socket.on(`close`,()=>this.handleClose())}handleOpen(){this.socket.send(JSON.stringify({type:`join`,rendezvous:this.options.rendezvous}));for(let e of this.outbox)this.writeSignal(e);this.outbox.length=0}handleMessage(e){let t;try{t=JSON.parse(typeof e==`string`?e:String(e))}catch{return}if(typeof t!=`object`||!t)return;let n=t;if(n.type===`joined`){this.joined=!0,this.options.onReady?.();return}if(n.type===`error`){this.fail(Error(`signaling relay rejected the connection: ${String(n.reason)}`));return}if(n.type===`signal`&&typeof n.kind==`string`&&Ne.has(n.kind)){let e={kind:n.kind,data:n.data};for(let t of this.handlers)t(e)}}handleClose(){this.closed||this.joined||this.fail(Error(`signaling socket closed before the rendezvous was joined`))}fail(e){this.options.onError?.(e)}writeSignal(e){this.socket.send(JSON.stringify({type:`signal`,kind:e.kind,data:e.data}))}send(e){this.closed||(this.socket.readyState===1?this.writeSignal(e):this.outbox.push(e))}onSignal(e){return this.handlers.push(e),()=>{let t=this.handlers.indexOf(e);t>=0&&this.handlers.splice(t,1)}}close(){this.closed=!0,this.handlers.length=0,this.outbox.length=0,this.socket.close()}};const Ie=/^[A-Za-z0-9_-]{22}$/,Le=6e4;function w(e){return typeof e==`string`&&Ie.test(e)}function T(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function Re(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(!(t.v!==1||!w(t.from))){if(t.kind===`hello`)return{v:1,kind:`hello`,from:t.from};if(!(!w(t.to)||!w(t.cid))){if(t.kind===`offer`||t.kind===`answer`)return T(t.sdp,49152)?{v:1,kind:t.kind,from:t.from,to:t.to,cid:t.cid,sdp:t.sdp}:void 0;if(t.kind===`ice`){let e=t.candidate;if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e;return!T(n.candidate,2048)||n.sdpMid!==void 0&&!T(n.sdpMid,64)||n.sdpMLineIndex!==void 0&&!(typeof n.sdpMLineIndex==`number`&&Number.isInteger(n.sdpMLineIndex)&&n.sdpMLineIndex>=0&&n.sdpMLineIndex<64)?void 0:{v:1,kind:`ice`,from:t.from,to:t.to,cid:t.cid,candidate:{candidate:n.candidate,...n.sdpMid===void 0?{}:{sdpMid:n.sdpMid},...n.sdpMLineIndex===void 0?{}:{sdpMLineIndex:n.sdpMLineIndex}}}}}}}function ze(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(!(t.t!==`mesh-msg`||typeof t.body!=`string`||t.body.length>6e4))return{t:`mesh-msg`,body:t.body}}var Be=class extends Error{end;stage;role;peer;channelClose;cause;constructor(e){let t=[`mesh link ended (${e.end}) during ${e.stage} as ${e.role}`];e.detail!==void 0&&t.push(e.detail),e.cause!==void 0&&t.push(e.cause instanceof Error?e.cause.message:String(e.cause));let n=e.peer;n!==void 0&&t.push(`connection ${n.state} [${n.history.join(` > `)}], ice ${n.ice??`?`}, gathering ${n.gathering??`?`}, candidates ${n.localCandidates} sent / ${n.remoteCandidates} applied, closed by ${n.closedBy??`the peer or the network`}${n.handlerError===void 0?``:` (${n.handlerError})`}`),e.channelClose!==void 0&&t.push(`channel ${e.channelClose}`),super(t.join(`; `)),this.name=`MeshLinkEndedError`,this.end=e.end,this.stage=e.stage,this.role=e.role,n!==void 0&&(this.peer=n),e.channelClose!==void 0&&(this.channelClose=e.channelClose),e.cause!==void 0&&(this.cause=e.cause)}};const Ve=`agent-file`,He=JSON.stringify({t:`mesh-admitted`});var Ue=class{options;state=`connecting`;peer;channel;localFingerprint;remoteFingerprint;tookRemoteDescription=!1;creatingPeer=!1;sentDescription=!1;localCandidates=[];remoteCandidates=0;handshake;fedProof=!1;held=[];handlers=new Set;endHandlers=new Set;fileChannels=new Set;fileHandlers=new Set;signalChain=Promise.resolve();stopAwaitingCertificate;timer;admissionResult;constructor(e){this.options=e,this.timer=setTimeout(()=>this.end(`timeout`),e.connectTimeoutMs)}get role(){return this.options.role}get admitted(){return this.state===`admitted`}get ended(){return this.isEnded()}isEnded(){return this.state===`ended`}get admission(){return this.state===`admitted`?this.admissionResult:void 0}get channelBinding(){if(this.state===`admitted`&&this.localFingerprint!==void 0&&this.remoteFingerprint!==void 0)return{localFingerprint:this.localFingerprint,remoteFingerprint:this.remoteFingerprint}}async offer(){if(!(this.options.role!==`offerer`||this.creatingPeer||this.isEnded())){this.creatingPeer=!0;try{let e=await this.createPeer();if(e===void 0)return;this.adoptChannel(e.createDataChannel(`agent-mesh`));let t=await e.createOffer();if(this.isEnded())return;this.localFingerprint=(0,u.extractDtlsFingerprint)(t),this.sendDescription({kind:`offer`,sdp:t})}catch(e){this.end(`signaling`,e)}}}onSignal(e){this.isEnded()||(this.signalChain=this.signalChain.then(()=>this.applySignal(e)).catch(e=>this.end(`signaling`,e)))}async applySignal(e){if(this.isEnded())return;if(e.kind===`ice`){if(!this.tookRemoteDescription||!this.peer||++this.remoteCandidates>64)return;this.peer.addRemoteCandidate({candidate:e.candidate.candidate,mid:e.candidate.sdpMid??String(e.candidate.sdpMLineIndex??0)});return}let t=this.options.role===`offerer`?`answer`:`offer`;if(e.kind!==t||this.tookRemoteDescription)return;this.tookRemoteDescription=!0;let n;try{n=(0,u.extractDtlsFingerprintAttribute)(e.sdp).algorithm}catch(e){this.end(`channel-binding`,e);return}if(this.options.role===`offerer`){let t=this.peer;if(!t)return;t.acceptAnswer(e.sdp),this.awaitCertificate(t,n);return}let r=await this.createPeer();if(r===void 0)return;let i=await r.acceptOffer(e.sdp);this.isEnded()||(this.localFingerprint=(0,u.extractDtlsFingerprint)(i),this.sendDescription({kind:`answer`,sdp:i}),this.awaitCertificate(r,n))}async createPeer(){let e=await this.options.createPeer();if(this.isEnded()){e.close();return}return this.peer=e,e.onLocalCandidate(e=>{if(this.isEnded())return;let t={kind:`ice`,candidate:{candidate:e.candidate,sdpMid:e.mid}};this.sentDescription?this.options.sendSignal(t):this.localCandidates.length<64&&this.localCandidates.push(t)}),e.onStateChange(e=>{(e===`failed`||e===`closed`)&&this.end(`closed`,void 0,`connection ${e}`)}),e.onDataChannel(e=>this.incomingChannel(e)),e}incomingChannel(e){if(this.options.role===`answerer`&&this.channel===void 0&&!this.isEnded()){this.adoptChannel(e);return}if(this.state!==`admitted`||e.label!==Ve||this.fileHandlers.size===0||this.fileChannels.size>=4){e.close();return}this.trackFileChannel(e);for(let t of this.fileHandlers)t(e)}trackFileChannel(e){this.fileChannels.add(e),e.onStateChange(t=>{t===`closed`&&this.fileChannels.delete(e)})}openFileChannel(){let e=this.peer;if(this.state!==`admitted`||e===void 0)return Promise.reject(Error(`mesh link is not admitted`));if(this.fileChannels.size>=4)return Promise.reject(Error(`too many file transfers are open on this link`));let t=e.createDataChannel(Ve);return this.trackFileChannel(t),new Promise((e,n)=>{if(t.readyState===`open`){e(t);return}let r=setTimeout(()=>{i(),t.close(),n(Error(`the file channel did not open`))},1e4),i=t.onStateChange(a=>{a!==`connecting`&&(clearTimeout(r),i(),a===`open`?e(t):n(Error(`the file channel closed before it opened`)))})})}onFileChannel(e){return this.fileHandlers.add(e),()=>this.fileHandlers.delete(e)}sendDescription(e){this.options.sendSignal(e),this.sentDescription=!0;for(let e of this.localCandidates.splice(0))this.options.sendSignal(e)}awaitCertificate(e,t){this.stopAwaitingCertificate=_(e,t,e=>{this.isEnded()||(this.remoteFingerprint=e,this.maybeStartHandshake())},e=>this.end(`channel-binding`,Error(e)))}adoptChannel(e){this.channel=e,e.onMessage(e=>this.inbound(e)),e.onStateChange(e=>{e===`open`?this.maybeStartHandshake():e===`closed`&&this.end(`closed`,void 0,`data channel closed`)}),e.readyState===`open`&&this.maybeStartHandshake()}maybeStartHandshake(){let e=this.channel;if(this.state!==`connecting`||this.handshake!==void 0||e===void 0||this.localFingerprint===void 0||this.remoteFingerprint===void 0||e.readyState!==`open`)return;let t;try{t=this.options.startHandshake({localFingerprint:this.localFingerprint,remoteFingerprint:this.remoteFingerprint,send:e=>this.write(JSON.stringify(e))})}catch(e){this.end(`handshake`,e);return}this.handshake=t,t.result.then(e=>this.confirm(e),e=>this.end(`handshake`,e));let n=this.held.splice(0);for(let e of n)this.feed(e)}inbound(e){if(!this.isEnded()){if(this.state===`admitted`){this.deliver(e);return}if(this.state===`confirming`){this.confirmed(e);return}if(this.handshake===void 0){this.hold(e);return}this.feed(e)}}hold(e){if(this.held.length>=16){this.end(`protocol`);return}this.held.push(e)}feed(e){if(this.fedProof){this.hold(e);return}let t;try{t=JSON.parse(e)}catch{t=e}typeof t==`object`&&t&&t.t===`dh-prove`&&(this.fedProof=!0),this.handshake?.onFrame(t)}confirm(e){if(this.state!==`connecting`)return;if(this.options.accepts!==void 0&&!this.options.accepts(e)){this.end(`handshake`,Error(`the admitted device is not the one this link is for`));return}this.state=`confirming`,this.admissionResult=e,this.write(He);let t=this.held.splice(0);for(let e of t)this.inbound(e)}confirmed(e){let t;try{t=JSON.parse(e)}catch{t=void 0}let n=this.admissionResult;if(n===void 0||typeof t!=`object`||!t||t.t!==`mesh-admitted`){this.end(`protocol`);return}clearTimeout(this.timer),this.state=`admitted`,this.options.onAdmitted(n)}deliver(e){let t;try{t=JSON.parse(e)}catch{t=void 0}let n=ze(t);if(n===void 0){this.end(`protocol`);return}for(let e of this.handlers)e(n.body)}write(e){try{this.channel?.send(e)}catch(e){this.end(`closed`,e)}}send(e){if(this.state!==`admitted`)throw Error(`mesh link is not admitted`);if(e.length>6e4)throw Error(`mesh message exceeds ${Le} characters`);this.write(JSON.stringify({t:`mesh-msg`,body:e}))}onMessage(e){return this.handlers.add(e),()=>this.handlers.delete(e)}onEnd(e){return this.endHandlers.add(e),()=>this.endHandlers.delete(e)}close(){this.end(`closed`,void 0,`closed by this side`)}get stage(){return this.state===`admitted`||this.state===`confirming`?this.state:this.handshake===void 0?this.remoteFingerprint===void 0?this.tookRemoteDescription?`connecting`:`signaling`:`awaiting-channel`:`handshake`}end(e,t,n){if(this.isEnded())return;let r=new Be({end:e,stage:this.stage,role:this.options.role,...n===void 0?{}:{detail:n},...this.peer===void 0?{}:{peer:this.peer.diagnostics()},...this.channel?.closeCause===void 0?{}:{channelClose:this.channel.closeCause},...t===void 0?{}:{cause:t}});this.state=`ended`,clearTimeout(this.timer),this.stopAwaitingCertificate?.(),this.held.length=0,this.handshake?.onFrame(void 0),this.channel?.close();for(let e of this.fileChannels)e.close();this.fileChannels.clear(),this.fileHandlers.clear();let i=this.peer;i&&setTimeout(()=>i.close(),250).unref?.(),this.options.onEnded(e,r);for(let t of this.endHandlers)t(e);this.endHandlers.clear(),this.handlers.clear()}};const E=554869826,D={Binding:1,Allocate:3,Refresh:4,Send:6,Data:7,CreatePermission:8,ChannelBind:9},O={Request:0,Indication:1,Success:2,Error:3},k={MappedAddress:1,Username:6,MessageIntegrity:8,ErrorCode:9,UnknownAttributes:10,ChannelNumber:12,Lifetime:13,XorPeerAddress:18,Data:19,Realm:20,Nonce:21,XorRelayedAddress:22,RequestedAddressFamily:23,EvenPort:24,RequestedTransport:25,DontFragment:26,MessageIntegritySha256:28,PasswordAlgorithm:29,Userhash:30,XorMappedAddress:32,ReservationToken:34,Priority:36,UseCandidate:37,Fingerprint:32808};function We(e,t){return e&15|(e&112)<<1|(e&3968)<<2|(t&1)<<4|(t&2)<<7}function Ge(e){return e.length>=20&&(e[0]&192)==0&&e.readUInt32BE(4)===554869826}function Ke(e){if(!Ge(e))return;let t=e.readUInt16BE(0),n=e.readUInt16BE(2);if(n%4!=0||20+n>e.length)return;let r=t&15|(t&224)>>1|(t&15872)>>2,i=(t&16)>>4|(t&256)>>7,a=[],o=20,s=20+n;for(;o<s;){if(o+4>s)return;let t=e.readUInt16BE(o),n=e.readUInt16BE(o+2);if(o+4+n>s)return;a.push({type:t,value:e.subarray(o+4,o+4+n),offset:o}),o+=4+n+(4-n%4)%4}if(o===s)return{method:r,cls:i,transactionId:Buffer.from(e.subarray(8,20)),attributes:a,raw:e.subarray(0,s)}}function A(e,t){return e.attributes.find(e=>e.type===t)?.value}function qe(e,t){return e.attributes.filter(e=>e.type===t).map(e=>e.value)}function Je(e){let t=e.attributes.findIndex(e=>e.type===k.MessageIntegrity);return t<0?e:{...e,attributes:e.attributes.slice(0,t+1)}}function Ye(e,t){if(e.length<8)return;let n=e[1],r=e.readUInt16BE(2)^E>>>16;if(n===1&&e.length===8){let t=e.readUInt32BE(4)^E;return{address:[t>>>24,t>>>16&255,t>>>8&255,t&255].join(`.`),port:r}}if(n===2&&e.length===20){let n=Buffer.alloc(16);n.writeUInt32BE(E,0),t.copy(n,4);let i=[];for(let t=0;t<16;t+=2)i.push(((e.readUInt16BE(4+t)^n.readUInt16BE(t))&65535).toString(16));return{address:i.join(`:`),port:r}}}function Xe(e){let[t=``,n=``]=e.split(`::`),r=t.length>0?t.split(`:`):[],i=e.includes(`::`)&&n.length>0?n.split(`:`):[],a=e.includes(`::`)?[...r,...Array(8-r.length-i.length).fill(`0`),...i]:r,o=Buffer.alloc(16);return a.forEach((e,t)=>o.writeUInt16BE(parseInt(e,16)&65535,t*2)),o}function j(e,t){let n=(e.port^E>>>16)&65535;if((0,m.isIPv4)(e.address)){let t=Buffer.alloc(8);t[1]=1,t.writeUInt16BE(n,2);let r=e.address.split(`.`).reduce((e,t)=>e<<8|Number(t),0);return t.writeUInt32BE((r^E)>>>0,4),t}if(!(0,m.isIPv6)(e.address))throw Error(`not an IP address: ${e.address}`);let r=Buffer.alloc(20);r[1]=2,r.writeUInt16BE(n,2);let i=Buffer.alloc(16);i.writeUInt32BE(E,0),t.copy(i,4);let a=Xe(e.address);for(let e=0;e<16;e+=1)r[4+e]=a[e]^i[e];return r}function Ze(e,t,n){return(0,p.createHash)(`md5`).update(`${e}:${t}:${n}`,`utf8`).digest()}function Qe(e,t){let n=e.attributes.find(e=>e.type===k.MessageIntegrity);if(n===void 0||n.value.length!==20)return!1;let r=Buffer.from(e.raw.subarray(0,n.offset));return r.writeUInt16BE(n.offset-20+24,2),(0,p.timingSafeEqual)((0,p.createHmac)(`sha1`,t).update(r).digest(),n.value)}const $e=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t+=1){let n=t;for(let e=0;e<8;e+=1)n=n&1?3988292384^n>>>1:n>>>1;e[t]=n>>>0}return e})();function et(e){let t=4294967295;for(let n of e)t=$e[(t^n)&255]^t>>>8;return(t^4294967295)>>>0}function M(e,t,n,r,i={}){let a=[],o=Buffer.alloc(20);o.writeUInt16BE(We(e,t),0),o.writeUInt32BE(E,4),n.copy(o,8,0,12),a.push(o);let s=(e,t)=>{let n=Buffer.alloc(4);n.writeUInt16BE(e,0),n.writeUInt16BE(t.length,2),a.push(n,t,Buffer.alloc((4-t.length%4)%4))};for(let e of r)s(e.type,e.value);let c=()=>Buffer.concat(a);if(i.integrityKey!==void 0){let e=c();e.writeUInt16BE(e.length-20+24,2),s(k.MessageIntegrity,(0,p.createHmac)(`sha1`,i.integrityKey).update(e).digest())}if(i.fingerprint!==!1){let e=c();e.writeUInt16BE(e.length-20+8,2);let t=Buffer.alloc(4);t.writeUInt32BE((et(e)^1398035790)>>>0,0),s(k.Fingerprint,t)}let l=c();if(l.writeUInt16BE(l.length-20,2),l.length>65535)throw Error(`STUN message too large`);return l}function tt(e,t){let n=Buffer.from(t,`utf8`),r=Buffer.alloc(4+n.length);return r[2]=Math.floor(e/100),r[3]=e%100,n.copy(r,4),r}function N(e){let t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),t}function nt(e){return e.length>=4&&(e[0]&192)==64}function rt(e){if(!nt(e))return;let t=e.readUInt16BE(0),n=e.readUInt16BE(2);if(!(4+n>e.length))return{channel:t,payload:e.subarray(4,4+n)}}function it(e,t){let n=Buffer.alloc(4);return n.writeUInt16BE(e,0),n.writeUInt16BE(t.length,2),Buffer.concat([n,t,Buffer.alloc((4-t.length%4)%4)])}const at={allocationsPerOwner:8,totalAllocations:64,bytesPerSecondPerOwner:1024*1024,maxLifetimeSeconds:3600,maxAllocationAgeMs:720*60*1e3,permissionsPerAllocation:32,channelsPerAllocation:32},ot={perSourcePerSecond:10,totalPerSecond:2e3},st=3e5,ct=new Set([k.MappedAddress,k.Username,k.MessageIntegrity,k.ErrorCode,k.ChannelNumber,k.Lifetime,k.XorPeerAddress,k.Data,k.Realm,k.Nonce,k.RequestedAddressFamily,k.RequestedTransport,k.MessageIntegritySha256,k.PasswordAlgorithm,k.XorMappedAddress,k.Priority,k.UseCandidate]);function P(e){return`${e.address}:${e.port}`}function lt(){for(let e of Object.values((0,h.networkInterfaces)()))for(let t of e??[])if(t.family===`IPv4`&&!t.internal)return t.address;return`127.0.0.1`}function ut(e){return e.startsWith(`127.`)||e===`::1`}function dt(e){let[t=0,n=0]=e.split(`.`).map(Number);return t===10||t===172&&n>=16&&n<=31||t===192&&n===168||t===169&&n===254||t===100&&n>=64&&n<=127}function ft(e,t){return n=>{if(!(0,m.isIPv4)(n))return!1;let r=Number(n.split(`.`)[0]);return r===0||r>=224?!1:r===127?e:t||!dt(n)}}async function pt(e,t){let n=(0,te.createSocket)(`udp4`);try{return await new Promise((r,i)=>{n.once(`error`,i),n.bind(e,t,()=>{n.off(`error`,i),r()})}),n}catch(e){try{n.close()}catch{}throw e}}async function F(e,t){try{return await pt(e,t)}catch{return}}function mt(e,t,n){let r=e instanceof Error?e.code:void 0,i=r===`EADDRINUSE`?`the port is taken`:r===`EADDRNOTAVAIL`?`${t} is not an address of this machine`:r===`EACCES`?`port ${n} needs privileges this process does not have`:gt(e).message;return Error(`the TURN relay cannot listen on UDP ${t}:${n}: ${i}`,{cause:e})}function ht(){let e=new Set;for(let t of Object.values((0,h.networkInterfaces)()))for(let n of t??[])e.add(n.address);return e}function I(e,t,n,r=1){let i=Math.max(0,n-e.at);return e.tokens=Math.min(Math.max(t,r),e.tokens+i/1e3*t),e.at=n,e.tokens>=r}function gt(e){return e instanceof Error?e:Error(String(e))}var _t=class e{socket;options;bindHost;relayAddress;allocations=new Map;buckets=new Map;quotas;realm;limits;answerBuckets=new Map;answerBudget;nonceSecret=(0,p.randomBytes)(32);ownAddresses=ht();allowPeer;sweeper;retained;closed=!1;constructor(e,t,n,r){this.socket=e,this.options=t,this.bindHost=n,this.relayAddress=r,this.quotas={...at,...t.quotas},this.realm=t.realm??`r`,this.limits={...ot,...t.unauthenticatedLimits},this.allowPeer=t.allowPeer??ft(ut(r),t.allowPrivatePeers??!0),e.on(`message`,(e,t)=>this.receive(e,t)),e.on(`error`,e=>t.onError?.(e)),this.sweeper=setInterval(()=>this.sweep(),5e3),this.sweeper.unref?.()}static async start(t){let n=Buffer.byteLength(t.realm??`r`);if(n===0||n>4)throw Error(`TURN realm must be 1 to 4 bytes`);let r=t.host??`0.0.0.0`,i=t.port??3478,a;try{a=await pt(i,r)}catch(e){throw mt(e,r,i)}let o=t.relayAddress??(r===`0.0.0.0`?lt():r);return new e(a,t,r,o)}get address(){let e=this.socket.address();return{address:this.bindHost===`0.0.0.0`?this.relayAddress:e.address,port:e.port}}allocationCount(e){if(e===void 0)return this.allocations.size;let t=0;for(let n of this.allocations.values())n.owner===e&&(t+=1);return t}retain(e){this.retained=new Set(e);for(let t of[...this.allocations.values()])e.has(t.owner)||this.remove(t);for(let t of[...this.buckets.keys()])e.has(t)||this.buckets.delete(t)}close(){if(this.closed)return Promise.resolve();this.closed=!0,clearInterval(this.sweeper);for(let e of[...this.allocations.values()])this.remove(e);return new Promise(e=>this.socket.close(()=>e()))}now(){return(this.options.now??Date.now)()}receive(e,t){if(this.closed)return;if(nt(e)){this.fromClientChannel(e,t);return}let n=Ke(e);if(n!==void 0){if(n.cls===O.Indication){n.method===D.Send&&this.fromClientSend(n,t);return}n.cls===O.Request&&this.request(n,t).catch(e=>this.options.onError?.(gt(e)))}}send(e,t){this.closed||this.socket.send(e,t.port,t.address,e=>{e&&this.options.onError?.(e)})}reply(e,t,n,r){let i=M(e.method,O.Success,e.transactionId,n,{...r===void 0?{}:{integrityKey:r}});return this.send(i,t),i}fail(e,t,n,r,i=[],a){let o=M(e.method,O.Error,e.transactionId,[{type:k.ErrorCode,value:tt(n,r)},...i],{...a===void 0?{}:{integrityKey:a}});this.send(o,t)}nonce(e){let t=Buffer.alloc(4);return t.writeUInt32BE(Math.floor(this.now()/1e3)>>>0,0),Buffer.concat([t,this.nonceMac(t,e)]).toString(`base64url`)}nonceMac(e,t){return(0,p.createHmac)(`sha256`,this.nonceSecret).update(e).update(P(t)).digest().subarray(0,8)}nonceValid(e,t){if(!/^[A-Za-z0-9_-]{16}$/.test(e))return!1;let n=Buffer.from(e,`base64url`),r=n.subarray(0,4);if(!(0,p.timingSafeEqual)(n.subarray(4),this.nonceMac(r,t)))return!1;let i=this.now()-r.readUInt32BE(0)*1e3;return i>=-6e4&&i<=6e5}answerUnauthenticated(e,t,n,r){let i=this.now(),a=this.answerBudget??={tokens:this.limits.totalPerSecond,at:i},o=this.answerBuckets.get(t.address)??{tokens:this.limits.perSourcePerSecond,at:i};if(this.answerBuckets.set(t.address,o),e.raw.length<28||!I(o,this.limits.perSourcePerSecond,i)||!I(a,this.limits.totalPerSecond,i))return;let s=M(e.method,n,e.transactionId,r(),{fingerprint:!1});s.length>e.raw.length||(--o.tokens,--a.tokens,this.send(s,t))}refuseUnauthenticated(e,t,n,r=()=>[]){this.answerUnauthenticated(e,t,O.Error,()=>[{type:k.ErrorCode,value:tt(n,``)},...r()])}challenge(e,t,n){this.refuseUnauthenticated(e,t,n,()=>[{type:k.Realm,value:Buffer.from(this.realm)},{type:k.Nonce,value:Buffer.from(this.nonce(t))}])}async authenticate(e,t,n){if(A(e,k.MessageIntegrity)===void 0){this.challenge(e,t,401);return}let r=A(e,k.Username)?.toString(`utf8`),i=A(e,k.Realm)?.toString(`utf8`),a=A(e,k.Nonce)?.toString(`utf8`);if(r===void 0||i===void 0||a===void 0){this.refuseUnauthenticated(e,t,400);return}if(i!==this.realm){this.challenge(e,t,401);return}if(!this.nonceValid(a,t)){this.challenge(e,t,438);return}if(n!==void 0){if(r!==n.username){this.refuseUnauthenticated(e,t,441);return}if(!Qe(e,n.integrityKey)){this.challenge(e,t,401);return}return{auth:{owner:n.owner,password:``},key:n.integrityKey,username:r}}let o;try{o=await this.options.authorize(r)}catch{o=void 0}if(this.closed)return;let s=o===void 0?void 0:Ze(r,this.realm,o.password);if(o===void 0||s===void 0||!Qe(e,s)){this.challenge(e,t,401);return}return{auth:o,key:s,username:r}}unknownAttributes(e){return e.attributes.map(e=>e.type).filter(e=>e<32768&&!ct.has(e))}async request(e,t){let n={address:t.address,port:t.port};if(e.method===D.Binding){this.answerUnauthenticated(e,n,O.Success,()=>[{type:k.XorMappedAddress,value:j(n,e.transactionId)}]);return}if(![D.Allocate,D.Refresh,D.CreatePermission,D.ChannelBind].includes(e.method)){this.refuseUnauthenticated(e,n,400);return}let r=this.allocations.get(P(n)),i=this.live(r)?r:void 0;if(e.method===D.Allocate&&i!==void 0&&i.transactionId.equals(e.transactionId)){i.response.length<=e.raw.length&&this.send(i.response,n);return}let a=await this.authenticate(e,n,i);a!==void 0&&await this.authenticatedRequest(Je(e),n,a)}async authenticatedRequest(e,t,n){let{key:r}=n,i=this.unknownAttributes(e);if(i.length>0){let n=Buffer.alloc(i.length*2);i.forEach((e,t)=>n.writeUInt16BE(e,t*2)),this.fail(e,t,420,`Unknown Attribute`,[{type:k.UnknownAttributes,value:n}],r);return}let a=this.allocations.get(P(t)),o=this.live(a)?a:void 0;if(e.method===D.Allocate){await this.allocate(e,t,n,o);return}if(o===void 0||o.owner!==n.auth.owner){this.fail(e,t,437,`Allocation Mismatch`,[],r);return}e.method===D.Refresh?this.refresh(e,t,o):e.method===D.CreatePermission?this.permit(e,t,o):this.bindChannel(e,t,o)}async allocate(e,t,n,r){let{auth:i,key:a,username:o}=n;if(r!==void 0){this.fail(e,t,437,`Allocation Mismatch`,[],a);return}let s=A(e,k.RequestedTransport);if(s===void 0||s.length!==4){this.fail(e,t,400,`Bad Request`,[],a);return}if(s[0]!==17){this.fail(e,t,442,`Unsupported Transport Protocol`,[],a);return}let c=A(e,k.RequestedAddressFamily);if(c!==void 0&&c[0]!==1){this.fail(e,t,440,`Address Family not Supported`,[],a);return}if(this.retained!==void 0&&!this.retained.has(i.owner)){this.fail(e,t,403,`Forbidden`,[],a);return}if(this.allocations.size>=this.quotas.totalAllocations){this.fail(e,t,508,`Insufficient Capacity`,[],a);return}if(this.allocationCount(i.owner)>=this.quotas.allocationsPerOwner){this.fail(e,t,486,`Allocation Quota Reached`,[],a);return}let l=await this.relayedSocket();if(l===void 0){this.fail(e,t,508,`Insufficient Capacity`,[],a);return}if(!this.closed&&this.retained!==void 0&&!this.retained.has(i.owner)){l.close(),this.fail(e,t,403,`Forbidden`,[],a);return}if(this.closed||this.allocations.has(P(t))||this.allocationCount(i.owner)>=this.quotas.allocationsPerOwner||this.allocations.size>=this.quotas.totalAllocations){l.close(),this.closed||this.fail(e,t,486,`Allocation Quota Reached`,[],a);return}let u=this.now(),d=this.grantedLifetime(e,u,u),f={key:P(t),client:t,owner:i.owner,username:o,integrityKey:a,transactionId:Buffer.from(e.transactionId),socket:l,relayed:{address:this.relayAddress,port:l.address().port},createdAt:u,expiresAt:u+d*1e3,permissions:new Map,channelsByNumber:new Map,channelsByPeer:new Map,response:Buffer.alloc(0)};l.on(`message`,(e,t)=>this.fromPeer(f,e,t)),l.on(`error`,e=>this.options.onError?.(e)),this.allocations.set(f.key,f),f.response=this.reply(e,t,[{type:k.XorRelayedAddress,value:j(f.relayed,e.transactionId)},{type:k.Lifetime,value:N(d)},{type:k.XorMappedAddress,value:j(t,e.transactionId)}],a)}async relayedSocket(){let e=this.options.relayPorts;if(e===void 0)return F(0,this.bindHost);let t=e.max-e.min+1;for(let n=0;n<Math.min(t,8);n+=1){let t=await F((0,p.randomInt)(e.min,e.max+1),this.bindHost);if(t!==void 0)return t}let n=new Set(this.allocationPorts());for(let t=e.min;t<=e.max;t+=1){if(n.has(t))continue;let e=await F(t,this.bindHost);if(e!==void 0)return e}}allocationPorts(){return[...this.allocations.values()].map(e=>e.relayed.port)}isServerItself(e){return e.port===this.socket.address().port&&(ut(e.address)||e.address===this.relayAddress||e.address===this.bindHost||this.bindHost===`0.0.0.0`&&this.ownAddresses.has(e.address))}grantedLifetime(e,t,n){let r=A(e,k.Lifetime),i=r!==void 0&&r.length===4?r.readUInt32BE(0):600,a=Math.floor((t+this.quotas.maxAllocationAgeMs-n)/1e3);return Math.max(0,Math.min(i,this.quotas.maxLifetimeSeconds,a))}refresh(e,t,n){let r=this.now(),i=this.grantedLifetime(e,n.createdAt,r);if(i===0){this.remove(n),this.reply(e,t,[{type:k.Lifetime,value:N(0)}],n.integrityKey);return}n.expiresAt=r+i*1e3,this.reply(e,t,[{type:k.Lifetime,value:N(i)}],n.integrityKey)}peerAddresses(e){let t=[];for(let n of qe(e,k.XorPeerAddress)){let r=Ye(n,e.transactionId);if(r===void 0)return;t.push(r)}return t.length>0?t:void 0}permit(e,t,n){let r=n.integrityKey,i=this.peerAddresses(e);if(i===void 0){this.fail(e,t,400,`Bad Request`,[],r);return}if(i.some(e=>!(0,m.isIPv4)(e.address))){this.fail(e,t,443,`Peer Address Family Mismatch`,[],r);return}if(i.some(e=>!this.allowPeer(e.address))){this.fail(e,t,403,`Forbidden`,[],r);return}let a=new Set(i.map(e=>e.address).filter(e=>!n.permissions.has(e)));if(n.permissions.size+a.size>this.quotas.permissionsPerAllocation){this.fail(e,t,508,`Insufficient Capacity`,[],r);return}let o=this.now()+st;for(let e of i)n.permissions.set(e.address,o);this.reply(e,t,[],r)}bindChannel(e,t,n){let r=n.integrityKey,i=A(e,k.ChannelNumber),a=this.peerAddresses(e),o=i!==void 0&&i.length===4?i.readUInt16BE(0):-1;if(o<16384||o>20479||a===void 0||a.length!==1){this.fail(e,t,400,`Bad Request`,[],r);return}let s=a[0];if(!(0,m.isIPv4)(s.address)){this.fail(e,t,443,`Peer Address Family Mismatch`,[],r);return}if(!this.allowPeer(s.address)){this.fail(e,t,403,`Forbidden`,[],r);return}let c=n.channelsByNumber.get(o),l=n.channelsByPeer.get(P(s));if(c!==void 0&&P(c.peer)!==P(s)||l!==void 0&&l.number!==o){this.fail(e,t,400,`Bad Request`,[],r);return}if(c===void 0&&n.channelsByNumber.size>=this.quotas.channelsPerAllocation||!n.permissions.has(s.address)&&n.permissions.size>=this.quotas.permissionsPerAllocation){this.fail(e,t,508,`Insufficient Capacity`,[],r);return}let u=this.now(),d=c??{number:o,peer:s,expiresAt:0};d.expiresAt=u+6e5,n.channelsByNumber.set(o,d),n.channelsByPeer.set(P(s),d),n.permissions.set(s.address,u+st),this.reply(e,t,[],r)}permitted(e,t){let n=e.permissions.get(t);return n!==void 0&&n>this.now()}spend(e,t){let n=this.now(),r=this.quotas.bytesPerSecondPerOwner,i=this.buckets.get(e)??{tokens:r,at:n};return this.buckets.set(e,i),I(i,r,n,t)?(i.tokens-=t,!0):!1}live(e){return e===void 0?!1:e.expiresAt>this.now()?!0:(this.remove(e),!1)}fromClientSend(e,t){let n=this.allocations.get(P(t));if(!this.live(n))return;let r=A(e,k.XorPeerAddress),i=A(e,k.Data);if(r===void 0||i===void 0)return;let a=Ye(r,e.transactionId);a===void 0||!this.permitted(n,a.address)||this.isServerItself(a)||this.spend(n.owner,i.length)&&n.socket.send(i,a.port,a.address)}fromClientChannel(e,t){let n=this.allocations.get(P(t));if(!this.live(n))return;let r=rt(e);if(r===void 0)return;let i=n.channelsByNumber.get(r.channel);i===void 0||i.expiresAt<=this.now()||this.permitted(n,i.peer.address)&&(this.isServerItself(i.peer)||this.spend(n.owner,r.payload.length)&&n.socket.send(r.payload,i.peer.port,i.peer.address))}fromPeer(e,t,n){if(this.allocations.get(e.key)!==e||!this.live(e)||!this.permitted(e,n.address)||!this.spend(e.owner,t.length))return;let r=e.channelsByPeer.get(P(n));if(r!==void 0&&r.expiresAt>this.now()){this.send(it(r.number,t),e.client);return}let i=(0,p.randomBytes)(12);this.send(M(D.Data,O.Indication,i,[{type:k.XorPeerAddress,value:j({address:n.address,port:n.port},i)},{type:k.Data,value:t}]),e.client)}remove(e){this.allocations.get(e.key)===e&&this.allocations.delete(e.key);try{e.socket.close()}catch{}}sweep(){let e=this.now();for(let[t,n]of this.answerBuckets)Math.abs(e-n.at)>=1e3&&this.answerBuckets.delete(t);for(let t of[...this.allocations.values()]){if(t.expiresAt<=e){this.remove(t);continue}for(let[n,r]of t.permissions)r<=e&&t.permissions.delete(n);for(let[n,r]of t.channelsByNumber)r.expiresAt>e||(t.channelsByNumber.delete(n),t.channelsByPeer.delete(P(r.peer)))}}};const vt=600*1e3,yt=3600*1e3,bt=/^(\d{1,12}):([A-Za-z0-9_-]{22})$/;function xt(e){return Buffer.from(e).toString(`base64url`)}async function St(e,t,n=vt){let r=Math.min(Math.max(n,1e3),yt),i=(await e.tag(`relay-user`,`outbound`,(0,u.rendezvousEpoch)(t))).slice(0,16),a=`${Math.floor((t+r)/1e3)}:${xt(i)}`;return{username:a,credential:await e.relayPassword(`outbound`,a)}}function Ct(e){return`turn:${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}?transport=udp`}async function wt(e,t,n,r){if(t.length===0)return[];let{username:i,credential:a}=await St(e,n,r);return t.map(e=>({urls:Ct(e),username:i,credential:a}))}var L=class extends Error{deviceId;need;constructor(e,t,n){let r=t===`relay-only`?`only relayed connections are allowed`:`no direct path was found (${n?.cause instanceof Error?n.cause.message:String(n?.cause)})`;super(`a relay device is needed to reach device ${e}: ${r}, and no paired device advertises a relay and no TURN server is configured. Run the relay on an always-on device, or configure a TURN server.`,n?.cause===void 0?void 0:{cause:n.cause}),this.name=`MeshRelayNeededError`,this.deviceId=e,this.need=t}},Tt=class e{server;now;peers=[];owners;constructor(e,t){this.server=e,this.now=t}static async start(t={}){let n=t.now??Date.now,r,i=await _t.start({...t.host===void 0?{}:{host:t.host},...t.port===void 0?{}:{port:t.port},...t.relayAddress===void 0?{}:{relayAddress:t.relayAddress},...t.relayPorts===void 0?{}:{relayPorts:t.relayPorts},...t.quotas===void 0?{}:{quotas:t.quotas},...t.allowPeer===void 0?{}:{allowPeer:t.allowPeer},...t.allowPrivatePeers===void 0?{}:{allowPrivatePeers:t.allowPrivatePeers},...t.onError===void 0?{}:{onError:t.onError},now:n,authorize:e=>r===void 0?Promise.resolve(void 0):r.authorize(e)});return r=new e(i,n),r}get endpoint(){let{address:e,port:t}=this.server.address;return{host:e,port:t}}allocationCount(e){return this.server.allocationCount(e)}declarePeers(e){this.peers=[...e],this.server.retain(new Set(e.map(e=>e.deviceId)))}async authorize(e){let t=bt.exec(e);if(t===null)return;let n=this.now(),r=Number(t[1])*1e3;if(r<=n||r-n>366e4)return;let i=(await this.tagOwners((0,u.rendezvousEpoch)(n))).get(t[2]);if(!(i===void 0||!this.peers.some(e=>e.deviceId===i.deviceId)))return{owner:i.deviceId,password:await i.rendezvous.relayPassword(`inbound`,e)}}tagOwners(e){let t=this.owners;if(t!==void 0&&t.epoch===e&&t.peers===this.peers)return t.byTag;let n=this.peers,r=(async()=>{let t=new Map;for(let r of n)for(let n of await r.rendezvous.lookupTags(`relay-user`,e))t.set(xt(n.slice(0,16)),r);return t})();return r.catch(()=>{this.owners?.byTag===r&&(this.owners=void 0)}),this.owners={epoch:e,peers:n,byTag:r},r}close(){return this.peers=[],this.server.close()}};const Et=2e4,Dt=1e3,Ot=3e3,kt=`mesh-lists`,At=`{"t":"${kt}"`;function jt(e){return{send:t=>e.send(t),onFrame:t=>e.onMessage(t),onClose:t=>e.readyState===`closed`?(queueMicrotask(t),()=>void 0):e.onStateChange(e=>{e===`closed`&&t()}),close:()=>e.close()}}var Mt=class{last;waiting;timer;run(e){let t=Date.now();if(this.last===void 0||t-this.last>=Dt){this.last=t,e();return}this.waiting=e,this.timer===void 0&&(this.timer=setTimeout(()=>{this.timer=void 0;let e=this.waiting;this.waiting=void 0,e!==void 0&&this.run(e)},Dt-(t-this.last)),this.timer.unref?.())}cancel(){this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0,this.waiting=void 0}};function Nt(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function R(e,t){return t!==void 0&&t.seq>e.seq&&t.signingKeyId===e.signingKeyId}function Pt(e,t){return e===void 0?t:t===void 0?e:Math.max(e,t)}function Ft(e,t){let n=new Map;for(let r of[e.bySigningKey??{},t.bySigningKey??{}])for(let[e,t]of Object.entries(r)){let r=n.get(e)??{},i=Pt(r.rosterSeq,t.rosterSeq),a=Pt(r.revocationSeq,t.revocationSeq);n.set(e,{...i===void 0?{}:{rosterSeq:i},...a===void 0?{}:{revocationSeq:a}})}let r=Object.fromEntries(n),i=Pt(e.signingKeyRevocationSeq,t.signingKeyRevocationSeq);return{...i===void 0?{}:{signingKeyRevocationSeq:i},bySigningKey:r}}function It(e,t){let n=t.signingKeyCertificate.signingKeyId===e.signingKeyCertificate.signingKeyId;return{...t,...n&&R(t.roster,e.roster)?{roster:e.roster}:{},...n&&R(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Ft(e.marks,t.marks)}}function Lt(e,t){return t.signingKeyCertificate.signingKeyId===e.signingKeyCertificate.signingKeyId?t.roster.seq>e.roster.seq||t.revocation.seq>e.revocation.seq||t.signingKeyRevocation.seq>e.signingKeyRevocation.seq:!1}function Rt(e){if(e.startsWith(At))try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:void 0}catch{return{}}}var zt=class{options;instance=Nt();identity;sessionDescriptor;peers=new Map;byInbound=new Map;linkHandlers=new Set;refusalHandlers=new Set;waiters=new Set;unsubscribes=[];started=!1;stopped=!1;sync=Promise.resolve();constructor(e){this.options=e,this.identity=e.identity,this.sessionDescriptor=e.sessionDescriptor}get deviceId(){return this.identity.deviceCertificate.deviceId}async start(){if(this.started)throw Error(`DeviceMeshNode already started`);this.started=!0,this.unsubscribes.push(this.options.relay.onMessage((e,t)=>this.receive(e,t))),await this.syncPeers()}refresh(e){if(e.sessionDescriptor!==void 0&&(this.sessionDescriptor=e.sessionDescriptor),e.identity===void 0)return Promise.resolve();let t=this.identity;this.identity=It(t,e.identity);let n=this.syncPeers();return Lt(t,this.identity)&&n.then(()=>this.pushLists(),()=>void 0),n}pushLists(){if(this.stopped)return;let{roster:e,revocation:t,signingKeyRevocation:n}=this.identity,r=JSON.stringify({t:kt,roster:e,revocation:t,signingKeyRevocation:n});for(let e of this.peers.values())try{e.admitted?.exposed?.send(r)}catch{}}async receiveLists(e){let t=this.identity,n=(0,u.decodeDeviceRoster)(this.options.cryptoContext,e.roster),r=(0,u.decodeDeviceRevocationList)(this.options.cryptoContext,e.revocation),i=(0,u.decodeSigningKeyRevocation)(this.options.cryptoContext,e.signingKeyRevocation),a={...n.ok&&R(t.roster,n.value)?{roster:n.value}:{},...r.ok&&R(t.revocation,r.value)?{revocation:r.value}:{},...i.ok&&i.value.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:i.value}:{}};if(Object.keys(a).length===0)return;let o=await(0,u.verifyDeviceChain)(this.options.cryptoContext,{masterPublicKey:t.masterPublicKey,signingKeyCert:t.signingKeyCertificate,deviceCert:t.deviceCertificate,roster:a.roster??t.roster,revocation:a.revocation??t.revocation,signingKeyRevocation:a.signingKeyRevocation??t.signingKeyRevocation,now:(this.options.now??Date.now)(),lastSeen:t.marks,required:{roster:!0,revocation:!0,signingKeyRevocation:!0},listExpiryGraceMs:1/0});if(!o.ok||this.stopped)return;let{rosterSeq:s,revocationSeq:c,signingKeyRevocationSeq:l}=o.accepted;this.adoptLists({...a,marks:{...a.signingKeyRevocation!==void 0&&l!==void 0?{signingKeyRevocationSeq:l}:{},bySigningKey:{[o.signingKeyId]:{...a.roster!==void 0&&s!==void 0?{rosterSeq:s}:{},...a.revocation!==void 0&&c!==void 0?{revocationSeq:c}:{}}}}})}syncPeers(){this.sync=this.sync.then(async()=>{if(this.stopped)return;let e=this.identity,t=e.deviceCertificate,n=new Set(e.revocation.revokedDeviceIds),r=new Map;for(let i of e.roster.devices)i.deviceId!==t.deviceId&&!n.has(i.deviceId)&&r.set(i.deviceId,i);for(let[e,t]of this.peers){let n=r.get(e);(n===void 0||n.kaKey!==t.device.kaKey||n.kaEpoch!==t.device.kaEpoch)&&this.drop(t)}let i=[];for(let[n,a]of r){if(this.peers.has(n))continue;let r,o;try{r=await(0,u.derivePairRendezvous)(this.options.cryptoContext,{ownKaPrivateKey:e.kaPrivateKey,own:t,peerDeviceId:n,lists:e}),o=await r.relayInbox()}catch{continue}let s={device:a,role:t.deviceId<a.deviceId?`offerer`:`answerer`,rendezvous:r,inbound:o.inbound,outbound:o.outbound,attempts:new Mt,replies:new Mt,relayFailures:0};this.peers.set(n,s),this.byInbound.set(o.inbound,s),i.push(s)}if(this.stopped)return;this.options.relayServer?.declarePeers([...this.peers.values()].map(e=>({deviceId:e.device.deviceId,rendezvous:e.rendezvous}))),this.options.relay.declarePresence([...this.byInbound.keys()]);let a=this.peerRoutes();this.options.relay.declarePeers?.(a),this.options.relays?.advertised?.(a,AbortSignal.timeout(Ot)).catch(()=>void 0);for(let e of i)this.hello(e)});let e=this.sync;return this.sync=e.catch(()=>void 0),e}drop(e){this.peers.delete(e.device.deviceId),this.byInbound.delete(e.inbound),e.attempts.cancel(),e.replies.cancel();let{pending:t,admitted:n}=e;if(e.pending=void 0,e.admitted=void 0,t?.link.close(),n?.link.close(),t!==void 0&&!this.stopped){let t={deviceId:e.device.deviceId,end:`closed`,error:Error(`peer device was revoked or is no longer in the roster`)};for(let e of this.refusalHandlers)e(t)}}roleFor(e){return this.peers.get(e)?.role}link(e){return this.peers.get(e)?.admitted?.exposed}connect(e,t=Et){if(this.stopped)return Promise.reject(Error(`device mesh node stopped`));let n=this.peers.get(e);if(n===void 0)return Promise.reject(Error(`not a rostered, unrevoked peer device`));let r=n.admitted?.exposed;return r===void 0?new Promise((r,i)=>{let a=()=>{clearTimeout(s),c(),l(),this.waiters.delete(o)},o=e=>{a(),i(e)},s=setTimeout(()=>o(Error(`peer device did not connect in time`)),t);s.unref?.();let c=this.onLink(t=>{t.admission.deviceId===e&&(a(),r(t))}),l=this.onRefusal(t=>{t.deviceId===e&&o(t.error instanceof Error?t.error:Error(`connection ${t.end}`))});this.waiters.add(o),this.hello(n)}):Promise.resolve(r)}onLink(e){return this.linkHandlers.add(e),()=>this.linkHandlers.delete(e)}onRefusal(e){return this.refusalHandlers.add(e),()=>this.refusalHandlers.delete(e)}stop(){if(!this.stopped){this.stopped=!0;for(let e of this.unsubscribes.splice(0))e();for(let e of[...this.peers.values()])this.drop(e);for(let e of[...this.waiters])e(Error(`device mesh node stopped`));this.linkHandlers.clear(),this.refusalHandlers.clear()}}hello(e){this.stopped||this.options.relay.send(e.outbound,{v:1,kind:`hello`,from:this.instance})}receive(e,t){if(this.stopped)return;let n=this.byInbound.get(e);if(n===void 0)return;let r=Re(t);if(r===void 0)return;if(r.kind===`hello`){this.onHello(n,r.from);return}if(r.to!==this.instance)return;if(r.kind===`offer`){this.onOffer(n,r);return}for(let e of[n.pending,n.admitted])if(e?.cid===r.cid&&e.remoteInstance===r.from){e.link.onSignal(z(r));return}let i=n.waitingOffer;r.kind===`ice`&&i?.cid===r.cid&&i.from===r.from&&i.ice.length<64&&i.ice.push(z(r))}serves(e,t){return e.admitted?.remoteInstance===t||e.pending?.remoteInstance===t}onHello(e,t){if(!this.serves(e,t)){if(e.role===`answerer`){e.replies.run(()=>this.hello(e));return}e.attempts.run(()=>{this.stopped||this.peers.get(e.device.deviceId)!==e||this.serves(e,t)||this.startAttempt(e,t,Nt()).link.offer()})}}onOffer(e,t){if(e.role!==`answerer`||e.admitted?.cid===t.cid||e.pending?.cid===t.cid)return;let n={cid:t.cid,from:t.from,ice:[]};e.waitingOffer=n,e.attempts.run(()=>{if(e.waitingOffer===n&&(e.waitingOffer=void 0),this.stopped||this.peers.get(e.device.deviceId)!==e||e.admitted?.cid===t.cid||e.pending?.cid===t.cid)return;let{link:r}=this.startAttempt(e,t.from,t.cid);r.onSignal(z(t));for(let e of n.ice)r.onSignal(e)})}startAttempt(e,t,n){let r=e.pending;e.pending=void 0,r?.link.close();let i=r=>{this.stopped||this.options.relay.send(e.outbound,{v:1,from:this.instance,to:t,cid:n,...r})},a,o=new Ue({role:e.role,createPeer:async()=>{let{stage:t,servers:n}=await this.relayStage(e);return a!==void 0&&(a.relayStage=t),this.createPeer(n)},sendSignal:i,startHandshake:t=>(0,u.startDeviceHandshake)(this.options.cryptoContext,{role:e.role===`offerer`?`initiator`:`responder`,identity:this.identity,sessionDescriptor:this.sessionDescriptor,...e.role===`offerer`?{expectedPeerDeviceId:e.device.deviceId}:{},localFingerprint:t.localFingerprint,remoteFingerprint:t.remoteFingerprint,locality:`another-host`,localPolicy:this.options.localPolicy,send:t.send,...this.options.fetchLatestLists===void 0?{}:{fetchLatestLists:this.options.fetchLatestLists},onListsAdopted:e=>this.adoptLists(e),...this.options.now===void 0?{}:{now:this.options.now},...this.options.handshakeTimeoutMs===void 0?{}:{timeoutMs:this.options.handshakeTimeoutMs}}),connectTimeoutMs:this.options.connectTimeoutMs??Et,accepts:t=>t.admission.deviceId===e.device.deviceId,onAdmitted:t=>this.admitted(e,o,t),onEnded:(t,n)=>this.ended(e,o,t,n)});return a={cid:n,remoteInstance:t,link:o},e.pending=a,a}adoptLists(e){let t=this.identity,n={...t,...R(t.roster,e.roster)?{roster:e.roster}:{},...R(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation!==void 0&&e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Ft(t.marks,e.marks)};this.refresh({identity:n}).catch(()=>void 0),this.options.onListsAdopted?.(e)}admitted(e,t,n){let r=e.pending;if(r===void 0||r.link!==t)return;if(n.admission.deviceId!==e.device.deviceId){t.close();return}let i=n.admission,a=t.channelBinding;if(a===void 0){t.close();return}let o=new ee.ConnectionAuthority({deviceId:i.deviceId,sessionId:i.sessionId,locality:i.locality,capabilities:i.capabilities},this.options.operatorApprover);t.onEnd(()=>o.close());let s=o.authorize(`message`);t.onMessage(e=>{let t=Rt(e);t!==void 0&&this.receiveLists(t).catch(()=>void 0)});let c={admission:i,result:n,channelBinding:a,authority:o,send:e=>t.send(e),onMessage:e=>t.onMessage(n=>{Rt(n)===void 0&&s.then(r=>{r.allowed&&!t.ended?e(n):t.close()})}),openFileChannel:async()=>jt(await t.openFileChannel()),onFileChannel:e=>t.onFileChannel(t=>e(jt(t))),onClose:e=>t.onEnd(()=>e()),close:()=>t.close()};r.exposed=c,e.relayFailures=0;let l=e.admitted;e.admitted=r,e.pending=void 0,l?.link.close(),this.options.relay.confirmPeer?.(i.deviceId);for(let e of this.linkHandlers)e(c)}ended(e,t,n,r){if(e.admitted?.link===t){e.admitted=void 0;return}if(e.pending?.link!==t)return;let i=e.pending.relayStage;e.pending=void 0;let a=r.stage===`connecting`&&(n===`timeout`||r.peer?.state===`failed`)&&r.peer?.history.includes(`connected`)!==!0,o=r;r.cause instanceof L?o=r.cause:a&&i===`direct`?o=new L(e.device.deviceId,`no-direct-path`,{cause:r}):a&&(e.relayFailures+=1);let s={deviceId:e.device.deviceId,end:n,error:o};for(let e of this.refusalHandlers)e(s)}async relayStage(e){let t=this.options.relays,n=[],r=await this.embeddedRelays(e);if(r.length>0&&n.push({stage:`embedded`,servers:r}),t?.configured!==void 0&&t.configured.length>0&&n.push({stage:`configured`,servers:t.configured}),n.length===0){if(t?.relayOnly===!0)throw new L(e.device.deviceId,`relay-only`);return{stage:`direct`,servers:[]}}return n[e.relayFailures%n.length]}peerRoutes(e){let t=[...this.peers.values()];return(e===void 0?t:[e,...t.filter(t=>t!==e)]).map(e=>({deviceId:e.device.deviceId,inbound:e.inbound,outbound:e.outbound,rendezvous:e.rendezvous}))}async embeddedRelays(e){let t=this.options.relays?.advertised;if(t===void 0)return[];let n;try{n=await t(this.peerRoutes(e),AbortSignal.timeout(Ot))}catch{return[]}let r=e.device.deviceId,i=[r,...[...n.keys()].filter(e=>e!==r)],a=(this.options.now??Date.now)(),o=[],s=0;for(let e of i){if(s>=2)break;let t=n.get(e),r=this.peers.get(e);t!==void 0&&t.length!==0&&r!==void 0&&(s+=1,o.push(...await wt(r.rendezvous,t.slice(0,3),a,this.options.relays?.credentialTtlMs)))}return o}createPeer(e){let t=[...this.options.iceServers??[],...e];return new b({...t.length>0?{iceServers:t}:{},...this.options.relays?.relayOnly===!0?{forceTurn:!0}:{},...this.options.loadDataChannel===void 0?{}:{loadDataChannel:this.options.loadDataChannel}})}};function z(e){return e.kind===`ice`?{kind:`ice`,candidate:{...e.candidate}}:{kind:e.kind,sdp:e.sdp}}function Bt(){let e=new Map;return{connect(){let t={messages:new Set,absents:new Set,topics:new Set,open:!0},n=()=>{for(let n of t.topics)e.get(n)===t&&e.delete(n);t.topics=new Set};return{declarePresence(r){if(t.open){n(),t.topics=new Set(r);for(let n of r)e.set(n,t)}},send(n,r){if(!t.open)return;let i=JSON.parse(JSON.stringify(r));queueMicrotask(()=>{let r=e.get(n);if(r===void 0||r===t||!r.open){for(let e of t.absents)e(n);return}for(let e of r.messages)e(n,i)})},onMessage(e){return t.messages.add(e),()=>t.messages.delete(e)},onAbsent(e){return t.absents.add(e),()=>t.absents.delete(e)},close(){t.open=!1,n(),t.messages.clear(),t.absents.clear()}}}}}var Vt=class{options;socket;messages=new Set;absents=new Set;outbox=[];topics;closed=!1;constructor(e){this.options=e;let t=e.createSocket??(e=>new f.default(e));this.socket=t(e.url),this.socket.on(`open`,()=>this.flush()),this.socket.on(`message`,e=>this.receive(e)),this.socket.on(`error`,e=>this.options.onError?.(e instanceof Error?e:Error(String(e)))),this.socket.on(`close`,()=>{this.closed||this.options.onError?.(Error(`signaling relay connection closed`))})}flush(){this.topics!==void 0&&this.write({type:`presence`,topics:this.topics});for(let e of this.outbox.splice(0))this.socket.send(e)}write(e){this.socket.send(JSON.stringify(e))}receive(e){let t;try{t=JSON.parse(typeof e==`string`?e:String(e))}catch{return}if(typeof t!=`object`||!t)return;let n=t;if(n.type===`message`&&typeof n.topic==`string`)for(let e of this.messages)e(n.topic,n.data);else if(n.type===`absent`&&typeof n.topic==`string`)for(let e of this.absents)e(n.topic);else n.type===`present`?this.options.onPresent?.():n.type===`error`&&this.options.onError?.(Error(`signaling relay refused a frame: ${String(n.reason)}`))}declarePresence(e){this.closed||(this.topics=[...e],this.socket.readyState===1&&this.write({type:`presence`,topics:this.topics}))}send(e,t){if(this.closed)return;let n=JSON.stringify({type:`message`,topic:e,data:t});this.socket.readyState===1?this.socket.send(n):this.outbox.length<256?this.outbox.push(n):this.options.onError?.(Error(`signaling relay is not reachable; message dropped`))}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){this.closed=!0,this.messages.clear(),this.absents.clear(),this.outbox.length=0,this.socket.close()}};function Ht(e){return{candidates:t=>Promise.resolve(e.recall(t.deviceId))}}function Ut(e,t){return e.host===t.host&&e.port===t.port}function Wt(e,t){return[{host:t.host,port:t.port},...e.filter(e=>!Ut(e,t))].slice(0,3)}function Gt(){let e=new Map,t;return{recall:t=>e.get(t)??[],remember:(t,n)=>{e.set(t,Wt(e.get(t)??[],n))},retain:t=>{let n=new Set(t);for(let t of[...e.keys()])n.has(t)||e.delete(t)},lastListenPort:()=>t,rememberListenPort:e=>{t=e}}}const Kt=/^[A-Za-z0-9_-]{43}$/,qt=/^[A-Za-z0-9_-]{22}$/,Jt=12e4,Yt=1008;function B(e){return(0,p.createHash)(`sha256`).update(`lan-address:${e}`).digest(`base64url`)}function Xt(e,t){return(0,p.createHmac)(`sha256`,e).update(`lan-present:${t}`).digest(`base64url`)}function Zt(e,t,n){if(typeof n!=`string`)return!1;let r=Buffer.from(Xt(e,t)),i=Buffer.from(n);return i.length===r.length&&(0,p.timingSafeEqual)(i,r)}function Qt(e,t){return new Promise((n,r)=>{let i=new f.WebSocketServer({port:e,...t===void 0?{}:{host:t},maxPayload:65536,perMessageDeflate:!1,verifyClient:e=>e.origin===void 0||e.origin===``}),a=e=>{i.close(),r(e)};i.once(`error`,a),i.once(`listening`,()=>{i.off(`error`,a),n(i)})})}function $t(e){let t;try{t=JSON.parse(String(e))}catch{return}if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;if(!(typeof n.type!=`string`||typeof n.to!=`string`||!Kt.test(n.to)))return n.type===`probe`?typeof n.nonce==`string`&&qt.test(n.nonce)?{type:n.type,to:n.to,nonce:n.nonce}:void 0:{type:n.type,to:n.to,data:n.data}}async function en(e={}){let t;try{t=await Qt(e.port??0,e.host)}catch(n){if(e.port===void 0||e.port===0)throw n;t=await Qt(0,e.host)}let n=t.address(),r=typeof n==`object`&&n?n.port:0,i=new Map,a=new Set;return t.on(`connection`,e=>{if(t.clients.size>32){e.close(Yt);return}let n=0,r=Date.now(),o=setTimeout(()=>e.close(),Jt);o.unref?.(),e.on(`close`,()=>clearTimeout(o)),e.on(`error`,()=>e.close()),e.on(`message`,t=>{let s=Date.now();if(s-r>1e4&&(r=s,n=0),n+=1,n>128){e.close(Yt);return}clearTimeout(o),o=setTimeout(()=>e.close(),Jt),o.unref?.();let c=$t(t);if(c===void 0)return;let l=i.get(c.to);if(l===void 0){e.send(JSON.stringify({type:`absent`,to:c.to}));return}if(c.type===`probe`&&c.nonce!==void 0){e.send(JSON.stringify({type:`present`,to:c.to,nonce:c.nonce,proof:Xt(l,c.nonce)}));return}if(c.type===`message`)for(let e of a)e(l,c.data)})}),{port:r,setPresence(e){i=new Map(e.map(e=>[B(e),e]))},onMessage(e){return a.add(e),()=>a.delete(e)},close(){a.clear(),i=new Map;for(let e of t.clients)e.terminate();return new Promise(e=>t.close(()=>e()))}}}const V=`_rdv._tcp.local`;function tn(){return(0,d.createRequire)(require("url").pathToFileURL(__filename).href)(`multicast-dns`)()}function nn(){let e=[];for(let t of Object.values((0,h.networkInterfaces)()))for(let n of t??[])n.internal||(n.family===`IPv4`||n.family===`IPv6`&&!n.address.startsWith(`fe80`))&&e.push(n.address);return e}function rn(e){let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),Buffer.from(t).toString(`hex`)}function an(e){return Buffer.from(e.subarray(0,16)).toString(`hex`)}function on(e){return Math.max(8,Math.ceil(e/8)*8)}function H(e,t){return e.toLowerCase()===t.toLowerCase()}var sn=class{options;transport;routes=[];port;records;instances=new Set;timer;generation=0;closed=!1;epochCover;announced;lastAnswer;answerTimer;constructor(e={}){this.options=e}now(){return(this.options.now??Date.now)()}open(){if(!this.closed){if(this.transport!==void 0)return this.transport;try{let e=(this.options.createTransport??tn)();return e.on(`query`,e=>this.onQuery(e)),e.on(`error`,e=>this.options.onError?.(e)),this.transport=e,e}catch(e){this.closed=!0,this.options.onError?.(e instanceof Error?e:Error(String(e)));return}}}advertise(e,t){return this.routes=e,this.port=t,this.rebuild()}async rebuild(){let e=++this.generation,t=this.port;if(this.closed||t===void 0)return;let n=(0,u.rendezvousEpoch)(this.now()),r=await Promise.all(this.routes.map(e=>e.rendezvous.tag(`mdns`,`outbound`,n)));if(e!==this.generation||this.closed)return;this.epochCover?.epoch!==n&&(this.epochCover={epoch:n,padding:[],target:`${rn(8)}.local`});let{padding:i,target:a}=this.epochCover,o=on(r.length)-r.length;for(;i.length<o;)i.push(rn(16));let s=[...r.map(an),...i.slice(0,o)].sort(),c=JSON.stringify([n,t,s]),l=s.map(e=>({name:V,type:`PTR`,ttl:120,data:`${e}.${V}`})),d=[];for(let e of s){let n=`${e}.${V}`;d.push({name:n,type:`SRV`,ttl:120,data:{priority:0,weight:0,port:t,target:a}},{name:n,type:`TXT`,ttl:120,data:[]})}for(let e of(this.options.addresses??nn)())d.push({name:a,type:e.includes(`:`)?`AAAA`:`A`,ttl:120,data:e});this.records={answers:l,additionals:d},this.instances=new Set(s.map(e=>`${e}.${V}`.toLowerCase())),this.schedule(n),c!==this.announced&&(this.announced=c,this.open()?.respond(this.records))}schedule(e){this.timer!==void 0&&clearTimeout(this.timer);let t=Math.max(0,(e+1)*u.RENDEZVOUS_EPOCH_MS-this.now());this.timer=setTimeout(()=>{this.rebuild().catch(()=>void 0)},t),this.timer.unref?.()}onQuery(e){this.records===void 0||this.closed||(e.questions??[]).some(e=>H(e.name,`_rdv._tcp.local`)&&(e.type===`PTR`||e.type===`ANY`)||this.instances.has(e.name.toLowerCase()))&&this.answer()}answer(){if(this.answerTimer!==void 0)return;let e=this.options.minAnswerIntervalMs??500,t=this.lastAnswer===void 0?0:this.lastAnswer+e-this.now(),n=()=>{this.answerTimer=void 0,!(this.closed||this.records===void 0)&&(this.lastAnswer=this.now(),this.transport?.respond(this.records))};if(t<=0){n();return}this.answerTimer=setTimeout(n,t),this.answerTimer.unref?.()}async candidates(e,t){let n=this.open();if(n===void 0||t.aborted)return[];let r=(0,u.rendezvousEpoch)(this.now()),i=new Set((await e.rendezvous.lookupTags(`mdns`,r)).map(e=>`${an(e)}.${V}`));return t.aborted||this.closed?[]:new Promise(e=>{let r=[],a,o=()=>{clearTimeout(c),clearTimeout(a),t.removeEventListener(`abort`,o),n.removeListener(`response`,s),e(r)},s=(e,t)=>{let n=[...e.answers??[],...e.additionals??[]];for(let e of n){if(e.type!==`PTR`||!H(e.name,`_rdv._tcp.local`)||typeof e.data!=`string`||!i.has(e.data.toLowerCase()))continue;let a=n.find(t=>t.type===`SRV`&&H(t.name,e.data))?.data?.port;if(typeof a!=`number`||!Number.isInteger(a)||a<=0||a>65535)continue;let o=r.filter(e=>e.host===t.address);r.length<8&&o.length<2&&!o.some(e=>e.port===a)&&r.push({host:t.address,port:a})}r.length!==0&&a===void 0&&(a=setTimeout(o,this.options.answerGraceMs??200),a.unref?.())},c=setTimeout(o,this.options.lookupTimeoutMs??1e3);c.unref?.(),t.addEventListener(`abort`,o,{once:!0}),n.on(`response`,s),n.query({questions:[{name:V,type:`PTR`}]})})}close(){this.closed=!0,this.generation+=1,this.timer!==void 0&&clearTimeout(this.timer),this.answerTimer!==void 0&&clearTimeout(this.answerTimer),this.transport?.destroy(),this.transport=void 0}};function cn(){let e=new Set,t=[],n=(t,n,r)=>{let i=JSON.parse(JSON.stringify(n));queueMicrotask(()=>{for(let n of e)for(let e of r(n))e(i,{address:t.address})})};return{responses:t,transport(r){let i={address:r,queries:new Set,responses:new Set};return e.add(i),{on(e,t){e===`query`&&i.queries.add(t),e===`response`&&i.responses.add(t)},removeListener(e,t){i.responses.delete(t)},query(e){n(i,e,e=>e.queries)},respond(e){t.push(JSON.parse(JSON.stringify(e))),n(i,e,e=>e.responses)},destroy(){e.delete(i)}}}}}var ln=class{until=new Map;failures=new Map;has(e,t){let n=this.until.get(e);return n===void 0?!1:n>t?!0:(this.until.delete(e),!1)}fail(e,t,n){let r=(this.failures.get(e)??0)+1;this.failures.delete(e),this.failures.set(e,r);for(let e of this.failures.keys()){if(this.failures.size<=32)break;this.failures.delete(e),this.until.delete(e)}let i=Math.min(2**(r-1),16);this.until.set(e,t+n*i)}clear(){this.until.clear(),this.failures.clear()}};function un(e){if(typeof e!=`object`||!e)return!1;let t=e.kind;return t===`hello`||t===`offer`||t===`answer`}function dn(e){return`${e.host}:${e.port}`}function fn(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function pn(e){return Buffer.from(e).toString(`base64url`)}function mn(e){return`ws://${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}`}function hn(e){try{let t=JSON.parse(String(e));return typeof t==`object`&&t?t:void 0}catch{return}}var gn=class{options;routes=new Map;byDevice=new Map;lanIn=new Map;messages=new Set;absents=new Set;unsubscribes=[];abort=new AbortController;sync=Promise.resolve();pendingPeers=0;waiting=[];timer;closed=!1;constructor(e){this.options=e;for(let e of this.carriers())this.unsubscribes.push(e.onMessage((e,t)=>this.deliver(e,t)),e.onAbsent(e=>this.absent(e)));this.unsubscribes.push(e.listener.onMessage((e,t)=>{let n=this.lanIn.get(e);n!==void 0&&this.deliver(n,t)}))}now(){return(this.options.now??Date.now)()}carriers(){return[...this.options.signaling??[],...this.options.relay===void 0?[]:[this.options.relay]]}deliver(e,t){if(!this.closed)for(let n of this.messages)n(e,t)}absent(e){if(!this.closed)for(let t of this.absents)t(e)}declarePresence(e){for(let t of this.carriers())t.declarePresence(e)}declarePeers(e){for(let t of this.carriers())t.declarePeers?.(e);this.pendingPeers+=1,this.sync=this.sync.then(()=>this.applyPeers(e)).catch(e=>{this.options.onError?.(e instanceof Error?e:Error(String(e)))}).finally(()=>{if(--this.pendingPeers,!(this.pendingPeers>0))for(let{topic:e,data:t}of this.waiting.splice(0))this.send(e,t)})}async applyPeers(e){if(this.closed)return;let t=(0,u.rendezvousEpoch)(this.now()),n=new Map,r=new Map;for(let i of e){let e=pn(await i.rendezvous.tag(`lan-inbox`,`outbound`,t));for(let e of await i.rendezvous.lookupTags(`lan-inbox`,t))n.set(pn(e),i.inbound);let a=this.routes.get(i.outbound),o=a!==void 0&&a.route.deviceId===i.deviceId?a:{route:i,lanOut:e,path:{kind:`unresolved`},avoid:new ln,avoidCarriers:new ln};o.route=i,o.lanOut=e,r.set(i.outbound,o)}if(!this.closed){for(let[e,t]of this.routes)r.get(e)!==t&&this.reset(t);this.routes.clear(),this.byDevice.clear();for(let[e,t]of r)this.routes.set(e,t),this.byDevice.set(t.route.deviceId,t);this.lanIn=n,this.options.listener.setPresence([...n.keys()]),this.cacheWrite(()=>this.options.cache?.retain(e.map(e=>e.deviceId))),await Promise.all((this.options.advertisers??[]).map(t=>t.advertise(e,this.options.listener.port))),!this.closed&&this.scheduleEpoch(t,e)}}scheduleEpoch(e,t){this.timer!==void 0&&clearTimeout(this.timer);let n=Math.max(0,(e+1)*u.RENDEZVOUS_EPOCH_MS-this.now());this.timer=setTimeout(()=>this.declarePeers(t),n),this.timer.unref?.()}confirmPeer(e){let t=this.byDevice.get(e),n=t?.path;if(!(t===void 0||n?.kind!==`direct`&&n?.kind!==`relay`)){if(clearTimeout(n.deadline),n.deadline=void 0,n.kind===`relay`){t.avoidCarriers.clear();return}t.avoid.clear(),this.cacheWrite(()=>this.options.cache?.remember(e,n.candidate))}}cacheWrite(e){try{e()}catch(e){this.options.onError?.(e instanceof Error?e:Error(String(e)))}}send(e,t){if(this.closed)return;if(this.pendingPeers>0){this.waiting.length<256?this.waiting.push({topic:e,data:t}):this.viaRelay(e,t);return}let n=this.routes.get(e);if(n===void 0){this.viaRelay(e,t);return}let r=n.path;if(r.kind===`direct`&&r.socket.readyState===1){this.sendDirect(n,r,t);return}if(r.kind===`relay`&&this.now()<r.until){this.viaCarrier(n,r,t);return}if(r.kind===`resolving`){r.queue.length<256?r.queue.push(t):this.viaRelay(e,t);return}r.kind===`direct`&&this.reset(n);let i=[t];n.path={kind:`resolving`,queue:i},this.resolve(n,i)}sendDirect(e,t,n){un(n)&&this.armDeadline(e,t),t.socket.send(JSON.stringify({type:`message`,to:B(e.lanOut),data:n}))}viaRelay(e,t){let n=this.carriers().at(-1);if(n===void 0){queueMicrotask(()=>this.absent(e));return}n.send(e,t)}viaCarrier(e,t,n){un(n)&&t.carrier!==this.carriers().at(-1)&&this.armDeadline(e,t),t.carrier.send(e.route.outbound,n)}async resolve(e,t){let n=new Set;for(let r of this.options.sources){if(this.closed||e.path.kind!==`resolving`)return;for(let i of await this.look(r,e.route)){let r=dn(i);if(n.size>=8)break;if(n.has(r)||e.avoid.has(r,this.now()))continue;n.add(r);let a=await this.probe(i,e.lanOut);if(a===void 0)continue;if(this.closed||e.path.kind!==`resolving`||this.routes.get(e.route.outbound)!==e){a.close();return}let o=this.useDirect(e,a,i);for(let n of t)this.sendDirect(e,o,n);return}}if(this.closed||e.path.kind!==`resolving`)return;this.fallBack(e);let r=e.path;for(let n of t)r.kind===`relay`?this.viaCarrier(e,r,n):this.viaRelay(e.route.outbound,n)}fallBack(e){let t=this.now(),n=this.carriers(),r=n.find(n=>!e.avoidCarriers.has(n,t))??n.at(-1);e.path=r===void 0?{kind:`unresolved`}:{kind:`relay`,until:t+this.recheckMs(),carrier:r}}recheckMs(){return this.options.relayRecheckMs??3e4}async look(e,t){let n=AbortSignal.timeout(e.timeoutMs??this.options.sourceTimeoutMs??1500),r=AbortSignal.any([n,this.abort.signal]);try{return await Promise.race([e.candidates(t,r),new Promise(e=>r.addEventListener(`abort`,()=>e([]),{once:!0}))])}catch{return[]}}probe(e,t){let n=B(t),r=fn();return new Promise(i=>{let a;try{a=(this.options.connect??(e=>new f.default(mn(e),{maxPayload:4096})))(e)}catch{i(void 0);return}let o=!1,s=e=>{o||(o=!0,clearTimeout(c),e||a.close(),i(e?a:void 0))},c=setTimeout(()=>s(!1),this.options.probeTimeoutMs??1500);c.unref?.(),a.on(`open`,()=>a.send(JSON.stringify({type:`probe`,to:n,nonce:r}))),a.on(`message`,e=>{let i=hn(e);if(i?.to===n){if(i.type===`absent`){s(!1);return}s(Zt(t,r,i.proof))}}),a.on(`error`,()=>s(!1)),a.on(`close`,()=>s(!1))})}armDeadline(e,t){t.deadline===void 0&&(t.deadline=setTimeout(()=>{e.path===t&&(t.kind===`direct`?e.avoid.fail(dn(t.candidate),this.now(),this.recheckMs()):e.avoidCarriers.fail(t.carrier,this.now(),this.recheckMs()),this.reset(e),this.fallBack(e))},this.options.admissionTimeoutMs??2e4),t.deadline.unref?.())}useDirect(e,t,n){let r={kind:`direct`,socket:t,candidate:n};e.path=r;let i=()=>{e.path===r&&this.reset(e)};return t.on(`close`,i),t.on(`error`,i),t.on(`message`,t=>{let n=hn(t);n?.type===`absent`&&n.to===B(e.lanOut)&&i()}),r}reset(e){let t=e.path;e.path={kind:`unresolved`},t.kind===`relay`&&clearTimeout(t.deadline),t.kind===`direct`&&(clearTimeout(t.deadline),t.socket.close())}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){if(!this.closed){this.closed=!0,this.abort.abort(),this.timer!==void 0&&clearTimeout(this.timer);for(let e of this.unsubscribes.splice(0))e();for(let e of this.routes.values())this.reset(e);this.routes.clear(),this.byDevice.clear(),this.messages.clear(),this.absents.clear(),this.waiting=[];for(let e of this.options.advertisers??[])e.close();this.options.listener.close().catch(()=>void 0)}}};async function _n(e={}){let t=e.cache??Gt(),n=t.lastListenPort(),r=await en({...n===void 0?{}:{port:n},...e.host===void 0?{}:{host:e.host}});try{t.rememberListenPort(r.port)}catch(t){e.onError?.(t instanceof Error?t:Error(String(t)))}let i=e.mdns===!1?void 0:new sn({...e.onError===void 0?{}:{onError:e.onError},...e.mdns}),a=e.internet?.dht,o=e.internet?.signaling??[];return new gn({...e.relay===void 0?{}:{relay:e.relay},...o.length>0?{signaling:o}:{},listener:r,sources:[Ht(t),...i===void 0?[]:[i],...a===void 0?[]:[a]],cache:t,advertisers:[...i===void 0?[]:[i],...a===void 0?[]:[a]],...e.onError===void 0?{}:{onError:e.onError}})}const vn=Uint8Array.from([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),U=new TextEncoder,yn=new TextDecoder;function W(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function bn(e){let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),n=new Uint8Array(t.length);for(let e=0;e<t.length;e+=1)n[e]=t.charCodeAt(e);return n}function G(e){let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t}function xn(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r+=1)n|=e[r]^t[r];return n===0}async function Sn(e){if(e.length!==32)throw Error(`an Ed25519 seed is 32 bytes`);let t=await globalThis.crypto.subtle.importKey(`pkcs8`,W(G([vn,e])),{name:`Ed25519`},!0,[`sign`]),n=await globalThis.crypto.subtle.exportKey(`jwk`,t);if(typeof n.x!=`string`)throw Error(`Ed25519 public key unavailable`);return{publicKey:bn(n.x),sign:async e=>new Uint8Array(await globalThis.crypto.subtle.sign({name:`Ed25519`},t,W(e)))}}async function Cn(e,t,n){if(e.length!==32||n.length!==64)return!1;try{let r=await globalThis.crypto.subtle.importKey(`raw`,W(e),{name:`Ed25519`},!1,[`verify`]);return await globalThis.crypto.subtle.verify({name:`Ed25519`},r,W(n),W(t))}catch{return!1}}function K(e,t,n){let r=[];return e!==void 0&&e.length>0&&r.push(U.encode(`4:salt${e.length}:`),e),r.push(U.encode(`3:seqi${t}e1:v${n.length}:`),n),G(r)}async function wn(e,t,n,r){if(r.length>999)throw Error(`record value exceeds 999 bytes`);if(t!==void 0&&t.length>64)throw Error(`salt exceeds 64 bytes`);if(!Number.isSafeInteger(n)||n<0)throw Error(`seq must be a non-negative integer`);let i=await e.sign(K(t,n,r));return{k:e.publicKey,...t===void 0?{}:{salt:t},seq:n,v:r,sig:i}}async function q(e,t,n){return!xn(e.k,t)||!xn(e.salt??new Uint8Array,n??new Uint8Array)||e.v.length>999||!Number.isSafeInteger(e.seq)||e.seq<0?!1:Cn(t,K(n,e.seq,e.v),e.sig)}const Tn={hints:`bep44-salt`,revocation:`bep44-revocation-salt`};async function J(e){return new Uint8Array(await globalThis.crypto.subtle.digest(`SHA-256`,W(G(e))))}async function En(e,t,n,r,i=0){let[a,o]=await Promise.all([e.signingSeed(n,r,t),e.tag(Tn[t],n,r)]);if(i===0)return{key:await Sn(a),salt:o};let s=U.encode(`chunk`),c=Uint8Array.of(i),[l,u]=await Promise.all([J([s,a,c]),J([s,o,c])]);return{key:await Sn(l),salt:u}}async function Dn(e){let t=U.encode(JSON.stringify(e)),n=(await J([t])).subarray(0,8),r=Math.max(1,Math.ceil(t.length/854));if(r>8)throw Error(`device lists too large to publish as records`);return Array.from({length:r},(e,i)=>{let a=new Uint8Array(864).fill(32);return a[0]=r,a[1]=i,a.set(n,2),a.set(t.subarray(i*854,(i+1)*854),10),a})}function On(e){let t=e[0];if(e.length===864&&e[1]===0)return t!==void 0&&t>=1&&t<=8?t:void 0}function kn(e){let t=e.length,n=e[0]?.subarray(2,10),r=[];for(let[i,a]of e.entries()){if(a.length!==864||a[0]!==t||a[1]!==i||!An(a.subarray(2,10),n))return;r.push(a.subarray(10))}return Y(G(r))}function An(e,t){return t!==void 0&&e.length===t.length&&e.every((e,n)=>e===t[n])}function jn(e,t){let n=U.encode(JSON.stringify(e));if(n.length>t)throw Error(`record does not fit its fixed size`);let r=new Uint8Array(t).fill(32);return r.set(n),r}function Y(e){try{return JSON.parse(yn.decode(e))}catch{return}}function Mn(e,t){let n=[];for(let r of e){if(n.length>=t)break;r.host.length===0||r.host.length>64||n.push([r.host,r.port])}return n}function Nn(e,t=[]){let n=Mn(e,8),r=Mn(t,4);for(;;)try{return jn({v:1,c:n,...r.length>0?{t:r}:{}},640)}catch(e){if(n.length>0)n.pop();else if(r.length>0)r.pop();else throw e}}const Pn=/^[0-9A-Za-z.:%_-]{1,64}$/;function Fn(e){return Ln(e,`c`,8)}function In(e){return Ln(e,`t`,4)}function Ln(e,t,n){let r=Y(e);if(typeof r!=`object`||!r)return[];let i=r,a=i[t];if(i.v!==1||!Array.isArray(a))return[];let o=[];for(let e of a.slice(0,n)){if(!Array.isArray(e)||e.length!==2)continue;let[t,n]=e;typeof t!=`string`||!Pn.test(t)||typeof n!=`number`||!Number.isInteger(n)||n<1||n>65535||o.push({host:t,port:n})}return o}function Rn(e,t=Math.random){let n=t();return Math.floor((Number.isFinite(n)?Math.min(Math.max(n,0),1):0)*Math.max(0,e))}function zn(e){if(typeof e!=`object`||!e)return-1;let t=e.seq;return typeof t==`number`&&Number.isSafeInteger(t)?t:-1}function X(e){return e instanceof Error?e:Error(String(e))}var Bn=class{options;timeoutMs;scheduled=new Map;routes=[];listsFound;prefetchedEpoch;relaysFound=new Map;relayLookups=new Map;closed=!1;constructor(e){this.options=e,this.timeoutMs=e.lookupTimeoutMs??6e3}now(){return(this.options.now??Date.now)()}async candidates(e,t){let n=(0,u.rendezvousEpoch)(this.now()),r=await this.lookup(e,`hints`,n,t);t.aborted||this.rememberRelays(e,n,r);let i=[],a=new Set;for(let e of r.sort((e,t)=>t.epoch-e.epoch))for(let t of Fn(e.data)){let e=`${t.host}:${t.port}`;a.has(e)||(a.add(e),i.push(t))}return i}rememberRelays(e,t,n){let r=[...n].sort((e,t)=>t.epoch-e.epoch)[0],i=r===void 0?[]:In(r.data);this.relaysFound.set(e.deviceId,{epoch:t,checkedAt:this.now(),endpoints:i})}async relayAdverts(e,t){let n=this.now(),r=(0,u.rendezvousEpoch)(n),i=e.slice(0,16),a=[];for(let e of i){let t=this.relaysFound.get(e.deviceId);t!==void 0&&t.epoch===r&&(t.endpoints.length>0||n-t.checkedAt<12e4)||a.push(this.lookUpRelay(e,r))}if(a.length>0){let e=new Promise(e=>{t.aborted&&e(),t.addEventListener(`abort`,()=>e(),{once:!0})});await Promise.race([Promise.all(a),e])}let o=new Set(e.map(e=>e.deviceId));for(let e of[...this.relaysFound.keys()])o.has(e)||this.relaysFound.delete(e);let s=new Map;for(let e of i){let t=this.relaysFound.get(e.deviceId)?.endpoints??[];t.length>0&&s.set(e.deviceId,t)}return s}lookUpRelay(e,t){let n=this.relayLookups.get(e.deviceId);if(n!==void 0)return n;let r=AbortSignal.timeout(this.timeoutMs),i=this.lookup(e,`hints`,t,r).then(n=>{!r.aborted&&!this.closed&&this.rememberRelays(e,t,n)}).finally(()=>this.relayLookups.delete(e.deviceId));return this.relayLookups.set(e.deviceId,i),i}async lookup(e,t,n,r){let i=[n-1,n,n+1].flatMap(n=>this.options.stores.map(async i=>{let a=await this.read(i,e,t,n,0,r);return a===void 0?void 0:{epoch:n,data:a}}));return(await Promise.all(i)).filter(e=>e!==void 0)}async read(e,t,n,r,i,a){try{let o=await En(t.rendezvous,n,`inbound`,r,i),s=await e.get(o.key.publicKey,o.salt,a);if(s===void 0)return;let c=await t.rendezvous.openRecord(s,r,n);return c?.epoch===r?c.hints:void 0}catch{return}}async lookupLists(e,t,n){let r=[t-1,t,t+1].flatMap(t=>this.options.stores.map(async r=>{let i=await this.read(r,e,`revocation`,t,0,n),a=i===void 0?void 0:On(i);if(i===void 0||a===void 0)return;let o=await Promise.all(Array.from({length:a-1},(i,a)=>this.read(r,e,`revocation`,t,a+1,n)));if(!o.some(e=>e===void 0))return kn([i,...o])}));return(await Promise.all(r)).filter(e=>e!==void 0)}advertise(e,t){if(this.closed)return Promise.resolve();this.routes=e;let n=(0,u.rendezvousEpoch)(this.now()),r=new Set(e.map(e=>e.outbound));for(let[e,t]of this.scheduled)r.has(e)||(clearTimeout(t.timer),this.scheduled.delete(e));this.prefetchedEpoch!==n&&(this.prefetchedEpoch=n,this.findLists(AbortSignal.timeout(3e4)));let i=this.options.maxPublishJitterMs??9e4;for(let r of e){let e=this.scheduled.get(r.outbound);if(e!==void 0&&e.epoch===n&&e.port===t)continue;e!==void 0&&clearTimeout(e.timer);let a=setTimeout(()=>{this.scheduled.delete(r.outbound),this.publish(r,t)},Rn(i,this.options.random));a.unref?.(),this.scheduled.set(r.outbound,{timer:a,epoch:n,port:t})}return Promise.resolve()}async publish(e,t){if(this.closed)return;let n=this.now(),r=(0,u.rendezvousEpoch)(n),i=[];try{i.push({purpose:`hints`,chunk:0,plaintext:Nn(this.options.addresses().map(e=>({host:e,port:t})),this.options.relayEndpoints?.()??[])});let e=this.options.lists?.();if(e!==void 0){let t=await Dn({r:e.revocation,...e.signingKeyRevocation===void 0?{}:{s:e.signingKeyRevocation}});for(let[e,n]of t.entries())i.push({purpose:`revocation`,chunk:e,plaintext:n})}}catch(e){this.options.onError?.(X(e))}for(let{purpose:t,chunk:a,plaintext:o}of i)try{let i=await e.rendezvous.sealRecord(o,r,t),s=await En(e.rendezvous,t,`outbound`,r,a),c=await Promise.allSettled(this.options.stores.map(e=>e.put(s,i,n)));for(let e of c)e.status===`rejected`&&this.options.onError?.(X(e.reason))}catch(e){this.options.onError?.(X(e))}}async latestLists(e){let t=new Promise(t=>{e.aborted&&t(void 0),e.addEventListener(`abort`,()=>t(void 0),{once:!0})});return await Promise.race([this.findLists(e),t])??this.listsFound}async findLists(e){let t=(0,u.rendezvousEpoch)(this.now()),n=await Promise.all(this.routes.slice(0,16).map(n=>this.lookupLists(n,t,e))),r=[],i=[];for(let e of n){let t=[],n=[];for(let r of e){if(typeof r!=`object`||!r)continue;let e=r;e.r!==void 0&&t.push(e.r),e.s!==void 0&&n.push(e.s)}r.push(t),i.push(n)}let a=Un(r),o=Un(i),s=a.length===0&&o.length===0?void 0:{...a.length>0?{revocation:a}:{},...o.length>0?{signingKeyRevocation:o}:{}};return e.aborted||(this.listsFound=s),s}close(){if(!this.closed){this.closed=!0;for(let{timer:e}of this.scheduled.values())clearTimeout(e);this.scheduled.clear();for(let e of this.options.stores)e.close()}}};function Vn(e){let t=new Set;return e.filter(e=>{let n=JSON.stringify(e);return t.has(n)?!1:(t.add(n),!0)})}function Hn(e){return Vn(e).sort((e,t)=>zn(t)-zn(e))}function Un(e){let t=e.map(e=>Hn(e).slice(0,2)),n=[];for(let e=0;e<2;e+=1)n.push(...Hn(t.flatMap(t=>t.slice(e,e+1))));return Vn(n).slice(0,16)}function Wn(e){let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}function Gn(){let e=new Map,t=e=>e,n=(e,t)=>`${Wn(e)}/${Wn(t??new Uint8Array)}`;return{store:()=>({async put(t,r,i){let a=await wn(t.key,t.salt,Math.floor(i/1e3),r);if(!await q(a,a.k,a.salt))throw Error(`item refused`);let o=n(a.k,a.salt),s=e.get(o);if(s!==void 0&&s.seq>a.seq)throw Error(`item refused: older seq`);e.set(o,a)},async get(r,i){await Promise.resolve();let a=e.get(n(r,i)),o=a===void 0?void 0:t(a);if(o!==void 0)return await q(o,r,i)?o.v:void 0},close:()=>void 0}),items:()=>[...e.values()],serve:e=>{t=e}}}const Kn=`ybndrfg8ejkmcpqxot1uwisza345h769`;function qn(e){let t=``,n=0,r=0;for(let i of e)for(n=n<<8|i,r+=8;r>=5;)t+=Kn[n>>>r-5&31],r-=5;return r>0&&(t+=Kn[n<<5-r&31]),t}function Z(e){return Uint8Array.from([e>>>8&255,e&255])}function Jn(e,t){let n=G([...[`_r`,qn(e)].flatMap(e=>[Uint8Array.of(e.length),new TextEncoder().encode(e)]),Uint8Array.of(0)]),r=[];for(let e=0;e<t.length;e+=255){let n=t.subarray(e,e+255);r.push(Uint8Array.of(n.length),n)}t.length===0&&r.push(Uint8Array.of(0));let i=G(r);return G([Uint8Array.from([0,0,132,0,0,0,0,1,0,0,0,0]),n,Z(16),Z(1),Uint8Array.from([0,0,1,44]),Z(i.length),i])}function Yn(e){let t=t=>(e[t]??0)<<8|(e[t+1]??0);if(e.length<12)return;let n=t(4),r=t(6),i=12,a=()=>{for(let t=0;t<128;t+=1){let t=e[i];if(t===void 0)return!1;if(t===0)return i+=1,!0;if((t&192)==192)return i+=2,!0;i+=1+t}return!1};for(let e=0;e<n;e+=1){if(!a())return;i+=4}for(let n=0;n<r;n+=1){if(!a()||i+10>e.length)return;let n=t(i),r=t(i+8),o=i+10,s=o+r;if(s>e.length)return;if(n===16){let t=[],n=o;for(;n<s;){let r=e[n];if(n+1+r>s)return;t.push(e.subarray(n+1,n+1+r)),n+=1+r}return G(t)}i=s}}function Xn(e){let t=new Uint8Array(8);return new DataView(t.buffer).setBigUint64(0,BigInt(e)),t}function Zn(e){let t=e.length;for(;t>0&&e[t-1]===`/`;)--t;return e.slice(0,t)}function Qn(e){let t=e.fetch??globalThis.fetch.bind(globalThis),n=(e,t)=>`${Zn(e)}/${qn(t)}`;return{async put(r,i,a,o){let s=Jn(r.key.publicKey,i);if(s.length>999)throw Error(`record too large for a pkarr relay`);let c=Math.floor(a)*1e3,l=G([await r.key.sign(K(void 0,c,s)),Xn(c),s]);if(!(await Promise.allSettled(e.relays.map(async e=>{let i=await t(n(e,r.key.publicKey),{method:`PUT`,headers:{"content-type":`application/pkarr.org/relays#payload`},body:l.slice().buffer,...o===void 0?{}:{signal:o}});if(!i.ok)throw Error(`pkarr relay refused (${i.status})`)}))).some(e=>e.status===`fulfilled`))throw Error(`no pkarr relay took the record`)},async get(r,i,a){let o=await Promise.all(e.relays.map(async e=>{try{let i=await t(n(e,r),{signal:a});if(!i.ok)return;let o=new Uint8Array(await i.arrayBuffer());if(o.length<=72||o.length>1200)return;let s=o.subarray(0,64),c=Number(new DataView(o.buffer,o.byteOffset+64,8).getBigUint64(0)),l=o.slice(72);if(!Number.isSafeInteger(c)||!await Cn(r,K(void 0,c,l),s))return;let u=Yn(l);return u===void 0?void 0:{seq:c,value:u}}catch{return}})),s;for(let e of o)e!==void 0&&(s===void 0||e.seq>s.seq)&&(s=e);return s?.value},close:()=>void 0}}const $n=Uint8Array.from([48,42,48,5,6,3,43,101,112,3,33,0]),er=(e,t,n)=>{if(n.length!==32||e.length!==64)return!1;try{return(0,p.verify)(null,t,(0,p.createPublicKey)({key:Buffer.from(G([$n,n])),format:`der`,type:`spki`}),e)}catch{return!1}};async function tr(e){return new(await(import(`bittorrent-dht`))).default({verify:e})}function Q(e){return Buffer.from(e.buffer,e.byteOffset,e.byteLength)}function nr(e){if(e!==void 0)return new Promise((t,n)=>{e.aborted&&n(Error(`aborted`)),e.addEventListener(`abort`,()=>n(Error(`aborted`)),{once:!0})})}async function rr(e={}){let t=await(e.createDht??tr)(er),n=t=>e.onError?.(t);t.on(`error`,n),t.on(`warning`,n);let r=!1;return{async put(e,n,i,a){if(r)throw Error(`DHT store closed`);if(n.length>999)throw Error(`record value exceeds 999 bytes`);let o=await wn(e.key,e.salt,Math.floor(i/1e3),n),s=new Promise((n,r)=>{t.put({k:Q(o.k),salt:Q(e.salt),seq:o.seq,v:Q(o.v),sig:Q(o.sig)},(e,t,i)=>{e===null?i===0?r(Error(`no DHT node took the record`)):n():r(e)})}),c=nr(a);await(c===void 0?s:Promise.race([s,c]))},async get(e,n,i){if(r||i.aborted)return;let a=(0,p.createHash)(`sha1`).update(G([e,n])).digest(),o=new Promise(e=>{t.get(a,{salt:Q(n),cache:!1},(t,n)=>e(t===null?n:null))});try{let t=await Promise.race([o,nr(i)]);if(t?.v===void 0||t.k===void 0||t.sig===void 0)return;let r={k:new Uint8Array(t.k),salt:n,seq:t.seq??0,v:new Uint8Array(t.v),sig:new Uint8Array(t.sig)};return await q(r,e,n)?r.v:void 0}catch{return}},close(){r||(r=!0,t.destroy())}}}const ir=/^[0-9a-f]{64}$/,ar=/^[0-9a-f]{128}$/;function or(e){return 2e4+((e[0]??0)<<8|(e[1]??0))%1e4}function sr(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function cr(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e+=1)n[e]=t.charCodeAt(e);return n}catch{return}}function lr(e){if(typeof e!=`object`||!e)return;let t=e;if(!(typeof t.id!=`string`||!ir.test(t.id))&&!(typeof t.pubkey!=`string`||!ir.test(t.pubkey))&&!(typeof t.sig!=`string`||!ar.test(t.sig))&&!(typeof t.kind!=`number`||!Number.isInteger(t.kind))&&!(typeof t.created_at!=`number`||!Number.isInteger(t.created_at))&&!(typeof t.content!=`string`||t.content.length>49152)&&!(!Array.isArray(t.tags)||t.tags.length!==0))return{id:t.id,pubkey:t.pubkey,sig:t.sig,kind:t.kind,created_at:t.created_at,content:t.content,tags:[]}}var ur=class{options;messages=new Set;absents=new Set;outbound=new Map;inbound=new Map;subscription;chain=Promise.resolve();seen=new Set;routes=[];epoch;timer;closed=!1;constructor(e){this.options=e}now(){return(this.options.now??Date.now)()}report(e){this.options.onError?.(e instanceof Error?e:Error(String(e)))}enqueue(e){this.chain=this.chain.then(e).catch(e=>this.report(e))}whenIdle(){return this.chain}declarePresence(){}declarePeers(e){this.enqueue(()=>this.derive(e))}async derive(e){if(this.closed)return;this.routes=e;let t=(0,u.rendezvousEpoch)(this.now()),n=new Map,r=new Map;for(let i of e){let e=await i.rendezvous.signingSeed(`outbound`,t,`signal`),a=or(await i.rendezvous.tag(`nostr-kind`,`outbound`,t));n.set(i.outbound,{route:i,epoch:t,secretKey:e,kind:a});for(let e of[t-1,t,t+1]){let t=await i.rendezvous.signingSeed(`inbound`,e,`signal`),n=or(await i.rendezvous.tag(`nostr-kind`,`inbound`,e));r.set((0,g.getPublicKey)(t),{route:i,epoch:e,kind:n})}}this.closed||(this.outbound=n,this.inbound=r,this.epoch=t,this.subscription?.close(),this.subscription=r.size===0?void 0:this.options.pool.subscribe({kinds:[...new Set([...r.values()].map(e=>e.kind))],authors:[...r.keys()],since:Math.floor(this.now()/1e3)-(this.options.maxEventAgeS??120)},e=>this.enqueue(()=>this.receive(e))),this.timer!==void 0&&clearTimeout(this.timer),this.timer=setTimeout(()=>this.declarePeers(this.routes),Math.max(0,(t+1)*u.RENDEZVOUS_EPOCH_MS-this.now())),this.timer.unref?.())}send(e,t){this.closed||this.enqueue(async()=>{if(this.closed)return;this.epoch!==void 0&&(0,u.rendezvousEpoch)(this.now())!==this.epoch&&await this.derive(this.routes);let n=this.outbound.get(e);if(n===void 0){for(let t of this.absents)t(e);return}let r=new TextEncoder().encode(JSON.stringify(t)).length;if(r>32768)throw Error(`signal too large for a Nostr event`);let i=jn(t,Math.ceil(r/512)*512),a=await n.route.rendezvous.sealRecord(i,n.epoch,`signal`),o=(0,g.finalizeEvent)({kind:n.kind,created_at:Math.floor(this.now()/1e3),tags:[],content:sr(a)},n.secretKey);if(!await this.options.pool.publish(o))throw Error(`no Nostr relay took the signal`)})}async receive(e){if(this.closed)return;let t=lr(e);if(t===void 0||this.seen.has(t.id))return;let n=this.inbound.get(t.pubkey);if(n===void 0||t.kind!==n.kind||Math.abs(Math.floor(this.now()/1e3)-t.created_at)>(this.options.maxEventAgeS??120)||!(0,g.verifyEvent)(t))return;this.remember(t.id);let r=cr(t.content);if(r===void 0)return;let i=await n.route.rendezvous.openRecord(r,n.epoch,`signal`);if(i?.epoch!==n.epoch)return;let a=Y(i.hints);if(!(a===void 0||this.closed))for(let e of this.messages)e(n.route.inbound,a)}remember(e){if(this.seen.add(e),this.seen.size<=2048)return;let t=this.seen.values().next().value;t!==void 0&&this.seen.delete(t)}onMessage(e){return this.messages.add(e),()=>this.messages.delete(e)}onAbsent(e){return this.absents.add(e),()=>this.absents.delete(e)}close(){this.closed||(this.closed=!0,this.timer!==void 0&&clearTimeout(this.timer),this.subscription?.close(),this.messages.clear(),this.absents.clear(),this.options.pool.close())}};function dr(e,t){return e.kinds.includes(t.kind)&&e.authors.includes(t.pubkey)}function fr(){let e=new Set,t=[],n=t=>{let n=JSON.parse(JSON.stringify(t));queueMicrotask(()=>{for(let t of[...e])dr(t.filter,n)&&t.onEvent(n)})};return{pool:()=>{let r=new Set;return{publish:e=>{let r=lr(e);return r===void 0||!(0,g.verifyEvent)(r)?Promise.resolve(!1):(t.push(JSON.parse(JSON.stringify(e))),n(e),Promise.resolve(!0))},subscribe:(t,n)=>{let i={filter:t,onEvent:n};return e.add(i),r.add(i),{close:()=>{e.delete(i),r.delete(i)}}},close:()=>{for(let t of r)e.delete(t);r.clear()}}},events:t,inject:e=>n(e)}}function pr(e){if(e.length===0)throw Error(`a Nostr relay pool needs at least one relay`);let t=new ne.SimplePool,n=[...e];return{publish:async e=>(await Promise.allSettled(t.publish(n,e))).some(e=>e.status===`fulfilled`),subscribe:(e,r)=>t.subscribeMany(n,{kinds:[...e.kinds],authors:[...e.authors],...e.since===void 0?{}:{since:e.since}},{onevent:e=>r(e)}),close:()=>t.destroy()}}const mr=[`wss://relay.damus.io`,`wss://nos.lol`,`wss://relay.primal.net`],hr=[`https://pkarr.pubky.app`,`https://pkarr.pubky.org`,`https://dns.iroh.link/pkarr`],gr=/^[A-Za-z0-9_-]{22}$/;var $=class extends Error{reason;constructor(e,t){super(`enrollment connection failed (${e})${t===void 0?``:`: ${t}`}`),this.name=`EnrollmentLinkError`,this.reason=e}};function _r(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function vr(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(t.v!==1||typeof t.cid!=`string`||!gr.test(t.cid))return;let n=t.cid;if(t.kind===`offer`||t.kind===`answer`)return _r(t.sdp,49152)?{kind:t.kind,cid:n,sdp:t.sdp}:void 0;if(t.kind===`ice`){let e=t.candidate;if(typeof e!=`object`||!e||Array.isArray(e))return;let r=e;return!_r(r.candidate,2048)||!_r(r.mid,64)?void 0:{kind:`ice`,cid:n,candidate:{candidate:r.candidate,mid:r.mid}}}}function yr(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}var br=class{role;cid;options;onBound;onFailed;peer;channel;localFingerprint;remoteFingerprint;tookRemoteDescription=!1;sentDescription=!1;localCandidates=[];remoteCandidates=0;chain=Promise.resolve();stopAwaiting;timer;done=!1;early=[];frameHandlers=new Set;closeHandlers=new Set;constructor(e,t,n,r,i){this.role=e,this.cid=t,this.options=n,this.onBound=r,this.onFailed=i,this.timer=setTimeout(()=>this.fail(new $(`timeout`)),n.connectTimeoutMs??2e4)}async offer(){try{let e=this.createPeer();this.adopt(e.createDataChannel(`agent-enroll`));let t=await e.createOffer();if(this.done)return;this.localFingerprint=(0,u.extractDtlsFingerprint)(t),this.sendDescription({kind:`offer`,cid:this.cid,sdp:t})}catch(e){this.fail(new $(`signaling`,xr(e)))}}onSignal(e){this.done||(this.chain=this.chain.then(()=>this.apply(e)).catch(e=>this.fail(new $(`signaling`,xr(e)))))}async apply(e){if(this.done)return;if(e.kind===`ice`){if(this.peer===void 0||++this.remoteCandidates>64)return;this.peer.addRemoteCandidate(e.candidate);return}let t=this.role===`offerer`?`answer`:`offer`;if(e.kind!==t||this.tookRemoteDescription)return;this.tookRemoteDescription=!0;let n;try{n=(0,u.extractDtlsFingerprintAttribute)(e.sdp).algorithm}catch(e){this.fail(new $(`channel-binding`,xr(e)));return}if(this.role===`offerer`){let t=this.peer;if(t===void 0)return;t.acceptAnswer(e.sdp),this.awaitCertificate(t,n);return}let r=this.createPeer(),i=await r.acceptOffer(e.sdp);this.done||(this.localFingerprint=(0,u.extractDtlsFingerprint)(i),this.sendDescription({kind:`answer`,cid:this.cid,sdp:i}),this.awaitCertificate(r,n))}createPeer(){let e=new b({...this.options.iceServers===void 0?{}:{iceServers:this.options.iceServers},...this.options.loadDataChannel===void 0?{}:{loadDataChannel:this.options.loadDataChannel}});return this.peer=e,e.onLocalCandidate(e=>{if(this.done)return;let t={kind:`ice`,cid:this.cid,candidate:{candidate:e.candidate,mid:e.mid}};this.sentDescription?this.send(t):this.localCandidates.length<64&&this.localCandidates.push(t)}),e.onStateChange(e=>{(e===`failed`||e===`closed`)&&this.fail(new $(`closed`,`connection ${e}`))}),e.onDataChannel(e=>{this.role===`answerer`&&this.channel===void 0&&!this.done?this.adopt(e):e.close()}),e}send(e){this.options.relay.send(this.options.outbound,{v:1,...e})}sendDescription(e){this.send(e),this.sentDescription=!0;for(let e of this.localCandidates.splice(0))this.send(e)}awaitCertificate(e,t){this.stopAwaiting=_(e,t,e=>{this.remoteFingerprint=e,this.maybeBound()},e=>this.fail(new $(`channel-binding`,e)))}adopt(e){this.channel=e,e.onMessage(e=>this.inbound(e)),e.onStateChange(e=>{e===`open`?this.maybeBound():e===`closed`&&this.closed()}),e.readyState===`open`&&this.maybeBound()}inbound(e){if(e.length>262144){this.closeAll();return}if(this.frameHandlers.size===0){if(this.early.length>=16){this.closeAll();return}this.early.push(e);return}this.deliver(e)}deliver(e){let t;try{t=JSON.parse(e)}catch{t=void 0}for(let e of this.frameHandlers)e(t)}maybeBound(){let e=this.channel;if(this.done||e===void 0||e.readyState!==`open`)return;let t=this.localFingerprint,n=this.remoteFingerprint;t!==void 0&&n!==void 0&&(this.done=!0,clearTimeout(this.timer),this.stopAwaiting?.(),this.onBound({localFingerprint:t,remoteFingerprint:n,send:t=>{try{e.send(JSON.stringify(t))}catch{}},onFrame:e=>{this.frameHandlers.add(e);let t=this.early.splice(0);return t.length>0&&queueMicrotask(()=>t.forEach(e=>this.deliver(e))),()=>this.frameHandlers.delete(e)},onClose:t=>e.readyState===`closed`?(queueMicrotask(t),()=>void 0):(this.closeHandlers.add(t),()=>this.closeHandlers.delete(t)),close:()=>this.closeAll()}))}closed(){if(!this.done){this.fail(new $(`closed`,`data channel closed`));return}this.closeAll()}closeAll(){this.channel?.close();let e=this.peer;e!==void 0&&setTimeout(()=>e.close(),250).unref?.();let t=[...this.closeHandlers];this.closeHandlers.clear(),this.frameHandlers.clear();for(let e of t)e()}fail(e){this.done||(this.done=!0,clearTimeout(this.timer),this.stopAwaiting?.(),this.channel?.close(),this.peer?.close(),this.onFailed(e))}};function xr(e){return e instanceof Error?e.message:String(e)}function Sr(e){return new Promise((t,n)=>{let r=[],i=()=>{for(let e of r.splice(0))e()},a=new br(`offerer`,yr(),e,e=>{i(),t(e)},e=>{i(),n(e)});r.push(e.relay.onMessage((t,n)=>{if(t!==e.inbound)return;let r=vr(n);r!==void 0&&r.cid===a.cid&&a.onSignal(r)}),e.relay.onAbsent(t=>{t===e.outbound&&a.fail(new $(`absent`))})),e.relay.declarePresence([e.inbound]),a.offer()})}function Cr(e){let t,n=!1,r=e.relay.onMessage((r,i)=>{if(n||r!==e.inbound)return;let a=vr(i);if(a===void 0)return;if(t!==void 0){a.cid===t.cid&&t.onSignal(a);return}if(a.kind!==`offer`)return;let o=new br(`answerer`,a.cid,e,r=>{if(n){r.close();return}r.onClose(()=>{t===o&&(t=void 0)}),e.onChannel(r)},n=>{t===o&&(t=void 0),e.onAttemptFailed?.(n)});t=o,o.onSignal(a)});return e.relay.declarePresence([e.inbound]),{close:()=>{n||(n=!0,r(),t?.fail(new $(`closed`,`no longer listening`)))}}}exports.DEFAULT_MAX_PUBLISH_JITTER_MS=9e4,exports.DEFAULT_NOSTR_RELAYS=mr,exports.DEFAULT_PKARR_RELAYS=hr,exports.DEFAULT_RELAY_CREDENTIAL_TTL_MS=vt,exports.DEFAULT_TURN_QUOTAS=at,exports.DEFAULT_UNAUTHENTICATED_LIMITS=ot,exports.DeviceMeshNode=zt,exports.DiscoveringMeshRelay=gn,exports.EnrollmentLinkError=$,exports.MAX_CACHED_CANDIDATES=3,exports.MAX_MESH_MESSAGE_CHARS=Le,exports.MAX_RELAY_CREDENTIAL_TTL_MS=yt,exports.MESH_MDNS_SERVICE=V,exports.MeshDht=Bn,exports.MeshLinkEndedError=Be,exports.MeshMdns=sn,exports.MeshRelayNeededError=L,exports.MeshTurnRelay=Tt,exports.NostrMeshRelay=ur,exports.RtcChannel=y,exports.RtcPeer=b,exports.TurnServer=_t,exports.WebRtcTransport=Ae,exports.WsMeshRelayClient=Vt,exports.WsSignalingClient=Fe,exports.addressCacheSource=Ht,exports.createInMemoryItemNetwork=Gn,exports.createInMemoryMdnsBus=cn,exports.createInMemoryMeshAddressCache=Gt,exports.createInMemoryMeshRelayHub=Bt,exports.createInMemoryNostrHub=fr,exports.createInMemorySignalingPair=Me,exports.createNostrRelayPool=pr,exports.createPkarrRelayStore=Qn,exports.dialEnrollment=Sr,exports.handoffGrantFrame=me,exports.judgeHandoffGrant=pe,exports.listenForEnrollment=Cr,exports.loadDataChannel=oe,exports.localInterfaceAddresses=nn,exports.localProofFrame=_e,exports.meshRelayCredential=St,exports.meshRelayIceServers=wt,exports.paddedInstanceCount=on,exports.startLanMeshRelay=_n,exports.startMainlineDhtStore=rr,exports.startMeshLanListener=en;
|