herdr-remote 0.3.33 → 0.3.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/chunks/{VD54DF7R.js → 2IM3AVNW.js} +1 -1
  2. package/dist/chunks/{MCUVFSSK.js → 2RUREFQO.js} +1 -1
  3. package/dist/chunks/{RMHH3IAX.js → 6M7I477E.js} +1 -1
  4. package/dist/chunks/{KGOQKOHH.js → 72JMGTAK.js} +1 -1
  5. package/dist/chunks/{MEFDV375.js → FN6VM2O7.js} +1 -1
  6. package/dist/chunks/{O2LNVFUT.js → I6K6O3EE.js} +1 -1
  7. package/dist/chunks/{K5RFPHSF.js → IRV2W3ZL.js} +1 -1
  8. package/dist/chunks/J427SPKK.js +3 -0
  9. package/dist/chunks/{M52LJEES.js → MHS44P3Y.js} +1 -1
  10. package/dist/chunks/{CVJ4HBMP.js → MLSLOPR7.js} +1 -1
  11. package/dist/chunks/{QCSILMFB.js → MRXHG2UD.js} +1 -1
  12. package/dist/chunks/NKDFWWLU.js +3 -0
  13. package/dist/chunks/{LPR662JH.js → NY3SVG3W.js} +2 -2
  14. package/dist/chunks/{MKAEXKXG.js → QRQJLJWT.js} +1 -1
  15. package/dist/chunks/{WY7WHEJ4.js → QXMBBOKS.js} +1 -1
  16. package/dist/chunks/{H24ZP5D5.js → S3V2O6BK.js} +1 -1
  17. package/dist/chunks/{DGUZCGQN.js → S57VTPH5.js} +1 -1
  18. package/dist/chunks/{FONUO5O5.js → TSP3KNDA.js} +1 -1
  19. package/dist/chunks/{44IGVPMA.js → UK7XZS2G.js} +1 -1
  20. package/dist/chunks/{LY2ZGCXN.js → W24FRSKQ.js} +1 -1
  21. package/dist/chunks/W27D73NQ.js +3 -0
  22. package/dist/chunks/{B76DFI4H.js → WDPLLWBV.js} +1 -1
  23. package/dist/chunks/{AX4EPJCP.js → Y5CEFDIU.js} +1 -1
  24. package/dist/chunks/{PBRQ3HEG.js → ZZOEVJ3V.js} +1 -1
  25. package/dist/cli.js +4 -4
  26. package/dist/connector/main.js +12 -12
  27. package/herdr-plugin.toml +1 -1
  28. package/node_modules/herdr-remote-relay/bin/herdr-remote-relay.js +10 -10
  29. package/node_modules/herdr-remote-relay/package.json +1 -1
  30. package/node_modules/herdr-remote-relay/web/dist/assets/index-CnRQXj8k.js +61 -0
  31. package/node_modules/herdr-remote-relay/web/dist/index.html +1 -1
  32. package/package.json +2 -2
  33. package/dist/chunks/5LZFJ6UZ.js +0 -3
  34. package/dist/chunks/BYGDPZZD.js +0 -3
  35. package/dist/chunks/PBMBFWLQ.js +0 -3
  36. package/node_modules/herdr-remote-relay/web/dist/assets/index-DfycvWFA.js +0 -61
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __herdrCreateRequire } from 'node:module';
3
3
  const require = __herdrCreateRequire(import.meta.url);
4
- var an=Object.create;var is=Object.defineProperty;var ln=Object.getOwnPropertyDescriptor;var cn=Object.getOwnPropertyNames;var fn=Object.getPrototypeOf,un=Object.prototype.hasOwnProperty;var S=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,s)=>(typeof require<"u"?require:e)[s]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var v=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var dn=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of cn(e))!un.call(t,n)&&n!==s&&is(t,n,{get:()=>e[n],enumerable:!(r=ln(e,n))||r.enumerable});return t};var G=(t,e,s)=>(s=t!=null?an(fn(t)):{},dn(e||!t||!t.__esModule?is(s,"default",{value:t,enumerable:!0}):s,t));var F=v((sa,cs)=>{"use strict";var as=["nodebuffer","arraybuffer","fragments"],ls=typeof Blob<"u";ls&&as.push("blob");cs.exports={BINARY_TYPES:as,CLOSE_TIMEOUT:3e4,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:ls,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var Ae=v((ra,Ue)=>{"use strict";var{EMPTY_BUFFER:Tn}=F(),pt=Buffer[Symbol.species];function wn(t,e){if(t.length===0)return Tn;if(t.length===1)return t[0];let s=Buffer.allocUnsafe(e),r=0;for(let n=0;n<t.length;n++){let i=t[n];s.set(i,r),r+=i.length}return r<e?new pt(s.buffer,s.byteOffset,r):s}function fs(t,e,s,r,n){for(let i=0;i<n;i++)s[r+i]=t[i]^e[i&3]}function us(t,e){for(let s=0;s<t.length;s++)t[s]^=e[s&3]}function An(t){return t.length===t.buffer.byteLength?t.buffer:t.buffer.slice(t.byteOffset,t.byteOffset+t.length)}function _t(t){if(_t.readOnly=!0,Buffer.isBuffer(t))return t;let e;return t instanceof ArrayBuffer?e=new pt(t):ArrayBuffer.isView(t)?e=new pt(t.buffer,t.byteOffset,t.byteLength):(e=Buffer.from(t),_t.readOnly=!1),e}Ue.exports={concat:wn,mask:fs,toArrayBuffer:An,toBuffer:_t,unmask:us};if(!process.env.WS_NO_BUFFER_UTIL)try{let t=S("bufferutil");Ue.exports.mask=function(e,s,r,n,i){i<48?fs(e,s,r,n,i):t.mask(e,s,r,n,i)},Ue.exports.unmask=function(e,s){e.length<32?us(e,s):t.unmask(e,s)}}catch{}});var ms=v((na,hs)=>{"use strict";var ds=Symbol("kDone"),yt=Symbol("kRun"),gt=class{constructor(e){this[ds]=()=>{this.pending--,this[yt]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[yt]()}[yt](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[ds])}}};hs.exports=gt});var fe=v((ia,gs)=>{"use strict";var ve=S("zlib"),ps=Ae(),vn=ms(),{kStatusCode:_s}=F(),In=Buffer[Symbol.species],On=Buffer.from([0,0,255,255]),He=Symbol("permessage-deflate"),H=Symbol("total-length"),le=Symbol("callback"),j=Symbol("buffers"),ce=Symbol("error"),Fe,St=class{constructor(e){if(this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,!Fe){let s=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;Fe=new vn(s)}}static get extensionName(){return"permessage-deflate"}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let e=this._deflate[le];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){let s=this._options,r=e.find(n=>!(s.serverNoContextTakeover===!1&&n.server_no_context_takeover||n.server_max_window_bits&&(s.serverMaxWindowBits===!1||typeof s.serverMaxWindowBits=="number"&&s.serverMaxWindowBits>n.server_max_window_bits)||typeof s.clientMaxWindowBits=="number"&&(typeof n.client_max_window_bits=="number"?s.clientMaxWindowBits>n.client_max_window_bits:!n.client_max_window_bits)));if(!r)throw new Error("None of the extension offers can be accepted");return s.serverNoContextTakeover&&(r.server_no_context_takeover=!0),s.clientNoContextTakeover&&(r.client_no_context_takeover=!0),typeof s.serverMaxWindowBits=="number"&&(r.server_max_window_bits=s.serverMaxWindowBits),typeof s.clientMaxWindowBits=="number"?r.client_max_window_bits=s.clientMaxWindowBits:(r.client_max_window_bits===!0||s.clientMaxWindowBits===!1)&&delete r.client_max_window_bits,r}acceptAsClient(e){let s=e[0];if(this._options.clientNoContextTakeover===!1&&s.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!s.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(s.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&s.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return s}normalizeParams(e){return e.forEach(s=>{Object.keys(s).forEach(r=>{let n=s[r];if(n.length>1)throw new Error(`Parameter "${r}" must have only a single value`);if(n=n[0],r==="client_max_window_bits"){if(n!==!0){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=i}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else if(r==="server_max_window_bits"){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=i}else if(r==="client_no_context_takeover"||r==="server_no_context_takeover"){if(n!==!0)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else throw new Error(`Unknown parameter "${r}"`);s[r]=n})}),e}decompress(e,s,r){Fe.add(n=>{this._decompress(e,s,(i,o)=>{n(),r(i,o)})})}compress(e,s,r){Fe.add(n=>{this._compress(e,s,(i,o)=>{n(),r(i,o)})})}_decompress(e,s,r){let n=this._isServer?"client":"server";if(!this._inflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?ve.Z_DEFAULT_WINDOWBITS:this.params[i];this._inflate=ve.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[He]=this,this._inflate[H]=0,this._inflate[j]=[],this._inflate.on("error",Pn),this._inflate.on("data",ys)}this._inflate[le]=r,this._inflate.write(e),s&&this._inflate.write(On),this._inflate.flush(()=>{let i=this._inflate[ce];if(i){this._inflate.close(),this._inflate=null,r(i);return}let o=ps.concat(this._inflate[j],this._inflate[H]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[H]=0,this._inflate[j]=[],s&&this.params[`${n}_no_context_takeover`]&&this._inflate.reset()),r(null,o)})}_compress(e,s,r){let n=this._isServer?"server":"client";if(!this._deflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?ve.Z_DEFAULT_WINDOWBITS:this.params[i];this._deflate=ve.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[H]=0,this._deflate[j]=[],this._deflate.on("data",Cn)}this._deflate[le]=r,this._deflate.write(e),this._deflate.flush(ve.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let i=ps.concat(this._deflate[j],this._deflate[H]);s&&(i=new In(i.buffer,i.byteOffset,i.length-4)),this._deflate[le]=null,this._deflate[H]=0,this._deflate[j]=[],s&&this.params[`${n}_no_context_takeover`]&&this._deflate.reset(),r(null,i)})}};gs.exports=St;function Cn(t){this[j].push(t),this[H]+=t.length}function ys(t){if(this[H]+=t.length,this[He]._maxPayload<1||this[H]<=this[He]._maxPayload){this[j].push(t);return}this[ce]=new RangeError("Max payload size exceeded"),this[ce].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[ce][_s]=1009,this.removeListener("data",ys),this.reset()}function Pn(t){if(this[He]._inflate=null,this[ce]){this[le](this[ce]);return}t[_s]=1007,this[le](t)}});var ue=v((oa,Ye)=>{"use strict";var{isUtf8:Ss}=S("buffer"),{hasBlob:Rn}=F(),kn=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function Ln(t){return t>=1e3&&t<=1014&&t!==1004&&t!==1005&&t!==1006||t>=3e3&&t<=4999}function xt(t){let e=t.length,s=0;for(;s<e;)if((t[s]&128)===0)s++;else if((t[s]&224)===192){if(s+1===e||(t[s+1]&192)!==128||(t[s]&254)===192)return!1;s+=2}else if((t[s]&240)===224){if(s+2>=e||(t[s+1]&192)!==128||(t[s+2]&192)!==128||t[s]===224&&(t[s+1]&224)===128||t[s]===237&&(t[s+1]&224)===160)return!1;s+=3}else if((t[s]&248)===240){if(s+3>=e||(t[s+1]&192)!==128||(t[s+2]&192)!==128||(t[s+3]&192)!==128||t[s]===240&&(t[s+1]&240)===128||t[s]===244&&t[s+1]>143||t[s]>244)return!1;s+=4}else return!1;return!0}function Nn(t){return Rn&&typeof t=="object"&&typeof t.arrayBuffer=="function"&&typeof t.type=="string"&&typeof t.stream=="function"&&(t[Symbol.toStringTag]==="Blob"||t[Symbol.toStringTag]==="File")}Ye.exports={isBlob:Nn,isValidStatusCode:Ln,isValidUTF8:xt,tokenChars:kn};if(Ss)Ye.exports.isValidUTF8=function(t){return t.length<24?xt(t):Ss(t)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let t=S("utf-8-validate");Ye.exports.isValidUTF8=function(e){return e.length<32?xt(e):t(e)}}catch{}});var At=v((aa,vs)=>{"use strict";var{Writable:Mn}=S("stream"),xs=fe(),{BINARY_TYPES:Dn,EMPTY_BUFFER:Es,kStatusCode:Bn,kWebSocket:Un}=F(),{concat:Et,toArrayBuffer:Fn,unmask:Hn}=Ae(),{isValidStatusCode:Yn,isValidUTF8:bs}=ue(),$e=Buffer[Symbol.species],P=0,Ts=1,ws=2,As=3,bt=4,Tt=5,We=6,wt=class extends Mn{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||Dn[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxBufferedChunks=e.maxBufferedChunks|0,this._maxFragments=e.maxFragments|0,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[Un]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._numFragments=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=P}_write(e,s,r){if(this._opcode===8&&this._state==P)return r();if(this._maxBufferedChunks>0&&this._buffers.length>=this._maxBufferedChunks){r(this.createError(RangeError,"Too many buffered chunks",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS"));return}this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(r)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e<this._buffers[0].length){let r=this._buffers[0];return this._buffers[0]=new $e(r.buffer,r.byteOffset+e,r.length-e),new $e(r.buffer,r.byteOffset,e)}let s=Buffer.allocUnsafe(e);do{let r=this._buffers[0],n=s.length-e;e>=r.length?s.set(this._buffers.shift(),n):(s.set(new Uint8Array(r.buffer,r.byteOffset,e),n),this._buffers[0]=new $e(r.buffer,r.byteOffset+e,r.length-e)),e-=r.length}while(e>0);return s}startLoop(e){this._loop=!0;do switch(this._state){case P:this.getInfo(e);break;case Ts:this.getPayloadLength16(e);break;case ws:this.getPayloadLength64(e);break;case As:this.getMask();break;case bt:this.getData(e);break;case Tt:case We:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let s=this.consume(2);if((s[0]&48)!==0){let n=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(n);return}let r=(s[0]&64)===64;if(r&&!this._extensions[xs.extensionName]){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._fin=(s[0]&128)===128,this._opcode=s[0]&15,this._payloadLength=s[1]&127,this._opcode===0){if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(!this._fragmented){let n=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._compressed=r}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let n=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");e(n);return}if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let n=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(n);return}}else{let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(s[1]&128)===128,this._isServer){if(!this._masked){let n=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");e(n);return}}else if(this._masked){let n=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");e(n);return}this._payloadLength===126?this._state=Ts:this._payloadLength===127?this._state=ws:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let s=this.consume(8),r=s.readUInt32BE(0);if(r>Math.pow(2,21)-1){let n=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(n);return}this._payloadLength=r*Math.pow(2,32)+s.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let s=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(s);return}this._masked?this._state=As:this._state=bt}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=bt}getData(e){let s=Es;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=!1;return}s=this.consume(this._payloadLength),this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0&&Hn(s,this._mask)}if(this._opcode>7){this.controlMessage(s,e);return}if(this._maxFragments>0&&++this._numFragments>this._maxFragments){let r=this.createError(RangeError,"Too many message fragments",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS");e(r);return}if(this._compressed){this._state=Tt,this.decompress(s,e);return}s.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(s)),this.dataMessage(e)}decompress(e,s){this._extensions[xs.extensionName].decompress(e,this._fin,(n,i)=>{if(n)return s(n);if(i.length){if(this._messageLength+=i.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let o=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");s(o);return}this._fragments.push(i)}this.dataMessage(s),this._state===P&&this.startLoop(s)})}dataMessage(e){if(!this._fin){this._state=P;return}let s=this._messageLength,r=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._numFragments=0,this._fragments=[],this._opcode===2){let n;this._binaryType==="nodebuffer"?n=Et(r,s):this._binaryType==="arraybuffer"?n=Fn(Et(r,s)):this._binaryType==="blob"?n=new Blob(r):n=r,this._allowSynchronousEvents?(this.emit("message",n,!0),this._state=P):(this._state=We,setImmediate(()=>{this.emit("message",n,!0),this._state=P,this.startLoop(e)}))}else{let n=Et(r,s);if(!this._skipUTF8Validation&&!bs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");e(i);return}this._state===Tt||this._allowSynchronousEvents?(this.emit("message",n,!1),this._state=P):(this._state=We,setImmediate(()=>{this.emit("message",n,!1),this._state=P,this.startLoop(e)}))}}controlMessage(e,s){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit("conclude",1005,Es),this.end();else{let r=e.readUInt16BE(0);if(!Yn(r)){let i=this.createError(RangeError,`invalid status code ${r}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");s(i);return}let n=new $e(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!bs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");s(i);return}this._loop=!1,this.emit("conclude",r,n),this.end()}this._state=P;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",e),this._state=P):(this._state=We,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",e),this._state=P,this.startLoop(s)}))}createError(e,s,r,n,i){this._loop=!1,this._errored=!0;let o=new e(r?`Invalid WebSocket frame: ${s}`:s);return Error.captureStackTrace(o,this.createError),o.code=i,o[Bn]=n,o}};vs.exports=wt});var Ot=v((ca,Cs)=>{"use strict";var{Duplex:la}=S("stream"),{randomFillSync:$n}=S("crypto"),{types:{isUint8Array:Wn}}=S("util"),Is=fe(),{EMPTY_BUFFER:Gn,kWebSocket:jn,NOOP:Vn}=F(),{isBlob:de,isValidStatusCode:qn}=ue(),{mask:Os,toBuffer:K}=Ae(),R=Symbol("kByteLength"),zn=Buffer.alloc(4),Ge=8*1024,J,he=Ge,L=0,Xn=1,Kn=2,vt=class t{constructor(e,s,r){this._extensions=s||{},r&&(this._generateMask=r,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=L,this.onerror=Vn,this[jn]=void 0}static frame(e,s){let r,n=!1,i=2,o=!1;s.mask&&(r=s.maskBuffer||zn,s.generateMask?s.generateMask(r):(he===Ge&&(J===void 0&&(J=Buffer.alloc(Ge)),$n(J,0,Ge),he=0),r[0]=J[he++],r[1]=J[he++],r[2]=J[he++],r[3]=J[he++]),o=(r[0]|r[1]|r[2]|r[3])===0,i=6);let a;typeof e=="string"?(!s.mask||o)&&s[R]!==void 0?a=s[R]:(e=Buffer.from(e),a=e.length):(a=e.length,n=s.mask&&s.readOnly&&!o);let l=a;a>=65536?(i+=8,l=127):a>125&&(i+=2,l=126);let c=Buffer.allocUnsafe(n?a+i:i);return c[0]=s.fin?s.opcode|128:s.opcode,s.rsv1&&(c[0]|=64),c[1]=l,l===126?c.writeUInt16BE(a,2):l===127&&(c[2]=c[3]=0,c.writeUIntBE(a,4,6)),s.mask?(c[1]|=128,c[i-4]=r[0],c[i-3]=r[1],c[i-2]=r[2],c[i-1]=r[3],o?[c,e]:n?(Os(e,r,c,i,a),[c]):(Os(e,r,e,0,a),[c,e])):[c,e]}close(e,s,r,n){let i;if(e===void 0)i=Gn;else{if(typeof e!="number"||!qn(e))throw new TypeError("First argument must be a valid error code number");if(s===void 0||!s.length)i=Buffer.allocUnsafe(2),i.writeUInt16BE(e,0);else{let a=Buffer.byteLength(s);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");if(i=Buffer.allocUnsafe(2+a),i.writeUInt16BE(e,0),typeof s=="string")i.write(s,2);else if(Wn(s))i.set(s,2);else throw new TypeError("Second argument must be a string or a Uint8Array")}}let o={[R]:i.length,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state!==L?this.enqueue([this.dispatch,i,!1,o,n]):this.sendFrame(t.frame(i,o),n)}ping(e,s,r){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):de(e)?(n=e.size,i=!1):(e=K(e),n=e.length,i=K.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[R]:n,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:9,readOnly:i,rsv1:!1};de(e)?this._state!==L?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==L?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(t.frame(e,o),r)}pong(e,s,r){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):de(e)?(n=e.size,i=!1):(e=K(e),n=e.length,i=K.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[R]:n,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:10,readOnly:i,rsv1:!1};de(e)?this._state!==L?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==L?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(t.frame(e,o),r)}send(e,s,r){let n=this._extensions[Is.extensionName],i=s.binary?2:1,o=s.compress,a,l;typeof e=="string"?(a=Buffer.byteLength(e),l=!1):de(e)?(a=e.size,l=!1):(e=K(e),a=e.length,l=K.readOnly),this._firstFragment?(this._firstFragment=!1,o&&n&&n.params[n._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=n._threshold),this._compress=o):(o=!1,i=0),s.fin&&(this._firstFragment=!0);let c={[R]:a,fin:s.fin,generateMask:this._generateMask,mask:s.mask,maskBuffer:this._maskBuffer,opcode:i,readOnly:l,rsv1:o};de(e)?this._state!==L?this.enqueue([this.getBlobData,e,this._compress,c,r]):this.getBlobData(e,this._compress,c,r):this._state!==L?this.enqueue([this.dispatch,e,this._compress,c,r]):this.dispatch(e,this._compress,c,r)}getBlobData(e,s,r,n){this._bufferedBytes+=r[R],this._state=Kn,e.arrayBuffer().then(i=>{if(this._socket.destroyed){let a=new Error("The socket was closed while the blob was being read");process.nextTick(It,this,a,n);return}this._bufferedBytes-=r[R];let o=K(i);s?this.dispatch(o,s,r,n):(this._state=L,this.sendFrame(t.frame(o,r),n),this.dequeue())}).catch(i=>{process.nextTick(Jn,this,i,n)})}dispatch(e,s,r,n){if(!s){this.sendFrame(t.frame(e,r),n);return}let i=this._extensions[Is.extensionName];this._bufferedBytes+=r[R],this._state=Xn,i.compress(e,r.fin,(o,a)=>{if(this._socket.destroyed){let l=new Error("The socket was closed while data was being compressed");It(this,l,n);return}this._bufferedBytes-=r[R],this._state=L,r.readOnly=!1,this.sendFrame(t.frame(a,r),n),this.dequeue()})}dequeue(){for(;this._state===L&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][R],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][R],this._queue.push(e)}sendFrame(e,s){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],s),this._socket.uncork()):this._socket.write(e[0],s)}};Cs.exports=vt;function It(t,e,s){typeof s=="function"&&s(e);for(let r=0;r<t._queue.length;r++){let n=t._queue[r],i=n[n.length-1];typeof i=="function"&&i(e)}}function Jn(t,e,s){It(t,e,s),t.onerror(e)}});var Us=v((fa,Bs)=>{"use strict";var{kForOnEventAttribute:Ie,kListener:Ct}=F(),Ps=Symbol("kCode"),Rs=Symbol("kData"),ks=Symbol("kError"),Ls=Symbol("kMessage"),Ns=Symbol("kReason"),me=Symbol("kTarget"),Ms=Symbol("kType"),Ds=Symbol("kWasClean"),Y=class{constructor(e){this[me]=null,this[Ms]=e}get target(){return this[me]}get type(){return this[Ms]}};Object.defineProperty(Y.prototype,"target",{enumerable:!0});Object.defineProperty(Y.prototype,"type",{enumerable:!0});var Z=class extends Y{constructor(e,s={}){super(e),this[Ps]=s.code===void 0?0:s.code,this[Ns]=s.reason===void 0?"":s.reason,this[Ds]=s.wasClean===void 0?!1:s.wasClean}get code(){return this[Ps]}get reason(){return this[Ns]}get wasClean(){return this[Ds]}};Object.defineProperty(Z.prototype,"code",{enumerable:!0});Object.defineProperty(Z.prototype,"reason",{enumerable:!0});Object.defineProperty(Z.prototype,"wasClean",{enumerable:!0});var pe=class extends Y{constructor(e,s={}){super(e),this[ks]=s.error===void 0?null:s.error,this[Ls]=s.message===void 0?"":s.message}get error(){return this[ks]}get message(){return this[Ls]}};Object.defineProperty(pe.prototype,"error",{enumerable:!0});Object.defineProperty(pe.prototype,"message",{enumerable:!0});var Oe=class extends Y{constructor(e,s={}){super(e),this[Rs]=s.data===void 0?null:s.data}get data(){return this[Rs]}};Object.defineProperty(Oe.prototype,"data",{enumerable:!0});var Zn={addEventListener(t,e,s={}){for(let n of this.listeners(t))if(!s[Ie]&&n[Ct]===e&&!n[Ie])return;let r;if(t==="message")r=function(i,o){let a=new Oe("message",{data:o?i:i.toString()});a[me]=this,je(e,this,a)};else if(t==="close")r=function(i,o){let a=new Z("close",{code:i,reason:o.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});a[me]=this,je(e,this,a)};else if(t==="error")r=function(i){let o=new pe("error",{error:i,message:i.message});o[me]=this,je(e,this,o)};else if(t==="open")r=function(){let i=new Y("open");i[me]=this,je(e,this,i)};else return;r[Ie]=!!s[Ie],r[Ct]=e,s.once?this.once(t,r):this.on(t,r)},removeEventListener(t,e){for(let s of this.listeners(t))if(s[Ct]===e&&!s[Ie]){this.removeListener(t,s);break}}};Bs.exports={CloseEvent:Z,ErrorEvent:pe,Event:Y,EventTarget:Zn,MessageEvent:Oe};function je(t,e,s){typeof t=="object"&&t.handleEvent?t.handleEvent.call(t,s):t.call(e,s)}});var Ve=v((ua,Fs)=>{"use strict";var{tokenChars:Ce}=ue();function D(t,e,s){t[e]===void 0?t[e]=[s]:t[e].push(s)}function Qn(t){let e=Object.create(null),s=Object.create(null),r=!1,n=!1,i=!1,o,a,l=-1,c=-1,f=-1,d=0;for(;d<t.length;d++)if(c=t.charCodeAt(d),o===void 0)if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(d!==0&&(c===32||c===9))f===-1&&l!==-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d);let h=t.slice(l,f);c===44?(D(e,h,s),s=Object.create(null)):o=h,l=f=-1}else throw new SyntaxError(`Unexpected character at index ${d}`);else if(a===void 0)if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(c===32||c===9)f===-1&&l!==-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d),D(s,t.slice(l,f),!0),c===44&&(D(e,o,s),s=Object.create(null),o=void 0),l=f=-1}else if(c===61&&l!==-1&&f===-1)a=t.slice(l,d),l=f=-1;else throw new SyntaxError(`Unexpected character at index ${d}`);else if(n){if(Ce[c]!==1)throw new SyntaxError(`Unexpected character at index ${d}`);l===-1?l=d:r||(r=!0),n=!1}else if(i)if(Ce[c]===1)l===-1&&(l=d);else if(c===34&&l!==-1)i=!1,f=d;else if(c===92)n=!0;else throw new SyntaxError(`Unexpected character at index ${d}`);else if(c===34&&t.charCodeAt(d-1)===61)i=!0;else if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(l!==-1&&(c===32||c===9))f===-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d);let h=t.slice(l,f);r&&(h=h.replace(/\\/g,""),r=!1),D(s,a,h),c===44&&(D(e,o,s),s=Object.create(null),o=void 0),a=void 0,l=f=-1}else throw new SyntaxError(`Unexpected character at index ${d}`);if(l===-1||i||c===32||c===9)throw new SyntaxError("Unexpected end of input");f===-1&&(f=d);let u=t.slice(l,f);return o===void 0?D(e,u,s):(a===void 0?D(s,u,!0):r?D(s,a,u.replace(/\\/g,"")):D(s,a,u),D(e,o,s)),e}function ei(t){return Object.keys(t).map(e=>{let s=t[e];return Array.isArray(s)||(s=[s]),s.map(r=>[e].concat(Object.keys(r).map(n=>{let i=r[n];return Array.isArray(i)||(i=[i]),i.map(o=>o===!0?n:`${n}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}Fs.exports={format:ei,parse:Qn}});var Ke=v((ma,Js)=>{"use strict";var ti=S("events"),si=S("https"),ri=S("http"),$s=S("net"),ni=S("tls"),{randomBytes:ii,createHash:oi}=S("crypto"),{Duplex:da,Readable:ha}=S("stream"),{URL:Pt}=S("url"),V=fe(),ai=At(),li=Ot(),{isBlob:ci}=ue(),{BINARY_TYPES:Hs,CLOSE_TIMEOUT:fi,EMPTY_BUFFER:qe,GUID:ui,kForOnEventAttribute:Rt,kListener:di,kStatusCode:hi,kWebSocket:E,NOOP:Ws}=F(),{EventTarget:{addEventListener:mi,removeEventListener:pi}}=Us(),{format:_i,parse:yi}=Ve(),{toBuffer:gi}=Ae(),Gs=Symbol("kAborted"),kt=[8,13],$=["CONNECTING","OPEN","CLOSING","CLOSED"],Si=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,g=class t extends ti{constructor(e,s,r){super(),this._binaryType=Hs[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=qe,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol="",this._readyState=t.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,s===void 0?s=[]:Array.isArray(s)||(typeof s=="object"&&s!==null?(r=s,s=[]):s=[s]),js(this,e,s,r)):(this._autoPong=r.autoPong,this._closeTimeout=r.closeTimeout,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(e){Hs.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,s,r){let n=new ai({allowSynchronousEvents:r.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxBufferedChunks:r.maxBufferedChunks,maxFragments:r.maxFragments,maxPayload:r.maxPayload,skipUTF8Validation:r.skipUTF8Validation}),i=new li(e,this._extensions,r.generateMask);this._receiver=n,this._sender=i,this._socket=e,n[E]=this,i[E]=this,e[E]=this,n.on("conclude",bi),n.on("drain",Ti),n.on("error",wi),n.on("message",Ai),n.on("ping",vi),n.on("pong",Ii),i.onerror=Oi,e.setTimeout&&e.setTimeout(0),e.setNoDelay&&e.setNoDelay(),s.length>0&&e.unshift(s),e.on("close",zs),e.on("data",Xe),e.on("end",Xs),e.on("error",Ks),this._readyState=t.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[V.extensionName]&&this._extensions[V.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,s){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===t.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=t.CLOSING,this._sender.close(e,s,!this._isServer,r=>{r||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),qs(this)}}pause(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=s=void 0):typeof s=="function"&&(r=s,s=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}s===void 0&&(s=!this._isServer),this._sender.ping(e||qe,s,r)}pong(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=s=void 0):typeof s=="function"&&(r=s,s=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}s===void 0&&(s=!this._isServer),this._sender.pong(e||qe,s,r)}resume(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof s=="function"&&(r=s,s={}),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}let n={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...s};this._extensions[V.extensionName]||(n.compress=!1),this._sender.send(e||qe,n,r)}terminate(){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=t.CLOSING,this._socket.destroy())}}};Object.defineProperty(g,"CONNECTING",{enumerable:!0,value:$.indexOf("CONNECTING")});Object.defineProperty(g.prototype,"CONNECTING",{enumerable:!0,value:$.indexOf("CONNECTING")});Object.defineProperty(g,"OPEN",{enumerable:!0,value:$.indexOf("OPEN")});Object.defineProperty(g.prototype,"OPEN",{enumerable:!0,value:$.indexOf("OPEN")});Object.defineProperty(g,"CLOSING",{enumerable:!0,value:$.indexOf("CLOSING")});Object.defineProperty(g.prototype,"CLOSING",{enumerable:!0,value:$.indexOf("CLOSING")});Object.defineProperty(g,"CLOSED",{enumerable:!0,value:$.indexOf("CLOSED")});Object.defineProperty(g.prototype,"CLOSED",{enumerable:!0,value:$.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(t=>{Object.defineProperty(g.prototype,t,{enumerable:!0})});["open","error","close","message"].forEach(t=>{Object.defineProperty(g.prototype,`on${t}`,{enumerable:!0,get(){for(let e of this.listeners(t))if(e[Rt])return e[di];return null},set(e){for(let s of this.listeners(t))if(s[Rt]){this.removeListener(t,s);break}typeof e=="function"&&this.addEventListener(t,e,{[Rt]:!0})}})});g.prototype.addEventListener=mi;g.prototype.removeEventListener=pi;Js.exports=g;function js(t,e,s,r){let n={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:fi,protocolVersion:kt[1],maxBufferedChunks:262144,maxFragments:16384,maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...r,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(t._autoPong=n.autoPong,t._closeTimeout=n.closeTimeout,!kt.includes(n.protocolVersion))throw new RangeError(`Unsupported protocol version: ${n.protocolVersion} (supported versions: ${kt.join(", ")})`);let i;if(e instanceof Pt)i=e;else try{i=new Pt(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}i.protocol==="http:"?i.protocol="ws:":i.protocol==="https:"&&(i.protocol="wss:"),t._url=i.href;let o=i.protocol==="wss:",a=i.protocol==="ws+unix:",l;if(i.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:a&&!i.pathname?l="The URL's pathname is empty":i.hash&&(l="The URL contains a fragment identifier"),l){let _=new SyntaxError(l);if(t._redirects===0)throw _;ze(t,_);return}let c=o?443:80,f=ii(16).toString("base64"),d=o?si.request:ri.request,u=new Set,h;if(n.createConnection=n.createConnection||(o?Ei:xi),n.defaultPort=n.defaultPort||c,n.port=i.port||c,n.host=i.hostname.startsWith("[")?i.hostname.slice(1,-1):i.hostname,n.headers={...n.headers,"Sec-WebSocket-Version":n.protocolVersion,"Sec-WebSocket-Key":f,Connection:"Upgrade",Upgrade:"websocket"},n.path=i.pathname+i.search,n.timeout=n.handshakeTimeout,n.perMessageDeflate&&(h=new V({...n.perMessageDeflate,isServer:!1,maxPayload:n.maxPayload}),n.headers["Sec-WebSocket-Extensions"]=_i({[V.extensionName]:h.offer()})),s.length){for(let _ of s){if(typeof _!="string"||!Si.test(_)||u.has(_))throw new SyntaxError("An invalid or duplicated subprotocol was specified");u.add(_)}n.headers["Sec-WebSocket-Protocol"]=s.join(",")}if(n.origin&&(n.protocolVersion<13?n.headers["Sec-WebSocket-Origin"]=n.origin:n.headers.Origin=n.origin),(i.username||i.password)&&(n.auth=`${i.username}:${i.password}`),a){let _=n.path.split(":");n.socketPath=_[0],n.path=_[1]}let p;if(n.followRedirects){if(t._redirects===0){t._originalIpc=a,t._originalSecure=o,t._originalHostOrSocketPath=a?n.socketPath:i.host;let _=r&&r.headers;if(r={...r,headers:{}},_)for(let[b,ie]of Object.entries(_))r.headers[b.toLowerCase()]=ie}else if(t.listenerCount("redirect")===0){let _=a?t._originalIpc?n.socketPath===t._originalHostOrSocketPath:!1:t._originalIpc?!1:i.host===t._originalHostOrSocketPath;(!_||t._originalSecure&&!o)&&(delete n.headers.authorization,delete n.headers.cookie,_||delete n.headers.host,n.auth=void 0)}n.auth&&!r.headers.authorization&&(r.headers.authorization="Basic "+Buffer.from(n.auth).toString("base64")),p=t._req=d(n),t._redirects&&t.emit("redirect",t.url,p)}else p=t._req=d(n);n.timeout&&p.on("timeout",()=>{O(t,p,"Opening handshake has timed out")}),p.on("error",_=>{p===null||p[Gs]||(p=t._req=null,ze(t,_))}),p.on("response",_=>{let b=_.headers.location,ie=_.statusCode;if(b&&n.followRedirects&&ie>=300&&ie<400){if(++t._redirects>n.maxRedirects){O(t,p,"Maximum redirects exceeded");return}p.abort();let be;try{be=new Pt(b,e)}catch{let oe=new SyntaxError(`Invalid URL: ${b}`);ze(t,oe);return}js(t,be,s,r)}else t.emit("unexpected-response",p,_)||O(t,p,`Unexpected server response: ${_.statusCode}`)}),p.on("upgrade",(_,b,ie)=>{if(t.emit("upgrade",_),t.readyState!==g.CONNECTING)return;p=t._req=null;let be=_.headers.upgrade;if(be===void 0||be.toLowerCase()!=="websocket"){O(t,b,"Invalid Upgrade header");return}let ss=oi("sha1").update(f+ui).digest("base64");if(_.headers["sec-websocket-accept"]!==ss){O(t,b,"Invalid Sec-WebSocket-Accept header");return}let oe=_.headers["sec-websocket-protocol"],Te;if(oe!==void 0?u.size?u.has(oe)||(Te="Server sent an invalid subprotocol"):Te="Server sent a subprotocol but none was requested":u.size&&(Te="Server sent no subprotocol"),Te){O(t,b,Te);return}oe&&(t._protocol=oe);let rs=_.headers["sec-websocket-extensions"];if(rs!==void 0){if(!h){O(t,b,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let ft;try{ft=yi(rs)}catch{O(t,b,"Invalid Sec-WebSocket-Extensions header");return}let ns=Object.keys(ft);if(ns.length!==1||ns[0]!==V.extensionName){O(t,b,"Server indicated an extension that was not requested");return}try{h.accept(ft[V.extensionName])}catch{O(t,b,"Invalid Sec-WebSocket-Extensions header");return}t._extensions[V.extensionName]=h}t.setSocket(b,ie,{allowSynchronousEvents:n.allowSynchronousEvents,generateMask:n.generateMask,maxBufferedChunks:n.maxBufferedChunks,maxFragments:n.maxFragments,maxPayload:n.maxPayload,skipUTF8Validation:n.skipUTF8Validation})}),n.finishRequest?n.finishRequest(p,t):p.end()}function ze(t,e){t._readyState=g.CLOSING,t._errorEmitted=!0,t.emit("error",e),t.emitClose()}function xi(t){return t.path=t.socketPath,$s.connect(t)}function Ei(t){return t.path=void 0,!t.servername&&t.servername!==""&&(t.servername=$s.isIP(t.host)?"":t.host),ni.connect(t)}function O(t,e,s){t._readyState=g.CLOSING;let r=new Error(s);Error.captureStackTrace(r,O),e.setHeader?(e[Gs]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(ze,t,r)):(e.destroy(r),e.once("error",t.emit.bind(t,"error")),e.once("close",t.emitClose.bind(t)))}function Lt(t,e,s){if(e){let r=ci(e)?e.size:gi(e).length;t._socket?t._sender._bufferedBytes+=r:t._bufferedAmount+=r}if(s){let r=new Error(`WebSocket is not open: readyState ${t.readyState} (${$[t.readyState]})`);process.nextTick(s,r)}}function bi(t,e){let s=this[E];s._closeFrameReceived=!0,s._closeMessage=e,s._closeCode=t,s._socket[E]!==void 0&&(s._socket.removeListener("data",Xe),process.nextTick(Vs,s._socket),t===1005?s.close():s.close(t,e))}function Ti(){let t=this[E];t.isPaused||t._socket.resume()}function wi(t){let e=this[E];e._socket[E]!==void 0&&(e._socket.removeListener("data",Xe),process.nextTick(Vs,e._socket),e.close(t[hi])),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t))}function Ys(){this[E].emitClose()}function Ai(t,e){this[E].emit("message",t,e)}function vi(t){let e=this[E];e._autoPong&&e.pong(t,!this._isServer,Ws),e.emit("ping",t)}function Ii(t){this[E].emit("pong",t)}function Vs(t){t.resume()}function Oi(t){let e=this[E];e.readyState!==g.CLOSED&&(e.readyState===g.OPEN&&(e._readyState=g.CLOSING,qs(e)),this._socket.end(),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t)))}function qs(t){t._closeTimer=setTimeout(t._socket.destroy.bind(t._socket),t._closeTimeout)}function zs(){let t=this[E];if(this.removeListener("close",zs),this.removeListener("data",Xe),this.removeListener("end",Xs),t._readyState=g.CLOSING,!this._readableState.endEmitted&&!t._closeFrameReceived&&!t._receiver._writableState.errorEmitted&&this._readableState.length!==0){let e=this.read(this._readableState.length);t._receiver.write(e)}t._receiver.end(),this[E]=void 0,clearTimeout(t._closeTimer),t._receiver._writableState.finished||t._receiver._writableState.errorEmitted?t.emitClose():(t._receiver.on("error",Ys),t._receiver.on("finish",Ys))}function Xe(t){this[E]._receiver.write(t)||this.pause()}function Xs(){let t=this[E];t._readyState=g.CLOSING,t._receiver.end(),this.end()}function Ks(){let t=this[E];this.removeListener("error",Ks),this.on("error",Ws),t&&(t._readyState=g.CLOSING,this.destroy())}});var tr=v((_a,er)=>{"use strict";var pa=Ke(),{Duplex:Ci}=S("stream");function Zs(t){t.emit("close")}function Pi(){!this.destroyed&&this._writableState.finished&&this.destroy()}function Qs(t){this.removeListener("error",Qs),this.destroy(),this.listenerCount("error")===0&&this.emit("error",t)}function Ri(t,e){let s=!0,r=new Ci({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return t.on("message",function(i,o){let a=!o&&r._readableState.objectMode?i.toString():i;r.push(a)||t.pause()}),t.once("error",function(i){r.destroyed||(s=!1,r.destroy(i))}),t.once("close",function(){r.destroyed||r.push(null)}),r._destroy=function(n,i){if(t.readyState===t.CLOSED){i(n),process.nextTick(Zs,r);return}let o=!1;t.once("error",function(l){o=!0,i(l)}),t.once("close",function(){o||i(n),process.nextTick(Zs,r)}),s&&t.terminate()},r._final=function(n){if(t.readyState===t.CONNECTING){t.once("open",function(){r._final(n)});return}t._socket!==null&&(t._socket._writableState.finished?(n(),r._readableState.endEmitted&&r.destroy()):(t._socket.once("finish",function(){n()}),t.close()))},r._read=function(){t.isPaused&&t.resume()},r._write=function(n,i,o){if(t.readyState===t.CONNECTING){t.once("open",function(){r._write(n,i,o)});return}t.send(n,o)},r.on("end",Pi),r.on("error",Qs),r}er.exports=Ri});var Nt=v((ya,sr)=>{"use strict";var{tokenChars:ki}=ue();function Li(t){let e=new Set,s=-1,r=-1,n=0;for(n;n<t.length;n++){let o=t.charCodeAt(n);if(r===-1&&ki[o]===1)s===-1&&(s=n);else if(n!==0&&(o===32||o===9))r===-1&&s!==-1&&(r=n);else if(o===44){if(s===-1)throw new SyntaxError(`Unexpected character at index ${n}`);r===-1&&(r=n);let a=t.slice(s,r);if(e.has(a))throw new SyntaxError(`The "${a}" subprotocol is duplicated`);e.add(a),s=r=-1}else throw new SyntaxError(`Unexpected character at index ${n}`)}if(s===-1||r!==-1)throw new SyntaxError("Unexpected end of input");let i=t.slice(s,n);if(e.has(i))throw new SyntaxError(`The "${i}" subprotocol is duplicated`);return e.add(i),e}sr.exports={parse:Li}});var cr=v((Sa,lr)=>{"use strict";var Ni=S("events"),Je=S("http"),{Duplex:ga}=S("stream"),{createHash:Mi}=S("crypto"),rr=Ve(),Q=fe(),Di=Nt(),Bi=Ke(),{CLOSE_TIMEOUT:Ui,GUID:Fi,kWebSocket:Hi}=F(),Yi=/^[+/0-9A-Za-z]{22}==$/,nr=0,ir=1,ar=2,Mt=class extends Ni{constructor(e,s){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxBufferedChunks:256*1024,maxFragments:16*1024,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,closeTimeout:Ui,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:Bi,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(e.port!=null?(this._server=Je.createServer((r,n)=>{let i=Je.STATUS_CODES[426];n.writeHead(426,{"Content-Length":i.length,"Content-Type":"text/plain"}),n.end(i)}),this._server.listen(e.port,e.host,e.backlog,s)):e.server&&(this._server=e.server),this._server){let r=this.emit.bind(this,"connection");this._removeListeners=$i(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(n,i,o)=>{this.handleUpgrade(n,i,o,r)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=nr}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===ar){e&&this.once("close",()=>{e(new Error("The server is not running"))}),process.nextTick(Pe,this);return}if(e&&this.once("close",e),this._state!==ir)if(this._state=ir,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(Pe,this):process.nextTick(Pe,this);else{let s=this._server;this._removeListeners(),this._removeListeners=this._server=null,s.close(()=>{Pe(this)})}}shouldHandle(e){if(this.options.path){let s=e.url.indexOf("?");if((s!==-1?e.url.slice(0,s):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,s,r,n){s.on("error",or);let i=e.headers["sec-websocket-key"],o=e.headers.upgrade,a=+e.headers["sec-websocket-version"];if(e.method!=="GET"){ee(this,e,s,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){ee(this,e,s,400,"Invalid Upgrade header");return}if(i===void 0||!Yi.test(i)){ee(this,e,s,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==13&&a!==8){ee(this,e,s,400,"Missing or invalid Sec-WebSocket-Version header",{"Sec-WebSocket-Version":"13, 8"});return}if(!this.shouldHandle(e)){Re(s,400);return}let l=e.headers["sec-websocket-protocol"],c=new Set;if(l!==void 0)try{c=Di.parse(l)}catch{ee(this,e,s,400,"Invalid Sec-WebSocket-Protocol header");return}let f=e.headers["sec-websocket-extensions"],d={};if(this.options.perMessageDeflate&&f!==void 0){let u=new Q({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let h=rr.parse(f);h[Q.extensionName]&&(u.accept(h[Q.extensionName]),d[Q.extensionName]=u)}catch{ee(this,e,s,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let u={origin:e.headers[`${a===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(u,(h,p,_,b)=>{if(!h)return Re(s,p||401,_,b);this.completeUpgrade(d,i,c,e,s,r,n)});return}if(!this.options.verifyClient(u))return Re(s,401)}this.completeUpgrade(d,i,c,e,s,r,n)}completeUpgrade(e,s,r,n,i,o,a){if(!i.readable||!i.writable)return i.destroy();if(i[Hi])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>nr)return Re(i,503);let c=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${Mi("sha1").update(s+Fi).digest("base64")}`],f=new this.options.WebSocket(null,void 0,this.options);if(r.size){let d=this.options.handleProtocols?this.options.handleProtocols(r,n):r.values().next().value;d&&(c.push(`Sec-WebSocket-Protocol: ${d}`),f._protocol=d)}if(e[Q.extensionName]){let d=e[Q.extensionName].params,u=rr.format({[Q.extensionName]:[d]});c.push(`Sec-WebSocket-Extensions: ${u}`),f._extensions=e}this.emit("headers",c,n),i.write(c.concat(`\r
4
+ var cn=Object.create;var is=Object.defineProperty;var fn=Object.getOwnPropertyDescriptor;var un=Object.getOwnPropertyNames;var dn=Object.getPrototypeOf,hn=Object.prototype.hasOwnProperty;var S=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,s)=>(typeof require<"u"?require:e)[s]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var I=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var pn=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of un(e))!hn.call(t,n)&&n!==s&&is(t,n,{get:()=>e[n],enumerable:!(r=fn(e,n))||r.enumerable});return t};var G=(t,e,s)=>(s=t!=null?cn(dn(t)):{},pn(e||!t||!t.__esModule?is(s,"default",{value:t,enumerable:!0}):s,t));var U=I((na,cs)=>{"use strict";var as=["nodebuffer","arraybuffer","fragments"],ls=typeof Blob<"u";ls&&as.push("blob");cs.exports={BINARY_TYPES:as,CLOSE_TIMEOUT:3e4,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:ls,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var Ae=I((ia,Fe)=>{"use strict";var{EMPTY_BUFFER:An}=U(),mt=Buffer[Symbol.species];function In(t,e){if(t.length===0)return An;if(t.length===1)return t[0];let s=Buffer.allocUnsafe(e),r=0;for(let n=0;n<t.length;n++){let i=t[n];s.set(i,r),r+=i.length}return r<e?new mt(s.buffer,s.byteOffset,r):s}function fs(t,e,s,r,n){for(let i=0;i<n;i++)s[r+i]=t[i]^e[i&3]}function us(t,e){for(let s=0;s<t.length;s++)t[s]^=e[s&3]}function vn(t){return t.length===t.buffer.byteLength?t.buffer:t.buffer.slice(t.byteOffset,t.byteOffset+t.length)}function _t(t){if(_t.readOnly=!0,Buffer.isBuffer(t))return t;let e;return t instanceof ArrayBuffer?e=new mt(t):ArrayBuffer.isView(t)?e=new mt(t.buffer,t.byteOffset,t.byteLength):(e=Buffer.from(t),_t.readOnly=!1),e}Fe.exports={concat:In,mask:fs,toArrayBuffer:vn,toBuffer:_t,unmask:us};if(!process.env.WS_NO_BUFFER_UTIL)try{let t=S("bufferutil");Fe.exports.mask=function(e,s,r,n,i){i<48?fs(e,s,r,n,i):t.mask(e,s,r,n,i)},Fe.exports.unmask=function(e,s){e.length<32?us(e,s):t.unmask(e,s)}}catch{}});var ps=I((oa,hs)=>{"use strict";var ds=Symbol("kDone"),yt=Symbol("kRun"),gt=class{constructor(e){this[ds]=()=>{this.pending--,this[yt]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[yt]()}[yt](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[ds])}}};hs.exports=gt});var ue=I((aa,gs)=>{"use strict";var Ie=S("zlib"),ms=Ae(),On=ps(),{kStatusCode:_s}=U(),Cn=Buffer[Symbol.species],Pn=Buffer.from([0,0,255,255]),He=Symbol("permessage-deflate"),H=Symbol("total-length"),ce=Symbol("callback"),j=Symbol("buffers"),fe=Symbol("error"),Ue,St=class{constructor(e){if(this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,!Ue){let s=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;Ue=new On(s)}}static get extensionName(){return"permessage-deflate"}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let e=this._deflate[ce];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){let s=this._options,r=e.find(n=>!(s.serverNoContextTakeover===!1&&n.server_no_context_takeover||n.server_max_window_bits&&(s.serverMaxWindowBits===!1||typeof s.serverMaxWindowBits=="number"&&s.serverMaxWindowBits>n.server_max_window_bits)||typeof s.clientMaxWindowBits=="number"&&(typeof n.client_max_window_bits=="number"?s.clientMaxWindowBits>n.client_max_window_bits:!n.client_max_window_bits)));if(!r)throw new Error("None of the extension offers can be accepted");return s.serverNoContextTakeover&&(r.server_no_context_takeover=!0),s.clientNoContextTakeover&&(r.client_no_context_takeover=!0),typeof s.serverMaxWindowBits=="number"&&(r.server_max_window_bits=s.serverMaxWindowBits),typeof s.clientMaxWindowBits=="number"?r.client_max_window_bits=s.clientMaxWindowBits:(r.client_max_window_bits===!0||s.clientMaxWindowBits===!1)&&delete r.client_max_window_bits,r}acceptAsClient(e){let s=e[0];if(this._options.clientNoContextTakeover===!1&&s.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!s.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(s.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&s.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return s}normalizeParams(e){return e.forEach(s=>{Object.keys(s).forEach(r=>{let n=s[r];if(n.length>1)throw new Error(`Parameter "${r}" must have only a single value`);if(n=n[0],r==="client_max_window_bits"){if(n!==!0){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=i}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else if(r==="server_max_window_bits"){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=i}else if(r==="client_no_context_takeover"||r==="server_no_context_takeover"){if(n!==!0)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else throw new Error(`Unknown parameter "${r}"`);s[r]=n})}),e}decompress(e,s,r){Ue.add(n=>{this._decompress(e,s,(i,o)=>{n(),r(i,o)})})}compress(e,s,r){Ue.add(n=>{this._compress(e,s,(i,o)=>{n(),r(i,o)})})}_decompress(e,s,r){let n=this._isServer?"client":"server";if(!this._inflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?Ie.Z_DEFAULT_WINDOWBITS:this.params[i];this._inflate=Ie.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[He]=this,this._inflate[H]=0,this._inflate[j]=[],this._inflate.on("error",kn),this._inflate.on("data",ys)}this._inflate[ce]=r,this._inflate.write(e),s&&this._inflate.write(Pn),this._inflate.flush(()=>{let i=this._inflate[fe];if(i){this._inflate.close(),this._inflate=null,r(i);return}let o=ms.concat(this._inflate[j],this._inflate[H]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[H]=0,this._inflate[j]=[],s&&this.params[`${n}_no_context_takeover`]&&this._inflate.reset()),r(null,o)})}_compress(e,s,r){let n=this._isServer?"server":"client";if(!this._deflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?Ie.Z_DEFAULT_WINDOWBITS:this.params[i];this._deflate=Ie.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[H]=0,this._deflate[j]=[],this._deflate.on("data",Rn)}this._deflate[ce]=r,this._deflate.write(e),this._deflate.flush(Ie.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let i=ms.concat(this._deflate[j],this._deflate[H]);s&&(i=new Cn(i.buffer,i.byteOffset,i.length-4)),this._deflate[ce]=null,this._deflate[H]=0,this._deflate[j]=[],s&&this.params[`${n}_no_context_takeover`]&&this._deflate.reset(),r(null,i)})}};gs.exports=St;function Rn(t){this[j].push(t),this[H]+=t.length}function ys(t){if(this[H]+=t.length,this[He]._maxPayload<1||this[H]<=this[He]._maxPayload){this[j].push(t);return}this[fe]=new RangeError("Max payload size exceeded"),this[fe].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[fe][_s]=1009,this.removeListener("data",ys),this.reset()}function kn(t){if(this[He]._inflate=null,this[fe]){this[ce](this[fe]);return}t[_s]=1007,this[ce](t)}});var de=I((la,$e)=>{"use strict";var{isUtf8:Ss}=S("buffer"),{hasBlob:Ln}=U(),Mn=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function Nn(t){return t>=1e3&&t<=1014&&t!==1004&&t!==1005&&t!==1006||t>=3e3&&t<=4999}function xt(t){let e=t.length,s=0;for(;s<e;)if((t[s]&128)===0)s++;else if((t[s]&224)===192){if(s+1===e||(t[s+1]&192)!==128||(t[s]&254)===192)return!1;s+=2}else if((t[s]&240)===224){if(s+2>=e||(t[s+1]&192)!==128||(t[s+2]&192)!==128||t[s]===224&&(t[s+1]&224)===128||t[s]===237&&(t[s+1]&224)===160)return!1;s+=3}else if((t[s]&248)===240){if(s+3>=e||(t[s+1]&192)!==128||(t[s+2]&192)!==128||(t[s+3]&192)!==128||t[s]===240&&(t[s+1]&240)===128||t[s]===244&&t[s+1]>143||t[s]>244)return!1;s+=4}else return!1;return!0}function Dn(t){return Ln&&typeof t=="object"&&typeof t.arrayBuffer=="function"&&typeof t.type=="string"&&typeof t.stream=="function"&&(t[Symbol.toStringTag]==="Blob"||t[Symbol.toStringTag]==="File")}$e.exports={isBlob:Dn,isValidStatusCode:Nn,isValidUTF8:xt,tokenChars:Mn};if(Ss)$e.exports.isValidUTF8=function(t){return t.length<24?xt(t):Ss(t)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let t=S("utf-8-validate");$e.exports.isValidUTF8=function(e){return e.length<32?xt(e):t(e)}}catch{}});var At=I((ca,Is)=>{"use strict";var{Writable:Bn}=S("stream"),xs=ue(),{BINARY_TYPES:Fn,EMPTY_BUFFER:Es,kStatusCode:Un,kWebSocket:Hn}=U(),{concat:Et,toArrayBuffer:$n,unmask:Yn}=Ae(),{isValidStatusCode:Wn,isValidUTF8:bs}=de(),Ye=Buffer[Symbol.species],P=0,Ts=1,ws=2,As=3,bt=4,Tt=5,We=6,wt=class extends Bn{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||Fn[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxBufferedChunks=e.maxBufferedChunks|0,this._maxFragments=e.maxFragments|0,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[Hn]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._numFragments=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=P}_write(e,s,r){if(this._opcode===8&&this._state==P)return r();if(this._maxBufferedChunks>0&&this._buffers.length>=this._maxBufferedChunks){r(this.createError(RangeError,"Too many buffered chunks",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS"));return}this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(r)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e<this._buffers[0].length){let r=this._buffers[0];return this._buffers[0]=new Ye(r.buffer,r.byteOffset+e,r.length-e),new Ye(r.buffer,r.byteOffset,e)}let s=Buffer.allocUnsafe(e);do{let r=this._buffers[0],n=s.length-e;e>=r.length?s.set(this._buffers.shift(),n):(s.set(new Uint8Array(r.buffer,r.byteOffset,e),n),this._buffers[0]=new Ye(r.buffer,r.byteOffset+e,r.length-e)),e-=r.length}while(e>0);return s}startLoop(e){this._loop=!0;do switch(this._state){case P:this.getInfo(e);break;case Ts:this.getPayloadLength16(e);break;case ws:this.getPayloadLength64(e);break;case As:this.getMask();break;case bt:this.getData(e);break;case Tt:case We:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let s=this.consume(2);if((s[0]&48)!==0){let n=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(n);return}let r=(s[0]&64)===64;if(r&&!this._extensions[xs.extensionName]){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._fin=(s[0]&128)===128,this._opcode=s[0]&15,this._payloadLength=s[1]&127,this._opcode===0){if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(!this._fragmented){let n=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._compressed=r}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let n=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");e(n);return}if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let n=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(n);return}}else{let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(s[1]&128)===128,this._isServer){if(!this._masked){let n=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");e(n);return}}else if(this._masked){let n=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");e(n);return}this._payloadLength===126?this._state=Ts:this._payloadLength===127?this._state=ws:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let s=this.consume(8),r=s.readUInt32BE(0);if(r>Math.pow(2,21)-1){let n=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(n);return}this._payloadLength=r*Math.pow(2,32)+s.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let s=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(s);return}this._masked?this._state=As:this._state=bt}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=bt}getData(e){let s=Es;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=!1;return}s=this.consume(this._payloadLength),this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0&&Yn(s,this._mask)}if(this._opcode>7){this.controlMessage(s,e);return}if(this._maxFragments>0&&++this._numFragments>this._maxFragments){let r=this.createError(RangeError,"Too many message fragments",!1,1008,"WS_ERR_TOO_MANY_BUFFERED_PARTS");e(r);return}if(this._compressed){this._state=Tt,this.decompress(s,e);return}s.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(s)),this.dataMessage(e)}decompress(e,s){this._extensions[xs.extensionName].decompress(e,this._fin,(n,i)=>{if(n)return s(n);if(i.length){if(this._messageLength+=i.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let o=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");s(o);return}this._fragments.push(i)}this.dataMessage(s),this._state===P&&this.startLoop(s)})}dataMessage(e){if(!this._fin){this._state=P;return}let s=this._messageLength,r=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._numFragments=0,this._fragments=[],this._opcode===2){let n;this._binaryType==="nodebuffer"?n=Et(r,s):this._binaryType==="arraybuffer"?n=$n(Et(r,s)):this._binaryType==="blob"?n=new Blob(r):n=r,this._allowSynchronousEvents?(this.emit("message",n,!0),this._state=P):(this._state=We,setImmediate(()=>{this.emit("message",n,!0),this._state=P,this.startLoop(e)}))}else{let n=Et(r,s);if(!this._skipUTF8Validation&&!bs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");e(i);return}this._state===Tt||this._allowSynchronousEvents?(this.emit("message",n,!1),this._state=P):(this._state=We,setImmediate(()=>{this.emit("message",n,!1),this._state=P,this.startLoop(e)}))}}controlMessage(e,s){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit("conclude",1005,Es),this.end();else{let r=e.readUInt16BE(0);if(!Wn(r)){let i=this.createError(RangeError,`invalid status code ${r}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");s(i);return}let n=new Ye(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!bs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");s(i);return}this._loop=!1,this.emit("conclude",r,n),this.end()}this._state=P;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",e),this._state=P):(this._state=We,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",e),this._state=P,this.startLoop(s)}))}createError(e,s,r,n,i){this._loop=!1,this._errored=!0;let o=new e(r?`Invalid WebSocket frame: ${s}`:s);return Error.captureStackTrace(o,this.createError),o.code=i,o[Un]=n,o}};Is.exports=wt});var Ot=I((ua,Cs)=>{"use strict";var{Duplex:fa}=S("stream"),{randomFillSync:Gn}=S("crypto"),{types:{isUint8Array:jn}}=S("util"),vs=ue(),{EMPTY_BUFFER:Vn,kWebSocket:qn,NOOP:zn}=U(),{isBlob:he,isValidStatusCode:Xn}=de(),{mask:Os,toBuffer:K}=Ae(),R=Symbol("kByteLength"),Kn=Buffer.alloc(4),Ge=8*1024,J,pe=Ge,L=0,Jn=1,Zn=2,It=class t{constructor(e,s,r){this._extensions=s||{},r&&(this._generateMask=r,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=L,this.onerror=zn,this[qn]=void 0}static frame(e,s){let r,n=!1,i=2,o=!1;s.mask&&(r=s.maskBuffer||Kn,s.generateMask?s.generateMask(r):(pe===Ge&&(J===void 0&&(J=Buffer.alloc(Ge)),Gn(J,0,Ge),pe=0),r[0]=J[pe++],r[1]=J[pe++],r[2]=J[pe++],r[3]=J[pe++]),o=(r[0]|r[1]|r[2]|r[3])===0,i=6);let a;typeof e=="string"?(!s.mask||o)&&s[R]!==void 0?a=s[R]:(e=Buffer.from(e),a=e.length):(a=e.length,n=s.mask&&s.readOnly&&!o);let l=a;a>=65536?(i+=8,l=127):a>125&&(i+=2,l=126);let c=Buffer.allocUnsafe(n?a+i:i);return c[0]=s.fin?s.opcode|128:s.opcode,s.rsv1&&(c[0]|=64),c[1]=l,l===126?c.writeUInt16BE(a,2):l===127&&(c[2]=c[3]=0,c.writeUIntBE(a,4,6)),s.mask?(c[1]|=128,c[i-4]=r[0],c[i-3]=r[1],c[i-2]=r[2],c[i-1]=r[3],o?[c,e]:n?(Os(e,r,c,i,a),[c]):(Os(e,r,e,0,a),[c,e])):[c,e]}close(e,s,r,n){let i;if(e===void 0)i=Vn;else{if(typeof e!="number"||!Xn(e))throw new TypeError("First argument must be a valid error code number");if(s===void 0||!s.length)i=Buffer.allocUnsafe(2),i.writeUInt16BE(e,0);else{let a=Buffer.byteLength(s);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");if(i=Buffer.allocUnsafe(2+a),i.writeUInt16BE(e,0),typeof s=="string")i.write(s,2);else if(jn(s))i.set(s,2);else throw new TypeError("Second argument must be a string or a Uint8Array")}}let o={[R]:i.length,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state!==L?this.enqueue([this.dispatch,i,!1,o,n]):this.sendFrame(t.frame(i,o),n)}ping(e,s,r){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):he(e)?(n=e.size,i=!1):(e=K(e),n=e.length,i=K.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[R]:n,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:9,readOnly:i,rsv1:!1};he(e)?this._state!==L?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==L?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(t.frame(e,o),r)}pong(e,s,r){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):he(e)?(n=e.size,i=!1):(e=K(e),n=e.length,i=K.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[R]:n,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:10,readOnly:i,rsv1:!1};he(e)?this._state!==L?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==L?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(t.frame(e,o),r)}send(e,s,r){let n=this._extensions[vs.extensionName],i=s.binary?2:1,o=s.compress,a,l;typeof e=="string"?(a=Buffer.byteLength(e),l=!1):he(e)?(a=e.size,l=!1):(e=K(e),a=e.length,l=K.readOnly),this._firstFragment?(this._firstFragment=!1,o&&n&&n.params[n._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=n._threshold),this._compress=o):(o=!1,i=0),s.fin&&(this._firstFragment=!0);let c={[R]:a,fin:s.fin,generateMask:this._generateMask,mask:s.mask,maskBuffer:this._maskBuffer,opcode:i,readOnly:l,rsv1:o};he(e)?this._state!==L?this.enqueue([this.getBlobData,e,this._compress,c,r]):this.getBlobData(e,this._compress,c,r):this._state!==L?this.enqueue([this.dispatch,e,this._compress,c,r]):this.dispatch(e,this._compress,c,r)}getBlobData(e,s,r,n){this._bufferedBytes+=r[R],this._state=Zn,e.arrayBuffer().then(i=>{if(this._socket.destroyed){let a=new Error("The socket was closed while the blob was being read");process.nextTick(vt,this,a,n);return}this._bufferedBytes-=r[R];let o=K(i);s?this.dispatch(o,s,r,n):(this._state=L,this.sendFrame(t.frame(o,r),n),this.dequeue())}).catch(i=>{process.nextTick(Qn,this,i,n)})}dispatch(e,s,r,n){if(!s){this.sendFrame(t.frame(e,r),n);return}let i=this._extensions[vs.extensionName];this._bufferedBytes+=r[R],this._state=Jn,i.compress(e,r.fin,(o,a)=>{if(this._socket.destroyed){let l=new Error("The socket was closed while data was being compressed");vt(this,l,n);return}this._bufferedBytes-=r[R],this._state=L,r.readOnly=!1,this.sendFrame(t.frame(a,r),n),this.dequeue()})}dequeue(){for(;this._state===L&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][R],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][R],this._queue.push(e)}sendFrame(e,s){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],s),this._socket.uncork()):this._socket.write(e[0],s)}};Cs.exports=It;function vt(t,e,s){typeof s=="function"&&s(e);for(let r=0;r<t._queue.length;r++){let n=t._queue[r],i=n[n.length-1];typeof i=="function"&&i(e)}}function Qn(t,e,s){vt(t,e,s),t.onerror(e)}});var Fs=I((da,Bs)=>{"use strict";var{kForOnEventAttribute:ve,kListener:Ct}=U(),Ps=Symbol("kCode"),Rs=Symbol("kData"),ks=Symbol("kError"),Ls=Symbol("kMessage"),Ms=Symbol("kReason"),me=Symbol("kTarget"),Ns=Symbol("kType"),Ds=Symbol("kWasClean"),$=class{constructor(e){this[me]=null,this[Ns]=e}get target(){return this[me]}get type(){return this[Ns]}};Object.defineProperty($.prototype,"target",{enumerable:!0});Object.defineProperty($.prototype,"type",{enumerable:!0});var Z=class extends ${constructor(e,s={}){super(e),this[Ps]=s.code===void 0?0:s.code,this[Ms]=s.reason===void 0?"":s.reason,this[Ds]=s.wasClean===void 0?!1:s.wasClean}get code(){return this[Ps]}get reason(){return this[Ms]}get wasClean(){return this[Ds]}};Object.defineProperty(Z.prototype,"code",{enumerable:!0});Object.defineProperty(Z.prototype,"reason",{enumerable:!0});Object.defineProperty(Z.prototype,"wasClean",{enumerable:!0});var _e=class extends ${constructor(e,s={}){super(e),this[ks]=s.error===void 0?null:s.error,this[Ls]=s.message===void 0?"":s.message}get error(){return this[ks]}get message(){return this[Ls]}};Object.defineProperty(_e.prototype,"error",{enumerable:!0});Object.defineProperty(_e.prototype,"message",{enumerable:!0});var Oe=class extends ${constructor(e,s={}){super(e),this[Rs]=s.data===void 0?null:s.data}get data(){return this[Rs]}};Object.defineProperty(Oe.prototype,"data",{enumerable:!0});var ei={addEventListener(t,e,s={}){for(let n of this.listeners(t))if(!s[ve]&&n[Ct]===e&&!n[ve])return;let r;if(t==="message")r=function(i,o){let a=new Oe("message",{data:o?i:i.toString()});a[me]=this,je(e,this,a)};else if(t==="close")r=function(i,o){let a=new Z("close",{code:i,reason:o.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});a[me]=this,je(e,this,a)};else if(t==="error")r=function(i){let o=new _e("error",{error:i,message:i.message});o[me]=this,je(e,this,o)};else if(t==="open")r=function(){let i=new $("open");i[me]=this,je(e,this,i)};else return;r[ve]=!!s[ve],r[Ct]=e,s.once?this.once(t,r):this.on(t,r)},removeEventListener(t,e){for(let s of this.listeners(t))if(s[Ct]===e&&!s[ve]){this.removeListener(t,s);break}}};Bs.exports={CloseEvent:Z,ErrorEvent:_e,Event:$,EventTarget:ei,MessageEvent:Oe};function je(t,e,s){typeof t=="object"&&t.handleEvent?t.handleEvent.call(t,s):t.call(e,s)}});var Ve=I((ha,Us)=>{"use strict";var{tokenChars:Ce}=de();function D(t,e,s){t[e]===void 0?t[e]=[s]:t[e].push(s)}function ti(t){let e=Object.create(null),s=Object.create(null),r=!1,n=!1,i=!1,o,a,l=-1,c=-1,f=-1,d=0;for(;d<t.length;d++)if(c=t.charCodeAt(d),o===void 0)if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(d!==0&&(c===32||c===9))f===-1&&l!==-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d);let h=t.slice(l,f);c===44?(D(e,h,s),s=Object.create(null)):o=h,l=f=-1}else throw new SyntaxError(`Unexpected character at index ${d}`);else if(a===void 0)if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(c===32||c===9)f===-1&&l!==-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d),D(s,t.slice(l,f),!0),c===44&&(D(e,o,s),s=Object.create(null),o=void 0),l=f=-1}else if(c===61&&l!==-1&&f===-1)a=t.slice(l,d),l=f=-1;else throw new SyntaxError(`Unexpected character at index ${d}`);else if(n){if(Ce[c]!==1)throw new SyntaxError(`Unexpected character at index ${d}`);l===-1?l=d:r||(r=!0),n=!1}else if(i)if(Ce[c]===1)l===-1&&(l=d);else if(c===34&&l!==-1)i=!1,f=d;else if(c===92)n=!0;else throw new SyntaxError(`Unexpected character at index ${d}`);else if(c===34&&t.charCodeAt(d-1)===61)i=!0;else if(f===-1&&Ce[c]===1)l===-1&&(l=d);else if(l!==-1&&(c===32||c===9))f===-1&&(f=d);else if(c===59||c===44){if(l===-1)throw new SyntaxError(`Unexpected character at index ${d}`);f===-1&&(f=d);let h=t.slice(l,f);r&&(h=h.replace(/\\/g,""),r=!1),D(s,a,h),c===44&&(D(e,o,s),s=Object.create(null),o=void 0),a=void 0,l=f=-1}else throw new SyntaxError(`Unexpected character at index ${d}`);if(l===-1||i||c===32||c===9)throw new SyntaxError("Unexpected end of input");f===-1&&(f=d);let u=t.slice(l,f);return o===void 0?D(e,u,s):(a===void 0?D(s,u,!0):r?D(s,a,u.replace(/\\/g,"")):D(s,a,u),D(e,o,s)),e}function si(t){return Object.keys(t).map(e=>{let s=t[e];return Array.isArray(s)||(s=[s]),s.map(r=>[e].concat(Object.keys(r).map(n=>{let i=r[n];return Array.isArray(i)||(i=[i]),i.map(o=>o===!0?n:`${n}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}Us.exports={format:si,parse:ti}});var Ke=I((_a,Js)=>{"use strict";var ri=S("events"),ni=S("https"),ii=S("http"),Ys=S("net"),oi=S("tls"),{randomBytes:ai,createHash:li}=S("crypto"),{Duplex:pa,Readable:ma}=S("stream"),{URL:Pt}=S("url"),V=ue(),ci=At(),fi=Ot(),{isBlob:ui}=de(),{BINARY_TYPES:Hs,CLOSE_TIMEOUT:di,EMPTY_BUFFER:qe,GUID:hi,kForOnEventAttribute:Rt,kListener:pi,kStatusCode:mi,kWebSocket:E,NOOP:Ws}=U(),{EventTarget:{addEventListener:_i,removeEventListener:yi}}=Fs(),{format:gi,parse:Si}=Ve(),{toBuffer:xi}=Ae(),Gs=Symbol("kAborted"),kt=[8,13],Y=["CONNECTING","OPEN","CLOSING","CLOSED"],Ei=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,g=class t extends ri{constructor(e,s,r){super(),this._binaryType=Hs[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=qe,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol="",this._readyState=t.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,s===void 0?s=[]:Array.isArray(s)||(typeof s=="object"&&s!==null?(r=s,s=[]):s=[s]),js(this,e,s,r)):(this._autoPong=r.autoPong,this._closeTimeout=r.closeTimeout,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(e){Hs.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,s,r){let n=new ci({allowSynchronousEvents:r.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxBufferedChunks:r.maxBufferedChunks,maxFragments:r.maxFragments,maxPayload:r.maxPayload,skipUTF8Validation:r.skipUTF8Validation}),i=new fi(e,this._extensions,r.generateMask);this._receiver=n,this._sender=i,this._socket=e,n[E]=this,i[E]=this,e[E]=this,n.on("conclude",wi),n.on("drain",Ai),n.on("error",Ii),n.on("message",vi),n.on("ping",Oi),n.on("pong",Ci),i.onerror=Pi,e.setTimeout&&e.setTimeout(0),e.setNoDelay&&e.setNoDelay(),s.length>0&&e.unshift(s),e.on("close",zs),e.on("data",Xe),e.on("end",Xs),e.on("error",Ks),this._readyState=t.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[V.extensionName]&&this._extensions[V.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,s){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===t.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=t.CLOSING,this._sender.close(e,s,!this._isServer,r=>{r||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),qs(this)}}pause(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=s=void 0):typeof s=="function"&&(r=s,s=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}s===void 0&&(s=!this._isServer),this._sender.ping(e||qe,s,r)}pong(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=s=void 0):typeof s=="function"&&(r=s,s=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}s===void 0&&(s=!this._isServer),this._sender.pong(e||qe,s,r)}resume(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,s,r){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof s=="function"&&(r=s,s={}),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Lt(this,e,r);return}let n={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...s};this._extensions[V.extensionName]||(n.compress=!1),this._sender.send(e||qe,n,r)}terminate(){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){O(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=t.CLOSING,this._socket.destroy())}}};Object.defineProperty(g,"CONNECTING",{enumerable:!0,value:Y.indexOf("CONNECTING")});Object.defineProperty(g.prototype,"CONNECTING",{enumerable:!0,value:Y.indexOf("CONNECTING")});Object.defineProperty(g,"OPEN",{enumerable:!0,value:Y.indexOf("OPEN")});Object.defineProperty(g.prototype,"OPEN",{enumerable:!0,value:Y.indexOf("OPEN")});Object.defineProperty(g,"CLOSING",{enumerable:!0,value:Y.indexOf("CLOSING")});Object.defineProperty(g.prototype,"CLOSING",{enumerable:!0,value:Y.indexOf("CLOSING")});Object.defineProperty(g,"CLOSED",{enumerable:!0,value:Y.indexOf("CLOSED")});Object.defineProperty(g.prototype,"CLOSED",{enumerable:!0,value:Y.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(t=>{Object.defineProperty(g.prototype,t,{enumerable:!0})});["open","error","close","message"].forEach(t=>{Object.defineProperty(g.prototype,`on${t}`,{enumerable:!0,get(){for(let e of this.listeners(t))if(e[Rt])return e[pi];return null},set(e){for(let s of this.listeners(t))if(s[Rt]){this.removeListener(t,s);break}typeof e=="function"&&this.addEventListener(t,e,{[Rt]:!0})}})});g.prototype.addEventListener=_i;g.prototype.removeEventListener=yi;Js.exports=g;function js(t,e,s,r){let n={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:di,protocolVersion:kt[1],maxBufferedChunks:262144,maxFragments:16384,maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...r,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(t._autoPong=n.autoPong,t._closeTimeout=n.closeTimeout,!kt.includes(n.protocolVersion))throw new RangeError(`Unsupported protocol version: ${n.protocolVersion} (supported versions: ${kt.join(", ")})`);let i;if(e instanceof Pt)i=e;else try{i=new Pt(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}i.protocol==="http:"?i.protocol="ws:":i.protocol==="https:"&&(i.protocol="wss:"),t._url=i.href;let o=i.protocol==="wss:",a=i.protocol==="ws+unix:",l;if(i.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:a&&!i.pathname?l="The URL's pathname is empty":i.hash&&(l="The URL contains a fragment identifier"),l){let _=new SyntaxError(l);if(t._redirects===0)throw _;ze(t,_);return}let c=o?443:80,f=ai(16).toString("base64"),d=o?ni.request:ii.request,u=new Set,h;if(n.createConnection=n.createConnection||(o?Ti:bi),n.defaultPort=n.defaultPort||c,n.port=i.port||c,n.host=i.hostname.startsWith("[")?i.hostname.slice(1,-1):i.hostname,n.headers={...n.headers,"Sec-WebSocket-Version":n.protocolVersion,"Sec-WebSocket-Key":f,Connection:"Upgrade",Upgrade:"websocket"},n.path=i.pathname+i.search,n.timeout=n.handshakeTimeout,n.perMessageDeflate&&(h=new V({...n.perMessageDeflate,isServer:!1,maxPayload:n.maxPayload}),n.headers["Sec-WebSocket-Extensions"]=gi({[V.extensionName]:h.offer()})),s.length){for(let _ of s){if(typeof _!="string"||!Ei.test(_)||u.has(_))throw new SyntaxError("An invalid or duplicated subprotocol was specified");u.add(_)}n.headers["Sec-WebSocket-Protocol"]=s.join(",")}if(n.origin&&(n.protocolVersion<13?n.headers["Sec-WebSocket-Origin"]=n.origin:n.headers.Origin=n.origin),(i.username||i.password)&&(n.auth=`${i.username}:${i.password}`),a){let _=n.path.split(":");n.socketPath=_[0],n.path=_[1]}let m;if(n.followRedirects){if(t._redirects===0){t._originalIpc=a,t._originalSecure=o,t._originalHostOrSocketPath=a?n.socketPath:i.host;let _=r&&r.headers;if(r={...r,headers:{}},_)for(let[b,oe]of Object.entries(_))r.headers[b.toLowerCase()]=oe}else if(t.listenerCount("redirect")===0){let _=a?t._originalIpc?n.socketPath===t._originalHostOrSocketPath:!1:t._originalIpc?!1:i.host===t._originalHostOrSocketPath;(!_||t._originalSecure&&!o)&&(delete n.headers.authorization,delete n.headers.cookie,_||delete n.headers.host,n.auth=void 0)}n.auth&&!r.headers.authorization&&(r.headers.authorization="Basic "+Buffer.from(n.auth).toString("base64")),m=t._req=d(n),t._redirects&&t.emit("redirect",t.url,m)}else m=t._req=d(n);n.timeout&&m.on("timeout",()=>{O(t,m,"Opening handshake has timed out")}),m.on("error",_=>{m===null||m[Gs]||(m=t._req=null,ze(t,_))}),m.on("response",_=>{let b=_.headers.location,oe=_.statusCode;if(b&&n.followRedirects&&oe>=300&&oe<400){if(++t._redirects>n.maxRedirects){O(t,m,"Maximum redirects exceeded");return}m.abort();let be;try{be=new Pt(b,e)}catch{let ae=new SyntaxError(`Invalid URL: ${b}`);ze(t,ae);return}js(t,be,s,r)}else t.emit("unexpected-response",m,_)||O(t,m,`Unexpected server response: ${_.statusCode}`)}),m.on("upgrade",(_,b,oe)=>{if(t.emit("upgrade",_),t.readyState!==g.CONNECTING)return;m=t._req=null;let be=_.headers.upgrade;if(be===void 0||be.toLowerCase()!=="websocket"){O(t,b,"Invalid Upgrade header");return}let ss=li("sha1").update(f+hi).digest("base64");if(_.headers["sec-websocket-accept"]!==ss){O(t,b,"Invalid Sec-WebSocket-Accept header");return}let ae=_.headers["sec-websocket-protocol"],Te;if(ae!==void 0?u.size?u.has(ae)||(Te="Server sent an invalid subprotocol"):Te="Server sent a subprotocol but none was requested":u.size&&(Te="Server sent no subprotocol"),Te){O(t,b,Te);return}ae&&(t._protocol=ae);let rs=_.headers["sec-websocket-extensions"];if(rs!==void 0){if(!h){O(t,b,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let ft;try{ft=Si(rs)}catch{O(t,b,"Invalid Sec-WebSocket-Extensions header");return}let ns=Object.keys(ft);if(ns.length!==1||ns[0]!==V.extensionName){O(t,b,"Server indicated an extension that was not requested");return}try{h.accept(ft[V.extensionName])}catch{O(t,b,"Invalid Sec-WebSocket-Extensions header");return}t._extensions[V.extensionName]=h}t.setSocket(b,oe,{allowSynchronousEvents:n.allowSynchronousEvents,generateMask:n.generateMask,maxBufferedChunks:n.maxBufferedChunks,maxFragments:n.maxFragments,maxPayload:n.maxPayload,skipUTF8Validation:n.skipUTF8Validation})}),n.finishRequest?n.finishRequest(m,t):m.end()}function ze(t,e){t._readyState=g.CLOSING,t._errorEmitted=!0,t.emit("error",e),t.emitClose()}function bi(t){return t.path=t.socketPath,Ys.connect(t)}function Ti(t){return t.path=void 0,!t.servername&&t.servername!==""&&(t.servername=Ys.isIP(t.host)?"":t.host),oi.connect(t)}function O(t,e,s){t._readyState=g.CLOSING;let r=new Error(s);Error.captureStackTrace(r,O),e.setHeader?(e[Gs]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(ze,t,r)):(e.destroy(r),e.once("error",t.emit.bind(t,"error")),e.once("close",t.emitClose.bind(t)))}function Lt(t,e,s){if(e){let r=ui(e)?e.size:xi(e).length;t._socket?t._sender._bufferedBytes+=r:t._bufferedAmount+=r}if(s){let r=new Error(`WebSocket is not open: readyState ${t.readyState} (${Y[t.readyState]})`);process.nextTick(s,r)}}function wi(t,e){let s=this[E];s._closeFrameReceived=!0,s._closeMessage=e,s._closeCode=t,s._socket[E]!==void 0&&(s._socket.removeListener("data",Xe),process.nextTick(Vs,s._socket),t===1005?s.close():s.close(t,e))}function Ai(){let t=this[E];t.isPaused||t._socket.resume()}function Ii(t){let e=this[E];e._socket[E]!==void 0&&(e._socket.removeListener("data",Xe),process.nextTick(Vs,e._socket),e.close(t[mi])),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t))}function $s(){this[E].emitClose()}function vi(t,e){this[E].emit("message",t,e)}function Oi(t){let e=this[E];e._autoPong&&e.pong(t,!this._isServer,Ws),e.emit("ping",t)}function Ci(t){this[E].emit("pong",t)}function Vs(t){t.resume()}function Pi(t){let e=this[E];e.readyState!==g.CLOSED&&(e.readyState===g.OPEN&&(e._readyState=g.CLOSING,qs(e)),this._socket.end(),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t)))}function qs(t){t._closeTimer=setTimeout(t._socket.destroy.bind(t._socket),t._closeTimeout)}function zs(){let t=this[E];if(this.removeListener("close",zs),this.removeListener("data",Xe),this.removeListener("end",Xs),t._readyState=g.CLOSING,!this._readableState.endEmitted&&!t._closeFrameReceived&&!t._receiver._writableState.errorEmitted&&this._readableState.length!==0){let e=this.read(this._readableState.length);t._receiver.write(e)}t._receiver.end(),this[E]=void 0,clearTimeout(t._closeTimer),t._receiver._writableState.finished||t._receiver._writableState.errorEmitted?t.emitClose():(t._receiver.on("error",$s),t._receiver.on("finish",$s))}function Xe(t){this[E]._receiver.write(t)||this.pause()}function Xs(){let t=this[E];t._readyState=g.CLOSING,t._receiver.end(),this.end()}function Ks(){let t=this[E];this.removeListener("error",Ks),this.on("error",Ws),t&&(t._readyState=g.CLOSING,this.destroy())}});var tr=I((ga,er)=>{"use strict";var ya=Ke(),{Duplex:Ri}=S("stream");function Zs(t){t.emit("close")}function ki(){!this.destroyed&&this._writableState.finished&&this.destroy()}function Qs(t){this.removeListener("error",Qs),this.destroy(),this.listenerCount("error")===0&&this.emit("error",t)}function Li(t,e){let s=!0,r=new Ri({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return t.on("message",function(i,o){let a=!o&&r._readableState.objectMode?i.toString():i;r.push(a)||t.pause()}),t.once("error",function(i){r.destroyed||(s=!1,r.destroy(i))}),t.once("close",function(){r.destroyed||r.push(null)}),r._destroy=function(n,i){if(t.readyState===t.CLOSED){i(n),process.nextTick(Zs,r);return}let o=!1;t.once("error",function(l){o=!0,i(l)}),t.once("close",function(){o||i(n),process.nextTick(Zs,r)}),s&&t.terminate()},r._final=function(n){if(t.readyState===t.CONNECTING){t.once("open",function(){r._final(n)});return}t._socket!==null&&(t._socket._writableState.finished?(n(),r._readableState.endEmitted&&r.destroy()):(t._socket.once("finish",function(){n()}),t.close()))},r._read=function(){t.isPaused&&t.resume()},r._write=function(n,i,o){if(t.readyState===t.CONNECTING){t.once("open",function(){r._write(n,i,o)});return}t.send(n,o)},r.on("end",ki),r.on("error",Qs),r}er.exports=Li});var Mt=I((Sa,sr)=>{"use strict";var{tokenChars:Mi}=de();function Ni(t){let e=new Set,s=-1,r=-1,n=0;for(n;n<t.length;n++){let o=t.charCodeAt(n);if(r===-1&&Mi[o]===1)s===-1&&(s=n);else if(n!==0&&(o===32||o===9))r===-1&&s!==-1&&(r=n);else if(o===44){if(s===-1)throw new SyntaxError(`Unexpected character at index ${n}`);r===-1&&(r=n);let a=t.slice(s,r);if(e.has(a))throw new SyntaxError(`The "${a}" subprotocol is duplicated`);e.add(a),s=r=-1}else throw new SyntaxError(`Unexpected character at index ${n}`)}if(s===-1||r!==-1)throw new SyntaxError("Unexpected end of input");let i=t.slice(s,n);if(e.has(i))throw new SyntaxError(`The "${i}" subprotocol is duplicated`);return e.add(i),e}sr.exports={parse:Ni}});var cr=I((Ea,lr)=>{"use strict";var Di=S("events"),Je=S("http"),{Duplex:xa}=S("stream"),{createHash:Bi}=S("crypto"),rr=Ve(),Q=ue(),Fi=Mt(),Ui=Ke(),{CLOSE_TIMEOUT:Hi,GUID:$i,kWebSocket:Yi}=U(),Wi=/^[+/0-9A-Za-z]{22}==$/,nr=0,ir=1,ar=2,Nt=class extends Di{constructor(e,s){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxBufferedChunks:256*1024,maxFragments:16*1024,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,closeTimeout:Hi,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:Ui,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(e.port!=null?(this._server=Je.createServer((r,n)=>{let i=Je.STATUS_CODES[426];n.writeHead(426,{"Content-Length":i.length,"Content-Type":"text/plain"}),n.end(i)}),this._server.listen(e.port,e.host,e.backlog,s)):e.server&&(this._server=e.server),this._server){let r=this.emit.bind(this,"connection");this._removeListeners=Gi(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(n,i,o)=>{this.handleUpgrade(n,i,o,r)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=nr}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===ar){e&&this.once("close",()=>{e(new Error("The server is not running"))}),process.nextTick(Pe,this);return}if(e&&this.once("close",e),this._state!==ir)if(this._state=ir,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(Pe,this):process.nextTick(Pe,this);else{let s=this._server;this._removeListeners(),this._removeListeners=this._server=null,s.close(()=>{Pe(this)})}}shouldHandle(e){if(this.options.path){let s=e.url.indexOf("?");if((s!==-1?e.url.slice(0,s):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,s,r,n){s.on("error",or);let i=e.headers["sec-websocket-key"],o=e.headers.upgrade,a=+e.headers["sec-websocket-version"];if(e.method!=="GET"){ee(this,e,s,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){ee(this,e,s,400,"Invalid Upgrade header");return}if(i===void 0||!Wi.test(i)){ee(this,e,s,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==13&&a!==8){ee(this,e,s,400,"Missing or invalid Sec-WebSocket-Version header",{"Sec-WebSocket-Version":"13, 8"});return}if(!this.shouldHandle(e)){Re(s,400);return}let l=e.headers["sec-websocket-protocol"],c=new Set;if(l!==void 0)try{c=Fi.parse(l)}catch{ee(this,e,s,400,"Invalid Sec-WebSocket-Protocol header");return}let f=e.headers["sec-websocket-extensions"],d={};if(this.options.perMessageDeflate&&f!==void 0){let u=new Q({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let h=rr.parse(f);h[Q.extensionName]&&(u.accept(h[Q.extensionName]),d[Q.extensionName]=u)}catch{ee(this,e,s,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let u={origin:e.headers[`${a===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(u,(h,m,_,b)=>{if(!h)return Re(s,m||401,_,b);this.completeUpgrade(d,i,c,e,s,r,n)});return}if(!this.options.verifyClient(u))return Re(s,401)}this.completeUpgrade(d,i,c,e,s,r,n)}completeUpgrade(e,s,r,n,i,o,a){if(!i.readable||!i.writable)return i.destroy();if(i[Yi])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>nr)return Re(i,503);let c=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${Bi("sha1").update(s+$i).digest("base64")}`],f=new this.options.WebSocket(null,void 0,this.options);if(r.size){let d=this.options.handleProtocols?this.options.handleProtocols(r,n):r.values().next().value;d&&(c.push(`Sec-WebSocket-Protocol: ${d}`),f._protocol=d)}if(e[Q.extensionName]){let d=e[Q.extensionName].params,u=rr.format({[Q.extensionName]:[d]});c.push(`Sec-WebSocket-Extensions: ${u}`),f._extensions=e}this.emit("headers",c,n),i.write(c.concat(`\r
5
5
  `).join(`\r
6
- `)),i.removeListener("error",or),f.setSocket(i,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxBufferedChunks:this.options.maxBufferedChunks,maxFragments:this.options.maxFragments,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(f),f.on("close",()=>{this.clients.delete(f),this._shouldEmitClose&&!this.clients.size&&process.nextTick(Pe,this)})),a(f,n)}};lr.exports=Mt;function $i(t,e){for(let s of Object.keys(e))t.on(s,e[s]);return function(){for(let r of Object.keys(e))t.removeListener(r,e[r])}}function Pe(t){t._state=ar,t.emit("close")}function or(){this.destroy()}function Re(t,e,s,r){s=s||Je.STATUS_CODES[e],r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(s),...r},t.once("finish",t.destroy),t.end(`HTTP/1.1 ${e} ${Je.STATUS_CODES[e]}\r
6
+ `)),i.removeListener("error",or),f.setSocket(i,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxBufferedChunks:this.options.maxBufferedChunks,maxFragments:this.options.maxFragments,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(f),f.on("close",()=>{this.clients.delete(f),this._shouldEmitClose&&!this.clients.size&&process.nextTick(Pe,this)})),a(f,n)}};lr.exports=Nt;function Gi(t,e){for(let s of Object.keys(e))t.on(s,e[s]);return function(){for(let r of Object.keys(e))t.removeListener(r,e[r])}}function Pe(t){t._state=ar,t.emit("close")}function or(){this.destroy()}function Re(t,e,s,r){s=s||Je.STATUS_CODES[e],r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(s),...r},t.once("finish",t.destroy),t.end(`HTTP/1.1 ${e} ${Je.STATUS_CODES[e]}\r
7
7
  `+Object.keys(r).map(n=>`${n}: ${r[n]}`).join(`\r
8
8
  `)+`\r
9
9
  \r
10
- `+s)}function ee(t,e,s,r,n,i){if(t.listenerCount("wsClientError")){let o=new Error(n);Error.captureStackTrace(o,ee),t.emit("wsClientError",o,s,e)}else Re(s,r,n,i)}});import qo from"node:fs";import zo from"node:path";import hn from"node:fs";import mn from"node:os";import we from"node:path";var ae=we.resolve(import.meta.dirname,"..");function ht(){if(process.env.RELAY_STATE_DIR)return process.env.RELAY_STATE_DIR;let t=process.env.XDG_STATE_HOME||we.join(mn.homedir(),".local","state");return we.join(t,"herdr-remote-relay")}var x={relay:{mode:"remote",host:"127.0.0.1",port:8787,publicUrl:"http://127.0.0.1:8787",maxPayloadBytes:5*1024*1024,maxClientsPerHost:16,maxHosts:1024,maxPendingHandshakes:1024,maxBufferedBytesPerClient:4*1024*1024,allowedOrigins:[],trustProxy:!1,hostReconnectGraceMs:30*1e3},auth:{pairingTtlMs:600*1e3,deviceTtlMs:720*60*60*1e3,maxDevices:32,password:null,adminToken:null,stateFile:null},cleanup:{intervalMs:60*1e3,heartbeatIntervalMs:30*1e3,staleAfterMs:90*1e3}};function pn(t){return JSON.parse(JSON.stringify(t))}function _n(t){try{return JSON.parse(hn.readFileSync(t,"utf8"))}catch(e){let{code:s,message:r}=e;if(s==="ENOENT")return null;throw new Error(`cannot read relay config ${t}: ${r}`)}}function mt(t,e){if(t==null||t==="")return e;if(t===!0||t===!1)return t;let s=String(t).trim().toLowerCase();return["true","1","yes","on"].includes(s)?!0:["false","0","no","off"].includes(s)?!1:e}function I(t,e,s,r){let n=Number(t);return!Number.isInteger(n)||n<s||n>r?e:n}function os(t){return Array.isArray(t)?t.map(e=>String(e).trim()).filter(Boolean):typeof t!="string"?null:t.split(",").map(e=>e.trim()).filter(Boolean)}function dt(t,e){if(!e||typeof e!="object")return;let s=e;for(let r of Object.keys(t))s[r]!==void 0&&(t[r]=s[r])}function yn(t=[]){let e={},s=[],r=!1,n=!1;for(let i=0;i<t.length;i+=1){let o=t[i];if(o==="--help"||o==="-h"){r=!0;continue}if(o==="--version"||o==="-v"){n=!0;continue}if(!o.startsWith("--")){s.push(`unexpected argument: ${o}`);continue}let a=o.indexOf("="),l=a===-1?o.slice(2):o.slice(2,a),c=a===-1?void 0:o.slice(a+1);if(c===void 0){let f=t[i+1];f===void 0||f.startsWith("--")?c="true":(c=f,i+=1)}e[l]=c}return{options:e,help:r,version:n,errors:s}}function gn(t,e){if(!e||typeof e!="object")return;let s=e;dt(t.relay,s.relay),dt(t.auth,s.auth),dt(t.cleanup,s.cleanup)}function Sn(t,e){if((e.RELAY_DEPLOYMENT_MODE==="local"||e.RELAY_DEPLOYMENT_MODE==="remote")&&(t.relay.mode=e.RELAY_DEPLOYMENT_MODE),e.RELAY_BIND&&(t.relay.host=e.RELAY_BIND),e.RELAY_PORT&&(t.relay.port=e.RELAY_PORT),e.RELAY_PUBLIC_URL&&(t.relay.publicUrl=e.RELAY_PUBLIC_URL),e.RELAY_MAX_PAYLOAD_BYTES&&(t.relay.maxPayloadBytes=e.RELAY_MAX_PAYLOAD_BYTES),e.RELAY_MAX_CLIENTS_PER_HOST&&(t.relay.maxClientsPerHost=e.RELAY_MAX_CLIENTS_PER_HOST),e.RELAY_MAX_HOSTS&&(t.relay.maxHosts=e.RELAY_MAX_HOSTS),e.RELAY_MAX_PENDING_HANDSHAKES&&(t.relay.maxPendingHandshakes=e.RELAY_MAX_PENDING_HANDSHAKES),e.RELAY_MAX_BUFFERED_BYTES_PER_CLIENT&&(t.relay.maxBufferedBytesPerClient=e.RELAY_MAX_BUFFERED_BYTES_PER_CLIENT),e.RELAY_HOST_RECONNECT_GRACE_MS&&(t.relay.hostReconnectGraceMs=e.RELAY_HOST_RECONNECT_GRACE_MS),e.RELAY_ALLOWED_ORIGINS!==void 0){let s=os(e.RELAY_ALLOWED_ORIGINS);s&&(t.relay.allowedOrigins=s)}e.RELAY_TRUST_PROXY!==void 0&&(t.relay.trustProxy=mt(e.RELAY_TRUST_PROXY,t.relay.trustProxy)),e.RELAY_PASSWORD&&(t.auth.password=e.RELAY_PASSWORD),e.RELAY_ADMIN_TOKEN&&(t.auth.adminToken=e.RELAY_ADMIN_TOKEN),e.RELAY_AUTH_STATE_FILE&&(t.auth.stateFile=e.RELAY_AUTH_STATE_FILE),e.RELAY_PAIRING_TTL_MS&&(t.auth.pairingTtlMs=e.RELAY_PAIRING_TTL_MS),e.RELAY_DEVICE_TTL_MS&&(t.auth.deviceTtlMs=e.RELAY_DEVICE_TTL_MS),e.RELAY_MAX_DEVICES&&(t.auth.maxDevices=e.RELAY_MAX_DEVICES)}function xn(t,e){if((e["deployment-mode"]==="local"||e["deployment-mode"]==="remote")&&(t.relay.mode=e["deployment-mode"]),e.bind&&(t.relay.host=e.bind),e.port&&(t.relay.port=e.port),e["public-url"]&&(t.relay.publicUrl=e["public-url"]),e["allowed-origins"]!==void 0){let s=os(e["allowed-origins"]);s&&(t.relay.allowedOrigins=s)}e["trust-proxy"]!==void 0&&(t.relay.trustProxy=mt(e["trust-proxy"],t.relay.trustProxy)),e.password&&(t.auth.password=e.password),e["admin-token"]&&(t.auth.adminToken=e["admin-token"]),e["state-file"]&&(t.auth.stateFile=e["state-file"]),e["max-clients"]&&(t.relay.maxClientsPerHost=e["max-clients"]),e["max-hosts"]&&(t.relay.maxHosts=e["max-hosts"]),e["max-pending-handshakes"]&&(t.relay.maxPendingHandshakes=e["max-pending-handshakes"]),e["max-buffered-bytes"]&&(t.relay.maxBufferedBytesPerClient=e["max-buffered-bytes"]),e["host-reconnect-grace-ms"]&&(t.relay.hostReconnectGraceMs=e["host-reconnect-grace-ms"])}function En(t){return t.relay.mode!=="local"&&t.relay.mode!=="remote"&&(t.relay.mode=x.relay.mode),t.relay.port=I(t.relay.port,x.relay.port,0,65535),t.relay.maxPayloadBytes=I(t.relay.maxPayloadBytes,x.relay.maxPayloadBytes,4096,16*1024*1024),t.relay.maxClientsPerHost=I(t.relay.maxClientsPerHost,x.relay.maxClientsPerHost,1,256),t.relay.maxHosts=I(t.relay.maxHosts,x.relay.maxHosts,1,1e5),t.relay.maxPendingHandshakes=I(t.relay.maxPendingHandshakes,x.relay.maxPendingHandshakes,16,1e5),t.relay.maxBufferedBytesPerClient=I(t.relay.maxBufferedBytesPerClient,x.relay.maxBufferedBytesPerClient,64*1024,256*1024*1024),t.relay.hostReconnectGraceMs=I(t.relay.hostReconnectGraceMs,x.relay.hostReconnectGraceMs,1e3,1440*60*1e3),t.auth.pairingTtlMs=I(t.auth.pairingTtlMs,x.auth.pairingTtlMs,30*1e3,1440*60*1e3),t.auth.deviceTtlMs=I(t.auth.deviceTtlMs,x.auth.deviceTtlMs,60*1e3,365*24*60*60*1e3),t.auth.maxDevices=I(t.auth.maxDevices,x.auth.maxDevices,1,1e4),t.cleanup.intervalMs=I(t.cleanup.intervalMs,x.cleanup.intervalMs,1e3,1440*60*1e3),t.cleanup.heartbeatIntervalMs=I(t.cleanup.heartbeatIntervalMs,x.cleanup.heartbeatIntervalMs,1e3,600*1e3),t.cleanup.staleAfterMs=I(t.cleanup.staleAfterMs,x.cleanup.staleAfterMs,t.cleanup.heartbeatIntervalMs*2,1440*60*1e3),(typeof t.relay.host!="string"||t.relay.host.length===0)&&(t.relay.host=x.relay.host),(typeof t.relay.publicUrl!="string"||t.relay.publicUrl.length===0)&&(t.relay.publicUrl=`http://${t.relay.host}:${t.relay.port}`),t.relay.publicUrl=String(t.relay.publicUrl).replace(/\/+$/,""),Array.isArray(t.relay.allowedOrigins)||(t.relay.allowedOrigins=[]),t.relay.trustProxy=mt(t.relay.trustProxy,!1),t.auth.stateFile||(t.auth.stateFile=we.join(ht(),"relay-auth.json")),t}function bn(t){let e=[],s=["127.0.0.1","localhost","::1"].includes(t.relay.host),r;try{r=new URL(t.relay.publicUrl)}catch{e.push(`publicUrl is not a valid URL: ${t.relay.publicUrl}`)}return t.auth.password||e.push("no password set (RELAY_PASSWORD): this is a public relay, anyone may connect a workstation to it"),t.relay.mode==="remote"&&!t.auth.adminToken&&e.push("no admin token set (RELAY_ADMIN_TOKEN): the relay operator dashboard is unavailable"),!s&&r&&r.protocol==="http:"&&!["127.0.0.1","localhost"].includes(r.hostname)&&e.push(`publicUrl uses plain http on a non-loopback address (${t.relay.publicUrl}); terminate TLS in front of the relay`),e}function Be({argv:t=[],env:e=process.env}={}){let{options:s,help:r,version:n,errors:i}=yn(t),o=pn(x),a=s.config||e.HERDR_RELAY_CONFIG||null;if(a){let c=_n(we.resolve(a));if(c===null)throw new Error(`relay config not found: ${a}`);gn(o,c)}Sn(o,e),xn(o,s);let l=En(o);return{config:l,help:r,version:n,errors:i,configFile:a,warnings:bn(l)}}import jo from"node:http";import ts from"node:path";import{URL as Vo}from"node:url";var Wi=G(tr(),1),Gi=G(Ve(),1),ji=G(fe(),1),Vi=G(At(),1),qi=G(Ot(),1),zi=G(Nt(),1),T=G(Ke(),1),Dt=G(cr(),1);import Ft from"node:crypto";import Ki from"node:path";import fr from"node:crypto";import te from"node:fs";import Xi from"node:path";function ke(t){te.mkdirSync(t,{recursive:!0,mode:448});try{te.chmodSync(t,448)}catch{}}function ur(t,e){ke(Xi.dirname(t));let s=`${t}.${process.pid}.${fr.randomBytes(4).toString("hex")}.tmp`;te.writeFileSync(s,`${JSON.stringify(e,null,2)}
10
+ `+s)}function ee(t,e,s,r,n,i){if(t.listenerCount("wsClientError")){let o=new Error(n);Error.captureStackTrace(o,ee),t.emit("wsClientError",o,s,e)}else Re(s,r,n,i)}});import Xo from"node:fs";import Ko from"node:path";import mn from"node:fs";import _n from"node:os";import we from"node:path";var le=we.resolve(import.meta.dirname,"..");function ht(){if(process.env.RELAY_STATE_DIR)return process.env.RELAY_STATE_DIR;let t=process.env.XDG_STATE_HOME||we.join(_n.homedir(),".local","state");return we.join(t,"herdr-remote-relay")}var x={relay:{mode:"remote",host:"127.0.0.1",port:8787,publicUrl:"http://127.0.0.1:8787",maxPayloadBytes:5*1024*1024,maxClientsPerHost:16,maxHosts:1024,maxPendingHandshakes:1024,maxBufferedBytesPerClient:4*1024*1024,allowedOrigins:[],trustProxy:!1,hostReconnectGraceMs:30*1e3},auth:{pairingTtlMs:600*1e3,deviceTtlMs:720*60*60*1e3,maxDevices:32,password:null,adminToken:null,stateFile:null},cleanup:{intervalMs:60*1e3,heartbeatIntervalMs:30*1e3,staleAfterMs:90*1e3}};function yn(t){return JSON.parse(JSON.stringify(t))}function gn(t){try{return JSON.parse(mn.readFileSync(t,"utf8"))}catch(e){let{code:s,message:r}=e;if(s==="ENOENT")return null;throw new Error(`cannot read relay config ${t}: ${r}`)}}function pt(t,e){if(t==null||t==="")return e;if(t===!0||t===!1)return t;let s=String(t).trim().toLowerCase();return["true","1","yes","on"].includes(s)?!0:["false","0","no","off"].includes(s)?!1:e}function v(t,e,s,r){let n=Number(t);return!Number.isInteger(n)||n<s||n>r?e:n}function os(t){return Array.isArray(t)?t.map(e=>String(e).trim()).filter(Boolean):typeof t!="string"?null:t.split(",").map(e=>e.trim()).filter(Boolean)}function dt(t,e){if(!e||typeof e!="object")return;let s=e;for(let r of Object.keys(t))s[r]!==void 0&&(t[r]=s[r])}function Sn(t=[]){let e={},s=[],r=!1,n=!1;for(let i=0;i<t.length;i+=1){let o=t[i];if(o==="--help"||o==="-h"){r=!0;continue}if(o==="--version"||o==="-v"){n=!0;continue}if(!o.startsWith("--")){s.push(`unexpected argument: ${o}`);continue}let a=o.indexOf("="),l=a===-1?o.slice(2):o.slice(2,a),c=a===-1?void 0:o.slice(a+1);if(c===void 0){let f=t[i+1];f===void 0||f.startsWith("--")?c="true":(c=f,i+=1)}e[l]=c}return{options:e,help:r,version:n,errors:s}}function xn(t,e){if(!e||typeof e!="object")return;let s=e;dt(t.relay,s.relay),dt(t.auth,s.auth),dt(t.cleanup,s.cleanup)}function En(t,e){if((e.RELAY_DEPLOYMENT_MODE==="local"||e.RELAY_DEPLOYMENT_MODE==="remote")&&(t.relay.mode=e.RELAY_DEPLOYMENT_MODE),e.RELAY_BIND&&(t.relay.host=e.RELAY_BIND),e.RELAY_PORT&&(t.relay.port=e.RELAY_PORT),e.RELAY_PUBLIC_URL&&(t.relay.publicUrl=e.RELAY_PUBLIC_URL),e.RELAY_MAX_PAYLOAD_BYTES&&(t.relay.maxPayloadBytes=e.RELAY_MAX_PAYLOAD_BYTES),e.RELAY_MAX_CLIENTS_PER_HOST&&(t.relay.maxClientsPerHost=e.RELAY_MAX_CLIENTS_PER_HOST),e.RELAY_MAX_HOSTS&&(t.relay.maxHosts=e.RELAY_MAX_HOSTS),e.RELAY_MAX_PENDING_HANDSHAKES&&(t.relay.maxPendingHandshakes=e.RELAY_MAX_PENDING_HANDSHAKES),e.RELAY_MAX_BUFFERED_BYTES_PER_CLIENT&&(t.relay.maxBufferedBytesPerClient=e.RELAY_MAX_BUFFERED_BYTES_PER_CLIENT),e.RELAY_HOST_RECONNECT_GRACE_MS&&(t.relay.hostReconnectGraceMs=e.RELAY_HOST_RECONNECT_GRACE_MS),e.RELAY_ALLOWED_ORIGINS!==void 0){let s=os(e.RELAY_ALLOWED_ORIGINS);s&&(t.relay.allowedOrigins=s)}e.RELAY_TRUST_PROXY!==void 0&&(t.relay.trustProxy=pt(e.RELAY_TRUST_PROXY,t.relay.trustProxy)),e.RELAY_PASSWORD&&(t.auth.password=e.RELAY_PASSWORD),e.RELAY_ADMIN_TOKEN&&(t.auth.adminToken=e.RELAY_ADMIN_TOKEN),e.RELAY_AUTH_STATE_FILE&&(t.auth.stateFile=e.RELAY_AUTH_STATE_FILE),e.RELAY_PAIRING_TTL_MS&&(t.auth.pairingTtlMs=e.RELAY_PAIRING_TTL_MS),e.RELAY_DEVICE_TTL_MS&&(t.auth.deviceTtlMs=e.RELAY_DEVICE_TTL_MS),e.RELAY_MAX_DEVICES&&(t.auth.maxDevices=e.RELAY_MAX_DEVICES)}function bn(t,e){if((e["deployment-mode"]==="local"||e["deployment-mode"]==="remote")&&(t.relay.mode=e["deployment-mode"]),e.bind&&(t.relay.host=e.bind),e.port&&(t.relay.port=e.port),e["public-url"]&&(t.relay.publicUrl=e["public-url"]),e["allowed-origins"]!==void 0){let s=os(e["allowed-origins"]);s&&(t.relay.allowedOrigins=s)}e["trust-proxy"]!==void 0&&(t.relay.trustProxy=pt(e["trust-proxy"],t.relay.trustProxy)),e.password&&(t.auth.password=e.password),e["admin-token"]&&(t.auth.adminToken=e["admin-token"]),e["state-file"]&&(t.auth.stateFile=e["state-file"]),e["max-clients"]&&(t.relay.maxClientsPerHost=e["max-clients"]),e["max-hosts"]&&(t.relay.maxHosts=e["max-hosts"]),e["max-pending-handshakes"]&&(t.relay.maxPendingHandshakes=e["max-pending-handshakes"]),e["max-buffered-bytes"]&&(t.relay.maxBufferedBytesPerClient=e["max-buffered-bytes"]),e["host-reconnect-grace-ms"]&&(t.relay.hostReconnectGraceMs=e["host-reconnect-grace-ms"])}function Tn(t){return t.relay.mode!=="local"&&t.relay.mode!=="remote"&&(t.relay.mode=x.relay.mode),t.relay.port=v(t.relay.port,x.relay.port,0,65535),t.relay.maxPayloadBytes=v(t.relay.maxPayloadBytes,x.relay.maxPayloadBytes,4096,16*1024*1024),t.relay.maxClientsPerHost=v(t.relay.maxClientsPerHost,x.relay.maxClientsPerHost,1,256),t.relay.maxHosts=v(t.relay.maxHosts,x.relay.maxHosts,1,1e5),t.relay.maxPendingHandshakes=v(t.relay.maxPendingHandshakes,x.relay.maxPendingHandshakes,16,1e5),t.relay.maxBufferedBytesPerClient=v(t.relay.maxBufferedBytesPerClient,x.relay.maxBufferedBytesPerClient,64*1024,256*1024*1024),t.relay.hostReconnectGraceMs=v(t.relay.hostReconnectGraceMs,x.relay.hostReconnectGraceMs,1e3,1440*60*1e3),t.auth.pairingTtlMs=v(t.auth.pairingTtlMs,x.auth.pairingTtlMs,30*1e3,1440*60*1e3),t.auth.deviceTtlMs=v(t.auth.deviceTtlMs,x.auth.deviceTtlMs,60*1e3,365*24*60*60*1e3),t.auth.maxDevices=v(t.auth.maxDevices,x.auth.maxDevices,1,1e4),t.cleanup.intervalMs=v(t.cleanup.intervalMs,x.cleanup.intervalMs,1e3,1440*60*1e3),t.cleanup.heartbeatIntervalMs=v(t.cleanup.heartbeatIntervalMs,x.cleanup.heartbeatIntervalMs,1e3,600*1e3),t.cleanup.staleAfterMs=v(t.cleanup.staleAfterMs,x.cleanup.staleAfterMs,t.cleanup.heartbeatIntervalMs*2,1440*60*1e3),(typeof t.relay.host!="string"||t.relay.host.length===0)&&(t.relay.host=x.relay.host),(typeof t.relay.publicUrl!="string"||t.relay.publicUrl.length===0)&&(t.relay.publicUrl=`http://${t.relay.host}:${t.relay.port}`),t.relay.publicUrl=String(t.relay.publicUrl).replace(/\/+$/,""),Array.isArray(t.relay.allowedOrigins)||(t.relay.allowedOrigins=[]),t.relay.trustProxy=pt(t.relay.trustProxy,!1),t.auth.stateFile||(t.auth.stateFile=we.join(ht(),"relay-auth.json")),t}function wn(t){let e=[],s=["127.0.0.1","localhost","::1"].includes(t.relay.host),r;try{r=new URL(t.relay.publicUrl)}catch{e.push(`publicUrl is not a valid URL: ${t.relay.publicUrl}`)}return t.auth.password||e.push("no password set (RELAY_PASSWORD): this is a public relay, anyone may connect a workstation to it"),t.relay.mode==="remote"&&!t.auth.adminToken&&e.push("no admin token set (RELAY_ADMIN_TOKEN): the relay operator dashboard is unavailable"),!s&&r&&r.protocol==="http:"&&!["127.0.0.1","localhost"].includes(r.hostname)&&e.push(`publicUrl uses plain http on a non-loopback address (${t.relay.publicUrl}); terminate TLS in front of the relay`),e}function Be({argv:t=[],env:e=process.env}={}){let{options:s,help:r,version:n,errors:i}=Sn(t),o=yn(x),a=s.config||e.HERDR_RELAY_CONFIG||null;if(a){let c=gn(we.resolve(a));if(c===null)throw new Error(`relay config not found: ${a}`);xn(o,c)}En(o,e),bn(o,s);let l=Tn(o);return{config:l,help:r,version:n,errors:i,configFile:a,warnings:wn(l)}}import qo from"node:http";import ts from"node:path";import{URL as zo}from"node:url";var ji=G(tr(),1),Vi=G(Ve(),1),qi=G(ue(),1),zi=G(At(),1),Xi=G(Ot(),1),Ki=G(Mt(),1),T=G(Ke(),1),Dt=G(cr(),1);import Ut from"node:crypto";import Zi from"node:path";import fr from"node:crypto";import te from"node:fs";import Ji from"node:path";function ke(t){te.mkdirSync(t,{recursive:!0,mode:448});try{te.chmodSync(t,448)}catch{}}function ur(t,e){ke(Ji.dirname(t));let s=`${t}.${process.pid}.${fr.randomBytes(4).toString("hex")}.tmp`;te.writeFileSync(s,`${JSON.stringify(e,null,2)}
11
11
  `,{mode:384});try{te.chmodSync(s,384)}catch{}te.renameSync(s,t);try{te.chmodSync(t,384)}catch{}}function dr(t,e){try{return JSON.parse(te.readFileSync(t,"utf8"))}catch(s){let{code:r,message:n}=s;return r!=="ENOENT"&&process.stderr.write(`herdr-remote: invalid state at ${t}: ${n}
12
- `),e}}function Bt(t=32){return fr.randomBytes(t).toString("base64url")}function B(t){return Ft.createHash("sha256").update(String(t),"utf8").digest("hex")}function _e(t,e){if(typeof t!="string"||typeof e!="string")return!1;let s=Buffer.from(t,"hex"),r=Buffer.from(e,"hex");return s.length===r.length&&s.length>0&&Ft.timingSafeEqual(s,r)}function U(t=Date.now()){return new Date(t).toISOString()}function Ut(t){return typeof t=="string"&&/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(t)}var hr="ABCDEFGHJKMNPQRSTUVWXYZ23456789",Ji=6;function Zi(){let t="";for(let e=0;e<Ji;e+=1)t+=hr[Ft.randomInt(hr.length)];return t}var Ze=class{stateFile;pairingTtlMs;deviceTtlMs;maxDevices;password;pairings=new Map;lastDeviceSaveAt=new Map;state;constructor({stateFile:e,pairingTtlMs:s=600*1e3,deviceTtlMs:r=720*60*60*1e3,maxDevices:n=32,password:i=null}={}){if(!e)throw new TypeError("stateFile is required");this.stateFile=e,this.pairingTtlMs=s,this.deviceTtlMs=r,this.maxDevices=n,this.password=i||null,this.state=dr(e,{version:1,hosts:{},devices:{}}),this.state.version=1,this.state.hosts=this.state.hosts&&typeof this.state.hosts=="object"?this.state.hosts:{},this.state.devices=this.state.devices&&typeof this.state.devices=="object"?this.state.devices:{},ke(Ki.dirname(e))}save(){ur(this.stateFile,this.state)}checkPassword(e){return this.password?typeof e=="string"&&_e(B(e),B(this.password)):!0}registerHost(e,s,r=null,n=Date.now()){if(!Ut(e)||typeof s!="string"||s.length<16||s.length>4096)return{ok:!1,code:"invalid_host_credentials",message:"hostId and token are required"};if(!this.checkPassword(r))return{ok:!1,code:"relay_password_required",message:"the relay password is missing or wrong"};let i=this.state.hosts[e];return i?_e(i.tokenHash,B(s))?(i.lastSeenAt=U(n),this.save(),{ok:!0,hostId:e,firstSeen:!1}):{ok:!1,code:"host_auth_failed",message:"host token is invalid"}:(this.state.hosts[e]={tokenHash:B(s),createdAt:U(n),lastSeenAt:U(n)},this.save(),{ok:!0,hostId:e,firstSeen:!0})}authenticateHost(e,s){if(!Ut(e)||typeof s!="string"||s.length<16||s.length>4096)return!1;let r=this.state.hosts[e];return!!r&&_e(r.tokenHash,B(s))}hostCount(){return Object.keys(this.state.hosts).length}startPairing(e,s,r=Date.now()){if(!Ut(e)||!this.state.hosts[e])throw Object.assign(new Error("host is not connected or enrolled"),{code:"host_not_found"});this.cleanup(r);let n;do n=Zi();while([...this.pairings.values()].some(o=>_e(o.codeHash,B(n))));let i=r+this.pairingTtlMs;return this.pairings.set(n,{codeHash:B(n),hostId:e,expiresAt:i,publicUrl:s}),{code:n,hostId:e,publicUrl:s,expiresAt:i,expiresAtIso:U(i)}}completePairing(e,s=Date.now()){if(typeof e!="string"||e.length<4||e.length>32)return null;this.cleanup(s);let r=e.trim().toUpperCase(),n=this.pairings.get(r);if(!n||n.expiresAt<=s||!_e(n.codeHash,B(r)))return null;this.pairings.delete(r);let i=Object.values(this.state.devices);i.length>=this.maxDevices&&(i.sort((c,f)=>(c.lastSeenAt||"").localeCompare(f.lastSeenAt||"")),delete this.state.devices[i[0].deviceId]);let o=`device-${Bt(9)}`,a=Bt(32),l=s+this.deviceTtlMs;return this.state.devices[o]={deviceId:o,hostId:n.hostId,tokenHash:B(a),createdAt:U(s),lastSeenAt:U(s),expiresAt:l},this.save(),{deviceId:o,hostId:n.hostId,token:a,expiresAt:l,expiresAtIso:U(l),publicUrl:n.publicUrl}}noteDeviceSeen(e,{userAgent:s,ip:r}={},n=Date.now()){let i=this.state.devices[e];if(!i)return null;let o=!1;return s&&i.userAgent!==s&&(i.userAgent=String(s).slice(0,256),o=!0),r&&i.lastIp!==r&&(i.lastIp=String(r).slice(0,64),o=!0),i.lastSeenAt=U(n),o&&this.save(),{...i}}listDevices(e=Date.now()){return Object.values(this.state.devices).filter(s=>s&&s.expiresAt>e).map(s=>({deviceId:s.deviceId,hostId:s.hostId,createdAt:s.createdAt,lastSeenAt:s.lastSeenAt,expiresAt:s.expiresAt,expiresAtIso:U(s.expiresAt),userAgent:s.userAgent||null,lastIp:s.lastIp||null})).sort((s,r)=>String(r.lastSeenAt||"").localeCompare(String(s.lastSeenAt||"")))}revokeDevice(e){if(typeof e!="string"||!e)return null;let s=this.state.devices[e];return s?(delete this.state.devices[e],this.lastDeviceSaveAt.delete(e),this.save(),{deviceId:s.deviceId,hostId:s.hostId,userAgent:s.userAgent||null,lastIp:s.lastIp||null}):null}authenticateDevice(e,s=Date.now()){if(typeof e!="string"||e.length<16)return null;let r=B(e);for(let n of Object.values(this.state.devices)){if(n.expiresAt<=s||!_e(n.tokenHash,r))continue;n.lastSeenAt=U(s),n.expiresAt=s+this.deviceTtlMs;let i=this.lastDeviceSaveAt.get(n.deviceId)||0;return s-i>=60*1e3&&(this.lastDeviceSaveAt.set(n.deviceId,s),this.save()),{...n}}return null}cleanup(e=Date.now()){let s=0;for(let[n,i]of Object.entries(this.state.devices))(!i||i.expiresAt<=e)&&(delete this.state.devices[n],this.lastDeviceSaveAt.delete(n),s+=1);let r=0;for(let[n,i]of this.pairings.entries())i.expiresAt<=e&&(this.pairings.delete(n),r+=1);return s&&this.save(),{removedDevices:s,removedPairings:r}}deviceCount(){return Object.keys(this.state.devices).length}};import Qe from"node:os";import{monitorEventLoopDelay as Qi}from"node:perf_hooks";function et(t,e=0){return Number.isFinite(t)?t:e}function q(t,e,s){return!s||s<=0?0:Math.max(0,(t-e)*1e3/s)}function st(t=[]){let e=new Set;for(let s of t)s&&e.add(typeof s.deviceId=="string"&&s.deviceId?`device:${s.deviceId}`:`client:${s.id}`);return e.size}var tt=class{version;protocolVersion;startedAt;bytesIn;bytesOut;framesIn;framesOut;cleanup;lastSample;hostTraffic;cpuSampleAt;cpuSample;eventLoop;constructor({version:e="0.1.0",protocolVersion:s=1}={}){this.version=e,this.protocolVersion=s,this.startedAt=Date.now(),this.bytesIn=0,this.bytesOut=0,this.framesIn=0,this.framesOut=0,this.cleanup={staleClientsPurged:0,closedPtysCleaned:0,deadConnectionsClosed:0,idleHostsTerminated:0,slowClientsDropped:0,lastCleanupAt:null},this.lastSample={at:this.startedAt,bytesIn:0,bytesOut:0,framesIn:0,framesOut:0},this.hostTraffic=new Map,this.cpuSampleAt=process.hrtime.bigint(),this.cpuSample=process.cpuUsage(),this.eventLoop=Qi({resolution:20}),this.eventLoop.enable()}hostCounter(e){if(typeof e!="string"||e.length===0)return null;let s=this.hostTraffic.get(e);return s||(s={bytesIn:0,bytesOut:0,framesIn:0,framesOut:0,sampleAt:Date.now(),sampleBytesIn:0,sampleBytesOut:0,sampleFramesIn:0,sampleFramesOut:0},this.hostTraffic.set(e,s)),s}recordIn(e,s=null){let r=Math.max(0,Number(e)||0);this.bytesIn+=r,this.framesIn+=1;let n=this.hostCounter(s);n&&(n.bytesIn+=r,n.framesIn+=1)}recordOut(e,s=null){let r=Math.max(0,Number(e)||0);this.bytesOut+=r,this.framesOut+=1;let n=this.hostCounter(s);n&&(n.bytesOut+=r,n.framesOut+=1)}forgetHost(e){typeof e=="string"&&this.hostTraffic.delete(e)}hostThroughput(e,s=Date.now()){let r=this.hostCounter(e);if(!r)return{bytesIn:0,bytesOut:0,bytesInPerSec:0,bytesOutPerSec:0,framesIn:0,framesOut:0,framesInPerSec:0,framesOutPerSec:0};let n=s-r.sampleAt,i={bytesIn:r.bytesIn,bytesOut:r.bytesOut,bytesInPerSec:q(r.bytesIn,r.sampleBytesIn,n),bytesOutPerSec:q(r.bytesOut,r.sampleBytesOut,n),framesIn:r.framesIn,framesOut:r.framesOut,framesInPerSec:q(r.framesIn,r.sampleFramesIn,n),framesOutPerSec:q(r.framesOut,r.sampleFramesOut,n)};return r.sampleAt=s,r.sampleBytesIn=r.bytesIn,r.sampleBytesOut=r.bytesOut,r.sampleFramesIn=r.framesIn,r.sampleFramesOut=r.framesOut,i}recordCleanup(e,s=1){Object.hasOwn(this.cleanup,e)&&typeof this.cleanup[e]=="number"&&(this.cleanup[e]+=s),this.cleanup.lastCleanupAt=new Date().toISOString()}cpuPercent(){let e=process.hrtime.bigint(),s=Number(e-this.cpuSampleAt),r=process.cpuUsage(this.cpuSample);if(this.cpuSampleAt=e,this.cpuSample=process.cpuUsage(),s<=0)return 0;let n=(r.user+r.system)*1e5/s;return Math.max(0,Math.round(n*100)/100)}eventLoopDelay(){let e=s=>Math.round(et(s/1e6)*100)/100;return{p50Ms:e(this.eventLoop.percentile(50)),p90Ms:e(this.eventLoop.percentile(90)),p99Ms:e(this.eventLoop.percentile(99)),maxMs:e(this.eventLoop.max),meanMs:e(this.eventLoop.mean)}}snapshot({clients:e=[],hosts:s=[],ptys:r=[],sample:n=!0,scopeHostId:i=null,activeUserCount:o=null}={}){let a=Date.now(),l=a-this.lastSample.at,c={bytesIn:this.bytesIn,bytesOut:this.bytesOut,bytesInPerSec:q(this.bytesIn,this.lastSample.bytesIn,l),bytesOutPerSec:q(this.bytesOut,this.lastSample.bytesOut,l),framesIn:this.framesIn,framesOut:this.framesOut,framesInPerSec:q(this.framesIn,this.lastSample.framesIn,l),framesOutPerSec:q(this.framesOut,this.lastSample.framesOut,l)};n&&(this.lastSample={at:a,bytesIn:this.bytesIn,bytesOut:this.bytesOut,framesIn:this.framesIn,framesOut:this.framesOut});let f=process.memoryUsage(),d=Qe.loadavg(),u=e[0],h=i?this.hostThroughput(i,a):c;return{version:this.version,protocolVersion:this.protocolVersion,uptimeSeconds:Math.floor((a-this.startedAt)/1e3),startTime:new Date(this.startedAt).toISOString(),serverTime:new Date(a).toISOString(),activeControllerId:null,activeHostId:u?.hostId||s[0]?.id||null,clients:e,hosts:s,ptys:r,clientCount:e.length,hostCount:s.length,ptyCount:r.length,activeUserCount:Number.isFinite(o)?o:st(e),throughput:h,cpu:{load1m:et(d[0]),load5m:et(d[1]),load15m:et(d[2]),cpuPercent:this.cpuPercent(),cores:Qe.cpus().length},memory:{rssBytes:f.rss,heapUsedBytes:f.heapUsed,heapTotalBytes:f.heapTotal,externalBytes:f.external,systemTotalBytes:Qe.totalmem(),systemFreeBytes:Qe.freemem()},eventLoopDelay:this.eventLoopDelay(),cleanup:{...this.cleanup}}}close(){this.eventLoop.disable(),this.hostTraffic.clear()}};function Le(t){return Buffer.isBuffer(t)?t:(typeof t=="string"||t instanceof ArrayBuffer,Buffer.from(t))}function mr(t,e,s=Buffer.alloc(0)){if(typeof t!="string"||!t||typeof e!="string"||!e)throw new TypeError("type and streamId must be non-empty strings");let r=Le(s),n=Buffer.from(JSON.stringify({type:t,streamId:e}),"utf8");if(n.length>8192)throw new RangeError("stream frame header is too large");let i=Buffer.allocUnsafe(4);return i.writeUInt32BE(n.length,0),Buffer.concat([i,n,r])}function eo(t){let e=Le(t);if(e.length<4)throw new Error("stream frame is truncated");let s=e.readUInt32BE(0);if(s===0||s>8192||e.length<4+s)throw new Error("stream frame header is invalid");let r;try{r=JSON.parse(e.subarray(4,4+s).toString("utf8"))}catch(n){throw new Error(`stream frame header is not JSON: ${n.message}`)}if(!r||typeof r.type!="string"||typeof r.streamId!="string")throw new Error("stream frame header is missing routing fields");return{version:1,type:r.type,streamId:r.streamId,payload:e.subarray(4+s)}}function pr(t,e,s=Buffer.alloc(0)){let r=t;if(t==="output"?r=0:t==="input"&&(r=1),r!==0&&r!==1)throw new TypeError("type must be FRAME_TYPE_OUTPUT (0) or FRAME_TYPE_INPUT (1)");if(!Number.isInteger(e)||e<0||e>65535)throw new RangeError("streamIndex must be an unsigned 16-bit integer (0-65535)");let n=Le(s),i=Buffer.allocUnsafe(4+n.length);return i.writeUInt8(255,0),i.writeUInt8(r,1),i.writeUInt16BE(e,2),n.copy(i,4),i}function to(t){let e=Le(t);if(e.length<4)throw new Error("v2 stream frame is truncated");if(e.readUInt8(0)!==255)throw new Error("invalid v2 stream frame magic byte");let r=e.readUInt8(1);if(r!==0&&r!==1)throw new Error(`unknown v2 stream frame type: ${r}`);let n=e.readUInt16BE(2);return{version:2,type:r===0?"output":"input",typeCode:r,streamIndex:n,payload:e.subarray(4)}}function _r(t){let e=Le(t);if(e.length<4)throw new Error("stream frame is truncated");return e[0]===255?to(e):eo(e)}var yr=["black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite"],so=["regular","bold","italic","boldItalic"],ro=["truetype","opentype"],no=["cjk","all"];var io=/^#[0-9a-f]{6}$/i,oo=/["'\\;,{}<>@\u0000-\u001f\u007f]/,gr=/^[0-9a-f]{64}$/;function Ne(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Ht(t,e){return t.includes(e)}function Sr(t){return typeof t=="string"&&io.test(t)?t.toLowerCase():void 0}function Er(t){if(!Ne(t))return null;let e={};for(let r of["background","foreground","cursor"]){let n=Sr(t[r]);n&&(e[r]=n)}let s=t.ansi;if(Ne(s)){let r={};for(let n of yr){let i=Sr(s[n]);i&&(r[n]=i)}Object.keys(r).length===yr.length&&(e.ansi=r)}return Object.keys(e).length>0?e:null}function xr(t){let e=typeof t=="string"?t.trim():"";return!e||e.length>128||oo.test(e)?null:e}function rt(t){if(!Ne(t))return null;let e=xr(t.family);if(!e)return null;let s=Number(t.sizePx),r=Number.isFinite(s)&&s>=4&&s<=96?Math.round(s*10)/10:null,n=typeof t.source=="string"&&/^[a-z0-9-]{1,32}$/.test(t.source)?t.source:null,i=[],o=new Set;for(let l of Array.isArray(t.faces)?t.faces.slice(0,16):[]){if(!Ne(l))continue;let{style:c,format:f,bytes:d,sha256:u}=l;!Ht(so,c)||o.has(c)||Ht(ro,f)&&(typeof d!="number"||!Number.isInteger(d)||d<=0||d>16777216||typeof u!="string"||!gr.test(u)||(o.add(c),i.push({style:c,format:f,bytes:d,sha256:u})))}let a=[];for(let l of Array.isArray(t.subsets)?t.subsets.slice(0,16):[]){if(!Ne(l))continue;let c=xr(l.family),{scope:f,sha256:d}=l;!c||l.style!=="regular"||Ht(no,f)&&(typeof d!="string"||!gr.test(d)||a.some(u=>u.scope===f)||a.push({family:c,style:"regular",scope:f,sha256:d}))}return{family:e,...r!==null&&{sizePx:r},...n!==null&&{source:n},faces:i,subsets:a}}var ao=/^[\x21-\x7e]+$/;function br(t){if(!Array.isArray(t))return;let e=new Set;for(let s of t){if(e.size>=8)break;if(typeof s!="string")continue;let r=s.replace(/\s+/g,"").toLowerCase();r.length<=32&&ao.test(r)&&e.add(r)}return e.size>0?[...e]:void 0}var Yt="/ws/host",Tr="/ws/client",ye={hostHandoff:"host_handoff",idleHeartbeat:"idle_heartbeat",binaryFrameV2:"binary_frame_v2",adminTabs:"admin_tabs"};var wr={"image/png":".png","image/jpeg":".jpg","image/webp":".webp","image/gif":".gif"},Da=Object.keys(wr);function Ar(t){return typeof t=="string"&&Object.hasOwn(wr,t)}function vr(t,e){switch(t){case"image/png":return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71;case"image/jpeg":return e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255;case"image/webp":return e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80;case"image/gif":return e.length>=6&&e[0]===71&&e[1]===73&&e[2]===70&&e[3]===56;default:return!1}}var lo="dibin666/herdr-remote",Ir=`https://github.com/${lo}/releases`,Ua=`${Ir}/latest/download/latest.json`,Fa=`${Ir}/latest/download/herdr-remote.tgz`;import co from"node:crypto";var fo=500;function ge(t){return`${t}-${co.randomBytes(9).toString("base64url")}`}function z(t,e){return typeof t=="string"&&t.length>0?t.slice(0,e):null}function Me(t,e){let s=Number(t);return Number.isInteger(s)?Math.min(fo,Math.max(2,s)):e}function y(t){return!!t&&t?.readyState===T.default.OPEN}function m(t,e){y(t)&&t.send(JSON.stringify(e))}function k(t,e=1e3,s=""){if(!(!t||t.readyState===T.default.CLOSED||t.readyState===T.default.CLOSING))try{t.close(e,s.slice(0,120))}catch{}}function se(t){if(!(!t||t.readyState===T.default.CLOSED))try{typeof t.terminate=="function"?t.terminate():typeof t.destroy=="function"&&t.destroy()}catch{}}function Se(t){if(typeof t!="string")return null;try{return JSON.parse(t)}catch{return null}}function w(t,e,s="invalid_handshake"){m(t,{type:"error",code:s,message:e}),k(t,1008,e)}var Cr=4,Pr=3e4,Rr=Math.ceil(262144/3)*4,$t=/^[0-9a-f]{64}$/,uo=32*1024,ho=64,mo=16*1024*1024,kr=/^[A-Za-z0-9_-]{1,32}$/;function Wt(t){Array.isArray(t.fontChunkRequests)&&t.fontChunkRequests.length&&t.fontChunkRequests.shift()}function nt(t){Array.isArray(t.fontSubsetRequests)&&t.fontSubsetRequests.length&&t.fontSubsetRequests.shift()}function Lr(t,e,s){if(!e.session||!y(t.ws))return;let r=t.terminalFont?.faces?.find(a=>a.sha256===s.sha256),n=r?r.bytes:e.fontSubsets?.get(s.sha256)||0,i=Math.ceil(n/262144);if(!n||!Number.isInteger(s.index)||s.index<0||s.index>=i){m(e.ws,{type:"error",code:"host_font_unavailable",message:"The workstation did not offer this font file"});return}let o=Date.now();e.fontChunkRequests=(e.fontChunkRequests||[]).filter(a=>o-a<Pr),!(e.fontChunkRequests.length>=Cr)&&(e.fontChunkRequests.push(o),m(t.ws,{type:"host_font_chunk_request",clientId:e.session.streamId,streamId:e.session.streamId,sha256:s.sha256,index:s.index}))}function Nr(t,e,s){if(!e.session||!y(t.ws))return;if(!(t.terminalFont?.subsets?.some(o=>o.sha256===s.sha256)&&typeof s.text=="string"&&s.text.length>0&&s.text.length<=uo&&typeof s.requestId=="string"&&kr.test(s.requestId))){m(e.ws,{type:"error",code:"host_font_unavailable",message:"The workstation did not offer this font"});return}let i=Date.now();e.fontSubsetRequests=(e.fontSubsetRequests||[]).filter(o=>i-o<Pr),!(e.fontSubsetRequests.length>=Cr)&&(e.fontSubsetRequests.push(i),m(t.ws,{type:"host_font_subset_request",clientId:e.session.streamId,streamId:e.session.streamId,requestId:s.requestId,sha256:s.sha256,text:s.text}))}function Mr(t,e){if(nt(t),!!(typeof e.sha256=="string"&&$t.test(e.sha256)&&typeof e.subsetSha=="string"&&$t.test(e.subsetSha)&&typeof e.requestId=="string"&&kr.test(e.requestId)&&Number.isInteger(e.bytes)&&e.bytes>0&&e.bytes<=mo&&(e.dataBase64===void 0||typeof e.dataBase64=="string"&&e.dataBase64.length<=Rr))){if(e.dataBase64===void 0)for(t.fontSubsets||=new Map,t.fontSubsets.delete(e.subsetSha),t.fontSubsets.set(e.subsetSha,e.bytes);t.fontSubsets.size>ho;){let r=t.fontSubsets.keys().next().value;r!==void 0&&t.fontSubsets.delete(r)}m(t.ws,{type:"host_font_subset_ready",requestId:e.requestId,sha256:e.sha256,subsetSha:e.subsetSha,bytes:e.bytes,...e.dataBase64!==void 0?{dataBase64:e.dataBase64}:{}})}}function Dr(t,e){Wt(t),typeof e.sha256=="string"&&$t.test(e.sha256)&&Number.isInteger(e.index)&&e.index>=0&&Number.isInteger(e.total)&&e.total>e.index&&typeof e.dataBase64=="string"&&e.dataBase64.length<=Rr&&m(t.ws,{type:"host_font_chunk",sha256:e.sha256,index:e.index,total:e.total,dataBase64:e.dataBase64})}import Gt from"node:crypto";function po(t){let e=t.headers.authorization;if(typeof e!="string")return null;let s=/^Bearer\s+(.+)$/i.exec(e.trim());return s?s[1]:null}function _o(t,e){if(typeof t!="string"||t.length===0||typeof e!="string"||e.length===0)return!1;let s=Gt.createHash("sha256").update(t,"utf8").digest(),r=Gt.createHash("sha256").update(e,"utf8").digest();return Gt.timingSafeEqual(s,r)}function jt(t,e,s){if(!e||(t.config.relay.allowedOrigins||[]).includes(e))return!0;try{return new URL(e).host===s.headers.host}catch{return!1}}function Br(t,e){let s=e.headers.origin;return s?jt(t,s,e):!0}function Vt(t,e){let s=e.headers["x-herdr-host-id"],r=e.headers["x-herdr-host-token"];return typeof s!="string"||typeof r!="string"?null:t.auth.authenticateHost(s,r)?s:null}function yo(t,e){let s=po(e);return s?t.auth.authenticateDevice(s):null}function Ur(t,e){let s=e.headers["x-herdr-host-id"],r=e.headers["x-herdr-host-token"],n=s!==void 0||r!==void 0,i=e.headers.authorization!==void 0,o=Vt(t,e),a=yo(t,e);return n&&!o||i&&!a||o&&a&&o!==a.hostId?null:o?{kind:"host",hostId:o}:a?{kind:"device",hostId:a.hostId,deviceId:a.deviceId}:null}function Fr(t,e){return _o(e.headers["x-relay-admin-token"],t.adminToken)}function Hr(t,e){if(!t.trustProxy)return null;let s=e.headers["x-forwarded-for"];return typeof s!="string"||s.length===0?null:s.split(",")[0].trim()||null}function go(t,e){return Hr(t,e)||e.socket.remoteAddress||"unknown"}function Yr(t,e){return Hr(t,e)||e.socket.remoteAddress||null}function qt(t,e,s,r=20){let n=go(t,s),i=Date.now(),o=e.get(n);if(!o||i-o.startedAt>=6e4){if(e.size>=4096){let a=e.keys().next().value;a!==void 0&&e.delete(a)}return e.set(n,{startedAt:i,count:1}),!0}return o.count>=r?!1:(o.count+=1,!0)}function it(t,e){return qt(t,t.pairAttempts,e,20)}function $r(t,e){return qt(t,t.clientHandshakeAttempts,e,60)}function Wr(t,e){return qt(t,t.hostHandshakeAttempts,e,60)}function xe(t){!t||!y(t.ws)||m(t.ws,{type:"client_count",clientCount:t.clients.size})}function Gr(t,e,s,r){if(!s||!y(s.ws))return!1;let n=t.config.relay.maxBufferedBytesPerClient;if((Number(s.ws.bufferedAmount)||0)+r.length>n)return t.metrics.recordCleanup("slowClientsDropped"),C(t,s,{notify:!0,reason:"slow_client",closeCode:1013}),!1;let o=!1,a=()=>{if(y(s.ws))try{s.ws.send(r),s.bytesSent+=r.length,t.metrics.recordOut(r.length,e.id),o=!0}catch{C(t,s,{notify:!1,reason:"client_send_failed",closeCode:1011})}};return t.devLatencyMs>0?zt(t,s.ws,a):a(),t.devLatencyMs>0?!0:o}function zt(t,e,s){let r=t.sendQueues.get(e);if(!r){let i={items:[],timer:null};r=i,t.sendQueues.set(e,i),e.once("close",()=>{i.timer&&(clearTimeout(i.timer),t.activeDelayTimers.delete(i.timer),i.timer=null),i.items=[]})}let n=Date.now()+t.devDelayMs;if(r.items.push({sendAt:n,task:s}),!r.timer){let i=r,o=setTimeout(()=>jr(t,e,i),t.devDelayMs);r.timer=o,t.activeDelayTimers.add(o)}}function jr(t,e,s){s.timer&&(t.activeDelayTimers.delete(s.timer),s.timer=null);let r=Date.now();for(;s.items.length>0&&s.items[0].sendAt<=r;){let n=s.items.shift();try{n?.task()}catch{}}if(s.items.length>0&&!s.timer){let n=Math.max(0,s.items[0].sendAt-Date.now()),i=setTimeout(()=>jr(t,e,s),n);s.timer=i,t.activeDelayTimers.add(i)}}function X(t,e,s){for(let r of[...e.clients]){let n=t.clients.get(r);if(!n)continue;let i=s(n);i&&m(n.ws,i)}}var Xt=20,Kt=6;function So(t){if(!t)return null;let e=65536;for(let s=0;s<e;s++){let r=t.nextStreamIndex;if(t.nextStreamIndex=t.nextStreamIndex+1&65535,!t.streamIndices.has(r))return r}return null}function Ee(t,e,s){let r=s.session;r&&(r.streamIndex!==null&&r.streamIndex!==void 0&&e&&e.streamIndices.delete(r.streamIndex),t.streams.delete(r.streamId),s.session=null)}function ot(t,e,s,{restarted:r=!1}={}){if(!s||!y(e.ws))return;let n=ge("session"),i=null;e.binaryFrameV2&&(i=So(e),i!==null&&e.streamIndices.set(i,s.id)),s.session={streamId:n,streamIndex:i,cols:s.cols,rows:s.rows,ready:!1},t.streams.set(n,s.id),m(e.ws,{type:"session_start",clientId:n,streamId:n,cols:Math.max(Xt,s.cols),rows:Math.max(Kt,s.rows),role:"controller",...i!==null?{streamIndex:i}:{}}),r&&m(s.ws,{type:"session_restarted",streamId:n,cols:s.cols,rows:s.rows,hostname:e.hostname,platform:e.platform,...e.shellProfile?{shellProfile:e.shellProfile}:{},adminTerminalSupported:e.adminTabsAvailable,terminalPalette:e.terminalPalette||null,terminalFont:e.terminalFont||null,hostVersion:e.version,...e.herdrPrefixKeys?{herdrPrefixKeys:e.herdrPrefixKeys}:{}})}function Jt(t,e){for(let s of e.clients){let r=t.clients.get(s);r&&(r.role="controller",r.controllerId=null,m(r.ws,{type:"control_state",role:"controller",controllerId:null,clientCount:e.clients.size}))}}function Vr(t,e){if(!e)return 0;let s=0;for(let r of[...t.clients.values()])!r||r.deviceId!==e||(C(t,r,{notify:!1,reason:"device_revoked"}),k(r.ws,1e3,"this device has been revoked by the relay operator"),s+=1);return s}function C(t,e,{notify:s=!0,reason:r="client_disconnected",closeCode:n=1e3,terminate:i=!1}={}){if(!e||!t.clients.has(e.id))return;t.clients.delete(e.id);let o=t.hosts.get(e.hostId);if(e.session){let l=e.session.streamId;Ee(t,o,e),o&&y(o.ws)&&m(o.ws,{type:"session_stop",clientId:l,streamId:l})}o&&(o.clients.delete(e.id),xe(o),Jt(t,o),o.clients.size===0&&(o.controllerId=null,o.reconnecting&&N(t,o,{notify:!1,reason:"no_clients"})));let a=e.ws;e.ws=null,s&&m(a,{type:"error",code:r,message:r==="host_offline"?"Herdr host is offline":"connection closed"}),i||a?.readyState===T.default.CLOSING?se(a):k(a,n,r),t.metrics.recordCleanup("closedPtysCleaned")}function N(t,e,{notify:s=!0,reason:r="host_disconnected",terminate:n=!1}={}){if(!e||t.hosts.get(e.id)!==e)return;e.reconnectTimer&&clearTimeout(e.reconnectTimer),e.reconnectTimer=null,t.hosts.delete(e.id);for(let o of[...e.clients]){let a=t.clients.get(o);if(!a)continue;t.clients.delete(a.id),Ee(t,e,a);let l=a.ws;a.ws=null,s&&m(l,{type:"error",code:r,message:"Herdr host disconnected"}),n||l?.readyState===T.default.CLOSING?se(l):k(l,1012,r)}e.clients.clear(),t.metrics.forgetHost(e.id);let i=e.ws;e.ws=null,n||i?.readyState===T.default.CLOSING?se(i):k(i,1e3,r)}function at(t,e){if(!e?.handoffCapable||e.clients.size===0)return!1;for(let s of e.clients)if(!t.clients.get(s)?.handoffCapable)return!1;return!0}function lt(t,e,s="host_disconnected"){if(!e||t.hosts.get(e.id)!==e||e.reconnecting)return;if(!at(t,e)){N(t,e,{notify:!0,reason:s});return}e.ws=null,e.reconnecting=!0,e.reconnectStartedAt=Date.now(),e.lastSeenAt=Date.now(),e.load={},e.ptys=[];for(let n of e.clients){let i=t.clients.get(n);i&&Ee(t,e,i)}X(t,e,()=>({type:"host_reconnecting",code:s}));let r=setTimeout(()=>{e.reconnectTimer=null,t.hosts.get(e.id)===e&&e.reconnecting&&N(t,e,{notify:!0,reason:"host_reconnect_timeout"})},t.config.relay.hostReconnectGraceMs);e.reconnectTimer=r,r.unref?.()}var bo=3e3,To=2e3,wo=1e3;function Ao(t,e){if(typeof e!="string"||e.length===0)return!1;let s;try{s=Buffer.from(e.slice(0,32),"base64")}catch{return!1}return s.length===0?!1:vr(t,s)}function qr(t,e,s){let r={ws:e,req:s,authenticated:!1},n=setTimeout(()=>{r.authenticated||k(e,1008,"client hello timeout")},1e4);e.isAlive=!0,e.on("pong",()=>{e.isAlive=!0,r.client&&(r.client.lastSeenAt=Date.now(),r.client.lastPingAt=new Date().toISOString())}),e.on("ping",()=>{e.isAlive=!0,r.client&&(r.client.lastSeenAt=Date.now(),r.client.lastPingAt=new Date().toISOString())}),e.on("message",(i,o)=>{if(!r.authenticated){if(o)return w(e,"client hello must be JSON");let a=Se(i.toString());if(a?.type!=="hello"||a.protocol!==1)return w(e,"invalid client hello");if(!$r(t,s))return w(e,"too many connection attempts","rate_limited");let l=null,c=null;if(a.pairCode){if(!it(t,s))return w(e,"too many pairing attempts","rate_limited");c=t.auth.completePairing(a.pairCode)}if(c?l=c:a.token&&(l=t.auth.authenticateDevice(a.token)),!l)return w(e,"valid device token or pairing code required","auth_required");let f=t.hosts.get(l.hostId);if(!f||f.reconnecting||!y(f.ws))return w(e,"paired Herdr host is offline",f?.reconnecting?"host_reconnecting":"host_offline");if(f.clients.size>=t.config.relay.maxClientsPerHost)return w(e,"host client limit reached","too_many_clients");clearTimeout(n),t.finishHandshake(e);let u={id:ge("client"),ws:e,hostId:f.id,deviceId:l.deviceId,browserClientId:typeof a.clientId=="string"?a.clientId.slice(0,128):null,handoffCapable:Array.isArray(a.capabilities)&&a.capabilities.includes(ye.hostHandoff),session:null,role:"controller",controllerId:null,connectedAt:new Date().toISOString(),connectedAtMs:Date.now(),lastSeenAt:Date.now(),lastPingAt:null,bytesReceived:0,bytesSent:0,ip:Yr(t,s),userAgent:String(s.headers["user-agent"]||"").slice(0,256),cols:Me(a.cols,80),rows:Me(a.rows,24)};u.controllerId=null,t.auth.noteDeviceSeen(l.deviceId,{userAgent:u.userAgent,ip:u.ip}),r.authenticated=!0,r.client=u,t.clients.set(u.id,u),f.clients.add(u.id),xe(f),e.isAlive=!0,c&&m(e,{type:"paired",token:c.token,deviceId:c.deviceId,hostId:c.hostId,expiresAt:c.expiresAtIso}),m(e,{type:"ready",role:u.role,controllerId:null,hostId:f.id,hostname:f.hostname,platform:f.platform,...f.shellProfile?{shellProfile:f.shellProfile}:{},adminTerminalSupported:f.adminTabsAvailable,clientId:u.id,terminalPalette:f.terminalPalette||null,terminalFont:f.terminalFont||null,clientCount:f.clients.size,hostVersion:f.version,...f.herdrPrefixKeys?{herdrPrefixKeys:f.herdrPrefixKeys}:{}}),f.agentStatus&&m(e,f.agentStatus),f.updateStatus&&m(e,f.updateStatus),ot(t,f,u),Jt(t,f);return}r.client&&vo(t,r.client,i,o)}),e.on("close",()=>{clearTimeout(n),r.client&&C(t,r.client,{notify:!0})}),e.on("error",()=>{})}function vo(t,e,s,r){e.lastSeenAt=Date.now();let n=t.hosts.get(e.hostId);if(!n){C(t,e,{notify:!0,reason:"host_offline"});return}if(r){let o=s;if(o.length>t.config.relay.maxPayloadBytes||!e.session)return;let a=n.binaryFrameV2&&typeof e.session.streamIndex=="number"?pr(1,e.session.streamIndex,o):mr("input",e.session.streamId,o);if(y(n.ws)){let l=()=>{if(y(n.ws))try{n.ws.send(a),e.bytesReceived+=o.length,t.metrics.recordIn(o.length,n.id)}catch{lt(t,n,"host_send_failed")}};t.devLatencyMs>0?zt(t,n.ws,l):l()}return}let i=Se(s.toString());if(!i){m(e.ws,{type:"error",code:"invalid_json",message:"message must be JSON"});return}if(i.type==="ping")e.lastPingAt=new Date().toISOString(),m(e.ws,{type:"pong"});else if(i.type==="resize")e.cols=Me(i.cols,e.cols),e.rows=Me(i.rows,e.rows),e.session&&(e.session.cols=e.cols,e.session.rows=e.rows,y(n.ws)&&m(n.ws,{type:"resize",clientId:e.session.streamId,streamId:e.session.streamId,cols:Math.max(Xt,e.cols),rows:Math.max(Kt,e.rows)}));else if(i.type==="herdr_start"){if(!e.session){m(e.ws,{type:"error",code:"no_session",message:"terminal session is not ready"});return}let o=Date.now();if(e.herdrStartAt&&o-e.herdrStartAt<bo)return;e.herdrStartAt=o,y(n.ws)&&m(n.ws,{type:"herdr_start",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="admin_tab_open"){if(!e.session||!y(n.ws))return;if(!n.adminTabsAvailable){m(e.ws,{type:"error",code:"admin_terminal_unsupported",message:"Update the host connector to open administrator terminals."});return}let o=Date.now();if(e.adminTabAt&&o-e.adminTabAt<wo)return;e.adminTabAt=o,m(n.ws,{type:"admin_tab_open",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="host_font_chunk_request")Lr(n,e,i);else if(i.type==="host_font_subset_request")Nr(n,e,i);else if(i.type==="host_font_refresh"){if(!e.session||!y(n.ws))return;let o=Date.now();if(e.fontRefreshAt&&o-e.fontRefreshAt<To)return;e.fontRefreshAt=o,m(n.ws,{type:"host_font_refresh",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="claim_control")e.role="controller",m(e.ws,{type:"control_granted"});else if(i.type==="release_control")m(e.ws,{type:"control_state",role:"controller",controllerId:null});else if(i.type==="paste_file"){if(e.role==="viewer"){m(e.ws,{type:"error",code:"viewer_mode",message:"Viewer mode cannot paste to terminal"});return}if(!Ar(i.mime)){m(e.ws,{type:"error",code:"paste_file_unsupported",message:"Unsupported paste image format"});return}if(typeof i.dataBase64!="string"){m(e.ws,{type:"error",code:"paste_file_unsupported",message:"Invalid paste image payload"});return}let o=Buffer.byteLength(i.dataBase64,"base64");if(o===0){m(e.ws,{type:"error",code:"paste_file_empty",message:"Pasted image payload is empty"});return}if(o>3145728){m(e.ws,{type:"error",code:"paste_file_too_large",message:"Pasted image exceeds 3 MB limit"});return}if(!Ao(i.mime,i.dataBase64)){m(e.ws,{type:"error",code:"paste_file_unsupported",message:"Pasted image content does not match declared MIME type"});return}if(!y(n?.ws)){m(e.ws,{type:"error",code:"host_offline",message:"Host is offline or disconnected"});return}if(!e.session){m(e.ws,{type:"error",code:"no_session",message:"Terminal session is not ready"});return}m(n.ws,{type:"paste_file",clientId:e.session.streamId,streamId:e.session.streamId,mime:i.mime,dataBase64:i.dataBase64})}}import Co from"node:os";var Io=/^\d{1,6}\.\d{1,6}\.\d{1,6}(?:-[0-9A-Za-z.-]{1,32})?$/;function De(t){return typeof t=="string"&&Io.test(t)?t:null}var Oo=16;function zr(t,e,s){let r={};if(s.counts&&typeof s.counts=="object")for(let[o,a]of Object.entries(s.counts))typeof a=="number"&&Number.isFinite(a)&&(r[o.slice(0,32)]=Math.max(0,Math.min(9999,Math.trunc(a))));let n=(Array.isArray(s.agents)?s.agents:[]).slice(0,Oo).map(o=>({paneId:z(o?.paneId,64),workspaceId:z(o?.workspaceId,64),agent:z(o?.agent,32),title:z(o?.title,64),status:z(o?.status,16),focused:o?.focused===!0})),i={type:"agent_status",focusedPaneId:z(s.focusedPaneId,64),focusedAgent:z(s.focusedAgent,32),counts:r,total:typeof s.total=="number"&&Number.isFinite(s.total)?Math.max(0,Math.trunc(s.total)):n.length,agents:n};e.agentStatus=i,X(t,e,()=>i)}function Xr(t,e,s){let r=De(s.current),n=De(s.latest);if(!r||!n)return;let i={type:"update_status",current:r,installed:De(s.installed)||r,latest:n,updateAvailable:s.updateAvailable===!0,restartPending:s.restartPending===!0,updateCommand:s.updateCommand===!0};e.updateStatus=i,X(t,e,()=>i)}function Kr(t,e,s){e.terminalFont=rt(s.terminalFont);let r={type:"terminal_font",terminalFont:e.terminalFont||null};X(t,e,()=>r)}function Po(t,e,s,r=new Set){let n=Array.isArray(t.capabilities)?t.capabilities:[],i=br(t.herdrPrefixKeys);return{id:t.hostId,ws:e,hostname:typeof t.hostname=="string"?t.hostname.slice(0,128):Co.hostname(),platform:typeof t.platform=="string"?t.platform.slice(0,32):process.platform,...t.shellProfile==="git-bash"?{shellProfile:t.shellProfile}:{},adminTabsAvailable:n.includes(ye.adminTabs),arch:typeof t.arch=="string"?t.arch.slice(0,32):process.arch,connectedAt:new Date(s.connectedAt).toISOString(),connectedAtMs:s.connectedAt,terminalPalette:Er(t.terminalPalette),terminalFont:rt(t.terminalFont),...i?{herdrPrefixKeys:i}:{},agentStatus:null,updateStatus:null,version:De(t.version),lastSeenAt:Date.now(),clients:r,controllerId:null,load:{},ptys:[],reconnecting:!1,reconnectTimer:null,connectionGeneration:ge("host-connection"),handoffCapable:n.includes(ye.hostHandoff),binaryFrameV2:n.includes(ye.binaryFrameV2),streamIndices:new Map,nextStreamIndex:0,shutdownRequested:!1}}function Jr(t,e,s){let r={ws:e,remoteAddress:s.socket.remoteAddress,connectedAt:Date.now(),authenticated:!1},n=setTimeout(()=>{r.authenticated||k(e,1008,"host hello timeout")},1e4);e.isAlive=!0,e.on("pong",()=>{e.isAlive=!0,r.host&&(r.host.lastSeenAt=Date.now())}),e.on("ping",()=>{e.isAlive=!0,r.host&&(r.host.lastSeenAt=Date.now())}),e.on("message",(i,o)=>{if(!r.authenticated){if(o)return w(e,"host hello must be JSON");let a=Se(i.toString());if(a?.type!=="host_hello"||a.protocol!==1)return w(e,"invalid host hello");if(!Wr(t,s))return w(e,"too many connection attempts","rate_limited");let l=t.hosts.get(a.hostId);if(!l&&t.hosts.size>=t.config.relay.maxHosts)return w(e,"relay host limit reached","too_many_hosts");let c=t.auth.registerHost(a.hostId,a.token,a.password??null);if(!c.ok)return w(e,c.message,c.code);clearTimeout(n),r.authenticated=!0,t.finishHandshake(e);let f=at(t,l),d=f&&l?l.clients:new Set;if(l)if(l.reconnectTimer&&clearTimeout(l.reconnectTimer),l.reconnectTimer=null,f){for(let h of l.clients){let p=t.clients.get(h);p?.session&&(y(l.ws)&&m(l.ws,{type:"session_stop",clientId:p.session.streamId,streamId:p.session.streamId}),Ee(t,l,p))}l.load={},l.ptys=[],X(t,l,()=>({type:"host_reconnecting",code:"host_replaced"}))}else N(t,l,{notify:!0,reason:"host_replaced"});let u=Po(a,e,r,d);if(r.host=u,t.hosts.set(u.id,u),l&&f&&k(l.ws,1e3,"host_replaced"),m(e,{type:"host_ready",protocol:1,hostId:u.id,clientCount:u.clients.size}),xe(u),f)for(let h of u.clients){let p=t.clients.get(h);p&&ot(t,u,p,{restarted:!0})}return}r.host&&Ro(t,r.host,i,o)}),e.on("close",(i,o)=>{clearTimeout(n);let a=r.host;if(!a||t.hosts.get(a.id)!==a||a.ws!==e)return;if((o?o.toString():"")==="host_shutdown"&&(a.shutdownRequested=!0),a.shutdownRequested||!at(t,a)){N(t,a,{notify:!0,reason:a.shutdownRequested?"host_shutdown":"host_disconnected"});return}lt(t,a,"host_disconnected")}),e.on("error",()=>{})}function Ro(t,e,s,r){if(e.lastSeenAt=Date.now(),r){let c;try{c=_r(s)}catch(u){t.metrics.recordCleanup("deadConnectionsClosed"),k(e.ws,1003,u.message);return}if(c.type!=="output")return;let f=c.version===2?e.streamIndices.get(c.streamIndex):t.streams.get(c.streamId);if(!f)return;let d=t.clients.get(f);if(!d||!y(d.ws))return;Gr(t,e,d,c.payload);return}let n=Se(s.toString());if(!n)return;if(n.type==="heartbeat"){e.load=n.load&&typeof n.load=="object"?n.load:{},e.ptys=Array.isArray(n.ptys)?n.ptys.slice(0,256):[];return}if(n.type==="host_shutdown"){e.shutdownRequested=!0,t.hosts.get(e.id)===e&&N(t,e,{notify:!0,reason:"host_shutdown"});return}if(n.type==="agent_status"){zr(t,e,n);return}if(n.type==="update_status"){Xr(t,e,n);return}if(n.type==="terminal_font"){Kr(t,e,n);return}let i=n,o=typeof i.clientId=="string"?i.clientId:i.streamId,a=o?t.streams.get(o):null,l=a?t.clients.get(a):null;if(l)if(n.type==="session_ready")l.session&&(l.session.ready=!0),m(l.ws,{type:"session_ready",clientId:l.id});else if(n.type==="session_exit"){let c=Number.isInteger(n.code)?n.code:null;m(l.ws,{type:"exit",code:c}),Ee(t,e,l),C(t,l,{notify:!1})}else n.type==="host_font_chunk"?Dr(l,n):n.type==="host_font_subset_ready"?Mr(l,n):n.type==="paste_file_ready"?m(l.ws,{type:"paste_file_ready",path:n.path}):n.type==="error"&&(n.code==="host_font_unavailable"&&(Wt(l),nt(l)),n.code==="host_font_subset_failed"&&nt(l),m(l.ws,{type:"error",code:n.code||"host_error",message:String(n.message||"Host connector error")}))}import Zr from"node:fs";import re from"node:path";import{URL as No}from"node:url";function Zt(t,{sample:e=!0,includeDevices:s=!1,scopeHostId:r=null}={}){let n=r?[...t.clients.values()].filter(h=>h.hostId===r):[...t.clients.values()],i=r?[...t.hosts.values()].filter(h=>h.id===r):[...t.hosts.values()],o=n.map(h=>({id:h.id,role:h.role,...r?{}:{hostId:h.hostId},...s?{deviceId:h.deviceId}:{},userAgent:h.userAgent,connectedAt:h.connectedAt,lastPingAt:h.lastPingAt,bytesReceived:h.bytesReceived,bytesSent:h.bytesSent,ip:h.ip})),a=t.auth.listDevices(),l=new Map;for(let h of a)l.set(h.hostId,(l.get(h.hostId)||0)+1);let c=i.map(h=>({id:h.id,hostname:h.hostname,platform:h.platform,arch:h.arch,status:h.reconnecting?"reconnecting":h.clients.size?"busy":"online",connectedAt:h.connectedAt,activePtyCount:h.ptys.length,connectedDeviceCount:st([...h.clients].map(p=>t.clients.get(p)).filter(p=>!!p)),pairedDeviceCount:l.get(h.id)||0,version:h.version??h.updateStatus?.current??null,latestVersion:h.updateStatus?.updateAvailable?h.updateStatus.latest:null,load:h.load})),f=i.flatMap(h=>h.ptys.map(p=>({...p,...r?{}:{hostId:h.id},activeClients:h.clients.size}))),d=s?a:void 0,u=t.address();return{...t.metrics.snapshot({clients:o,hosts:c,ptys:f,sample:e,scopeHostId:r,activeUserCount:st(n)}),...d?{devices:d}:{},relayMode:t.relayMode,isRemoteRelay:t.relayMode==="remote",remoteAdminUrl:t.relayMode==="remote"?`${String(t.config.relay.publicUrl||"").replace(/\/+$/,"")}/admin`:void 0,relay:{mode:t.relayMode,publicUrl:t.config.relay.publicUrl,bind:t.config.relay.host,port:(u&&"port"in u?u.port:void 0)||t.config.relay.port,maxClientsPerHost:t.config.relay.maxClientsPerHost,maxHosts:t.config.relay.maxHosts,maxPendingHandshakes:t.config.relay.maxPendingHandshakes,maxBufferedBytesPerClient:t.config.relay.maxBufferedBytesPerClient,hostReconnectGraceMs:t.config.relay.hostReconnectGraceMs,adminConfigured:!!t.adminToken,adminStatusPath:"/api/admin/status",dashboardPath:"/admin"}}}import ko from"node:fs";import Lo from"node:path";var W=JSON.parse(ko.readFileSync(Lo.join(ae,"package.json"),"utf8")).version;var Qr=re.join(ae,"web","dist"),Mo=10080*60,Do={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon",".woff2":"font/woff2"};function Qt(t,e="application/json"){t.setHeader("Content-Type",e),t.setHeader("Cache-Control","no-store"),t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("Referrer-Policy","no-referrer"),t.setHeader("Content-Security-Policy","default-src 'self'; base-uri 'none'; object-src 'none'; frame-ancestors 'none'; connect-src 'self' ws: wss:; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'")}function ne(t,e,s){Qt(t),t.writeHead(e),t.end(JSON.stringify(s))}function A(t,e,s,r){ne(t,e,{ok:!1,code:s,message:r})}function en(t,e,s){return t.adminToken?Fr(t,e)?!0:(A(s,401,"admin_auth_required","a valid relay admin token is required"),!1):(A(s,503,"admin_not_configured","configure RELAY_ADMIN_TOKEN to access the relay dashboard"),!1)}var Bo=(t,e,s)=>{ne(s,200,{ok:!0,version:W,protocol:1,uptimeSeconds:Math.floor((Date.now()-t.startedAt)/1e3)})},Uo=(t,e,s)=>{let r=String(t.config.relay.publicUrl||"").replace(/\/+$/,"");ne(s,200,{ok:!0,version:W,protocol:1,relayMode:t.relayMode,isRemoteRelay:t.relayMode==="remote",adminConfigured:!!t.adminToken,adminPath:"/admin",adminStatusPath:"/api/admin/status",publicUrl:r,remoteAdminUrl:t.relayMode==="remote"?`${r}/admin`:null})},Fo=(t,e,s)=>{let r=Ur(t,e);if(!r){A(s,401,"auth_required","an authorized device or host token is required");return}ne(s,200,Zt(t,{scopeHostId:r.hostId}))},Ho=(t,e,s)=>{en(t,e,s)&&ne(s,200,Zt(t,{includeDevices:!0}))},Yo=(t,e,s,r)=>{if(!en(t,e,s))return;let n=decodeURIComponent(r.pathname.slice(19)),i=t.auth.revokeDevice(n);if(!i){A(s,404,"device_not_found","no such paired device");return}let o=Vr(t,n);ne(s,200,{ok:!0,deviceId:i.deviceId,disconnected:o})},$o=(t,e,s)=>{if(!it(t,e)){A(s,429,"rate_limited","too many pairing attempts");return}let r=Vt(t,e);if(!r){A(s,401,"host_auth_required","a valid host id and token are required");return}let n=t.hosts.get(r);if(!n||n.reconnecting||!y(n.ws)){A(s,409,"host_offline","no Herdr host is connected");return}try{let i=t.auth.startPairing(r,String(t.config.relay.publicUrl).replace(/\/$/,"")),o={ok:!0,...i,pairUrl:`${i.publicUrl}/?pairCode=${encodeURIComponent(i.code)}`};ne(s,200,o)}catch(i){let{code:o,message:a}=i;A(s,409,o||"pairing_failed",a)}},Wo=[{method:"GET",path:"/healthz",handle:Bo},{method:"GET",path:"/api/info",handle:Uo},{method:"GET",path:"/api/status",handle:Fo},{method:"GET",path:"/api/admin/status",handle:Ho},{method:"DELETE",path:"/api/admin/devices/",prefix:!0,handle:Yo},{method:"POST",path:"/api/pair/start",handle:$o}];function tn(t,e,s){let r;try{r=new No(e.url||"",`http://${e.headers.host||"localhost"}`)}catch{A(s,400,"bad_request","invalid URL");return}if(!Br(t,e)){A(s,403,"origin_denied","origin is not allowed");return}if(e.method==="OPTIONS"){s.writeHead(204,{"Access-Control-Allow-Origin":e.headers.origin||"*","Access-Control-Allow-Headers":"Authorization, Content-Type, X-Herdr-Host-Id, X-Herdr-Host-Token, X-Relay-Admin-Token","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS",Vary:"Origin"}),s.end();return}e.headers.origin&&(s.setHeader("Access-Control-Allow-Origin",e.headers.origin),s.setHeader("Vary","Origin"));let{pathname:n}=r,i=Wo.find(o=>o.method===e.method&&(o.prefix?n.startsWith(o.path):n===o.path));if(i){i.handle(t,e,s,r);return}if(n.startsWith("/api/")){A(s,404,"not_found","API route not found");return}Go(t.publicDir,n,s)}function Go(t,e,s){let r=e==="/"||e==="/admin"?"index.html":e.replace(/^\/+/,""),n=re.resolve(t,r);if(!n.startsWith(`${t}${re.sep}`)&&n!==re.join(t,"index.html")){A(s,403,"forbidden","path is not allowed");return}Zr.readFile(n,(i,o)=>{if(i&&!re.extname(r)){Zr.readFile(re.join(t,"index.html"),(l,c)=>{if(l){A(s,503,"web_not_built","frontend has not been built");return}Qt(s,"text/html; charset=utf-8"),s.end(c)});return}if(i){A(s,404,"not_found","file not found");return}let a=re.extname(n).toLowerCase();Qt(s,Do[a]||"application/octet-stream"),r.startsWith("fonts/")&&s.setHeader("Cache-Control",`public, max-age=${Mo}`),s.end(o)})}function sn(t){let e=[...[...t.hosts.values()].map(s=>s.ws),...[...t.clients.values()].map(s=>s.ws)].filter(s=>!!(s&&s.readyState!==T.default.CLOSED));for(let s of e){if(s.readyState===T.default.CLOSING){t.metrics.recordCleanup("deadConnectionsClosed"),se(s);continue}if(s.readyState===T.default.OPEN){if(!s.isAlive){t.metrics.recordCleanup("deadConnectionsClosed"),se(s);continue}s.isAlive=!1;try{s.ping()}catch{}}}}function es(t,e){for(let[s,r]of t.entries())e-r.startedAt>=6e4&&t.delete(s)}function rn(t){let e=Date.now(),s=t.config.cleanup.staleAfterMs;es(t.pairAttempts,e),es(t.clientHandshakeAttempts,e),es(t.hostHandshakeAttempts,e);for(let n of[...t.clients.values()])e-n.lastSeenAt>s&&(t.metrics.recordCleanup("staleClientsPurged"),C(t,n,{notify:!1,reason:"stale_client",terminate:!0}));for(let n of[...t.hosts.values()])n.reconnecting||e-n.lastSeenAt>s&&(t.metrics.recordCleanup("deadConnectionsClosed"),N(t,n,{notify:!0,reason:"stale_host",terminate:!0}));let r=t.auth.cleanup(e);(r.removedDevices||r.removedPairings)&&t.metrics.recordCleanup("staleClientsPurged",r.removedDevices),t.metrics.cleanup.lastCleanupAt=new Date(e).toISOString()}var ct=class{config;relayMode;hosts=new Map;clients=new Map;streams=new Map;pairAttempts=new Map;clientHandshakeAttempts=new Map;hostHandshakeAttempts=new Map;pendingHandshakes=new Set;startedAt=Date.now();metrics;stateFile;password;adminToken;trustProxy;devLatencyMs;devDelayMs;publicDir;sendQueues=new WeakMap;activeDelayTimers=new Set;auth;server;wss;heartbeatTimer=null;cleanupTimer=null;constructor(e=Be().config,s={}){this.config={relay:{...x.relay,...e.relay},auth:{...x.auth,...e.auth},cleanup:{...x.cleanup,...e.cleanup}};let{relay:r,auth:n}=this.config;this.relayMode=r.mode==="local"?"local":"remote",this.metrics=s.metrics||new tt({version:W,protocolVersion:1}),this.stateFile=s.stateFile||n.stateFile||ts.join(ht(),"relay-auth.json"),this.password=s.password??n.password??null,this.adminToken=s.adminToken??n.adminToken??null,this.trustProxy=!!(s.trustProxy??r.trustProxy),this.publicDir=ts.resolve(s.publicDir??Qr);let i=s.devLatencyMs??r.devLatencyMs??process.env.RELAY_DEV_LATENCY_MS;this.devLatencyMs=i?Math.max(0,Number.parseInt(String(i),10)||0):0,this.devDelayMs=this.devLatencyMs>0?Math.round(this.devLatencyMs/2):0,this.auth=s.auth||new Ze({stateFile:this.stateFile,pairingTtlMs:n.pairingTtlMs,deviceTtlMs:n.deviceTtlMs,maxDevices:n.maxDevices,password:this.password}),this.server=jo.createServer((o,a)=>tn(this,o,a)),this.wss=new Dt.default({noServer:!0,clientTracking:!1,maxPayload:r.maxPayloadBytes,perMessageDeflate:{threshold:1024,zlibDeflateOptions:{level:3},serverNoContextTakeover:!1,clientNoContextTakeover:!1,concurrencyLimit:10}}),this.server.on("upgrade",(o,a,l)=>this.handleUpgrade(o,a,l))}listen(e=this.config.relay.port,s=this.config.relay.host){return ke(ts.dirname(this.stateFile)),new Promise((r,n)=>{let i=a=>{this.server.off("listening",o),n(a)},o=()=>{this.server.off("error",i),this.heartbeatTimer=setInterval(()=>sn(this),this.config.cleanup.heartbeatIntervalMs),this.cleanupTimer=setInterval(()=>rn(this),this.config.cleanup.intervalMs),r(this.address())};this.server.once("error",i),this.server.once("listening",o),this.server.listen(e,s)})}address(){let e=this.server.address();return e?typeof e=="string"?{path:e}:{host:e.address,port:e.port}:null}async close(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.cleanupTimer&&clearInterval(this.cleanupTimer),this.heartbeatTimer=null,this.cleanupTimer=null;for(let e of this.activeDelayTimers)clearTimeout(e);this.activeDelayTimers.clear();for(let e of[...this.clients.values()])C(this,e,{notify:!1});for(let e of[...this.hosts.values()])N(this,e,{notify:!1});this.streams.clear(),this.pairAttempts.clear(),this.clientHandshakeAttempts.clear(),this.hostHandshakeAttempts.clear(),this.pendingHandshakes.clear(),this.metrics.close(),await new Promise(e=>{if(!this.server.listening)return e();this.server.close(()=>e())})}handleUpgrade(e,s,r){let n=(()=>{try{return new Vo(e.url||"","http://localhost").pathname}catch{return""}})();if(![Yt,Tr].includes(n)||!jt(this,e.headers.origin,e)){s.write(`HTTP/1.1 403 Forbidden\r
12
+ `),e}}function Bt(t=32){return fr.randomBytes(t).toString("base64url")}function B(t){return Ut.createHash("sha256").update(String(t),"utf8").digest("hex")}function ye(t,e){if(typeof t!="string"||typeof e!="string")return!1;let s=Buffer.from(t,"hex"),r=Buffer.from(e,"hex");return s.length===r.length&&s.length>0&&Ut.timingSafeEqual(s,r)}function F(t=Date.now()){return new Date(t).toISOString()}function Ft(t){return typeof t=="string"&&/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(t)}var hr="ABCDEFGHJKMNPQRSTUVWXYZ23456789",Qi=6;function eo(){let t="";for(let e=0;e<Qi;e+=1)t+=hr[Ut.randomInt(hr.length)];return t}var Ze=class{stateFile;pairingTtlMs;deviceTtlMs;maxDevices;password;pairings=new Map;lastDeviceSaveAt=new Map;state;constructor({stateFile:e,pairingTtlMs:s=600*1e3,deviceTtlMs:r=720*60*60*1e3,maxDevices:n=32,password:i=null}={}){if(!e)throw new TypeError("stateFile is required");this.stateFile=e,this.pairingTtlMs=s,this.deviceTtlMs=r,this.maxDevices=n,this.password=i||null,this.state=dr(e,{version:1,hosts:{},devices:{}}),this.state.version=1,this.state.hosts=this.state.hosts&&typeof this.state.hosts=="object"?this.state.hosts:{},this.state.devices=this.state.devices&&typeof this.state.devices=="object"?this.state.devices:{},ke(Zi.dirname(e))}save(){ur(this.stateFile,this.state)}checkPassword(e){return this.password?typeof e=="string"&&ye(B(e),B(this.password)):!0}registerHost(e,s,r=null,n=Date.now()){if(!Ft(e)||typeof s!="string"||s.length<16||s.length>4096)return{ok:!1,code:"invalid_host_credentials",message:"hostId and token are required"};if(!this.checkPassword(r))return{ok:!1,code:"relay_password_required",message:"the relay password is missing or wrong"};let i=this.state.hosts[e];return i?ye(i.tokenHash,B(s))?(i.lastSeenAt=F(n),this.save(),{ok:!0,hostId:e,firstSeen:!1}):{ok:!1,code:"host_auth_failed",message:"host token is invalid"}:(this.state.hosts[e]={tokenHash:B(s),createdAt:F(n),lastSeenAt:F(n)},this.save(),{ok:!0,hostId:e,firstSeen:!0})}authenticateHost(e,s){if(!Ft(e)||typeof s!="string"||s.length<16||s.length>4096)return!1;let r=this.state.hosts[e];return!!r&&ye(r.tokenHash,B(s))}hostCount(){return Object.keys(this.state.hosts).length}startPairing(e,s,r=Date.now()){if(!Ft(e)||!this.state.hosts[e])throw Object.assign(new Error("host is not connected or enrolled"),{code:"host_not_found"});this.cleanup(r);let n;do n=eo();while([...this.pairings.values()].some(o=>ye(o.codeHash,B(n))));let i=r+this.pairingTtlMs;return this.pairings.set(n,{codeHash:B(n),hostId:e,expiresAt:i,publicUrl:s}),{code:n,hostId:e,publicUrl:s,expiresAt:i,expiresAtIso:F(i)}}completePairing(e,s=Date.now()){if(typeof e!="string"||e.length<4||e.length>32)return null;this.cleanup(s);let r=e.trim().toUpperCase(),n=this.pairings.get(r);if(!n||n.expiresAt<=s||!ye(n.codeHash,B(r)))return null;this.pairings.delete(r);let i=Object.values(this.state.devices);i.length>=this.maxDevices&&(i.sort((c,f)=>(c.lastSeenAt||"").localeCompare(f.lastSeenAt||"")),delete this.state.devices[i[0].deviceId]);let o=`device-${Bt(9)}`,a=Bt(32),l=s+this.deviceTtlMs;return this.state.devices[o]={deviceId:o,hostId:n.hostId,tokenHash:B(a),createdAt:F(s),lastSeenAt:F(s),expiresAt:l},this.save(),{deviceId:o,hostId:n.hostId,token:a,expiresAt:l,expiresAtIso:F(l),publicUrl:n.publicUrl}}noteDeviceSeen(e,{userAgent:s,ip:r}={},n=Date.now()){let i=this.state.devices[e];if(!i)return null;let o=!1;return s&&i.userAgent!==s&&(i.userAgent=String(s).slice(0,256),o=!0),r&&i.lastIp!==r&&(i.lastIp=String(r).slice(0,64),o=!0),i.lastSeenAt=F(n),o&&this.save(),{...i}}listDevices(e=Date.now()){return Object.values(this.state.devices).filter(s=>s&&s.expiresAt>e).map(s=>({deviceId:s.deviceId,hostId:s.hostId,createdAt:s.createdAt,lastSeenAt:s.lastSeenAt,expiresAt:s.expiresAt,expiresAtIso:F(s.expiresAt),userAgent:s.userAgent||null,lastIp:s.lastIp||null})).sort((s,r)=>String(r.lastSeenAt||"").localeCompare(String(s.lastSeenAt||"")))}revokeDevice(e){if(typeof e!="string"||!e)return null;let s=this.state.devices[e];return s?(delete this.state.devices[e],this.lastDeviceSaveAt.delete(e),this.save(),{deviceId:s.deviceId,hostId:s.hostId,userAgent:s.userAgent||null,lastIp:s.lastIp||null}):null}authenticateDevice(e,s=Date.now()){if(typeof e!="string"||e.length<16)return null;let r=B(e);for(let n of Object.values(this.state.devices)){if(n.expiresAt<=s||!ye(n.tokenHash,r))continue;n.lastSeenAt=F(s),n.expiresAt=s+this.deviceTtlMs;let i=this.lastDeviceSaveAt.get(n.deviceId)||0;return s-i>=60*1e3&&(this.lastDeviceSaveAt.set(n.deviceId,s),this.save()),{...n}}return null}cleanup(e=Date.now()){let s=0;for(let[n,i]of Object.entries(this.state.devices))(!i||i.expiresAt<=e)&&(delete this.state.devices[n],this.lastDeviceSaveAt.delete(n),s+=1);let r=0;for(let[n,i]of this.pairings.entries())i.expiresAt<=e&&(this.pairings.delete(n),r+=1);return s&&this.save(),{removedDevices:s,removedPairings:r}}deviceCount(){return Object.keys(this.state.devices).length}};import Qe from"node:os";import{monitorEventLoopDelay as to}from"node:perf_hooks";function et(t,e=0){return Number.isFinite(t)?t:e}function q(t,e,s){return!s||s<=0?0:Math.max(0,(t-e)*1e3/s)}function st(t=[]){let e=new Set;for(let s of t)s&&e.add(typeof s.deviceId=="string"&&s.deviceId?`device:${s.deviceId}`:`client:${s.id}`);return e.size}var tt=class{version;protocolVersion;startedAt;bytesIn;bytesOut;framesIn;framesOut;cleanup;lastSample;hostTraffic;cpuSampleAt;cpuSample;eventLoop;constructor({version:e="0.1.0",protocolVersion:s=1}={}){this.version=e,this.protocolVersion=s,this.startedAt=Date.now(),this.bytesIn=0,this.bytesOut=0,this.framesIn=0,this.framesOut=0,this.cleanup={staleClientsPurged:0,closedPtysCleaned:0,deadConnectionsClosed:0,idleHostsTerminated:0,slowClientsDropped:0,lastCleanupAt:null},this.lastSample={at:this.startedAt,bytesIn:0,bytesOut:0,framesIn:0,framesOut:0},this.hostTraffic=new Map,this.cpuSampleAt=process.hrtime.bigint(),this.cpuSample=process.cpuUsage(),this.eventLoop=to({resolution:20}),this.eventLoop.enable()}hostCounter(e){if(typeof e!="string"||e.length===0)return null;let s=this.hostTraffic.get(e);return s||(s={bytesIn:0,bytesOut:0,framesIn:0,framesOut:0,sampleAt:Date.now(),sampleBytesIn:0,sampleBytesOut:0,sampleFramesIn:0,sampleFramesOut:0},this.hostTraffic.set(e,s)),s}recordIn(e,s=null){let r=Math.max(0,Number(e)||0);this.bytesIn+=r,this.framesIn+=1;let n=this.hostCounter(s);n&&(n.bytesIn+=r,n.framesIn+=1)}recordOut(e,s=null){let r=Math.max(0,Number(e)||0);this.bytesOut+=r,this.framesOut+=1;let n=this.hostCounter(s);n&&(n.bytesOut+=r,n.framesOut+=1)}forgetHost(e){typeof e=="string"&&this.hostTraffic.delete(e)}hostThroughput(e,s=Date.now()){let r=this.hostCounter(e);if(!r)return{bytesIn:0,bytesOut:0,bytesInPerSec:0,bytesOutPerSec:0,framesIn:0,framesOut:0,framesInPerSec:0,framesOutPerSec:0};let n=s-r.sampleAt,i={bytesIn:r.bytesIn,bytesOut:r.bytesOut,bytesInPerSec:q(r.bytesIn,r.sampleBytesIn,n),bytesOutPerSec:q(r.bytesOut,r.sampleBytesOut,n),framesIn:r.framesIn,framesOut:r.framesOut,framesInPerSec:q(r.framesIn,r.sampleFramesIn,n),framesOutPerSec:q(r.framesOut,r.sampleFramesOut,n)};return r.sampleAt=s,r.sampleBytesIn=r.bytesIn,r.sampleBytesOut=r.bytesOut,r.sampleFramesIn=r.framesIn,r.sampleFramesOut=r.framesOut,i}recordCleanup(e,s=1){Object.hasOwn(this.cleanup,e)&&typeof this.cleanup[e]=="number"&&(this.cleanup[e]+=s),this.cleanup.lastCleanupAt=new Date().toISOString()}cpuPercent(){let e=process.hrtime.bigint(),s=Number(e-this.cpuSampleAt),r=process.cpuUsage(this.cpuSample);if(this.cpuSampleAt=e,this.cpuSample=process.cpuUsage(),s<=0)return 0;let n=(r.user+r.system)*1e5/s;return Math.max(0,Math.round(n*100)/100)}eventLoopDelay(){let e=s=>Math.round(et(s/1e6)*100)/100;return{p50Ms:e(this.eventLoop.percentile(50)),p90Ms:e(this.eventLoop.percentile(90)),p99Ms:e(this.eventLoop.percentile(99)),maxMs:e(this.eventLoop.max),meanMs:e(this.eventLoop.mean)}}snapshot({clients:e=[],hosts:s=[],ptys:r=[],sample:n=!0,scopeHostId:i=null,activeUserCount:o=null}={}){let a=Date.now(),l=a-this.lastSample.at,c={bytesIn:this.bytesIn,bytesOut:this.bytesOut,bytesInPerSec:q(this.bytesIn,this.lastSample.bytesIn,l),bytesOutPerSec:q(this.bytesOut,this.lastSample.bytesOut,l),framesIn:this.framesIn,framesOut:this.framesOut,framesInPerSec:q(this.framesIn,this.lastSample.framesIn,l),framesOutPerSec:q(this.framesOut,this.lastSample.framesOut,l)};n&&(this.lastSample={at:a,bytesIn:this.bytesIn,bytesOut:this.bytesOut,framesIn:this.framesIn,framesOut:this.framesOut});let f=process.memoryUsage(),d=Qe.loadavg(),u=e[0],h=i?this.hostThroughput(i,a):c;return{version:this.version,protocolVersion:this.protocolVersion,uptimeSeconds:Math.floor((a-this.startedAt)/1e3),startTime:new Date(this.startedAt).toISOString(),serverTime:new Date(a).toISOString(),activeControllerId:null,activeHostId:u?.hostId||s[0]?.id||null,clients:e,hosts:s,ptys:r,clientCount:e.length,hostCount:s.length,ptyCount:r.length,activeUserCount:Number.isFinite(o)?o:st(e),throughput:h,cpu:{load1m:et(d[0]),load5m:et(d[1]),load15m:et(d[2]),cpuPercent:this.cpuPercent(),cores:Qe.cpus().length},memory:{rssBytes:f.rss,heapUsedBytes:f.heapUsed,heapTotalBytes:f.heapTotal,externalBytes:f.external,systemTotalBytes:Qe.totalmem(),systemFreeBytes:Qe.freemem()},eventLoopDelay:this.eventLoopDelay(),cleanup:{...this.cleanup}}}close(){this.eventLoop.disable(),this.hostTraffic.clear()}};function Le(t){return Buffer.isBuffer(t)?t:(typeof t=="string"||t instanceof ArrayBuffer,Buffer.from(t))}function pr(t,e,s=Buffer.alloc(0)){if(typeof t!="string"||!t||typeof e!="string"||!e)throw new TypeError("type and streamId must be non-empty strings");let r=Le(s),n=Buffer.from(JSON.stringify({type:t,streamId:e}),"utf8");if(n.length>8192)throw new RangeError("stream frame header is too large");let i=Buffer.allocUnsafe(4);return i.writeUInt32BE(n.length,0),Buffer.concat([i,n,r])}function so(t){let e=Le(t);if(e.length<4)throw new Error("stream frame is truncated");let s=e.readUInt32BE(0);if(s===0||s>8192||e.length<4+s)throw new Error("stream frame header is invalid");let r;try{r=JSON.parse(e.subarray(4,4+s).toString("utf8"))}catch(n){throw new Error(`stream frame header is not JSON: ${n.message}`)}if(!r||typeof r.type!="string"||typeof r.streamId!="string")throw new Error("stream frame header is missing routing fields");return{version:1,type:r.type,streamId:r.streamId,payload:e.subarray(4+s)}}function mr(t,e,s=Buffer.alloc(0)){let r=t;if(t==="output"?r=0:t==="input"&&(r=1),r!==0&&r!==1)throw new TypeError("type must be FRAME_TYPE_OUTPUT (0) or FRAME_TYPE_INPUT (1)");if(!Number.isInteger(e)||e<0||e>65535)throw new RangeError("streamIndex must be an unsigned 16-bit integer (0-65535)");let n=Le(s),i=Buffer.allocUnsafe(4+n.length);return i.writeUInt8(255,0),i.writeUInt8(r,1),i.writeUInt16BE(e,2),n.copy(i,4),i}function ro(t){let e=Le(t);if(e.length<4)throw new Error("v2 stream frame is truncated");if(e.readUInt8(0)!==255)throw new Error("invalid v2 stream frame magic byte");let r=e.readUInt8(1);if(r!==0&&r!==1)throw new Error(`unknown v2 stream frame type: ${r}`);let n=e.readUInt16BE(2);return{version:2,type:r===0?"output":"input",typeCode:r,streamIndex:n,payload:e.subarray(4)}}function _r(t){let e=Le(t);if(e.length<4)throw new Error("stream frame is truncated");return e[0]===255?ro(e):so(e)}var yr=["black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite"],no=["regular","bold","italic","boldItalic"],io=["truetype","opentype"],oo=["cjk","all"];var ao=/^#[0-9a-f]{6}$/i,lo=/["'\\;,{}<>@\u0000-\u001f\u007f]/,gr=/^[0-9a-f]{64}$/;function Me(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Ht(t,e){return t.includes(e)}function Sr(t){return typeof t=="string"&&ao.test(t)?t.toLowerCase():void 0}function Er(t){if(!Me(t))return null;let e={};for(let r of["background","foreground","cursor"]){let n=Sr(t[r]);n&&(e[r]=n)}let s=t.ansi;if(Me(s)){let r={};for(let n of yr){let i=Sr(s[n]);i&&(r[n]=i)}Object.keys(r).length===yr.length&&(e.ansi=r)}return Object.keys(e).length>0?e:null}function xr(t){let e=typeof t=="string"?t.trim():"";return!e||e.length>128||lo.test(e)?null:e}function rt(t){if(!Me(t))return null;let e=xr(t.family);if(!e)return null;let s=Number(t.sizePx),r=Number.isFinite(s)&&s>=4&&s<=96?Math.round(s*10)/10:null,n=typeof t.source=="string"&&/^[a-z0-9-]{1,32}$/.test(t.source)?t.source:null,i=[],o=new Set;for(let l of Array.isArray(t.faces)?t.faces.slice(0,16):[]){if(!Me(l))continue;let{style:c,format:f,bytes:d,sha256:u}=l;!Ht(no,c)||o.has(c)||Ht(io,f)&&(typeof d!="number"||!Number.isInteger(d)||d<=0||d>16777216||typeof u!="string"||!gr.test(u)||(o.add(c),i.push({style:c,format:f,bytes:d,sha256:u})))}let a=[];for(let l of Array.isArray(t.subsets)?t.subsets.slice(0,16):[]){if(!Me(l))continue;let c=xr(l.family),{scope:f,sha256:d}=l;!c||l.style!=="regular"||Ht(oo,f)&&(typeof d!="string"||!gr.test(d)||a.some(u=>u.scope===f)||a.push({family:c,style:"regular",scope:f,sha256:d}))}return{family:e,...r!==null&&{sizePx:r},...n!==null&&{source:n},faces:i,subsets:a}}var co=/^[\x21-\x7e]+$/;function br(t){if(!Array.isArray(t))return;let e=new Set;for(let s of t){if(e.size>=8)break;if(typeof s!="string")continue;let r=s.replace(/\s+/g,"").toLowerCase();r.length<=32&&co.test(r)&&e.add(r)}return e.size>0?[...e]:void 0}var $t="/ws/host",Tr="/ws/client",se={hostHandoff:"host_handoff",idleHeartbeat:"idle_heartbeat",binaryFrameV2:"binary_frame_v2",adminTabs:"admin_tabs",pasteAnyFile:"paste_any_file"};var wr="application/octet-stream";function Ar(t){if(typeof t!="string")return"file";let s=(t.normalize("NFC").split(/[\\/]/).pop()??"").replace(/[^\p{L}\p{N}._-]+/gu,"_").replace(/^[._]+|[._]+$/g,"");if([...s].length>120){let r=s.lastIndexOf("."),n=r>0&&s.length-r<=16?s.slice(r):"";s=[...s.slice(0,s.length-n.length)].slice(0,120-n.length).join("")+n}return s||"file"}var Ir={"image/png":".png","image/jpeg":".jpg","image/webp":".webp","image/gif":".gif"},Fa=Object.keys(Ir);function vr(t){return typeof t=="string"&&Object.hasOwn(Ir,t)}function Or(t,e){switch(t){case"image/png":return e.length>=8&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71;case"image/jpeg":return e.length>=3&&e[0]===255&&e[1]===216&&e[2]===255;case"image/webp":return e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80;case"image/gif":return e.length>=6&&e[0]===71&&e[1]===73&&e[2]===70&&e[3]===56;default:return!1}}var fo="dibin666/herdr-remote",Cr=`https://github.com/${fo}/releases`,Ha=`${Cr}/latest/download/latest.json`,$a=`${Cr}/latest/download/herdr-remote.tgz`;import uo from"node:crypto";var ho=500;function ge(t){return`${t}-${uo.randomBytes(9).toString("base64url")}`}function z(t,e){return typeof t=="string"&&t.length>0?t.slice(0,e):null}function Ne(t,e){let s=Number(t);return Number.isInteger(s)?Math.min(ho,Math.max(2,s)):e}function y(t){return!!t&&t?.readyState===T.default.OPEN}function p(t,e){y(t)&&t.send(JSON.stringify(e))}function k(t,e=1e3,s=""){if(!(!t||t.readyState===T.default.CLOSED||t.readyState===T.default.CLOSING))try{t.close(e,s.slice(0,120))}catch{}}function re(t){if(!(!t||t.readyState===T.default.CLOSED))try{typeof t.terminate=="function"?t.terminate():typeof t.destroy=="function"&&t.destroy()}catch{}}function Se(t){if(typeof t!="string")return null;try{return JSON.parse(t)}catch{return null}}function w(t,e,s="invalid_handshake"){p(t,{type:"error",code:s,message:e}),k(t,1008,e)}var Rr=4,kr=3e4,Lr=Math.ceil(262144/3)*4,Yt=/^[0-9a-f]{64}$/,po=32*1024,mo=64,_o=16*1024*1024,Mr=/^[A-Za-z0-9_-]{1,32}$/;function Wt(t){Array.isArray(t.fontChunkRequests)&&t.fontChunkRequests.length&&t.fontChunkRequests.shift()}function nt(t){Array.isArray(t.fontSubsetRequests)&&t.fontSubsetRequests.length&&t.fontSubsetRequests.shift()}function Nr(t,e,s){if(!e.session||!y(t.ws))return;let r=t.terminalFont?.faces?.find(a=>a.sha256===s.sha256),n=r?r.bytes:e.fontSubsets?.get(s.sha256)||0,i=Math.ceil(n/262144);if(!n||!Number.isInteger(s.index)||s.index<0||s.index>=i){p(e.ws,{type:"error",code:"host_font_unavailable",message:"The workstation did not offer this font file"});return}let o=Date.now();e.fontChunkRequests=(e.fontChunkRequests||[]).filter(a=>o-a<kr),!(e.fontChunkRequests.length>=Rr)&&(e.fontChunkRequests.push(o),p(t.ws,{type:"host_font_chunk_request",clientId:e.session.streamId,streamId:e.session.streamId,sha256:s.sha256,index:s.index}))}function Dr(t,e,s){if(!e.session||!y(t.ws))return;if(!(t.terminalFont?.subsets?.some(o=>o.sha256===s.sha256)&&typeof s.text=="string"&&s.text.length>0&&s.text.length<=po&&typeof s.requestId=="string"&&Mr.test(s.requestId))){p(e.ws,{type:"error",code:"host_font_unavailable",message:"The workstation did not offer this font"});return}let i=Date.now();e.fontSubsetRequests=(e.fontSubsetRequests||[]).filter(o=>i-o<kr),!(e.fontSubsetRequests.length>=Rr)&&(e.fontSubsetRequests.push(i),p(t.ws,{type:"host_font_subset_request",clientId:e.session.streamId,streamId:e.session.streamId,requestId:s.requestId,sha256:s.sha256,text:s.text}))}function Br(t,e){if(nt(t),!!(typeof e.sha256=="string"&&Yt.test(e.sha256)&&typeof e.subsetSha=="string"&&Yt.test(e.subsetSha)&&typeof e.requestId=="string"&&Mr.test(e.requestId)&&Number.isInteger(e.bytes)&&e.bytes>0&&e.bytes<=_o&&(e.dataBase64===void 0||typeof e.dataBase64=="string"&&e.dataBase64.length<=Lr))){if(e.dataBase64===void 0)for(t.fontSubsets||=new Map,t.fontSubsets.delete(e.subsetSha),t.fontSubsets.set(e.subsetSha,e.bytes);t.fontSubsets.size>mo;){let r=t.fontSubsets.keys().next().value;r!==void 0&&t.fontSubsets.delete(r)}p(t.ws,{type:"host_font_subset_ready",requestId:e.requestId,sha256:e.sha256,subsetSha:e.subsetSha,bytes:e.bytes,...e.dataBase64!==void 0?{dataBase64:e.dataBase64}:{}})}}function Fr(t,e){Wt(t),typeof e.sha256=="string"&&Yt.test(e.sha256)&&Number.isInteger(e.index)&&e.index>=0&&Number.isInteger(e.total)&&e.total>e.index&&typeof e.dataBase64=="string"&&e.dataBase64.length<=Lr&&p(t.ws,{type:"host_font_chunk",sha256:e.sha256,index:e.index,total:e.total,dataBase64:e.dataBase64})}import Gt from"node:crypto";function yo(t){let e=t.headers.authorization;if(typeof e!="string")return null;let s=/^Bearer\s+(.+)$/i.exec(e.trim());return s?s[1]:null}function go(t,e){if(typeof t!="string"||t.length===0||typeof e!="string"||e.length===0)return!1;let s=Gt.createHash("sha256").update(t,"utf8").digest(),r=Gt.createHash("sha256").update(e,"utf8").digest();return Gt.timingSafeEqual(s,r)}function jt(t,e,s){if(!e||(t.config.relay.allowedOrigins||[]).includes(e))return!0;try{return new URL(e).host===s.headers.host}catch{return!1}}function Ur(t,e){let s=e.headers.origin;return s?jt(t,s,e):!0}function Vt(t,e){let s=e.headers["x-herdr-host-id"],r=e.headers["x-herdr-host-token"];return typeof s!="string"||typeof r!="string"?null:t.auth.authenticateHost(s,r)?s:null}function So(t,e){let s=yo(e);return s?t.auth.authenticateDevice(s):null}function Hr(t,e){let s=e.headers["x-herdr-host-id"],r=e.headers["x-herdr-host-token"],n=s!==void 0||r!==void 0,i=e.headers.authorization!==void 0,o=Vt(t,e),a=So(t,e);return n&&!o||i&&!a||o&&a&&o!==a.hostId?null:o?{kind:"host",hostId:o}:a?{kind:"device",hostId:a.hostId,deviceId:a.deviceId}:null}function $r(t,e){return go(e.headers["x-relay-admin-token"],t.adminToken)}function Yr(t,e){if(!t.trustProxy)return null;let s=e.headers["x-forwarded-for"];return typeof s!="string"||s.length===0?null:s.split(",")[0].trim()||null}function xo(t,e){return Yr(t,e)||e.socket.remoteAddress||"unknown"}function Wr(t,e){return Yr(t,e)||e.socket.remoteAddress||null}function qt(t,e,s,r=20){let n=xo(t,s),i=Date.now(),o=e.get(n);if(!o||i-o.startedAt>=6e4){if(e.size>=4096){let a=e.keys().next().value;a!==void 0&&e.delete(a)}return e.set(n,{startedAt:i,count:1}),!0}return o.count>=r?!1:(o.count+=1,!0)}function it(t,e){return qt(t,t.pairAttempts,e,20)}function Gr(t,e){return qt(t,t.clientHandshakeAttempts,e,60)}function jr(t,e){return qt(t,t.hostHandshakeAttempts,e,60)}function xe(t){!t||!y(t.ws)||p(t.ws,{type:"client_count",clientCount:t.clients.size})}function Vr(t,e,s,r){if(!s||!y(s.ws))return!1;let n=t.config.relay.maxBufferedBytesPerClient;if((Number(s.ws.bufferedAmount)||0)+r.length>n)return t.metrics.recordCleanup("slowClientsDropped"),C(t,s,{notify:!0,reason:"slow_client",closeCode:1013}),!1;let o=!1,a=()=>{if(y(s.ws))try{s.ws.send(r),s.bytesSent+=r.length,t.metrics.recordOut(r.length,e.id),o=!0}catch{C(t,s,{notify:!1,reason:"client_send_failed",closeCode:1011})}};return t.devLatencyMs>0?zt(t,s.ws,a):a(),t.devLatencyMs>0?!0:o}function zt(t,e,s){let r=t.sendQueues.get(e);if(!r){let i={items:[],timer:null};r=i,t.sendQueues.set(e,i),e.once("close",()=>{i.timer&&(clearTimeout(i.timer),t.activeDelayTimers.delete(i.timer),i.timer=null),i.items=[]})}let n=Date.now()+t.devDelayMs;if(r.items.push({sendAt:n,task:s}),!r.timer){let i=r,o=setTimeout(()=>qr(t,e,i),t.devDelayMs);r.timer=o,t.activeDelayTimers.add(o)}}function qr(t,e,s){s.timer&&(t.activeDelayTimers.delete(s.timer),s.timer=null);let r=Date.now();for(;s.items.length>0&&s.items[0].sendAt<=r;){let n=s.items.shift();try{n?.task()}catch{}}if(s.items.length>0&&!s.timer){let n=Math.max(0,s.items[0].sendAt-Date.now()),i=setTimeout(()=>qr(t,e,s),n);s.timer=i,t.activeDelayTimers.add(i)}}function X(t,e,s){for(let r of[...e.clients]){let n=t.clients.get(r);if(!n)continue;let i=s(n);i&&p(n.ws,i)}}var Xt=20,Kt=6;function Eo(t){if(!t)return null;let e=65536;for(let s=0;s<e;s++){let r=t.nextStreamIndex;if(t.nextStreamIndex=t.nextStreamIndex+1&65535,!t.streamIndices.has(r))return r}return null}function Ee(t,e,s){let r=s.session;r&&(r.streamIndex!==null&&r.streamIndex!==void 0&&e&&e.streamIndices.delete(r.streamIndex),t.streams.delete(r.streamId),s.session=null)}function ot(t,e,s,{restarted:r=!1}={}){if(!s||!y(e.ws))return;let n=ge("session"),i=null;e.binaryFrameV2&&(i=Eo(e),i!==null&&e.streamIndices.set(i,s.id)),s.session={streamId:n,streamIndex:i,cols:s.cols,rows:s.rows,ready:!1},t.streams.set(n,s.id),p(e.ws,{type:"session_start",clientId:n,streamId:n,cols:Math.max(Xt,s.cols),rows:Math.max(Kt,s.rows),role:"controller",...i!==null?{streamIndex:i}:{}}),r&&p(s.ws,{type:"session_restarted",streamId:n,cols:s.cols,rows:s.rows,hostname:e.hostname,platform:e.platform,...e.shellProfile?{shellProfile:e.shellProfile}:{},adminTerminalSupported:e.adminTabsAvailable,terminalPalette:e.terminalPalette||null,terminalFont:e.terminalFont||null,hostVersion:e.version,...e.herdrPrefixKeys?{herdrPrefixKeys:e.herdrPrefixKeys}:{}})}function Jt(t,e){for(let s of e.clients){let r=t.clients.get(s);r&&(r.role="controller",r.controllerId=null,p(r.ws,{type:"control_state",role:"controller",controllerId:null,clientCount:e.clients.size}))}}function zr(t,e){if(!e)return 0;let s=0;for(let r of[...t.clients.values()])!r||r.deviceId!==e||(C(t,r,{notify:!1,reason:"device_revoked"}),k(r.ws,1e3,"this device has been revoked by the relay operator"),s+=1);return s}function C(t,e,{notify:s=!0,reason:r="client_disconnected",closeCode:n=1e3,terminate:i=!1}={}){if(!e||!t.clients.has(e.id))return;t.clients.delete(e.id);let o=t.hosts.get(e.hostId);if(e.session){let l=e.session.streamId;Ee(t,o,e),o&&y(o.ws)&&p(o.ws,{type:"session_stop",clientId:l,streamId:l})}o&&(o.clients.delete(e.id),xe(o),Jt(t,o),o.clients.size===0&&(o.controllerId=null,o.reconnecting&&M(t,o,{notify:!1,reason:"no_clients"})));let a=e.ws;e.ws=null,s&&p(a,{type:"error",code:r,message:r==="host_offline"?"Herdr host is offline":"connection closed"}),i||a?.readyState===T.default.CLOSING?re(a):k(a,n,r),t.metrics.recordCleanup("closedPtysCleaned")}function M(t,e,{notify:s=!0,reason:r="host_disconnected",terminate:n=!1}={}){if(!e||t.hosts.get(e.id)!==e)return;e.reconnectTimer&&clearTimeout(e.reconnectTimer),e.reconnectTimer=null,t.hosts.delete(e.id);for(let o of[...e.clients]){let a=t.clients.get(o);if(!a)continue;t.clients.delete(a.id),Ee(t,e,a);let l=a.ws;a.ws=null,s&&p(l,{type:"error",code:r,message:"Herdr host disconnected"}),n||l?.readyState===T.default.CLOSING?re(l):k(l,1012,r)}e.clients.clear(),t.metrics.forgetHost(e.id);let i=e.ws;e.ws=null,n||i?.readyState===T.default.CLOSING?re(i):k(i,1e3,r)}function at(t,e){if(!e?.handoffCapable||e.clients.size===0)return!1;for(let s of e.clients)if(!t.clients.get(s)?.handoffCapable)return!1;return!0}function lt(t,e,s="host_disconnected"){if(!e||t.hosts.get(e.id)!==e||e.reconnecting)return;if(!at(t,e)){M(t,e,{notify:!0,reason:s});return}e.ws=null,e.reconnecting=!0,e.reconnectStartedAt=Date.now(),e.lastSeenAt=Date.now(),e.load={},e.ptys=[];for(let n of e.clients){let i=t.clients.get(n);i&&Ee(t,e,i)}X(t,e,()=>({type:"host_reconnecting",code:s}));let r=setTimeout(()=>{e.reconnectTimer=null,t.hosts.get(e.id)===e&&e.reconnecting&&M(t,e,{notify:!0,reason:"host_reconnect_timeout"})},t.config.relay.hostReconnectGraceMs);e.reconnectTimer=r,r.unref?.()}var wo=3e3,Ao=2e3,Io=1e3;function vo(t,e){if(typeof e!="string"||e.length===0)return!1;let s;try{s=Buffer.from(e.slice(0,32),"base64")}catch{return!1}return s.length===0?!1:Or(t,s)}function Xr(t,e,s){let r={ws:e,req:s,authenticated:!1},n=setTimeout(()=>{r.authenticated||k(e,1008,"client hello timeout")},1e4);e.isAlive=!0,e.on("pong",()=>{e.isAlive=!0,r.client&&(r.client.lastSeenAt=Date.now(),r.client.lastPingAt=new Date().toISOString())}),e.on("ping",()=>{e.isAlive=!0,r.client&&(r.client.lastSeenAt=Date.now(),r.client.lastPingAt=new Date().toISOString())}),e.on("message",(i,o)=>{if(!r.authenticated){if(o)return w(e,"client hello must be JSON");let a=Se(i.toString());if(a?.type!=="hello"||a.protocol!==1)return w(e,"invalid client hello");if(!Gr(t,s))return w(e,"too many connection attempts","rate_limited");let l=null,c=null;if(a.pairCode){if(!it(t,s))return w(e,"too many pairing attempts","rate_limited");c=t.auth.completePairing(a.pairCode)}if(c?l=c:a.token&&(l=t.auth.authenticateDevice(a.token)),!l)return w(e,"valid device token or pairing code required","auth_required");let f=t.hosts.get(l.hostId);if(!f||f.reconnecting||!y(f.ws))return w(e,"paired Herdr host is offline",f?.reconnecting?"host_reconnecting":"host_offline");if(f.clients.size>=t.config.relay.maxClientsPerHost)return w(e,"host client limit reached","too_many_clients");clearTimeout(n),t.finishHandshake(e);let u={id:ge("client"),ws:e,hostId:f.id,deviceId:l.deviceId,browserClientId:typeof a.clientId=="string"?a.clientId.slice(0,128):null,handoffCapable:Array.isArray(a.capabilities)&&a.capabilities.includes(se.hostHandoff),session:null,role:"controller",controllerId:null,connectedAt:new Date().toISOString(),connectedAtMs:Date.now(),lastSeenAt:Date.now(),lastPingAt:null,bytesReceived:0,bytesSent:0,ip:Wr(t,s),userAgent:String(s.headers["user-agent"]||"").slice(0,256),cols:Ne(a.cols,80),rows:Ne(a.rows,24)};u.controllerId=null,t.auth.noteDeviceSeen(l.deviceId,{userAgent:u.userAgent,ip:u.ip}),r.authenticated=!0,r.client=u,t.clients.set(u.id,u),f.clients.add(u.id),xe(f),e.isAlive=!0,c&&p(e,{type:"paired",token:c.token,deviceId:c.deviceId,hostId:c.hostId,expiresAt:c.expiresAtIso}),p(e,{type:"ready",role:u.role,controllerId:null,hostId:f.id,hostname:f.hostname,platform:f.platform,...f.shellProfile?{shellProfile:f.shellProfile}:{},adminTerminalSupported:f.adminTabsAvailable,clientId:u.id,terminalPalette:f.terminalPalette||null,terminalFont:f.terminalFont||null,clientCount:f.clients.size,hostVersion:f.version,...f.herdrPrefixKeys?{herdrPrefixKeys:f.herdrPrefixKeys}:{}}),f.agentStatus&&p(e,f.agentStatus),f.updateStatus&&p(e,f.updateStatus),ot(t,f,u),Jt(t,f);return}r.client&&Oo(t,r.client,i,o)}),e.on("close",()=>{clearTimeout(n),r.client&&C(t,r.client,{notify:!0})}),e.on("error",()=>{})}function Oo(t,e,s,r){e.lastSeenAt=Date.now();let n=t.hosts.get(e.hostId);if(!n){C(t,e,{notify:!0,reason:"host_offline"});return}if(r){let o=s;if(o.length>t.config.relay.maxPayloadBytes||!e.session)return;let a=n.binaryFrameV2&&typeof e.session.streamIndex=="number"?mr(1,e.session.streamIndex,o):pr("input",e.session.streamId,o);if(y(n.ws)){let l=()=>{if(y(n.ws))try{n.ws.send(a),e.bytesReceived+=o.length,t.metrics.recordIn(o.length,n.id)}catch{lt(t,n,"host_send_failed")}};t.devLatencyMs>0?zt(t,n.ws,l):l()}return}let i=Se(s.toString());if(!i){p(e.ws,{type:"error",code:"invalid_json",message:"message must be JSON"});return}if(i.type==="ping")e.lastPingAt=new Date().toISOString(),p(e.ws,{type:"pong"});else if(i.type==="resize")e.cols=Ne(i.cols,e.cols),e.rows=Ne(i.rows,e.rows),e.session&&(e.session.cols=e.cols,e.session.rows=e.rows,y(n.ws)&&p(n.ws,{type:"resize",clientId:e.session.streamId,streamId:e.session.streamId,cols:Math.max(Xt,e.cols),rows:Math.max(Kt,e.rows)}));else if(i.type==="herdr_start"){if(!e.session){p(e.ws,{type:"error",code:"no_session",message:"terminal session is not ready"});return}let o=Date.now();if(e.herdrStartAt&&o-e.herdrStartAt<wo)return;e.herdrStartAt=o,y(n.ws)&&p(n.ws,{type:"herdr_start",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="admin_tab_open"){if(!e.session||!y(n.ws))return;if(!n.adminTabsAvailable){p(e.ws,{type:"error",code:"admin_terminal_unsupported",message:"Update the host connector to open administrator terminals."});return}let o=Date.now();if(e.adminTabAt&&o-e.adminTabAt<Io)return;e.adminTabAt=o,p(n.ws,{type:"admin_tab_open",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="host_font_chunk_request")Nr(n,e,i);else if(i.type==="host_font_subset_request")Dr(n,e,i);else if(i.type==="host_font_refresh"){if(!e.session||!y(n.ws))return;let o=Date.now();if(e.fontRefreshAt&&o-e.fontRefreshAt<Ao)return;e.fontRefreshAt=o,p(n.ws,{type:"host_font_refresh",clientId:e.session.streamId,streamId:e.session.streamId})}else if(i.type==="claim_control")e.role="controller",p(e.ws,{type:"control_granted"});else if(i.type==="release_control")p(e.ws,{type:"control_state",role:"controller",controllerId:null});else if(i.type==="paste_file"){let o=(c,f)=>p(e.ws,{type:"error",code:c,message:f});if(e.role==="viewer"){o("viewer_mode","Viewer mode cannot paste to terminal");return}let a=i.mime===wr;if(!a&&!vr(i.mime)){o("paste_file_unsupported","Unsupported paste image format");return}if(typeof i.dataBase64!="string"){o("paste_file_unsupported","Invalid paste payload");return}let l=Buffer.byteLength(i.dataBase64,"base64");if(l===0){o("paste_file_empty","Pasted payload is empty");return}if(l>3145728){o("paste_file_too_large","Pasted payload exceeds 3 MB limit");return}if(!a&&!vo(i.mime,i.dataBase64)){o("paste_file_unsupported","Pasted image content does not match declared MIME type");return}if(!y(n?.ws)){o("host_offline","Host is offline or disconnected");return}if(a&&!n.pasteAnyFile){o("paste_file_host_outdated","Host is too old to receive files; update herdr-remote");return}if(!e.session){o("no_session","Terminal session is not ready");return}p(n.ws,{type:"paste_file",clientId:e.session.streamId,streamId:e.session.streamId,mime:i.mime,dataBase64:i.dataBase64,...a?{name:Ar(i.name)}:{}})}}import Ro from"node:os";var Co=/^\d{1,6}\.\d{1,6}\.\d{1,6}(?:-[0-9A-Za-z.-]{1,32})?$/;function De(t){return typeof t=="string"&&Co.test(t)?t:null}var Po=16;function Kr(t,e,s){let r={};if(s.counts&&typeof s.counts=="object")for(let[o,a]of Object.entries(s.counts))typeof a=="number"&&Number.isFinite(a)&&(r[o.slice(0,32)]=Math.max(0,Math.min(9999,Math.trunc(a))));let n=(Array.isArray(s.agents)?s.agents:[]).slice(0,Po).map(o=>({paneId:z(o?.paneId,64),workspaceId:z(o?.workspaceId,64),agent:z(o?.agent,32),title:z(o?.title,64),status:z(o?.status,16),focused:o?.focused===!0})),i={type:"agent_status",focusedPaneId:z(s.focusedPaneId,64),focusedAgent:z(s.focusedAgent,32),counts:r,total:typeof s.total=="number"&&Number.isFinite(s.total)?Math.max(0,Math.trunc(s.total)):n.length,agents:n};e.agentStatus=i,X(t,e,()=>i)}function Jr(t,e,s){let r=De(s.current),n=De(s.latest);if(!r||!n)return;let i={type:"update_status",current:r,installed:De(s.installed)||r,latest:n,updateAvailable:s.updateAvailable===!0,restartPending:s.restartPending===!0,updateCommand:s.updateCommand===!0};e.updateStatus=i,X(t,e,()=>i)}function Zr(t,e,s){e.terminalFont=rt(s.terminalFont);let r={type:"terminal_font",terminalFont:e.terminalFont||null};X(t,e,()=>r)}function ko(t,e,s,r=new Set){let n=Array.isArray(t.capabilities)?t.capabilities:[],i=br(t.herdrPrefixKeys);return{id:t.hostId,ws:e,hostname:typeof t.hostname=="string"?t.hostname.slice(0,128):Ro.hostname(),platform:typeof t.platform=="string"?t.platform.slice(0,32):process.platform,...t.shellProfile==="git-bash"?{shellProfile:t.shellProfile}:{},adminTabsAvailable:n.includes(se.adminTabs),arch:typeof t.arch=="string"?t.arch.slice(0,32):process.arch,connectedAt:new Date(s.connectedAt).toISOString(),connectedAtMs:s.connectedAt,terminalPalette:Er(t.terminalPalette),terminalFont:rt(t.terminalFont),...i?{herdrPrefixKeys:i}:{},agentStatus:null,updateStatus:null,version:De(t.version),lastSeenAt:Date.now(),clients:r,controllerId:null,load:{},ptys:[],reconnecting:!1,reconnectTimer:null,connectionGeneration:ge("host-connection"),handoffCapable:n.includes(se.hostHandoff),binaryFrameV2:n.includes(se.binaryFrameV2),pasteAnyFile:n.includes(se.pasteAnyFile),streamIndices:new Map,nextStreamIndex:0,shutdownRequested:!1}}function Qr(t,e,s){let r={ws:e,remoteAddress:s.socket.remoteAddress,connectedAt:Date.now(),authenticated:!1},n=setTimeout(()=>{r.authenticated||k(e,1008,"host hello timeout")},1e4);e.isAlive=!0,e.on("pong",()=>{e.isAlive=!0,r.host&&(r.host.lastSeenAt=Date.now())}),e.on("ping",()=>{e.isAlive=!0,r.host&&(r.host.lastSeenAt=Date.now())}),e.on("message",(i,o)=>{if(!r.authenticated){if(o)return w(e,"host hello must be JSON");let a=Se(i.toString());if(a?.type!=="host_hello"||a.protocol!==1)return w(e,"invalid host hello");if(!jr(t,s))return w(e,"too many connection attempts","rate_limited");let l=t.hosts.get(a.hostId);if(!l&&t.hosts.size>=t.config.relay.maxHosts)return w(e,"relay host limit reached","too_many_hosts");let c=t.auth.registerHost(a.hostId,a.token,a.password??null);if(!c.ok)return w(e,c.message,c.code);clearTimeout(n),r.authenticated=!0,t.finishHandshake(e);let f=at(t,l),d=f&&l?l.clients:new Set;if(l)if(l.reconnectTimer&&clearTimeout(l.reconnectTimer),l.reconnectTimer=null,f){for(let h of l.clients){let m=t.clients.get(h);m?.session&&(y(l.ws)&&p(l.ws,{type:"session_stop",clientId:m.session.streamId,streamId:m.session.streamId}),Ee(t,l,m))}l.load={},l.ptys=[],X(t,l,()=>({type:"host_reconnecting",code:"host_replaced"}))}else M(t,l,{notify:!0,reason:"host_replaced"});let u=ko(a,e,r,d);if(r.host=u,t.hosts.set(u.id,u),l&&f&&k(l.ws,1e3,"host_replaced"),p(e,{type:"host_ready",protocol:1,hostId:u.id,clientCount:u.clients.size}),xe(u),f)for(let h of u.clients){let m=t.clients.get(h);m&&ot(t,u,m,{restarted:!0})}return}r.host&&Lo(t,r.host,i,o)}),e.on("close",(i,o)=>{clearTimeout(n);let a=r.host;if(!a||t.hosts.get(a.id)!==a||a.ws!==e)return;if((o?o.toString():"")==="host_shutdown"&&(a.shutdownRequested=!0),a.shutdownRequested||!at(t,a)){M(t,a,{notify:!0,reason:a.shutdownRequested?"host_shutdown":"host_disconnected"});return}lt(t,a,"host_disconnected")}),e.on("error",()=>{})}function Lo(t,e,s,r){if(e.lastSeenAt=Date.now(),r){let c;try{c=_r(s)}catch(u){t.metrics.recordCleanup("deadConnectionsClosed"),k(e.ws,1003,u.message);return}if(c.type!=="output")return;let f=c.version===2?e.streamIndices.get(c.streamIndex):t.streams.get(c.streamId);if(!f)return;let d=t.clients.get(f);if(!d||!y(d.ws))return;Vr(t,e,d,c.payload);return}let n=Se(s.toString());if(!n)return;if(n.type==="heartbeat"){e.load=n.load&&typeof n.load=="object"?n.load:{},e.ptys=Array.isArray(n.ptys)?n.ptys.slice(0,256):[];return}if(n.type==="host_shutdown"){e.shutdownRequested=!0,t.hosts.get(e.id)===e&&M(t,e,{notify:!0,reason:"host_shutdown"});return}if(n.type==="agent_status"){Kr(t,e,n);return}if(n.type==="update_status"){Jr(t,e,n);return}if(n.type==="terminal_font"){Zr(t,e,n);return}let i=n,o=typeof i.clientId=="string"?i.clientId:i.streamId,a=o?t.streams.get(o):null,l=a?t.clients.get(a):null;if(l)if(n.type==="session_ready")l.session&&(l.session.ready=!0),p(l.ws,{type:"session_ready",clientId:l.id});else if(n.type==="session_exit"){let c=Number.isInteger(n.code)?n.code:null;p(l.ws,{type:"exit",code:c}),Ee(t,e,l),C(t,l,{notify:!1})}else n.type==="host_font_chunk"?Fr(l,n):n.type==="host_font_subset_ready"?Br(l,n):n.type==="paste_file_ready"?p(l.ws,{type:"paste_file_ready",path:n.path}):n.type==="error"&&(n.code==="host_font_unavailable"&&(Wt(l),nt(l)),n.code==="host_font_subset_failed"&&nt(l),p(l.ws,{type:"error",code:n.code||"host_error",message:String(n.message||"Host connector error")}))}import en from"node:fs";import ne from"node:path";import{URL as Do}from"node:url";function Zt(t,{sample:e=!0,includeDevices:s=!1,scopeHostId:r=null}={}){let n=r?[...t.clients.values()].filter(h=>h.hostId===r):[...t.clients.values()],i=r?[...t.hosts.values()].filter(h=>h.id===r):[...t.hosts.values()],o=n.map(h=>({id:h.id,role:h.role,...r?{}:{hostId:h.hostId},...s?{deviceId:h.deviceId}:{},userAgent:h.userAgent,connectedAt:h.connectedAt,lastPingAt:h.lastPingAt,bytesReceived:h.bytesReceived,bytesSent:h.bytesSent,ip:h.ip})),a=t.auth.listDevices(),l=new Map;for(let h of a)l.set(h.hostId,(l.get(h.hostId)||0)+1);let c=i.map(h=>({id:h.id,hostname:h.hostname,platform:h.platform,arch:h.arch,status:h.reconnecting?"reconnecting":h.clients.size?"busy":"online",connectedAt:h.connectedAt,activePtyCount:h.ptys.length,connectedDeviceCount:st([...h.clients].map(m=>t.clients.get(m)).filter(m=>!!m)),pairedDeviceCount:l.get(h.id)||0,version:h.version??h.updateStatus?.current??null,latestVersion:h.updateStatus?.updateAvailable?h.updateStatus.latest:null,load:h.load})),f=i.flatMap(h=>h.ptys.map(m=>({...m,...r?{}:{hostId:h.id},activeClients:h.clients.size}))),d=s?a:void 0,u=t.address();return{...t.metrics.snapshot({clients:o,hosts:c,ptys:f,sample:e,scopeHostId:r,activeUserCount:st(n)}),...d?{devices:d}:{},relayMode:t.relayMode,isRemoteRelay:t.relayMode==="remote",remoteAdminUrl:t.relayMode==="remote"?`${String(t.config.relay.publicUrl||"").replace(/\/+$/,"")}/admin`:void 0,relay:{mode:t.relayMode,publicUrl:t.config.relay.publicUrl,bind:t.config.relay.host,port:(u&&"port"in u?u.port:void 0)||t.config.relay.port,maxClientsPerHost:t.config.relay.maxClientsPerHost,maxHosts:t.config.relay.maxHosts,maxPendingHandshakes:t.config.relay.maxPendingHandshakes,maxBufferedBytesPerClient:t.config.relay.maxBufferedBytesPerClient,hostReconnectGraceMs:t.config.relay.hostReconnectGraceMs,adminConfigured:!!t.adminToken,adminStatusPath:"/api/admin/status",dashboardPath:"/admin"}}}import Mo from"node:fs";import No from"node:path";var W=JSON.parse(Mo.readFileSync(No.join(le,"package.json"),"utf8")).version;var tn=ne.join(le,"web","dist"),Bo=10080*60,Fo={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon",".woff2":"font/woff2"};function Qt(t,e="application/json"){t.setHeader("Content-Type",e),t.setHeader("Cache-Control","no-store"),t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("Referrer-Policy","no-referrer"),t.setHeader("Content-Security-Policy","default-src 'self'; base-uri 'none'; object-src 'none'; frame-ancestors 'none'; connect-src 'self' ws: wss:; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'")}function ie(t,e,s){Qt(t),t.writeHead(e),t.end(JSON.stringify(s))}function A(t,e,s,r){ie(t,e,{ok:!1,code:s,message:r})}function sn(t,e,s){return t.adminToken?$r(t,e)?!0:(A(s,401,"admin_auth_required","a valid relay admin token is required"),!1):(A(s,503,"admin_not_configured","configure RELAY_ADMIN_TOKEN to access the relay dashboard"),!1)}var Uo=(t,e,s)=>{ie(s,200,{ok:!0,version:W,protocol:1,uptimeSeconds:Math.floor((Date.now()-t.startedAt)/1e3)})},Ho=(t,e,s)=>{let r=String(t.config.relay.publicUrl||"").replace(/\/+$/,"");ie(s,200,{ok:!0,version:W,protocol:1,relayMode:t.relayMode,isRemoteRelay:t.relayMode==="remote",adminConfigured:!!t.adminToken,adminPath:"/admin",adminStatusPath:"/api/admin/status",publicUrl:r,remoteAdminUrl:t.relayMode==="remote"?`${r}/admin`:null})},$o=(t,e,s)=>{let r=Hr(t,e);if(!r){A(s,401,"auth_required","an authorized device or host token is required");return}ie(s,200,Zt(t,{scopeHostId:r.hostId}))},Yo=(t,e,s)=>{sn(t,e,s)&&ie(s,200,Zt(t,{includeDevices:!0}))},Wo=(t,e,s,r)=>{if(!sn(t,e,s))return;let n=decodeURIComponent(r.pathname.slice(19)),i=t.auth.revokeDevice(n);if(!i){A(s,404,"device_not_found","no such paired device");return}let o=zr(t,n);ie(s,200,{ok:!0,deviceId:i.deviceId,disconnected:o})},Go=(t,e,s)=>{if(!it(t,e)){A(s,429,"rate_limited","too many pairing attempts");return}let r=Vt(t,e);if(!r){A(s,401,"host_auth_required","a valid host id and token are required");return}let n=t.hosts.get(r);if(!n||n.reconnecting||!y(n.ws)){A(s,409,"host_offline","no Herdr host is connected");return}try{let i=t.auth.startPairing(r,String(t.config.relay.publicUrl).replace(/\/$/,"")),o={ok:!0,...i,pairUrl:`${i.publicUrl}/?pairCode=${encodeURIComponent(i.code)}`};ie(s,200,o)}catch(i){let{code:o,message:a}=i;A(s,409,o||"pairing_failed",a)}},jo=[{method:"GET",path:"/healthz",handle:Uo},{method:"GET",path:"/api/info",handle:Ho},{method:"GET",path:"/api/status",handle:$o},{method:"GET",path:"/api/admin/status",handle:Yo},{method:"DELETE",path:"/api/admin/devices/",prefix:!0,handle:Wo},{method:"POST",path:"/api/pair/start",handle:Go}];function rn(t,e,s){let r;try{r=new Do(e.url||"",`http://${e.headers.host||"localhost"}`)}catch{A(s,400,"bad_request","invalid URL");return}if(!Ur(t,e)){A(s,403,"origin_denied","origin is not allowed");return}if(e.method==="OPTIONS"){s.writeHead(204,{"Access-Control-Allow-Origin":e.headers.origin||"*","Access-Control-Allow-Headers":"Authorization, Content-Type, X-Herdr-Host-Id, X-Herdr-Host-Token, X-Relay-Admin-Token","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS",Vary:"Origin"}),s.end();return}e.headers.origin&&(s.setHeader("Access-Control-Allow-Origin",e.headers.origin),s.setHeader("Vary","Origin"));let{pathname:n}=r,i=jo.find(o=>o.method===e.method&&(o.prefix?n.startsWith(o.path):n===o.path));if(i){i.handle(t,e,s,r);return}if(n.startsWith("/api/")){A(s,404,"not_found","API route not found");return}Vo(t.publicDir,n,s)}function Vo(t,e,s){let r=e==="/"||e==="/admin"?"index.html":e.replace(/^\/+/,""),n=ne.resolve(t,r);if(!n.startsWith(`${t}${ne.sep}`)&&n!==ne.join(t,"index.html")){A(s,403,"forbidden","path is not allowed");return}en.readFile(n,(i,o)=>{if(i&&!ne.extname(r)){en.readFile(ne.join(t,"index.html"),(l,c)=>{if(l){A(s,503,"web_not_built","frontend has not been built");return}Qt(s,"text/html; charset=utf-8"),s.end(c)});return}if(i){A(s,404,"not_found","file not found");return}let a=ne.extname(n).toLowerCase();Qt(s,Fo[a]||"application/octet-stream"),r.startsWith("fonts/")&&s.setHeader("Cache-Control",`public, max-age=${Bo}`),s.end(o)})}function nn(t){let e=[...[...t.hosts.values()].map(s=>s.ws),...[...t.clients.values()].map(s=>s.ws)].filter(s=>!!(s&&s.readyState!==T.default.CLOSED));for(let s of e){if(s.readyState===T.default.CLOSING){t.metrics.recordCleanup("deadConnectionsClosed"),re(s);continue}if(s.readyState===T.default.OPEN){if(!s.isAlive){t.metrics.recordCleanup("deadConnectionsClosed"),re(s);continue}s.isAlive=!1;try{s.ping()}catch{}}}}function es(t,e){for(let[s,r]of t.entries())e-r.startedAt>=6e4&&t.delete(s)}function on(t){let e=Date.now(),s=t.config.cleanup.staleAfterMs;es(t.pairAttempts,e),es(t.clientHandshakeAttempts,e),es(t.hostHandshakeAttempts,e);for(let n of[...t.clients.values()])e-n.lastSeenAt>s&&(t.metrics.recordCleanup("staleClientsPurged"),C(t,n,{notify:!1,reason:"stale_client",terminate:!0}));for(let n of[...t.hosts.values()])n.reconnecting||e-n.lastSeenAt>s&&(t.metrics.recordCleanup("deadConnectionsClosed"),M(t,n,{notify:!0,reason:"stale_host",terminate:!0}));let r=t.auth.cleanup(e);(r.removedDevices||r.removedPairings)&&t.metrics.recordCleanup("staleClientsPurged",r.removedDevices),t.metrics.cleanup.lastCleanupAt=new Date(e).toISOString()}var ct=class{config;relayMode;hosts=new Map;clients=new Map;streams=new Map;pairAttempts=new Map;clientHandshakeAttempts=new Map;hostHandshakeAttempts=new Map;pendingHandshakes=new Set;startedAt=Date.now();metrics;stateFile;password;adminToken;trustProxy;devLatencyMs;devDelayMs;publicDir;sendQueues=new WeakMap;activeDelayTimers=new Set;auth;server;wss;heartbeatTimer=null;cleanupTimer=null;constructor(e=Be().config,s={}){this.config={relay:{...x.relay,...e.relay},auth:{...x.auth,...e.auth},cleanup:{...x.cleanup,...e.cleanup}};let{relay:r,auth:n}=this.config;this.relayMode=r.mode==="local"?"local":"remote",this.metrics=s.metrics||new tt({version:W,protocolVersion:1}),this.stateFile=s.stateFile||n.stateFile||ts.join(ht(),"relay-auth.json"),this.password=s.password??n.password??null,this.adminToken=s.adminToken??n.adminToken??null,this.trustProxy=!!(s.trustProxy??r.trustProxy),this.publicDir=ts.resolve(s.publicDir??tn);let i=s.devLatencyMs??r.devLatencyMs??process.env.RELAY_DEV_LATENCY_MS;this.devLatencyMs=i?Math.max(0,Number.parseInt(String(i),10)||0):0,this.devDelayMs=this.devLatencyMs>0?Math.round(this.devLatencyMs/2):0,this.auth=s.auth||new Ze({stateFile:this.stateFile,pairingTtlMs:n.pairingTtlMs,deviceTtlMs:n.deviceTtlMs,maxDevices:n.maxDevices,password:this.password}),this.server=qo.createServer((o,a)=>rn(this,o,a)),this.wss=new Dt.default({noServer:!0,clientTracking:!1,maxPayload:r.maxPayloadBytes,perMessageDeflate:{threshold:1024,zlibDeflateOptions:{level:3},serverNoContextTakeover:!1,clientNoContextTakeover:!1,concurrencyLimit:10}}),this.server.on("upgrade",(o,a,l)=>this.handleUpgrade(o,a,l))}listen(e=this.config.relay.port,s=this.config.relay.host){return ke(ts.dirname(this.stateFile)),new Promise((r,n)=>{let i=a=>{this.server.off("listening",o),n(a)},o=()=>{this.server.off("error",i),this.heartbeatTimer=setInterval(()=>nn(this),this.config.cleanup.heartbeatIntervalMs),this.cleanupTimer=setInterval(()=>on(this),this.config.cleanup.intervalMs),r(this.address())};this.server.once("error",i),this.server.once("listening",o),this.server.listen(e,s)})}address(){let e=this.server.address();return e?typeof e=="string"?{path:e}:{host:e.address,port:e.port}:null}async close(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.cleanupTimer&&clearInterval(this.cleanupTimer),this.heartbeatTimer=null,this.cleanupTimer=null;for(let e of this.activeDelayTimers)clearTimeout(e);this.activeDelayTimers.clear();for(let e of[...this.clients.values()])C(this,e,{notify:!1});for(let e of[...this.hosts.values()])M(this,e,{notify:!1});this.streams.clear(),this.pairAttempts.clear(),this.clientHandshakeAttempts.clear(),this.hostHandshakeAttempts.clear(),this.pendingHandshakes.clear(),this.metrics.close(),await new Promise(e=>{if(!this.server.listening)return e();this.server.close(()=>e())})}handleUpgrade(e,s,r){let n=(()=>{try{return new zo(e.url||"","http://localhost").pathname}catch{return""}})();if(![$t,Tr].includes(n)||!jt(this,e.headers.origin,e)){s.write(`HTTP/1.1 403 Forbidden\r
13
13
  Connection: close\r
14
14
  \r
15
15
  `),s.destroy();return}if(this.pendingHandshakes.size>=this.config.relay.maxPendingHandshakes){s.write(`HTTP/1.1 503 Service Unavailable\r
16
16
  Connection: close\r
17
17
  \r
18
- `),s.destroy();return}try{let i=s;i.setNoDelay(!0),i.setKeepAlive?.(!0,this.config.cleanup.heartbeatIntervalMs)}catch{}this.wss.handleUpgrade(e,s,r,i=>{this.pendingHandshakes.add(i),i.once("close",()=>this.finishHandshake(i)),n===Yt?Jr(this,i,e):qr(this,i,e)})}finishHandshake(e){this.pendingHandshakes.delete(e)}};var nn=`herdr-remote-relay ${W} \u2014 standalone relay for Herdr Remote
18
+ `),s.destroy();return}try{let i=s;i.setNoDelay(!0),i.setKeepAlive?.(!0,this.config.cleanup.heartbeatIntervalMs)}catch{}this.wss.handleUpgrade(e,s,r,i=>{this.pendingHandshakes.add(i),i.once("close",()=>this.finishHandshake(i)),n===$t?Qr(this,i,e):Xr(this,i,e)})}finishHandshake(e){this.pendingHandshakes.delete(e)}};var an=`herdr-remote-relay ${W} \u2014 standalone relay for Herdr Remote
19
19
 
20
20
  Usage: herdr-remote-relay [options]
21
21
 
@@ -39,10 +39,10 @@ Options:
39
39
  -v, --version Show version
40
40
 
41
41
  Guide: docs/self-hosted-relay.md
42
- `;function Xo(){return qo.existsSync(zo.join(ae,"web","dist","index.html"))}async function Ko(t=process.argv.slice(2)){let e;try{e=Be({argv:t})}catch(u){process.stderr.write(`herdr-remote-relay: ${u.message}
43
- `),process.exitCode=1;return}let{config:s,help:r,version:n,errors:i,warnings:o,configFile:a}=e;if(r){process.stdout.write(nn);return}if(n){process.stdout.write(`${W}
42
+ `;function Jo(){return Xo.existsSync(Ko.join(le,"web","dist","index.html"))}async function Zo(t=process.argv.slice(2)){let e;try{e=Be({argv:t})}catch(u){process.stderr.write(`herdr-remote-relay: ${u.message}
43
+ `),process.exitCode=1;return}let{config:s,help:r,version:n,errors:i,warnings:o,configFile:a}=e;if(r){process.stdout.write(an);return}if(n){process.stdout.write(`${W}
44
44
  `);return}if(i.length>0){for(let u of i)process.stderr.write(`herdr-remote-relay: ${u}
45
- `);process.stderr.write(nn),process.exitCode=2;return}let l=new ct(s),c;try{c=await l.listen(s.relay.port,s.relay.host)}catch(u){let h=u.code==="EADDRINUSE"?` (port ${s.relay.port} is already in use)`:u.code==="EACCES"?` (no permission to bind port ${s.relay.port})`:"";process.stderr.write(`herdr-remote-relay: failed to listen${h}: ${u.message}
45
+ `);process.stderr.write(an),process.exitCode=2;return}let l=new ct(s),c;try{c=await l.listen(s.relay.port,s.relay.host)}catch(u){let h=u.code==="EADDRINUSE"?` (port ${s.relay.port} is already in use)`:u.code==="EACCES"?` (no permission to bind port ${s.relay.port})`:"";process.stderr.write(`herdr-remote-relay: failed to listen${h}: ${u.message}
46
46
  `),process.exitCode=1;return}process.stdout.write(`herdr-remote-relay ${W} (protocol ${1})
47
47
  `),process.stdout.write(` listening http://${s.relay.host}:${c.port}
48
48
  `),process.stdout.write(` public url ${s.relay.publicUrl}
@@ -50,8 +50,8 @@ Guide: docs/self-hosted-relay.md
50
50
  `),process.stdout.write(` admin ${s.auth.adminToken?"set (/admin)":"not configured"}
51
51
  `),process.stdout.write(` state file ${l.stateFile}
52
52
  `),a&&process.stdout.write(` config file ${a}
53
- `),Xo()||process.stdout.write(` web ui NOT BUILT (run "npm run build" in this package)
53
+ `),Jo()||process.stdout.write(` web ui NOT BUILT (run "npm run build" in this package)
54
54
  `);for(let u of o)process.stdout.write(` warning: ${u}
55
55
  `);let f=!1,d=u=>{f||(f=!0,process.stdout.write(`herdr-remote-relay: ${u} received, shutting down
56
- `),l.close().finally(()=>process.exit(0)))};process.on("SIGINT",()=>d("SIGINT")),process.on("SIGTERM",()=>d("SIGTERM"))}Ko().catch(t=>{process.stderr.write(`herdr-remote-relay: ${t.stack||t.message}
56
+ `),l.close().finally(()=>process.exit(0)))};process.on("SIGINT",()=>d("SIGINT")),process.on("SIGTERM",()=>d("SIGTERM"))}Zo().catch(t=>{process.stderr.write(`herdr-remote-relay: ${t.stack||t.message}
57
57
  `),process.exitCode=1});