herdr-remote 0.3.34 → 0.3.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/README.zh-CN.md +2 -0
- package/dist/chunks/{MHS44P3Y.js → 37NKZLLR.js} +1 -1
- package/dist/chunks/{6M7I477E.js → 4CO2WAXZ.js} +1 -1
- package/dist/chunks/{IRV2W3ZL.js → 54QMQDOL.js} +1 -1
- package/dist/chunks/{S57VTPH5.js → 5RGV2MW6.js} +1 -1
- package/dist/chunks/67FHQKXM.js +6 -0
- package/dist/chunks/{UK7XZS2G.js → B6LZOIKD.js} +1 -1
- package/dist/chunks/{QXMBBOKS.js → CUXGXJMW.js} +1 -1
- package/dist/chunks/{WDPLLWBV.js → D3LUHIKR.js} +1 -1
- package/dist/chunks/{72JMGTAK.js → ETEPTJGZ.js} +2 -2
- package/dist/chunks/GZIFCN7B.js +3 -0
- package/dist/chunks/{FN6VM2O7.js → HDHNFESR.js} +1 -1
- package/dist/chunks/{MLSLOPR7.js → HRFNURKU.js} +1 -1
- package/dist/chunks/{S3V2O6BK.js → IONXNA5T.js} +1 -1
- package/dist/chunks/KEUAW3VO.js +3 -0
- package/dist/chunks/{TSP3KNDA.js → KUDVTWG4.js} +1 -1
- package/dist/chunks/N3C7MVSO.js +3 -0
- package/dist/chunks/{MRXHG2UD.js → NYAKZHLQ.js} +1 -1
- package/dist/chunks/ODOBBR6N.js +9 -0
- package/dist/chunks/{2IM3AVNW.js → PDOEV4QJ.js} +1 -1
- package/dist/chunks/{2RUREFQO.js → QL4I7VLD.js} +1 -1
- package/dist/chunks/{42KARAL4.js → QOPTXTL7.js} +6 -6
- package/dist/chunks/{NY3SVG3W.js → QP6NLV4R.js} +2 -2
- package/dist/chunks/{I6K6O3EE.js → S4TW5MHM.js} +1 -1
- package/dist/chunks/SWVUDSHP.js +3 -0
- package/dist/chunks/{Y5CEFDIU.js → VSBBDPSE.js} +1 -1
- package/dist/chunks/{QRQJLJWT.js → W2FYGFNZ.js} +1 -1
- package/dist/chunks/{ZZOEVJ3V.js → ZAAEQP3M.js} +1 -1
- package/dist/chunks/{W24FRSKQ.js → ZUTRSLCH.js} +1 -1
- package/dist/cli.js +13 -13
- package/dist/connector/admin-broker.js +1 -1
- package/dist/connector/main.js +14 -14
- package/herdr-plugin.toml +2 -2
- package/node_modules/herdr-remote-relay/bin/herdr-remote-relay.js +11 -11
- package/node_modules/herdr-remote-relay/package.json +1 -1
- package/node_modules/herdr-remote-relay/web/dist/assets/{index-CnRQXj8k.js → index-DMbkU5R6.js} +11 -11
- package/node_modules/herdr-remote-relay/web/dist/index.html +1 -1
- package/package.json +2 -2
- package/dist/chunks/3FQAXVGC.js +0 -3
- package/dist/chunks/J427SPKK.js +0 -3
- package/dist/chunks/NKDFWWLU.js +0 -3
- package/dist/chunks/W27D73NQ.js +0 -3
|
@@ -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 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
|
|
4
|
+
var fn=Object.create;var is=Object.defineProperty;var un=Object.getOwnPropertyDescriptor;var dn=Object.getOwnPropertyNames;var hn=Object.getPrototypeOf,pn=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 mn=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of dn(e))!pn.call(t,n)&&n!==s&&is(t,n,{get:()=>e[n],enumerable:!(r=un(e,n))||r.enumerable});return t};var G=(t,e,s)=>(s=t!=null?fn(hn(t)):{},mn(e||!t||!t.__esModule?is(s,"default",{value:t,enumerable:!0}):s,t));var U=I((oa,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((aa,Fe)=>{"use strict";var{EMPTY_BUFFER:In}=U(),mt=Buffer[Symbol.species];function vn(t,e){if(t.length===0)return In;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 On(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:vn,mask:fs,toArrayBuffer:On,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((la,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((ca,gs)=>{"use strict";var Ie=S("zlib"),ms=Ae(),Cn=ps(),{kStatusCode:_s}=U(),Pn=Buffer[Symbol.species],Rn=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 Cn(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",Ln),this._inflate.on("data",ys)}this._inflate[ce]=r,this._inflate.write(e),s&&this._inflate.write(Rn),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",kn)}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 Pn(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 kn(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 Ln(t){if(this[He]._inflate=null,this[fe]){this[ce](this[fe]);return}t[_s]=1007,this[ce](t)}});var de=I((fa,$e)=>{"use strict";var{isUtf8:Ss}=S("buffer"),{hasBlob:Mn}=U(),Nn=[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 Dn(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 Bn(t){return Mn&&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:Bn,isValidStatusCode:Dn,isValidUTF8:xt,tokenChars:Nn};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((ua,Is)=>{"use strict";var{Writable:Fn}=S("stream"),xs=ue(),{BINARY_TYPES:Un,EMPTY_BUFFER:Es,kStatusCode:Hn,kWebSocket:$n}=U(),{concat:Et,toArrayBuffer:Yn,unmask:Wn}=Ae(),{isValidStatusCode:Gn,isValidUTF8:bs}=de(),Ye=Buffer[Symbol.species],P=0,Ts=1,ws=2,As=3,bt=4,Tt=5,We=6,wt=class extends Fn{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||Un[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[$n]=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&&Wn(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=Yn(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(!Gn(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[Hn]=n,o}};Is.exports=wt});var Ot=I((ha,Cs)=>{"use strict";var{Duplex:da}=S("stream"),{randomFillSync:jn}=S("crypto"),{types:{isUint8Array:Vn}}=S("util"),vs=ue(),{EMPTY_BUFFER:qn,kWebSocket:zn,NOOP:Xn}=U(),{isBlob:he,isValidStatusCode:Kn}=de(),{mask:Os,toBuffer:J}=Ae(),R=Symbol("kByteLength"),Jn=Buffer.alloc(4),Ge=8*1024,Z,pe=Ge,L=0,Zn=1,Qn=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=Xn,this[zn]=void 0}static frame(e,s){let r,n=!1,i=2,o=!1;s.mask&&(r=s.maskBuffer||Jn,s.generateMask?s.generateMask(r):(pe===Ge&&(Z===void 0&&(Z=Buffer.alloc(Ge)),jn(Z,0,Ge),pe=0),r[0]=Z[pe++],r[1]=Z[pe++],r[2]=Z[pe++],r[3]=Z[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=qn;else{if(typeof e!="number"||!Kn(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(Vn(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=J(e),n=e.length,i=J.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=J(e),n=e.length,i=J.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=J(e),a=e.length,l=J.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=Qn,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=J(i);s?this.dispatch(o,s,r,n):(this._state=L,this.sendFrame(t.frame(o,r),n),this.dequeue())}).catch(i=>{process.nextTick(ei,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=Zn,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 ei(t,e,s){vt(t,e,s),t.onerror(e)}});var Fs=I((pa,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 Q=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(Q.prototype,"code",{enumerable:!0});Object.defineProperty(Q.prototype,"reason",{enumerable:!0});Object.defineProperty(Q.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 ti={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 Q("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:Q,ErrorEvent:_e,Event:$,EventTarget:ti,MessageEvent:Oe};function je(t,e,s){typeof t=="object"&&t.handleEvent?t.handleEvent.call(t,s):t.call(e,s)}});var Ve=I((ma,Us)=>{"use strict";var{tokenChars:Ce}=de();function D(t,e,s){t[e]===void 0?t[e]=[s]:t[e].push(s)}function si(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 ri(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:ri,parse:si}});var Ke=I((ga,Js)=>{"use strict";var ni=S("events"),ii=S("https"),oi=S("http"),Ys=S("net"),ai=S("tls"),{randomBytes:li,createHash:ci}=S("crypto"),{Duplex:_a,Readable:ya}=S("stream"),{URL:Pt}=S("url"),V=ue(),fi=At(),ui=Ot(),{isBlob:di}=de(),{BINARY_TYPES:Hs,CLOSE_TIMEOUT:hi,EMPTY_BUFFER:qe,GUID:pi,kForOnEventAttribute:Rt,kListener:mi,kStatusCode:_i,kWebSocket:E,NOOP:Ws}=U(),{EventTarget:{addEventListener:yi,removeEventListener:gi}}=Fs(),{format:Si,parse:xi}=Ve(),{toBuffer:Ei}=Ae(),Gs=Symbol("kAborted"),kt=[8,13],Y=["CONNECTING","OPEN","CLOSING","CLOSED"],bi=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,g=class t extends ni{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 fi({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 ui(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",Ai),n.on("drain",Ii),n.on("error",vi),n.on("message",Oi),n.on("ping",Ci),n.on("pong",Pi),i.onerror=Ri,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[mi];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=yi;g.prototype.removeEventListener=gi;Js.exports=g;function js(t,e,s,r){let n={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:hi,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=li(16).toString("base64"),d=o?ii.request:oi.request,u=new Set,h;if(n.createConnection=n.createConnection||(o?wi:Ti),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"]=Si({[V.extensionName]:h.offer()})),s.length){for(let _ of s){if(typeof _!="string"||!bi.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=ci("sha1").update(f+pi).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=xi(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 Ti(t){return t.path=t.socketPath,Ys.connect(t)}function wi(t){return t.path=void 0,!t.servername&&t.servername!==""&&(t.servername=Ys.isIP(t.host)?"":t.host),ai.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=di(e)?e.size:Ei(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 Ai(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 Ii(){let t=this[E];t.isPaused||t._socket.resume()}function vi(t){let e=this[E];e._socket[E]!==void 0&&(e._socket.removeListener("data",Xe),process.nextTick(Vs,e._socket),e.close(t[_i])),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t))}function $s(){this[E].emitClose()}function Oi(t,e){this[E].emit("message",t,e)}function Ci(t){let e=this[E];e._autoPong&&e.pong(t,!this._isServer,Ws),e.emit("ping",t)}function Pi(t){this[E].emit("pong",t)}function Vs(t){t.resume()}function Ri(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((xa,er)=>{"use strict";var Sa=Ke(),{Duplex:ki}=S("stream");function Zs(t){t.emit("close")}function Li(){!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 Mi(t,e){let s=!0,r=new ki({...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",Li),r.on("error",Qs),r}er.exports=Mi});var Mt=I((Ea,sr)=>{"use strict";var{tokenChars:Ni}=de();function Di(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&&Ni[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:Di}});var cr=I((Ta,lr)=>{"use strict";var Bi=S("events"),Je=S("http"),{Duplex:ba}=S("stream"),{createHash:Fi}=S("crypto"),rr=Ve(),ee=ue(),Ui=Mt(),Hi=Ke(),{CLOSE_TIMEOUT:$i,GUID:Yi,kWebSocket:Wi}=U(),Gi=/^[+/0-9A-Za-z]{22}==$/,nr=0,ir=1,ar=2,Nt=class extends Bi{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:$i,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:Hi,...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=ji(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"){te(this,e,s,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){te(this,e,s,400,"Invalid Upgrade header");return}if(i===void 0||!Gi.test(i)){te(this,e,s,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==13&&a!==8){te(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=Ui.parse(l)}catch{te(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 ee({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let h=rr.parse(f);h[ee.extensionName]&&(u.accept(h[ee.extensionName]),d[ee.extensionName]=u)}catch{te(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[Wi])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: ${Fi("sha1").update(s+Yi).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[ee.extensionName]){let d=e[ee.extensionName].params,u=rr.format({[ee.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=Nt;function
|
|
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 ji(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
|
|
11
|
-
`,{mode:384});try{
|
|
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
|
|
10
|
+
`+s)}function te(t,e,s,r,n,i){if(t.listenerCount("wsClientError")){let o=new Error(n);Error.captureStackTrace(o,te),t.emit("wsClientError",o,s,e)}else Re(s,r,n,i)}});import Jo from"node:fs";import Zo from"node:path";import _n from"node:fs";import yn 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(yn.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 gn(t){return JSON.parse(JSON.stringify(t))}function Sn(t){try{return JSON.parse(_n.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 xn(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 En(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 bn(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 Tn(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 wn(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 An(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}=xn(t),o=gn(x),a=s.config||e.HERDR_RELAY_CONFIG||null;if(a){let c=Sn(we.resolve(a));if(c===null)throw new Error(`relay config not found: ${a}`);En(o,c)}bn(o,e),Tn(o,s);let l=wn(o);return{config:l,help:r,version:n,errors:i,configFile:a,warnings:An(l)}}import Xo from"node:http";import ts from"node:path";import{URL as Ko}from"node:url";var Vi=G(tr(),1),qi=G(Ve(),1),zi=G(ue(),1),Xi=G(At(),1),Ki=G(Ot(),1),Ji=G(Mt(),1),T=G(Ke(),1),Dt=G(cr(),1);import Ut from"node:crypto";import Qi from"node:path";import fr from"node:crypto";import se from"node:fs";import Zi from"node:path";function ke(t){se.mkdirSync(t,{recursive:!0,mode:448});try{se.chmodSync(t,448)}catch{}}function ur(t,e){ke(Zi.dirname(t));let s=`${t}.${process.pid}.${fr.randomBytes(4).toString("hex")}.tmp`;se.writeFileSync(s,`${JSON.stringify(e,null,2)}
|
|
11
|
+
`,{mode:384});try{se.chmodSync(s,384)}catch{}se.renameSync(s,t);try{se.chmodSync(t,384)}catch{}}function dr(t,e){try{return JSON.parse(se.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 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",eo=6;function to(){let t="";for(let e=0;e<eo;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(Qi.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=to();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 so}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=so({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 ro(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 no(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?no(e):ro(e)}var yr=["black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite"],io=["regular","bold","italic","boldItalic"],oo=["truetype","opentype"],ao=["cjk","all"];var lo=/^#[0-9a-f]{6}$/i,co=/["'\\;,{}<>@\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"&&lo.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||co.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(io,c)||o.has(c)||Ht(oo,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(ao,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 fo=8192;function br(t){if(typeof t!="string"||t.length>fo)return null;let e;try{e=new URL(t)}catch{return null}return e.protocol==="http:"||e.protocol==="https:"?t:null}var uo=/^[\x21-\x7e]+$/;function Tr(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&&uo.test(r)&&e.add(r)}return e.size>0?[...e]:void 0}var $t="/ws/host",wr="/ws/client",z={hostHandoff:"host_handoff",idleHeartbeat:"idle_heartbeat",binaryFrameV2:"binary_frame_v2",adminTabs:"admin_tabs",pasteAnyFile:"paste_any_file",openLink:"open_link"};var Ar="application/octet-stream";function Ir(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 vr={"image/png":".png","image/jpeg":".jpg","image/webp":".webp","image/gif":".gif"},Ha=Object.keys(vr);function Or(t){return typeof t=="string"&&Object.hasOwn(vr,t)}function Cr(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 ho="dibin666/herdr-remote",Pr=`https://github.com/${ho}/releases`,Ya=`${Pr}/latest/download/latest.json`,Wa=`${Pr}/latest/download/herdr-remote.tgz`;import po from"node:crypto";var mo=500;function ge(t){return`${t}-${po.randomBytes(9).toString("base64url")}`}function X(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(mo,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 kr=4,Lr=3e4,Mr=Math.ceil(262144/3)*4,Yt=/^[0-9a-f]{64}$/,_o=32*1024,yo=64,go=16*1024*1024,Nr=/^[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 Dr(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<Lr),!(e.fontChunkRequests.length>=kr)&&(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 Br(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<=_o&&typeof s.requestId=="string"&&Nr.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<Lr),!(e.fontSubsetRequests.length>=kr)&&(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 Fr(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"&&Nr.test(e.requestId)&&Number.isInteger(e.bytes)&&e.bytes>0&&e.bytes<=go&&(e.dataBase64===void 0||typeof e.dataBase64=="string"&&e.dataBase64.length<=Mr))){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>yo;){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 Ur(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<=Mr&&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 So(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 xo(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 Hr(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 Eo(t,e){let s=So(e);return s?t.auth.authenticateDevice(s):null}function $r(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=Eo(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 Yr(t,e){return xo(e.headers["x-relay-admin-token"],t.adminToken)}function Wr(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 bo(t,e){return Wr(t,e)||e.socket.remoteAddress||"unknown"}function Gr(t,e){return Wr(t,e)||e.socket.remoteAddress||null}function qt(t,e,s,r=20){let n=bo(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 jr(t,e){return qt(t,t.clientHandshakeAttempts,e,60)}function Vr(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 qr(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(()=>zr(t,e,i),t.devDelayMs);r.timer=o,t.activeDelayTimers.add(o)}}function zr(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(()=>zr(t,e,s),n);s.timer=i,t.activeDelayTimers.add(i)}}function K(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 To(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=To(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 Xr(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)}K(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 Io=3e3,vo=2e3,Oo=1e3;function Co(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:Cr(t,s)}function Kr(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(!jr(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(z.hostHandoff),session:null,role:"controller",controllerId:null,connectedAt:new Date().toISOString(),connectedAtMs:Date.now(),lastSeenAt:Date.now(),lastPingAt:null,bytesReceived:0,bytesSent:0,ip:Gr(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&&Po(t,r.client,i,o)}),e.on("close",()=>{clearTimeout(n),r.client&&C(t,r.client,{notify:!0})}),e.on("error",()=>{})}function Po(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<Io)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<Oo)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")Dr(n,e,i);else if(i.type==="host_font_subset_request")Br(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<vo)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===Ar;if(!a&&!Or(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&&!Co(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:Ir(i.name)}:{}})}}import Lo from"node:os";var Ro=/^\d{1,6}\.\d{1,6}\.\d{1,6}(?:-[0-9A-Za-z.-]{1,32})?$/;function De(t){return typeof t=="string"&&Ro.test(t)?t:null}var ko=16;function Jr(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,ko).map(o=>({paneId:X(o?.paneId,64),workspaceId:X(o?.workspaceId,64),agent:X(o?.agent,32),title:X(o?.title,64),status:X(o?.status,16),focused:o?.focused===!0})),i={type:"agent_status",focusedPaneId:X(s.focusedPaneId,64),focusedAgent:X(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,K(t,e,()=>i)}function Zr(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,K(t,e,()=>i)}function Qr(t,e,s){e.terminalFont=rt(s.terminalFont);let r={type:"terminal_font",terminalFont:e.terminalFont||null};K(t,e,()=>r)}function Mo(t,e,s,r=new Set){let n=Array.isArray(t.capabilities)?t.capabilities:[],i=Tr(t.herdrPrefixKeys);return{id:t.hostId,ws:e,hostname:typeof t.hostname=="string"?t.hostname.slice(0,128):Lo.hostname(),platform:typeof t.platform=="string"?t.platform.slice(0,32):process.platform,...t.shellProfile==="git-bash"?{shellProfile:t.shellProfile}:{},adminTabsAvailable:n.includes(z.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(z.hostHandoff),binaryFrameV2:n.includes(z.binaryFrameV2),pasteAnyFile:n.includes(z.pasteAnyFile),streamIndices:new Map,nextStreamIndex:0,shutdownRequested:!1}}function en(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(!Vr(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=[],K(t,l,()=>({type:"host_reconnecting",code:"host_replaced"}))}else M(t,l,{notify:!0,reason:"host_replaced"});let u=Mo(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,capabilities:[z.openLink]}),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&&No(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 No(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;qr(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"){Jr(t,e,n);return}if(n.type==="update_status"){Zr(t,e,n);return}if(n.type==="terminal_font"){Qr(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 if(n.type==="host_font_chunk")Ur(l,n);else if(n.type==="host_font_subset_ready")Fr(l,n);else if(n.type==="paste_file_ready")p(l.ws,{type:"paste_file_ready",path:n.path});else if(n.type==="open_link"){let c=br(n.url);c&&p(l.ws,{type:"open_link",url:c})}else 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 tn from"node:fs";import ne from"node:path";import{URL as Fo}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 Do from"node:fs";import Bo from"node:path";var W=JSON.parse(Do.readFileSync(Bo.join(le,"package.json"),"utf8")).version;var sn=ne.join(le,"web","dist"),Uo=10080*60,Ho={".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 rn(t,e,s){return t.adminToken?Yr(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 $o=(t,e,s)=>{ie(s,200,{ok:!0,version:W,protocol:1,uptimeSeconds:Math.floor((Date.now()-t.startedAt)/1e3)})},Yo=(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})},Wo=(t,e,s)=>{let r=$r(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}))},Go=(t,e,s)=>{rn(t,e,s)&&ie(s,200,Zt(t,{includeDevices:!0}))},jo=(t,e,s,r)=>{if(!rn(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=Xr(t,n);ie(s,200,{ok:!0,deviceId:i.deviceId,disconnected:o})},Vo=(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)}},qo=[{method:"GET",path:"/healthz",handle:$o},{method:"GET",path:"/api/info",handle:Yo},{method:"GET",path:"/api/status",handle:Wo},{method:"GET",path:"/api/admin/status",handle:Go},{method:"DELETE",path:"/api/admin/devices/",prefix:!0,handle:jo},{method:"POST",path:"/api/pair/start",handle:Vo}];function nn(t,e,s){let r;try{r=new Fo(e.url||"",`http://${e.headers.host||"localhost"}`)}catch{A(s,400,"bad_request","invalid URL");return}if(!Hr(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=qo.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}zo(t.publicDir,n,s)}function zo(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}tn.readFile(n,(i,o)=>{if(i&&!ne.extname(r)){tn.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,Ho[a]||"application/octet-stream"),r.startsWith("fonts/")&&s.setHeader("Cache-Control",`public, max-age=${Uo}`),s.end(o)})}function on(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 an(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??sn);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=Xo.createServer((o,a)=>nn(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(()=>on(this),this.config.cleanup.heartbeatIntervalMs),this.cleanupTimer=setInterval(()=>an(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 Ko(e.url||"","http://localhost").pathname}catch{return""}})();if(![$t,wr].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===$t?
|
|
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?en(this,i,e):Kr(this,i,e)})}finishHandshake(e){this.pendingHandshakes.delete(e)}};var ln=`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
|
|
43
|
-
`),process.exitCode=1;return}let{config:s,help:r,version:n,errors:i,warnings:o,configFile:a}=e;if(r){process.stdout.write(
|
|
42
|
+
`;function Qo(){return Jo.existsSync(Zo.join(le,"web","dist","index.html"))}async function ea(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(ln);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(
|
|
45
|
+
`);process.stderr.write(ln),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
|
-
`),
|
|
53
|
+
`),Qo()||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"))}
|
|
56
|
+
`),l.close().finally(()=>process.exit(0)))};process.on("SIGINT",()=>d("SIGINT")),process.on("SIGTERM",()=>d("SIGTERM"))}ea().catch(t=>{process.stderr.write(`herdr-remote-relay: ${t.stack||t.message}
|
|
57
57
|
`),process.exitCode=1});
|