@robota-sdk/agent-transport-webrtc 3.0.0-beta.100
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 +694 -0
- package/LICENSE +661 -0
- package/README.md +111 -0
- package/dist/node/index.cjs +1 -0
- package/dist/node/index.d.cts +1650 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +1650 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +93 -0
- package/src/__tests__/admission-secure-by-default.test.ts +63 -0
- package/src/__tests__/admission-steps.test.ts +46 -0
- package/src/__tests__/device-mesh-relay.test.ts +441 -0
- package/src/__tests__/device-mesh.test.ts +682 -0
- package/src/__tests__/discovering-mesh-relay.test.ts +234 -0
- package/src/__tests__/enrollment-link.test.ts +103 -0
- package/src/__tests__/fake-datachannel.ts +83 -0
- package/src/__tests__/handoff-grant-gate.test.ts +403 -0
- package/src/__tests__/local-peer-proof-gate.test.ts +215 -0
- package/src/__tests__/mesh-admission-contract.test.ts +38 -0
- package/src/__tests__/mesh-discovery.test.ts +820 -0
- package/src/__tests__/mesh-fixtures.ts +148 -0
- package/src/__tests__/mesh-internet.test.ts +942 -0
- package/src/__tests__/mesh-turn-relay.test.ts +161 -0
- package/src/__tests__/negotiated-certificate.test.ts +76 -0
- package/src/__tests__/nostr-source-condition.test.ts +27 -0
- package/src/__tests__/operator-approval-gate.test.ts +308 -0
- package/src/__tests__/outbound-delivery-carrier.test.ts +155 -0
- package/src/__tests__/pairing-e2e.test.ts +237 -0
- package/src/__tests__/pairing-gate-e3.test.ts +194 -0
- package/src/__tests__/pairing-gate-e4.test.ts +110 -0
- package/src/__tests__/pairing-gate.test.ts +296 -0
- package/src/__tests__/pairing-relay-in-the-middle.test.ts +225 -0
- package/src/__tests__/rtc-channel-close.test.ts +52 -0
- package/src/__tests__/rtc-peer-candidates.test.ts +61 -0
- package/src/__tests__/session-attachment-app-view.test.ts +66 -0
- package/src/__tests__/session-attachment-budget.test.ts +136 -0
- package/src/__tests__/turn-server-bind.test.ts +59 -0
- package/src/__tests__/turn-server.test.ts +335 -0
- package/src/__tests__/turn-test-client.ts +256 -0
- package/src/__tests__/webrtc-implementation.test.ts +83 -0
- package/src/__tests__/webrtc-transport.test.ts +349 -0
- package/src/__tests__/ws-mesh-relay-client.test.ts +95 -0
- package/src/__tests__/ws-signaling-client.test.ts +108 -0
- package/src/admission-steps.ts +55 -0
- package/src/channel-delivery.ts +44 -0
- package/src/datachannel-loader.ts +86 -0
- package/src/device-mesh-node.ts +1019 -0
- package/src/discovering-mesh-relay.ts +675 -0
- package/src/enrollment-link.ts +465 -0
- package/src/handoff-grant-gate.ts +186 -0
- package/src/index.ts +139 -0
- package/src/local-peer-proof.ts +135 -0
- package/src/mainline-dht-store.ts +174 -0
- package/src/mesh-dht.ts +446 -0
- package/src/mesh-discovery.ts +87 -0
- package/src/mesh-item-store.ts +287 -0
- package/src/mesh-lan-listener.ts +193 -0
- package/src/mesh-mdns.ts +406 -0
- package/src/mesh-peer-link.ts +600 -0
- package/src/mesh-public-relays.ts +25 -0
- package/src/mesh-records.ts +357 -0
- package/src/mesh-relay.ts +98 -0
- package/src/mesh-signal.ts +116 -0
- package/src/mesh-turn-relay.ts +238 -0
- package/src/negotiated-certificate.ts +72 -0
- package/src/nostr-mesh-relay.ts +391 -0
- package/src/pairing-channel-lifecycle.ts +31 -0
- package/src/pairing-controllers.ts +81 -0
- package/src/pairing-frames.ts +34 -0
- package/src/pairing-gate-options.ts +133 -0
- package/src/pairing-gate.ts +397 -0
- package/src/rtc-peer.ts +429 -0
- package/src/session-attachment.ts +96 -0
- package/src/signaling.ts +62 -0
- package/src/stun-message.ts +341 -0
- package/src/transport-lifecycle-error.ts +11 -0
- package/src/turn-server.ts +1028 -0
- package/src/webrtc-delivery-lifecycle.ts +54 -0
- package/src/webrtc-transport-options.ts +87 -0
- package/src/webrtc-transport.ts +368 -0
- package/src/ws-mesh-relay-client.ts +117 -0
- package/src/ws-signaling-client.ts +139 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/handoff-grant-gate.ts","../../src/local-peer-proof.ts","../../src/pairing-gate-options.ts","../../src/signaling.ts","../../src/datachannel-loader.ts","../../src/webrtc-transport-options.ts","../../src/webrtc-transport.ts","../../src/ws-signaling-client.ts","../../src/rtc-peer.ts","../../src/mesh-peer-link.ts","../../src/stun-message.ts","../../src/turn-server.ts","../../src/mesh-turn-relay.ts","../../src/mesh-discovery.ts","../../src/mesh-relay.ts","../../src/device-mesh-node.ts","../../src/mesh-signal.ts","../../src/ws-mesh-relay-client.ts","../../src/mesh-lan-listener.ts","../../src/mesh-mdns.ts","../../src/mesh-records.ts","../../src/mesh-item-store.ts","../../src/mesh-dht.ts","../../src/discovering-mesh-relay.ts","../../src/mainline-dht-store.ts","../../src/nostr-mesh-relay.ts","../../src/mesh-public-relays.ts","../../src/enrollment-link.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as e}from"node:module";import{HISTORY_PAGE_MAX_BYTES as t,createOutboundDelivery as n,createSessionMessageHandler as r}from"@robota-sdk/agent-transport";import{resolveAdmission as i}from"@robota-sdk/agent-transport/node";import{RENDEZVOUS_EPOCH_MS as a,decodeDeviceRevocationList as o,decodeDeviceRoster as s,decodeEnrollFrame as c,decodePairingFrame as l,decodeReconnectFrame as u,decodeSigningKeyRevocation as d,deriveIdentityId as f,derivePairRendezvous as ee,extractDtlsFingerprint as p,extractDtlsFingerprintAttribute as m,importPublicKey as te,rendezvousEpoch as h,startDeviceHandshake as ne,startHostReconnect as re,startPairingHandshake as ie,verifyDeviceChain as ae}from"@robota-sdk/agent-remote-pairing";import g,{WebSocketServer as oe}from"ws";import{ConnectionAuthority as se}from"@robota-sdk/agent-interface-session-mobility";import{createHash as _,createHmac as v,createPublicKey as ce,randomBytes as le,randomInt as ue,timingSafeEqual as y,verify as de}from"node:crypto";import{createSocket as fe}from"node:dgram";import{isIPv4 as b,isIPv6 as pe}from"node:net";import{networkInterfaces as x}from"node:os";import{SimplePool as me}from"nostr-tools/pool";import{finalizeEvent as he,getPublicKey as ge,verifyEvent as _e}from"nostr-tools/pure";function ve(e,t){return n(t=>e.send(JSON.stringify(t)),(e,n)=>t(e,n),()=>e.bufferedAmount)}const ye=/^[0-9A-F]{2}(?::[0-9A-F]{2})+$/;function S(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(!ye.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 be=t=>e(import.meta.url)(t);function xe(e=be){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 C(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 we(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 Te(e){return typeof e==`string`?e:Buffer.from(e).toString(`utf8`)}var w=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=Te(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`)}},T=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??xe)();this.native=new t.PeerConnection(`agent`,{iceServers:(e.iceServers??[]).map(we),...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 w(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=C(this.native.iceState?.bind(this.native)),t=C(this.native.gatheringState?.bind(this.native)),n=C(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 w(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 Ee(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 De(e){return typeof e==`object`&&!!e&&e.t===`handoff-grant`&&e.grant!==void 0}function E(e){return{admitted:!1,trust:`unproven`,reason:e}}async function Oe(e,t){if(t===void 0)return E(`no hand-off grant verifier is configured for this channel`);if(!De(e))return E(`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`?E(`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:E(`the person at this machine declined the transfer`)}catch(e){return E(`the grant verifier could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function ke(e){return{t:`handoff-grant`,grant:e}}function Ae(e){return typeof e==`object`&&!!e&&e.t===`local-proof`&&typeof e.nonce==`string`}function je(e){return{admitted:!1,trust:`unproven`,reason:e}}function Me(e,t){if(t===void 0)return je(`no local-peer proof is configured for this channel`);if(!Ae(e))return je(`expected a local-proof frame carrying the rendezvous nonce`);try{return t.redeem(e.nonce)}catch(e){return je(`the rendezvous ledger could not decide: ${e instanceof Error?e.message:`unknown error`}`)}}function Ne(e){return{t:`local-proof`,nonce:e}}function Pe(e,t){try{e.send(t)}catch{}}function Fe(e){try{e.close()}catch{}}function Ie(e,t,n){try{e?.(t,n)}catch{}}const D=Object.freeze({send:Pe,close:Fe,reportDeliveryError:Ie});function Le(e,t,n,r,i,a=ie){let o=a(e.cryptoContext,{secret:t,role:n,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,send:t=>D.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return o.result.then(r,i),o}function Re(e,t,n,r){let i=re(e.cryptoContext,{hostIdentityId:t.hostIdentityId,localFingerprint:e.localFingerprint,remoteFingerprint:e.remoteFingerprint,hostPrivateKey:t.hostPrivateKey,resolveDevicePublicKey:t.resolveDevicePublicKey,send:t=>D.send(e.channel,JSON.stringify(t)),...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}});return i.result.then(n,r),i}function ze(e){return l(e).ok}function Be(e){return u(e).ok}function Ve(e){return c(e).ok}function He(e,n,i){let a=e.resumeBridge;if(a)return a.attach(t=>e.channel.send(t),{awaitResume:n,onDeliveryError:i,pendingBytes:()=>e.channel.bufferedAmount}),{onSessionMessage:e=>a.onClientMessage(e),cleanup:()=>a.detach()};let{onMessage:o,cleanup:s}=(e.createHandler??r)({session:e.session,deliver:ve(e.channel,i),maxFrameBytes:t,...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:o,cleanup:s}}var Ue=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`){Be(t)&&t.t===`rc-hello`?(this.state=`reconnecting`,this.startReconnect(),this.reconnectController?.onFrame(t)):ze(t)&&t.t===`pair-nonce`&&(this.state=`pairing`,this.startFirstPair(),this.pairingController?.onFrame(t));return}if(this.state===`pairing`){ze(t)?this.pairingController?.onFrame(t):this.hold(e);return}if(this.state===`reconnecting`){Be(t)?this.reconnectController?.onFrame(t):this.hold(e);return}if(this.state===`local-proof`){let e=Me(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`){Ve(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=Le(this.options,this.options.secret,this.options.role,e=>this.onFirstPairAccepted(e),()=>this.rejectAndClose(),this.options.startHandshake??ie)}startReconnect(){let e=this.options.reconnect;if(!e){this.rejectAndClose();return}this.reconnectController=Re(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`,D.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 te(e);let t=await f(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=Ee(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=He(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 Oe(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(),D.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,D.reportDeliveryError(this.options.onDeliveryError,e,t),D.close(this.options.channel))}};function We(e){return Object.assign(Error(`WebRtcTransport ${e}.`),{name:`TransportLifecycleError`,code:e,transportName:`webrtc`})}var Ge=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()}},Ke=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 Ge({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.');i({open:!0,...this.options.openReason===void 0?{}:{openReason:this.options.openReason}})}}validateOptions(){return!0}attach(e){this.session=e}createPeer(){return new T({...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=qe(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 We(`not-attached`);if(this.peer)throw We(`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=p(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 m(n).algorithm}catch{this.failPairing(e);return}}failPairing(e){e.close(),this.options.onPairingFailed?.()}awaitVerifiedCertificate(e,t,n,r,i){this.stopAwaitingCertificate=S(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 Ue({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,n,i){if(this.options.secret){e.onMessage(e=>{i===this.generation&&(this.pairingGate?this.pairingGate.onInbound(e):this.pendingFrames.length<16&&this.pendingFrames.push(e))}),e.onStateChange(e=>{i===this.generation&&e===`closed`&&(this.pairingGate?.onChannelClosed(),this.deliveryLifecycle.handleDrop(i))}),this.cleanupHandler=()=>this.pairingGate?.cleanup();return}let{onMessage:a,cleanup:o}=r({session:n,deliver:ve(e,(t,n)=>this.deliveryLifecycle.handleFailure(e,i,t,n)),...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:t});this.cleanupHandler=o,e.onMessage(e=>{i===this.generation&&a(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 qe(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 Je(){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 Ye=new Set([`offer`,`answer`,`ice`]);function Xe(e){return new g(e)}var Ze=class{options;socket;handlers=[];outbox=[];joined=!1;closed=!1;constructor(e){this.options=e;let t=e.createSocket??Xe;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`&&Ye.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 Qe=/^[A-Za-z0-9_-]{22}$/,$e=6e4;function O(e){return typeof e==`string`&&Qe.test(e)}function k(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function et(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(!(t.v!==1||!O(t.from))){if(t.kind===`hello`)return{v:1,kind:`hello`,from:t.from};if(!(!O(t.to)||!O(t.cid))){if(t.kind===`offer`||t.kind===`answer`)return k(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!k(n.candidate,2048)||n.sdpMid!==void 0&&!k(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 tt(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 nt=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 rt=`agent-file`,it=JSON.stringify({t:`mesh-admitted`});var at=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=p(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=m(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=p(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!==rt||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(rt);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=S(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(it);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=tt(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 ${$e} 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 nt({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 A=554869826,j={Binding:1,Allocate:3,Refresh:4,Send:6,Data:7,CreatePermission:8,ChannelBind:9},M={Request:0,Indication:1,Success:2,Error:3},N={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 ot(e,t){return e&15|(e&112)<<1|(e&3968)<<2|(t&1)<<4|(t&2)<<7}function st(e){return e.length>=20&&(e[0]&192)==0&&e.readUInt32BE(4)===554869826}function ct(e){if(!st(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 P(e,t){return e.attributes.find(e=>e.type===t)?.value}function lt(e,t){return e.attributes.filter(e=>e.type===t).map(e=>e.value)}function ut(e){let t=e.attributes.findIndex(e=>e.type===N.MessageIntegrity);return t<0?e:{...e,attributes:e.attributes.slice(0,t+1)}}function dt(e,t){if(e.length<8)return;let n=e[1],r=e.readUInt16BE(2)^A>>>16;if(n===1&&e.length===8){let t=e.readUInt32BE(4)^A;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(A,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 ft(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 F(e,t){let n=(e.port^A>>>16)&65535;if(b(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^A)>>>0,4),t}if(!pe(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(A,0),t.copy(i,4);let a=ft(e.address);for(let e=0;e<16;e+=1)r[4+e]=a[e]^i[e];return r}function pt(e,t,n){return _(`md5`).update(`${e}:${t}:${n}`,`utf8`).digest()}function mt(e,t){let n=e.attributes.find(e=>e.type===N.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),y(v(`sha1`,t).update(r).digest(),n.value)}const ht=(()=>{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 gt(e){let t=4294967295;for(let n of e)t=ht[(t^n)&255]^t>>>8;return(t^4294967295)>>>0}function I(e,t,n,r,i={}){let a=[],o=Buffer.alloc(20);o.writeUInt16BE(ot(e,t),0),o.writeUInt32BE(A,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(N.MessageIntegrity,v(`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((gt(e)^1398035790)>>>0,0),s(N.Fingerprint,t)}let l=c();if(l.writeUInt16BE(l.length-20,2),l.length>65535)throw Error(`STUN message too large`);return l}function _t(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 L(e){let t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),t}function vt(e){return e.length>=4&&(e[0]&192)==64}function yt(e){if(!vt(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 bt(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 xt={allocationsPerOwner:8,totalAllocations:64,bytesPerSecondPerOwner:1024*1024,maxLifetimeSeconds:3600,maxAllocationAgeMs:720*60*1e3,permissionsPerAllocation:32,channelsPerAllocation:32},St={perSourcePerSecond:10,totalPerSecond:2e3},Ct=3e5,wt=new Set([N.MappedAddress,N.Username,N.MessageIntegrity,N.ErrorCode,N.ChannelNumber,N.Lifetime,N.XorPeerAddress,N.Data,N.Realm,N.Nonce,N.RequestedAddressFamily,N.RequestedTransport,N.MessageIntegritySha256,N.PasswordAlgorithm,N.XorMappedAddress,N.Priority,N.UseCandidate]);function R(e){return`${e.address}:${e.port}`}function Tt(){for(let e of Object.values(x()))for(let t of e??[])if(t.family===`IPv4`&&!t.internal)return t.address;return`127.0.0.1`}function Et(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 Ot(e,t){return n=>{if(!b(n))return!1;let r=Number(n.split(`.`)[0]);return r===0||r>=224?!1:r===127?e:t||!Dt(n)}}async function kt(e,t){let n=fe(`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 At(e,t){try{return await kt(e,t)}catch{return}}function jt(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`:Nt(e).message;return Error(`the TURN relay cannot listen on UDP ${t}:${n}: ${i}`,{cause:e})}function Mt(){let e=new Set;for(let t of Object.values(x()))for(let n of t??[])e.add(n.address);return e}function z(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 Nt(e){return e instanceof Error?e:Error(String(e))}var Pt=class e{socket;options;bindHost;relayAddress;allocations=new Map;buckets=new Map;quotas;realm;limits;answerBuckets=new Map;answerBudget;nonceSecret=le(32);ownAddresses=Mt();allowPeer;sweeper;retained;closed=!1;constructor(e,t,n,r){this.socket=e,this.options=t,this.bindHost=n,this.relayAddress=r,this.quotas={...xt,...t.quotas},this.realm=t.realm??`r`,this.limits={...St,...t.unauthenticatedLimits},this.allowPeer=t.allowPeer??Ot(Et(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 kt(i,r)}catch(e){throw jt(e,r,i)}let o=t.relayAddress??(r===`0.0.0.0`?Tt():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(vt(e)){this.fromClientChannel(e,t);return}let n=ct(e);if(n!==void 0){if(n.cls===M.Indication){n.method===j.Send&&this.fromClientSend(n,t);return}n.cls===M.Request&&this.request(n,t).catch(e=>this.options.onError?.(Nt(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=I(e.method,M.Success,e.transactionId,n,{...r===void 0?{}:{integrityKey:r}});return this.send(i,t),i}fail(e,t,n,r,i=[],a){let o=I(e.method,M.Error,e.transactionId,[{type:N.ErrorCode,value:_t(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 v(`sha256`,this.nonceSecret).update(e).update(R(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(!y(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||!z(o,this.limits.perSourcePerSecond,i)||!z(a,this.limits.totalPerSecond,i))return;let s=I(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,M.Error,()=>[{type:N.ErrorCode,value:_t(n,``)},...r()])}challenge(e,t,n){this.refuseUnauthenticated(e,t,n,()=>[{type:N.Realm,value:Buffer.from(this.realm)},{type:N.Nonce,value:Buffer.from(this.nonce(t))}])}async authenticate(e,t,n){if(P(e,N.MessageIntegrity)===void 0){this.challenge(e,t,401);return}let r=P(e,N.Username)?.toString(`utf8`),i=P(e,N.Realm)?.toString(`utf8`),a=P(e,N.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(!mt(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:pt(r,this.realm,o.password);if(o===void 0||s===void 0||!mt(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&&!wt.has(e))}async request(e,t){let n={address:t.address,port:t.port};if(e.method===j.Binding){this.answerUnauthenticated(e,n,M.Success,()=>[{type:N.XorMappedAddress,value:F(n,e.transactionId)}]);return}if(![j.Allocate,j.Refresh,j.CreatePermission,j.ChannelBind].includes(e.method)){this.refuseUnauthenticated(e,n,400);return}let r=this.allocations.get(R(n)),i=this.live(r)?r:void 0;if(e.method===j.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(ut(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:N.UnknownAttributes,value:n}],r);return}let a=this.allocations.get(R(t)),o=this.live(a)?a:void 0;if(e.method===j.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===j.Refresh?this.refresh(e,t,o):e.method===j.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=P(e,N.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=P(e,N.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(R(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:R(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:N.XorRelayedAddress,value:F(f.relayed,e.transactionId)},{type:N.Lifetime,value:L(d)},{type:N.XorMappedAddress,value:F(t,e.transactionId)}],a)}async relayedSocket(){let e=this.options.relayPorts;if(e===void 0)return At(0,this.bindHost);let t=e.max-e.min+1;for(let n=0;n<Math.min(t,8);n+=1){let t=await At(ue(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 At(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&&(Et(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=P(e,N.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:N.Lifetime,value:L(0)}],n.integrityKey);return}n.expiresAt=r+i*1e3,this.reply(e,t,[{type:N.Lifetime,value:L(i)}],n.integrityKey)}peerAddresses(e){let t=[];for(let n of lt(e,N.XorPeerAddress)){let r=dt(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=>!b(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()+Ct;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=P(e,N.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(!b(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(R(s));if(c!==void 0&&R(c.peer)!==R(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(R(s),d),n.permissions.set(s.address,u+Ct),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),z(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(R(t));if(!this.live(n))return;let r=P(e,N.XorPeerAddress),i=P(e,N.Data);if(r===void 0||i===void 0)return;let a=dt(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(R(t));if(!this.live(n))return;let r=yt(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(R(n));if(r!==void 0&&r.expiresAt>this.now()){this.send(bt(r.number,t),e.client);return}let i=le(12);this.send(I(j.Data,M.Indication,i,[{type:N.XorPeerAddress,value:F({address:n.address,port:n.port},i)},{type:N.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(R(r.peer)))}}};const Ft=600*1e3,It=3600*1e3,Lt=/^(\d{1,12}):([A-Za-z0-9_-]{22})$/;function Rt(e){return Buffer.from(e).toString(`base64url`)}async function zt(e,t,n=Ft){let r=Math.min(Math.max(n,1e3),It),i=(await e.tag(`relay-user`,`outbound`,h(t))).slice(0,16),a=`${Math.floor((t+r)/1e3)}:${Rt(i)}`;return{username:a,credential:await e.relayPassword(`outbound`,a)}}function Bt(e){return`turn:${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}?transport=udp`}async function Vt(e,t,n,r){if(t.length===0)return[];let{username:i,credential:a}=await zt(e,n,r);return t.map(e=>({urls:Bt(e),username:i,credential:a}))}var B=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}},Ht=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 Pt.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=Lt.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(h(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(Rt(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 Ut=2e4,Wt=1e3,Gt=3e3,Kt=`mesh-lists`,qt=`{"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 Yt=class{last;waiting;timer;run(e){let t=Date.now();if(this.last===void 0||t-this.last>=Wt){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)},Wt-(t-this.last)),this.timer.unref?.())}cancel(){this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0,this.waiting=void 0}};function Xt(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function V(e,t){return t!==void 0&&t.seq>e.seq&&t.signingKeyId===e.signingKeyId}function H(e,t){return e===void 0?t:t===void 0?e:Math.max(e,t)}function Zt(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=H(r.rosterSeq,t.rosterSeq),a=H(r.revocationSeq,t.revocationSeq);n.set(e,{...i===void 0?{}:{rosterSeq:i},...a===void 0?{}:{revocationSeq:a}})}let r=Object.fromEntries(n),i=H(e.signingKeyRevocationSeq,t.signingKeyRevocationSeq);return{...i===void 0?{}:{signingKeyRevocationSeq:i},bySigningKey:r}}function Qt(e,t){let n=t.signingKeyCertificate.signingKeyId===e.signingKeyCertificate.signingKeyId;return{...t,...n&&V(t.roster,e.roster)?{roster:e.roster}:{},...n&&V(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Zt(e.marks,t.marks)}}function $t(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 en(e){if(e.startsWith(qt))try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:void 0}catch{return{}}}var tn=class{options;instance=Xt();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=Qt(t,e.identity);let n=this.syncPeers();return $t(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=s(this.options.cryptoContext,e.roster),r=o(this.options.cryptoContext,e.revocation),i=d(this.options.cryptoContext,e.signingKeyRevocation),a={...n.ok&&V(t.roster,n.value)?{roster:n.value}:{},...r.ok&&V(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 c=await ae(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(!c.ok||this.stopped)return;let{rosterSeq:l,revocationSeq:u,signingKeyRevocationSeq:f}=c.accepted;this.adoptLists({...a,marks:{...a.signingKeyRevocation!==void 0&&f!==void 0?{signingKeyRevocationSeq:f}:{},bySigningKey:{[c.signingKeyId]:{...a.roster!==void 0&&l!==void 0?{rosterSeq:l}:{},...a.revocation!==void 0&&u!==void 0?{revocationSeq:u}:{}}}}})}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 ee(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 Yt,replies:new Yt,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(Gt)).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=Ut){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=et(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(U(r));return}let i=n.waitingOffer;r.kind===`ice`&&i?.cid===r.cid&&i.from===r.from&&i.ice.length<64&&i.ice.push(U(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,Xt()).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(U(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 at({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=>ne(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??Ut,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,...V(t.roster,e.roster)?{roster:e.roster}:{},...V(t.revocation,e.revocation)?{revocation:e.revocation}:{},...e.signingKeyRevocation!==void 0&&e.signingKeyRevocation.seq>t.signingKeyRevocation.seq?{signingKeyRevocation:e.signingKeyRevocation}:{},marks:Zt(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 se({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=en(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=>{en(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 B?o=r.cause:a&&i===`direct`?o=new B(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 B(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(Gt))}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 Vt(r.rendezvous,t.slice(0,3),a,this.options.relays?.credentialTtlMs)))}return o}createPeer(e){let t=[...this.options.iceServers??[],...e];return new T({...t.length>0?{iceServers:t}:{},...this.options.relays?.relayOnly===!0?{forceTurn:!0}:{},...this.options.loadDataChannel===void 0?{}:{loadDataChannel:this.options.loadDataChannel}})}};function U(e){return e.kind===`ice`?{kind:`ice`,candidate:{...e.candidate}}:{kind:e.kind,sdp:e.sdp}}function nn(){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 rn=class{options;socket;messages=new Set;absents=new Set;outbox=[];topics;closed=!1;constructor(e){this.options=e;let t=e.createSocket??(e=>new g(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()}};const an=3;function on(e){return{candidates:t=>Promise.resolve(e.recall(t.deviceId))}}function sn(e,t){return e.host===t.host&&e.port===t.port}function cn(e,t){return[{host:t.host,port:t.port},...e.filter(e=>!sn(e,t))].slice(0,3)}function ln(){let e=new Map,t;return{recall:t=>e.get(t)??[],remember:(t,n)=>{e.set(t,cn(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 un=/^[A-Za-z0-9_-]{43}$/,dn=/^[A-Za-z0-9_-]{22}$/,fn=12e4,pn=1008;function W(e){return _(`sha256`).update(`lan-address:${e}`).digest(`base64url`)}function mn(e,t){return v(`sha256`,e).update(`lan-present:${t}`).digest(`base64url`)}function hn(e,t,n){if(typeof n!=`string`)return!1;let r=Buffer.from(mn(e,t)),i=Buffer.from(n);return i.length===r.length&&y(i,r)}function gn(e,t){return new Promise((n,r)=>{let i=new oe({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 _n(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`||!un.test(n.to)))return n.type===`probe`?typeof n.nonce==`string`&&dn.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 vn(e={}){let t;try{t=await gn(e.port??0,e.host)}catch(n){if(e.port===void 0||e.port===0)throw n;t=await gn(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(pn);return}let n=0,r=Date.now(),o=setTimeout(()=>e.close(),fn);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(pn);return}clearTimeout(o),o=setTimeout(()=>e.close(),fn),o.unref?.();let c=_n(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:mn(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=>[W(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 G=`_rdv._tcp.local`;function yn(){return e(import.meta.url)(`multicast-dns`)()}function bn(){let e=[];for(let t of Object.values(x()))for(let n of t??[])n.internal||(n.family===`IPv4`||n.family===`IPv6`&&!n.address.startsWith(`fe80`))&&e.push(n.address);return e}function xn(e){let t=new Uint8Array(e);return globalThis.crypto.getRandomValues(t),Buffer.from(t).toString(`hex`)}function Sn(e){return Buffer.from(e.subarray(0,16)).toString(`hex`)}function Cn(e){return Math.max(8,Math.ceil(e/8)*8)}function K(e,t){return e.toLowerCase()===t.toLowerCase()}var wn=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??yn)();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=h(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:`${xn(8)}.local`});let{padding:i,target:a}=this.epochCover,o=Cn(r.length)-r.length;for(;i.length<o;)i.push(xn(16));let s=[...r.map(Sn),...i.slice(0,o)].sort(),c=JSON.stringify([n,t,s]),l=s.map(e=>({name:G,type:`PTR`,ttl:120,data:`${e}.${G}`})),u=[];for(let e of s){let n=`${e}.${G}`;u.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??bn)())u.push({name:a,type:e.includes(`:`)?`AAAA`:`A`,ttl:120,data:e});this.records={answers:l,additionals:u},this.instances=new Set(s.map(e=>`${e}.${G}`.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)*a-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=>K(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=h(this.now()),i=new Set((await e.rendezvous.lookupTags(`mdns`,r)).map(e=>`${Sn(e)}.${G}`));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`||!K(e.name,`_rdv._tcp.local`)||typeof e.data!=`string`||!i.has(e.data.toLowerCase()))continue;let a=n.find(t=>t.type===`SRV`&&K(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:G,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 Tn(){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 En=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 Dn(e){if(typeof e!=`object`||!e)return!1;let t=e.kind;return t===`hello`||t===`offer`||t===`answer`}function On(e){return`${e.host}:${e.port}`}function kn(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}function An(e){return Buffer.from(e).toString(`base64url`)}function jn(e){return`ws://${e.host.includes(`:`)?`[${e.host}]`:e.host}:${e.port}`}function Mn(e){try{let t=JSON.parse(String(e));return typeof t==`object`&&t?t:void 0}catch{return}}var Nn=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=h(this.now()),n=new Map,r=new Map;for(let i of e){let e=An(await i.rendezvous.tag(`lan-inbox`,`outbound`,t));for(let e of await i.rendezvous.lookupTags(`lan-inbox`,t))n.set(An(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 En,avoidCarriers:new En};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)*a-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){Dn(n)&&this.armDeadline(e,t),t.socket.send(JSON.stringify({type:`message`,to:W(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){Dn(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=On(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=W(t),r=kn();return new Promise(i=>{let a;try{a=(this.options.connect??(e=>new g(jn(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=Mn(e);if(i?.to===n){if(i.type===`absent`){s(!1);return}s(hn(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(On(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=Mn(t);n?.type===`absent`&&n.to===W(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 Pn(e={}){let t=e.cache??ln(),n=t.lastListenPort(),r=await vn({...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 wn({...e.onError===void 0?{}:{onError:e.onError},...e.mdns}),a=e.internet?.dht,o=e.internet?.signaling??[];return new Nn({...e.relay===void 0?{}:{relay:e.relay},...o.length>0?{signaling:o}:{},listener:r,sources:[on(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 Fn=Uint8Array.from([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),q=new TextEncoder,In=new TextDecoder;function J(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function Ln(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 Y(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 Rn(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 zn(e){if(e.length!==32)throw Error(`an Ed25519 seed is 32 bytes`);let t=await globalThis.crypto.subtle.importKey(`pkcs8`,J(Y([Fn,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:Ln(n.x),sign:async e=>new Uint8Array(await globalThis.crypto.subtle.sign({name:`Ed25519`},t,J(e)))}}async function Bn(e,t,n){if(e.length!==32||n.length!==64)return!1;try{let r=await globalThis.crypto.subtle.importKey(`raw`,J(e),{name:`Ed25519`},!1,[`verify`]);return await globalThis.crypto.subtle.verify({name:`Ed25519`},r,J(n),J(t))}catch{return!1}}function X(e,t,n){let r=[];return e!==void 0&&e.length>0&&r.push(q.encode(`4:salt${e.length}:`),e),r.push(q.encode(`3:seqi${t}e1:v${n.length}:`),n),Y(r)}async function Vn(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(X(t,n,r));return{k:e.publicKey,...t===void 0?{}:{salt:t},seq:n,v:r,sig:i}}async function Z(e,t,n){return!Rn(e.k,t)||!Rn(e.salt??new Uint8Array,n??new Uint8Array)||e.v.length>999||!Number.isSafeInteger(e.seq)||e.seq<0?!1:Bn(t,X(n,e.seq,e.v),e.sig)}const Hn={hints:`bep44-salt`,revocation:`bep44-revocation-salt`};async function Un(e){return new Uint8Array(await globalThis.crypto.subtle.digest(`SHA-256`,J(Y(e))))}async function Wn(e,t,n,r,i=0){let[a,o]=await Promise.all([e.signingSeed(n,r,t),e.tag(Hn[t],n,r)]);if(i===0)return{key:await zn(a),salt:o};let s=q.encode(`chunk`),c=Uint8Array.of(i),[l,u]=await Promise.all([Un([s,a,c]),Un([s,o,c])]);return{key:await zn(l),salt:u}}async function Gn(e){let t=q.encode(JSON.stringify(e)),n=(await Un([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 Kn(e){let t=e[0];if(e.length===864&&e[1]===0)return t!==void 0&&t>=1&&t<=8?t:void 0}function qn(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||!Jn(a.subarray(2,10),n))return;r.push(a.subarray(10))}return Xn(Y(r))}function Jn(e,t){return t!==void 0&&e.length===t.length&&e.every((e,n)=>e===t[n])}function Yn(e,t){let n=q.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 Xn(e){try{return JSON.parse(In.decode(e))}catch{return}}function Zn(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 Qn(e,t=[]){let n=Zn(e,8),r=Zn(t,4);for(;;)try{return Yn({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 $n=/^[0-9A-Za-z.:%_-]{1,64}$/;function er(e){return nr(e,`c`,8)}function tr(e){return nr(e,`t`,4)}function nr(e,t,n){let r=Xn(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`||!$n.test(t)||typeof n!=`number`||!Number.isInteger(n)||n<1||n>65535||o.push({host:t,port:n})}return o}function rr(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))}const ir=9e4;function ar(e){if(typeof e!=`object`||!e)return-1;let t=e.seq;return typeof t==`number`&&Number.isSafeInteger(t)?t:-1}function or(e){return e instanceof Error?e:Error(String(e))}var sr=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=h(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 er(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?[]:tr(r.data);this.relaysFound.set(e.deviceId,{epoch:t,checkedAt:this.now(),endpoints:i})}async relayAdverts(e,t){let n=this.now(),r=h(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 Wn(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:Kn(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 qn([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=h(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)},rr(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=h(n),i=[];try{i.push({purpose:`hints`,chunk:0,plaintext:Qn(this.options.addresses().map(e=>({host:e,port:t})),this.options.relayEndpoints?.()??[])});let e=this.options.lists?.();if(e!==void 0){let t=await Gn({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?.(or(e))}for(let{purpose:t,chunk:a,plaintext:o}of i)try{let i=await e.rendezvous.sealRecord(o,r,t),s=await Wn(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?.(or(e.reason))}catch(e){this.options.onError?.(or(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=h(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=ur(r),o=ur(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 cr(e){let t=new Set;return e.filter(e=>{let n=JSON.stringify(e);return t.has(n)?!1:(t.add(n),!0)})}function lr(e){return cr(e).sort((e,t)=>ar(t)-ar(e))}function ur(e){let t=e.map(e=>lr(e).slice(0,2)),n=[];for(let e=0;e<2;e+=1)n.push(...lr(t.flatMap(t=>t.slice(e,e+1))));return cr(n).slice(0,16)}function dr(e){let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}function fr(){let e=new Map,t=e=>e,n=(e,t)=>`${dr(e)}/${dr(t??new Uint8Array)}`;return{store:()=>({async put(t,r,i){let a=await Vn(t.key,t.salt,Math.floor(i/1e3),r);if(!await Z(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 Z(o,r,i)?o.v:void 0},close:()=>void 0}),items:()=>[...e.values()],serve:e=>{t=e}}}const pr=`ybndrfg8ejkmcpqxot1uwisza345h769`;function mr(e){let t=``,n=0,r=0;for(let i of e)for(n=n<<8|i,r+=8;r>=5;)t+=pr[n>>>r-5&31],r-=5;return r>0&&(t+=pr[n<<5-r&31]),t}function hr(e){return Uint8Array.from([e>>>8&255,e&255])}function gr(e,t){let n=Y([...[`_r`,mr(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=Y(r);return Y([Uint8Array.from([0,0,132,0,0,0,0,1,0,0,0,0]),n,hr(16),hr(1),Uint8Array.from([0,0,1,44]),hr(i.length),i])}function _r(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 Y(t)}i=s}}function vr(e){let t=new Uint8Array(8);return new DataView(t.buffer).setBigUint64(0,BigInt(e)),t}function yr(e){let t=e.length;for(;t>0&&e[t-1]===`/`;)--t;return e.slice(0,t)}function br(e){let t=e.fetch??globalThis.fetch.bind(globalThis),n=(e,t)=>`${yr(e)}/${mr(t)}`;return{async put(r,i,a,o){let s=gr(r.key.publicKey,i);if(s.length>999)throw Error(`record too large for a pkarr relay`);let c=Math.floor(a)*1e3,l=Y([await r.key.sign(X(void 0,c,s)),vr(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 Bn(r,X(void 0,c,l),s))return;let u=_r(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 xr=Uint8Array.from([48,42,48,5,6,3,43,101,112,3,33,0]),Sr=(e,t,n)=>{if(n.length!==32||e.length!==64)return!1;try{return de(null,t,ce({key:Buffer.from(Y([xr,n])),format:`der`,type:`spki`}),e)}catch{return!1}};async function Cr(e){return new(await(import(`bittorrent-dht`))).default({verify:e})}function Q(e){return Buffer.from(e.buffer,e.byteOffset,e.byteLength)}function wr(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 Tr(e={}){let t=await(e.createDht??Cr)(Sr),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 Vn(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=wr(a);await(c===void 0?s:Promise.race([s,c]))},async get(e,n,i){if(r||i.aborted)return;let a=_(`sha1`).update(Y([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,wr(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 Z(r,e,n)?r.v:void 0}catch{return}},close(){r||(r=!0,t.destroy())}}}const Er=/^[0-9a-f]{64}$/,Dr=/^[0-9a-f]{128}$/;function Or(e){return 2e4+((e[0]??0)<<8|(e[1]??0))%1e4}function kr(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function Ar(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 jr(e){if(typeof e!=`object`||!e)return;let t=e;if(!(typeof t.id!=`string`||!Er.test(t.id))&&!(typeof t.pubkey!=`string`||!Er.test(t.pubkey))&&!(typeof t.sig!=`string`||!Dr.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 Mr=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=h(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(ge(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)*a-this.now())),this.timer.unref?.())}send(e,t){this.closed||this.enqueue(async()=>{if(this.closed)return;this.epoch!==void 0&&h(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=Yn(t,Math.ceil(r/512)*512),a=await n.route.rendezvous.sealRecord(i,n.epoch,`signal`),o=he({kind:n.kind,created_at:Math.floor(this.now()/1e3),tags:[],content:kr(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=jr(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)||!_e(t))return;this.remember(t.id);let r=Ar(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=Xn(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 Nr(e,t){return e.kinds.includes(t.kind)&&e.authors.includes(t.pubkey)}function Pr(){let e=new Set,t=[],n=t=>{let n=JSON.parse(JSON.stringify(t));queueMicrotask(()=>{for(let t of[...e])Nr(t.filter,n)&&t.onEvent(n)})};return{pool:()=>{let r=new Set;return{publish:e=>{let r=jr(e);return r===void 0||!_e(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 Fr(e){if(e.length===0)throw Error(`a Nostr relay pool needs at least one relay`);let t=new me,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 Ir=[`wss://relay.damus.io`,`wss://nos.lol`,`wss://relay.primal.net`],Lr=[`https://pkarr.pubky.app`,`https://pkarr.pubky.org`,`https://dns.iroh.link/pkarr`],Rr=/^[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 zr(e,t){return typeof e==`string`&&e.length>0&&e.length<=t}function Br(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e;if(t.v!==1||typeof t.cid!=`string`||!Rr.test(t.cid))return;let n=t.cid;if(t.kind===`offer`||t.kind===`answer`)return zr(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!zr(r.candidate,2048)||!zr(r.mid,64)?void 0:{kind:`ice`,cid:n,candidate:{candidate:r.candidate,mid:r.mid}}}}function Vr(){let e=new Uint8Array(16);return globalThis.crypto.getRandomValues(e),Buffer.from(e).toString(`base64url`)}var Hr=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=p(t),this.sendDescription({kind:`offer`,cid:this.cid,sdp:t})}catch(e){this.fail(new $(`signaling`,Ur(e)))}}onSignal(e){this.done||(this.chain=this.chain.then(()=>this.apply(e)).catch(e=>this.fail(new $(`signaling`,Ur(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=m(e.sdp).algorithm}catch(e){this.fail(new $(`channel-binding`,Ur(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=p(i),this.sendDescription({kind:`answer`,cid:this.cid,sdp:i}),this.awaitCertificate(r,n))}createPeer(){let e=new T({...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=S(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 Ur(e){return e instanceof Error?e.message:String(e)}function Wr(e){return new Promise((t,n)=>{let r=[],i=()=>{for(let e of r.splice(0))e()},a=new Hr(`offerer`,Vr(),e,e=>{i(),t(e)},e=>{i(),n(e)});r.push(e.relay.onMessage((t,n)=>{if(t!==e.inbound)return;let r=Br(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 Gr(e){let t,n=!1,r=e.relay.onMessage((r,i)=>{if(n||r!==e.inbound)return;let a=Br(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 Hr(`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`)))}}}export{ir as DEFAULT_MAX_PUBLISH_JITTER_MS,Ir as DEFAULT_NOSTR_RELAYS,Lr as DEFAULT_PKARR_RELAYS,Ft as DEFAULT_RELAY_CREDENTIAL_TTL_MS,xt as DEFAULT_TURN_QUOTAS,St as DEFAULT_UNAUTHENTICATED_LIMITS,tn as DeviceMeshNode,Nn as DiscoveringMeshRelay,$ as EnrollmentLinkError,an as MAX_CACHED_CANDIDATES,$e as MAX_MESH_MESSAGE_CHARS,It as MAX_RELAY_CREDENTIAL_TTL_MS,G as MESH_MDNS_SERVICE,sr as MeshDht,nt as MeshLinkEndedError,wn as MeshMdns,B as MeshRelayNeededError,Ht as MeshTurnRelay,Mr as NostrMeshRelay,w as RtcChannel,T as RtcPeer,Pt as TurnServer,Ke as WebRtcTransport,rn as WsMeshRelayClient,Ze as WsSignalingClient,on as addressCacheSource,fr as createInMemoryItemNetwork,Tn as createInMemoryMdnsBus,ln as createInMemoryMeshAddressCache,nn as createInMemoryMeshRelayHub,Pr as createInMemoryNostrHub,Je as createInMemorySignalingPair,Fr as createNostrRelayPool,br as createPkarrRelayStore,Wr as dialEnrollment,ke as handoffGrantFrame,Oe as judgeHandoffGrant,Gr as listenForEnrollment,xe as loadDataChannel,bn as localInterfaceAddresses,Ne as localProofFrame,zt as meshRelayCredential,Vt as meshRelayIceServers,Cn as paddedInstanceCount,Pn as startLanMeshRelay,Tr as startMainlineDhtStore,vn as startMeshLanListener};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|