node-rtc-connection 2.0.8 → 2.0.9

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 CHANGED
@@ -17,7 +17,7 @@ ships type declarations.
17
17
  - ✅ **Browser interoperable**: Verified end-to-end against Chromium (Playwright) and OpenSSL
18
18
  - ✅ **Real protocols, not stubs**: Genuine DTLS 1.2 handshake + SCTP association over UDP
19
19
  - ✅ **ICE** (RFC 8445): connectivity checks with MESSAGE-INTEGRITY, host/srflx/relay candidates
20
- - ✅ **STUN/TURN** (RFC 5389/5766): NAT traversal and relay for restrictive networks
20
+ - ✅ **STUN/TURN** (RFC 5389/5766): NAT traversal and relay for restrictive networks, including encrypted `turns:` (TURN-over-DTLS and TURN-over-TLS)
21
21
  - ✅ **DTLS 1.2** (RFC 6347): `ECDHE_ECDSA_AES128_GCM`, mutual auth, self-signed ECDSA certs
22
22
  - ✅ **SCTP + DCEP** (RFC 8831/8832): ordered/unordered data channels, string + binary
23
23
  - ✅ **W3C API**: familiar `RTCPeerConnection` / `RTCDataChannel` surface
@@ -211,14 +211,33 @@ const config = {
211
211
  };
212
212
  ```
213
213
 
214
- **URL format:** `stun:host[:port]` and `turn:host[:port][?transport=udp&...]`.
214
+ **URL format:** `stun:host[:port]` and `turn(s):host[:port][?transport=udp|tcp&...]`.
215
215
  The default port is `3478` (`5349` for the `turns:` scheme).
216
216
 
217
- > **Transport support:** connectivity currently uses **UDP only**. STUN
218
- > reflexive and TURN relay candidates are gathered over UDP; `transport=tcp`
219
- > and the `turns:` (TLS) scheme are parsed but not yet used for the data path,
220
- > so list a UDP TURN URL for the relay to work. Unknown query parameters are
221
- > preserved and ignored.
217
+ > **Transport support:** the `turns:` scheme is encrypted end-to-end to the TURN
218
+ > server **DTLS** over UDP (`turns:host:5349`) or **TLS** over TCP
219
+ > (`turns:host:5349?transport=tcp`). Plain `turn:` (and STUN srflx) use UDP.
220
+ > Unknown query parameters are preserved and ignored.
221
+
222
+ #### TLS certificate validation (`turns:` over TCP)
223
+
224
+ For TURN-over-TLS, the server's certificate is validated by default. To accept a
225
+ self-signed or otherwise unverifiable certificate (e.g. a local/test TURN
226
+ server), set `rejectUnauthorized: false` on that ICE server entry — this is
227
+ insecure and intended for development only:
228
+
229
+ ```javascript
230
+ const config = {
231
+ iceServers: [
232
+ {
233
+ urls: 'turns:turn.example.com:5349?transport=tcp',
234
+ username: 'user',
235
+ credential: 'pass',
236
+ rejectUnauthorized: false // accept self-signed cert (insecure)
237
+ }
238
+ ]
239
+ };
240
+ ```
222
241
 
223
242
  ## Data Channel API
224
243
 
@@ -382,8 +401,10 @@ createPeerConnection().catch(console.error);
382
401
  The package includes runnable examples in `examples/`:
383
402
 
384
403
  - **`examples/node-to-node.ts`** — Two node-rtc-connection peers in one process
385
- establish a real data channel and exchange string + binary messages. The
386
- quickest way to see the full ICE/DTLS/SCTP stack work.
404
+ establish a real data channel through a TURN server and exchange string +
405
+ binary messages. The quickest way to see the full ICE/DTLS/SCTP stack work.
406
+ Configure the server via `TURN_URL`/`TURN_USER`/`TURN_PASS` (defaults match the
407
+ test-suite coturn), and set `RELAY_ONLY=1` to force traffic through the relay.
387
408
  - **`examples/browser-server.ts`** + **`examples/browser-client.html`** — A
388
409
  Node.js HTTP server that runs a node-rtc-connection peer (the offerer) and serves a chat
389
410
  page. A browser opens the page, runs its native `RTCPeerConnection` as the
@@ -459,10 +480,24 @@ For production use, it's recommended to run your own TURN server using [coturn](
459
480
  # Install coturn
460
481
  apt-get install coturn
461
482
 
462
- # Basic configuration
483
+ # Basic configuration (plain TURN over UDP)
463
484
  turnserver -v -L 0.0.0.0 -a -u user:password -r realm
464
485
  ```
465
486
 
487
+ For the encrypted `turns:` scheme, give coturn an **ECDSA** certificate (required
488
+ for the `ECDHE_ECDSA` cipher suite this library negotiates) and enable the
489
+ TLS/DTLS listener:
490
+
491
+ ```bash
492
+ turnserver -v -L 0.0.0.0 -a -u user:password -r realm \
493
+ --tls-listening-port=5349 \
494
+ --cert=/path/to/cert.pem --pkey=/path/to/key.pem
495
+ ```
496
+
497
+ Then connect with `turns:host:5349` (DTLS) or `turns:host:5349?transport=tcp`
498
+ (TLS). For a self-signed cert, set `rejectUnauthorized: false` on the ICE server
499
+ entry (see [TLS certificate validation](#tls-certificate-validation-turns-over-tcp)).
500
+
466
501
  ## Development
467
502
 
468
503
  The project is written in strict TypeScript. Sources live in `src/`; tests in
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("crypto"),t=require("events"),r=require("dgram"),s=require("os"),i=require("tls");function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var a=n(e),o=n(r),c=n(s),h=n(i);const d=Object.freeze({NONE:"none",DATA_CHANNEL_FAILURE:"data-channel-failure",DTLS_FAILURE:"dtls-failure",FINGERPRINT_FAILURE:"fingerprint-failure",SCTP_FAILURE:"sctp-failure",SDP_SYNTAX_ERROR:"sdp-syntax-error",HARDWARE_ENCODER_NOT_AVAILABLE:"hardware-encoder-not-available",HARDWARE_ENCODER_ERROR:"hardware-encoder-error",INVALID_STATE:"invalid-state",INVALID_MODIFICATION:"invalid-modification",INVALID_ACCESS_ERROR:"invalid-access-error",OPERATION_ERROR:"operation-error"});class l extends Error{static DetailType=d;#e;#t;#r;#s;#i;#n;constructor(e={},t=""){super(t),this.name="RTCError",Error.captureStackTrace&&Error.captureStackTrace(this,l);const r=e.errorDetail||d.NONE;if("string"!=typeof r)throw new TypeError("errorDetail must be a string");this.#e=r,this.#t=this.#a(e.sdpLineNumber,"sdpLineNumber"),this.#r=this.#a(e.httpRequestStatusCode,"httpRequestStatusCode"),this.#s=this.#a(e.sctpCauseCode,"sctpCauseCode"),this.#i=this.#o(e.receivedAlert,"receivedAlert"),this.#n=this.#o(e.sentAlert,"sentAlert")}#a(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r))throw new TypeError(`${t} must be an integer`);return r}#o(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r)||r<0)throw new TypeError(`${t} must be an unsigned integer`);return r}get errorDetail(){return this.#e}get sdpLineNumber(){return this.#t}get httpRequestStatusCode(){return this.#r}get sctpCauseCode(){return this.#s}get receivedAlert(){return this.#i}get sentAlert(){return this.#n}toJSON(){const e={name:this.name,message:this.message,errorDetail:this.#e};return null!==this.#t&&(e.sdpLineNumber=this.#t),null!==this.#r&&(e.httpRequestStatusCode=this.#r),null!==this.#s&&(e.sctpCauseCode=this.#s),null!==this.#i&&(e.receivedAlert=this.#i),null!==this.#n&&(e.sentAlert=this.#n),e}static fromNative(e){const t={errorDetail:e.error_detail||d.NONE};return void 0!==e.sctp_cause_code&&(t.sctpCauseCode=e.sctp_cause_code),new l(t,e.message||"Unknown error")}}class u{#c;#h;#d;#l;#u;constructor(e={}){if(null===e.sdpMid&&null===e.sdpMLineIndex)throw new TypeError("sdpMid and sdpMLineIndex are both null");this.#c=e.candidate||"",this.#h=void 0!==e.sdpMid?e.sdpMid:null,this.#d=void 0!==e.sdpMLineIndex?e.sdpMLineIndex:null,this.#l=e.usernameFragment||null,this.#u=this.#f(this.#c)}#f(e){const t={foundation:null,component:null,protocol:null,priority:null,address:null,port:null,type:null,tcpType:null,relatedAddress:null,relatedPort:null};if(!e||!e.startsWith("candidate:"))return t;const r=e.substring(10).trim().split(/\s+/);if(r.length<8)return t;t.foundation=r[0],t.component=r[1],t.protocol=r[2].toLowerCase(),t.priority=parseInt(r[3],10),t.address=r[4],t.port=parseInt(r[5],10),"typ"===r[6]&&(t.type=r[7]);for(let e=8;e<r.length;e+=2){const s=r[e],i=r[e+1];"raddr"===s?t.relatedAddress=i:"rport"===s?t.relatedPort=parseInt(i,10):"tcptype"===s&&(t.tcpType=i)}return t}get candidate(){return this.#c}get sdpMid(){return this.#h}get sdpMLineIndex(){return this.#d}get usernameFragment(){return this.#l}get foundation(){return this.#u.foundation}get component(){return this.#u.component}get priority(){return this.#u.priority}get address(){return this.#u.address}get protocol(){return this.#u.protocol}get port(){return this.#u.port}get type(){return this.#u.type}get tcpType(){return this.#u.tcpType}get relatedAddress(){return this.#u.relatedAddress}get relatedPort(){return this.#u.relatedPort}toJSON(){const e={candidate:this.#c,sdpMid:this.#h,sdpMLineIndex:this.#d};return this.#l&&(e.usernameFragment=this.#l),e}static fromString(e,t=null,r=0){return new u({candidate:e,sdpMid:t,sdpMLineIndex:r})}static isValid(e){return!(!e||"string"!=typeof e)&&(!!e.startsWith("candidate:")&&e.substring(10).trim().split(/\s+/).length>=8)}}const f=Object.freeze({BOOLEAN:1,INTEGER:2,BIT_STRING:3,OCTET_STRING:4,NULL:5,OID:6,UTF8_STRING:12,PRINTABLE_STRING:19,IA5_STRING:22,UTC_TIME:23,GENERALIZED_TIME:24,SEQUENCE:48,SET:49});function p(e){if(e<128)return Buffer.from([e]);const t=[];let r=e;for(;r>0;)t.unshift(255&r),r>>>=8;return Buffer.from([128|t.length,...t])}function m(e,t){return Buffer.concat([Buffer.from([e]),p(t.length),t])}function E(e){let t=0;for(;t<e.length-1&&0===e[t];)t++;let r=e.slice(t);return 128&r[0]&&(r=Buffer.concat([Buffer.from([0]),r])),m(f.INTEGER,r)}function g(e){const t=[];let r=e;for(;r>0;)t.unshift(255&r),r=Math.floor(r/256);return 128&t[0]&&t.unshift(0),m(f.INTEGER,Buffer.from(t))}function I(e){const t=e.split(".").map(Number);if(t.length<2)throw new Error(`Invalid OID: ${e}`);const r=[40*t[0]+t[1]];for(let e=2;e<t.length;e++){let s=t[e];const i=[127&s];for(s=Math.floor(s/128);s>0;)i.unshift(127&s|128),s=Math.floor(s/128);r.push(...i)}return m(f.OID,Buffer.from(r))}function T(e){return m(f.SEQUENCE,Buffer.concat(e))}function C(e){const t=e.getUTCFullYear(),r=(e,t=2)=>String(e).padStart(t,"0"),s=r(e.getUTCMonth()+1),i=r(e.getUTCDate()),n=r(e.getUTCHours()),a=r(e.getUTCMinutes()),o=r(e.getUTCSeconds());if(t<2050){const e=r(t%100);return m(f.UTC_TIME,Buffer.from(`${e}${s}${i}${n}${a}${o}Z`,"ascii"))}return m(f.GENERALIZED_TIME,Buffer.from(`${t}${s}${i}${n}${a}${o}Z`,"ascii"))}const S=Object.freeze({ecPublicKey:"1.2.840.10045.2.1",prime256v1:"1.2.840.10045.3.1.7",ecdsaWithSHA256:"1.2.840.10045.4.3.2",commonName:"2.5.4.3"});function y(){return T([I(S.ecdsaWithSHA256)])}function B(e={}){const t=e.commonName||`WebRTC-${a.randomBytes(8).toString("hex")}`,r=e.days||30,{publicKey:s,privateKey:i}=a.generateKeyPairSync("ec",{namedCurve:"prime256v1"}),n=s.export({type:"spki",format:"der"}),o=e.notBefore||new Date(Date.now()-864e5),c=new Date(o.getTime()+24*r*60*60*1e3),h=a.randomBytes(20);h[0]&=127,0===h[0]&&(h[0]=1);const d=function(e){const t=T([I(S.commonName),(r=e,m(f.UTF8_STRING,Buffer.from(r,"utf8")))]);var r,s;return T([(s=[t],m(f.SET,Buffer.concat(s)))])}(t),l=T([(u=g(2),m(160,u)),E(h),y(),d,T([C(o),C(c)]),d,n]);var u;const p=a.sign("sha256",l,i);var B;return{certDer:T([l,y(),(B=p,m(f.BIT_STRING,Buffer.concat([Buffer.from([0]),B])))]),privateKey:i,publicKey:s,notBefore:o,notAfter:c}}function R(e,t="sha-256"){const r=t.replace("-","").toLowerCase();return a.createHash(r).update(e).digest("hex").toUpperCase().match(/.{2}/g).join(":")}function A(e,t="sha-256"){return R(e,t)}class w{#p;#m;#E;#g;#I;constructor(e){this.#p=e.certDer||null,this.#m=e.privateKey,this.#E=e.publicKey,this.#g=e.expires,this.#I=null}getCertificateDer(){return this.#p}get expires(){return this.#g}getFingerprints(){if(!this.#p)throw new Error("Certificate has no DER encoding; cannot compute fingerprint");if(!this.#I){const e=this.#p,t=["sha-256","sha-384","sha-512"];this.#I=t.map(t=>({algorithm:t,value:A(e,t)}))}return this.#I.map(e=>({...e}))}getPrivateKeyObject(){return this.#T(this.#m,"private")}#T(e,t){return e&&"object"==typeof e&&e.type?e:"private"===t?a.createPrivateKey(e):a.createPublicKey(e)}getPrivateKey(){return this.#T(this.#m,"private").export({type:"pkcs8",format:"pem"})}getPublicKey(){return this.#T(this.#E,"public").export({type:"spki",format:"pem"})}toPEM(){const e=this.#p?`-----BEGIN CERTIFICATE-----\n${this.#p.toString("base64").match(/.{1,64}/g).join("\n")}\n-----END CERTIFICATE-----\n`:this.getPublicKey();return{pemPrivateKey:this.getPrivateKey(),pemCertificate:e}}isExpired(){return Date.now()>this.#g}static async generateCertificate(e={}){return new Promise((t,r)=>{try{let s;if(e.expires)s=e.expires;else{const t=e.days||30;s=Date.now()+24*t*60*60*1e3}setImmediate(()=>{try{const r=function(e={}){const{name:t,days:r=30}=e,{certDer:s,privateKey:i,publicKey:n,notAfter:a}=B({commonName:t,days:r});return{certDer:s,privateKey:i,publicKey:n,expires:a.getTime(),hash:"sha256"}}({name:e.name||"webrtc",days:Math.ceil((s-Date.now())/864e5),hash:e.hash||"sha256"});r.expires=s;const i=new w(r);t(i)}catch(e){r(e)}})}catch(e){r(e)}})}static fromPEM(e,t,r){if("string"!=typeof e||0===e.length)throw new TypeError("pemPrivateKey must be a non-empty string");if("string"!=typeof t||0===t.length)throw new TypeError("pemCertificate must be a non-empty string");const s=r||Date.now()+2592e6;let i=null,n=t;const o=t.match(/-----BEGIN CERTIFICATE-----([\s\S]+?)-----END CERTIFICATE-----/);return o&&(i=Buffer.from(o[1].replace(/\s/g,""),"base64"),n=a.createPublicKey(a.createPrivateKey(e))),new w({certDer:i,privateKey:e,publicKey:n,expires:s,hash:"sha256"})}static isSupportedKeyParams(e){if(!e||"object"!=typeof e)return!1;if("RSA"===e.type){const t=e.rsaModulusLength||2048;return t>=1024&&t<=4096}if("ECDSA"===e.type){const t=e.namedCurve;return["P-256","P-384","P-521"].includes(t)}return!1}}const N=Object.freeze({CONNECTING:"connecting",OPEN:"open",CLOSING:"closing",CLOSED:"closed"}),b=Object.freeze({SEND:Symbol("rtcdatachannel:send"),RECEIVE:Symbol("rtcdatachannel:receive"),OPEN:Symbol("rtcdatachannel:open"),SET_ID:Symbol("rtcdatachannel:setId")});class O extends t.EventEmitter{#C;#S;#y;#B;#R;#A;#w;#N;#b;#O;#D;#U;constructor(e,t={}){if(super(),"string"!=typeof e)throw new TypeError("label must be a string");this.#C=e,this.#S=void 0===t.ordered||t.ordered,this.#y=t.maxPacketLifeTime||null,this.#B=t.maxRetransmits||null,this.#R=t.protocol||"",this.#A=t.negotiated||!1,this.#w=void 0!==t.id?t.id:null,this.#N=N.CONNECTING,this.#b=0,this.#O=0,this.#D="arraybuffer",this.#U=!1,this.on(b.SET_ID,e=>{this.#w=e}),this.on(b.OPEN,()=>{this.#U=!0,this.#v(N.OPEN)}),this.on(b.RECEIVE,(e,t)=>{this.#k(e,t)})}get label(){return this.#C}get ordered(){return this.#S}get maxPacketLifeTime(){return this.#y}get maxRetransmits(){return this.#B}get protocol(){return this.#R}get negotiated(){return this.#A}get id(){return this.#w}get readyState(){return this.#N}get bufferedAmount(){return this.#b}get bufferedAmountLowThreshold(){return this.#O}set bufferedAmountLowThreshold(e){this.#O=e}get binaryType(){return this.#D}set binaryType(e){if("arraybuffer"!==e&&"blob"!==e)throw new TypeError('binaryType must be "arraybuffer" or "blob"');this.#D=e}get reliable(){return this.#S&&null===this.#y&&null===this.#B}send(e){if(this.#N!==N.OPEN)throw new Error('RTCDataChannel.readyState is not "open"');let t,r,s=0;if("string"==typeof e)t=Buffer.from(e,"utf8"),s=t.length,r=!1;else if(e instanceof ArrayBuffer)t=Buffer.from(e),s=e.byteLength,r=!0;else if(ArrayBuffer.isView(e))t=Buffer.from(e.buffer,e.byteOffset,e.byteLength),s=e.byteLength,r=!0;else{if(!Buffer.isBuffer(e))throw e&&"function"==typeof e.arrayBuffer?new Error("Blob sending not yet implemented"):new TypeError("Invalid data type");t=e,s=e.length,r=!0}if(!this.#U)throw new Error("Data channel not connected to a transport");this.#b+=s;try{this.emit(b.SEND,t,r),this.#b=Math.max(0,this.#b-s),this.#L()}catch(e){throw this.#b=Math.max(0,this.#b-s),this.emit("error",e),e}}#L(){this.#b<=this.#O&&this.emit("bufferedamountlow")}close(){this.#N!==N.CLOSING&&this.#N!==N.CLOSED&&(this.#v(N.CLOSING),setImmediate(()=>{this.#N===N.CLOSING&&this.#v(N.CLOSED)}))}#v(e){this.#N!==e&&(this.#N=e,e===N.OPEN?this.emit("open"):e===N.CLOSING?this.emit("closing"):e===N.CLOSED&&this.emit("close"))}#k(e,t){let r;r=t?"arraybuffer"===this.#D?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e:e.toString("utf8"),this.emit("message",{data:r})}}const D=Object.freeze({OFFER:"offer",PRANSWER:"pranswer",ANSWER:"answer",ROLLBACK:"rollback"});class U{#P;#_;constructor(e={}){if(this.#P=e.type||null,this.#_=e.sdp||null,this.#P&&!Object.values(D).includes(this.#P))throw new TypeError(`Invalid SDP type: ${this.#P}`)}get type(){return this.#P}set type(e){if(e&&!Object.values(D).includes(e))throw new TypeError(`Invalid SDP type: ${e}`);this.#P=e}get sdp(){return this.#_}set sdp(e){this.#_=e}toJSON(){return{type:this.#P,sdp:this.#_}}}function v(e){const{iceUfrag:t,icePwd:r,fingerprint:s,setup:i="actpass",candidates:n=[],sctpPort:o=5e3,maxMessageSize:c=262144}=e,h=[];h.push("v=0");const d=a.randomBytes(4).readUInt32BE(0);h.push(`o=- ${d} 2 IN IP4 127.0.0.1`),h.push("s=-"),h.push("t=0 0"),h.push("a=group:BUNDLE 0"),h.push("a=msid-semantic: WMS"),h.push("m=application 9 UDP/DTLS/SCTP webrtc-datachannel"),h.push("c=IN IP4 0.0.0.0"),h.push("a=ice-ufrag:"+t),h.push("a=ice-pwd:"+r),h.push("a=ice-options:trickle"),s&&h.push(`a=fingerprint:${s.algorithm} ${s.value}`),h.push(`a=setup:${i}`),h.push("a=mid:0"),h.push("a=sctp-port:"+o),h.push("a=max-message-size:"+c);for(const e of n){const t=e.sdp||e.candidate;t&&h.push("a="+(t.startsWith("candidate:")?t:"candidate:"+t))}return h.join("\r\n")+"\r\n"}function k(e){const t=(e.startsWith("candidate:")?e.slice(10):e).split(/\s+/);return t.length<8?null:{candidate:e.startsWith("candidate:")?e:"candidate:"+e,foundation:t[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10)>>>0,address:t[4],port:parseInt(t[5],10),type:t[7]}}const L=554869826,P=Object.freeze({BINDING_REQUEST:1,BINDING_SUCCESS:257,BINDING_ERROR:273}),_=Object.freeze({MAPPED_ADDRESS:1,USERNAME:6,MESSAGE_INTEGRITY:8,ERROR_CODE:9,XOR_MAPPED_ADDRESS:32,PRIORITY:36,USE_CANDIDATE:37,FINGERPRINT:32808,ICE_CONTROLLED:32809,ICE_CONTROLLING:32810});function x(e){return e+3&-4}const H=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})();class M{type;transactionId;attrs;constructor(e,t){this.type=e,this.transactionId=t||a.randomBytes(12),this.attrs=[]}addAttr(e,t){return this.attrs.push({type:e,value:t}),this}addUsername(e){return this.addAttr(_.USERNAME,Buffer.from(e,"utf8"))}addPriority(e){const t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),this.addAttr(_.PRIORITY,t)}addIceControlling(e){return this.addAttr(_.ICE_CONTROLLING,e)}addIceControlled(e){return this.addAttr(_.ICE_CONTROLLED,e)}addUseCandidate(){return this.addAttr(_.USE_CANDIDATE,Buffer.alloc(0))}addXorMappedAddress(e,t){return this.addAttr(_.XOR_MAPPED_ADDRESS,function(e,t){const r=Buffer.alloc(8);r.writeUInt8(0,0),r.writeUInt8(1,1),r.writeUInt16BE(8466^t,2);const s=e.split(".").map(Number),i=(s[0]<<24|s[1]<<16|s[2]<<8|s[3])>>>0;return r.writeUInt32BE((i^L)>>>0,4),r}(e,t,this.transactionId))}#x(){const e=[];for(const t of this.attrs){const r=Buffer.alloc(4);r.writeUInt16BE(t.type,0),r.writeUInt16BE(t.value.length,2);const s=Buffer.alloc(x(t.value.length));t.value.copy(s,0),e.push(r,s)}return Buffer.concat(e)}#H(e){const t=Buffer.alloc(20);return t.writeUInt16BE(this.type,0),t.writeUInt16BE(e,2),t.writeUInt32BE(L,4),this.transactionId.copy(t,8),t}build(e){let t=this.#x();if(e){const r=t.length+24,s=this.#H(r),i=a.createHmac("sha1",Buffer.from(e,"utf8")).update(Buffer.concat([s,t])).digest(),n=Buffer.alloc(4);n.writeUInt16BE(_.MESSAGE_INTEGRITY,0),n.writeUInt16BE(20,2),t=Buffer.concat([t,n,i])}const r=t.length+8,s=this.#H(r),i=(1398035790^function(e){let t=4294967295;for(let r=0;r<e.length;r++)t=H[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}(Buffer.concat([s,t])))>>>0,n=Buffer.alloc(8);return n.writeUInt16BE(_.FINGERPRINT,0),n.writeUInt16BE(4,2),n.writeUInt32BE(i,4),t=Buffer.concat([t,n]),Buffer.concat([this.#H(t.length),t])}}const F=Object.freeze({CHANGE_CIPHER_SPEC:20,ALERT:21,HANDSHAKE:22,APPLICATION_DATA:23}),K=Object.freeze({HELLO_REQUEST:0,CLIENT_HELLO:1,SERVER_HELLO:2,HELLO_VERIFY_REQUEST:3,CERTIFICATE:11,SERVER_KEY_EXCHANGE:12,CERTIFICATE_REQUEST:13,SERVER_HELLO_DONE:14,CERTIFICATE_VERIFY:15,CLIENT_KEY_EXCHANGE:16,FINISHED:20}),q=Object.freeze({WARNING:1,FATAL:2}),G=Object.freeze({CLOSE_NOTIFY:0,HANDSHAKE_FAILURE:40,BAD_CERTIFICATE:42,DECRYPT_ERROR:51,INTERNAL_ERROR:80}),$=49195,z=Object.freeze({secp256r1:23}),j=Object.freeze({uncompressed:0}),V=Object.freeze({sha256:4,sha384:5,sha512:6}),W=Object.freeze({rsa:1,ecdsa:3}),Y=Object.freeze({ecdsa_sign:64,rsa_sign:1}),X=Object.freeze({SUPPORTED_GROUPS:10,EC_POINT_FORMATS:11,SIGNATURE_ALGORITHMS:13,EXTENDED_MASTER_SECRET:23,RENEGOTIATION_INFO:65281}),Q=Object.freeze({CLIENT:"client finished",SERVER:"server finished"});function Z(e){return Buffer.from([e>>16&255,e>>8&255,255&e])}function J(e,t){return e[t]<<16|e[t+1]<<8|e[t+2]}function ee(e){return Buffer.concat([Buffer.from([e.length]),e])}function te(e){const t=Buffer.alloc(2);return t.writeUInt16BE(e.length,0),Buffer.concat([t,e])}function re(e){return Buffer.concat([Z(e.length),e])}function se(e,t,r){const s=Buffer.alloc(12);return s.writeUInt8(e,0),Z(r.length).copy(s,1),s.writeUInt16BE(t,4),Z(0).copy(s,6),Z(r.length).copy(s,9),Buffer.concat([s,r])}function ie(e,t,r,s){return function(e,t,r,s){const i=[];let n=0,o=r;for(;n<s;){o=a.createHmac(e,t).update(o).digest();const s=a.createHmac(e,t).update(Buffer.concat([o,r])).digest();i.push(s),n+=s.length}return Buffer.concat(i).slice(0,s)}("sha256",e,Buffer.concat([Buffer.from(t,"ascii"),r]),s)}function ne(e,t,r){return ie(e,"master secret",Buffer.concat([t,r]),48)}function ae(e,t){return ie(e,"extended master secret",t,48)}function oe(e,t,r,s,i){const n=Buffer.alloc(13);return n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6),n.writeUInt8(r,8),n.writeUInt16BE(s,9),n.writeUInt16BE(i,11),n}class ce{#M;#F;constructor(e,t){this.#M=e,this.#F=t}encrypt(e,t,r,s,i){const n=Buffer.alloc(8);n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6);const o=Buffer.concat([this.#F,n]),c=oe(e,t,r,s,i.length),h=a.createCipheriv("aes-128-gcm",this.#M,o);h.setAAD(c);const d=Buffer.concat([h.update(i),h.final()]),l=h.getAuthTag();return Buffer.concat([n,d,l])}decrypt(e,t,r,s,i){const n=i.slice(0,8),o=i.slice(i.length-16),c=i.slice(8,i.length-16),h=Buffer.concat([this.#F,n]),d=oe(e,t,r,s,c.length),l=a.createDecipheriv("aes-128-gcm",this.#M,h);return l.setAAD(d),l.setAuthTag(o),Buffer.concat([l.update(c),l.final()])}}const he=Object.freeze({CLIENT:"client",SERVER:"server"}),de=Object.freeze({NEW:"new",HANDSHAKING:"handshaking",CONNECTED:"connected",CLOSED:"closed",FAILED:"failed"});class le extends t.EventEmitter{role;state;#p;#m;#K;#q;#G;#$;#z;#j;#V;#W;#Y;#X;#Q;#Z;#J;#ee;#te;#re;#se;#ie;#ne;#ae;#oe;#ce;#he;#de;#le;#ue;constructor(e){super(),this.role=e.role,this.#p=e.certDer,this.#m=e.privateKey,this.#K=e.verifyFingerprint||null,this.#q=e.output,this.state=de.NEW,this.#G=0,this.#$=0,this.#z=0,this.#j=null,this.#V=null,this.#W=!1,this.#Y=null,this.#X=null,this.#Q=Buffer.alloc(0),this.#Z=null,this.#J=null,this.#ee=null,this.#te=null,this.#re=!1,this.#se=[],this.#ie=new Map,this.#ne=0,this.#ae=[],this.#oe=null,this.#ce=0,this.#he=!1,this.#ue=!1}start(){this.state===de.NEW&&(this.state=de.HANDSHAKING,this.role===he.CLIENT&&(this.#Y=this.#fe(),this.#pe()))}#fe(){const e=a.randomBytes(32);return e.writeUInt32BE(Math.floor(Date.now()/1e3),0),e}#me(e){const t=[];for(const r of e){const e=this.#z++,s=se(r.type,e,r.body);this.#se.push(s);const i=r.body.length;let n=0;do{const s=r.body.slice(n,n+1200),a=Buffer.alloc(12);a.writeUInt8(r.type,0),Z(i).copy(a,1),a.writeUInt16BE(e,4),Z(n).copy(a,6),Z(s.length).copy(a,9);const o=Buffer.concat([a,s]);t.push({type:F.HANDSHAKE,payload:o}),n+=s.length}while(n<i)}this.#ae=t,this.#ce=0,this.#Ee(),this.#ge()}#Ee(){for(const e of this.#ae)this.#Ie(e.type,e.payload)}#Te(){this.#Ie(F.CHANGE_CIPHER_SPEC,Buffer.from([1])),this.#G=1,this.#$=0,this.#W=!0}#Ie(e,t){let r=t;const s=this.#$++;this.#W&&this.#j&&(r=this.#j.encrypt(this.#G,s,e,65277,t));const i=function(e,t,r,s,i=65277){const n=Buffer.alloc(13);return n.writeUInt8(e,0),n.writeUInt16BE(i,1),n.writeUInt16BE(t,3),n.writeUIntBE(r,5,6),n.writeUInt16BE(s.length,11),Buffer.concat([n,s])}(e,this.#G,s,r,65277);this.#q(i)}#ge(){this.#Ce(),this.#oe=setTimeout(()=>{this.#he||this.state!==de.HANDSHAKING||(this.#ce>=10?this.#Se(new Error("DTLS handshake timed out")):(this.#ce++,this.#Ee(),this.#ge()))},1e3*Math.pow(2,this.#ce)),this.#oe.unref&&this.#oe.unref()}#Ce(){this.#oe&&(clearTimeout(this.#oe),this.#oe=null)}handlePacket(e){if(this.state===de.CLOSED||this.state===de.FAILED)return;let t;try{t=function(e){const t=[];let r=0;for(;r+13<=e.length;){const s=e.readUInt8(r),i=e.readUInt16BE(r+1),n=e.readUInt16BE(r+3),a=e.readUIntBE(r+5,6),o=e.readUInt16BE(r+11),c=r+13;if(c+o>e.length)break;t.push({type:s,version:i,epoch:n,seq:a,fragment:e.slice(c,c+o)}),r=c+o}return t}(e)}catch(e){return}for(const e of t)try{this.#ye(e)}catch(e){return void this.#Se(e instanceof Error?e:new Error(String(e)))}}#ye(e){let t=e.fragment;if(e.epoch>=1){if(!this.#V)return;t=this.#V.decrypt(e.epoch,e.seq,e.type,e.version,e.fragment)}switch(e.type){case F.HANDSHAKE:this.#Be(t);break;case F.CHANGE_CIPHER_SPEC:break;case F.APPLICATION_DATA:this.state===de.CONNECTED&&this.emit("data",t);break;case F.ALERT:this.#Re(t)}}#Re(e){if(e.length<2)return;const t=e[0],r=e[1];r===G.CLOSE_NOTIFY?this.close():t===q.FATAL&&this.#Se(new Error(`DTLS fatal alert: ${r}`))}#Be(e){const t=function(e){const t=e.readUInt8(0),r=J(e,1),s=e.readUInt16BE(4),i=J(e,6),n=J(e,9);return{msgType:t,length:r,messageSeq:s,fragmentOffset:i,fragmentLength:n,body:e.slice(12,12+n)}}(e);let r=this.#ie.get(t.messageSeq);for(r||(r={type:t.msgType,length:t.length,data:Buffer.alloc(t.length),received:0,ranges:[]},this.#ie.set(t.messageSeq,r)),t.body.copy(r.data,t.fragmentOffset),r.received=Math.max(r.received,t.fragmentOffset+t.fragmentLength);;){const e=this.#ie.get(this.#ne);if(!e||e.received<e.length)break;this.#ie.delete(this.#ne),this.#ne++,this.#Ae(e.type,e.data)}}#we(e,t){const r=this.#ne-1;this.#se.push(se(e,r,t))}#Ae(e,t){this.role===he.CLIENT?this.#Ne(e,t):this.#be(e,t)}#Oe(){const e=a.createHash("sha256");for(const t of this.#se)e.update(t);return e.digest()}#De(){return Buffer.concat(this.#se)}#pe(){const e=this.#Ue();if(0===this.#Q.length){const t=this.#z++,r=se(K.CLIENT_HELLO,t,e);this.#ae=[{type:F.HANDSHAKE,payload:r}],this.#Ee(),this.#ge()}else{const t=this.#z++,r=se(K.CLIENT_HELLO,t,e);this.#se.push(r),this.#ae=[{type:F.HANDSHAKE,payload:r}],this.#ce=0,this.#Ee(),this.#ge()}}#Ue(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#Y),e.push(ee(Buffer.alloc(0))),e.push(ee(this.#Q));const t=Buffer.alloc(2);return t.writeUInt16BE($,0),e.push(te(t)),e.push(ee(Buffer.from([0]))),e.push(te(this.#ve())),Buffer.concat(e)}#ve(){const e=[],t=Buffer.alloc(2);t.writeUInt16BE(z.secp256r1,0),e.push(this.#ke(X.SUPPORTED_GROUPS,te(t))),e.push(this.#ke(X.EC_POINT_FORMATS,ee(Buffer.from([j.uncompressed]))));const r=Buffer.from([V.sha256,W.ecdsa]);return e.push(this.#ke(X.SIGNATURE_ALGORITHMS,te(r))),e.push(this.#ke(X.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),Buffer.concat(e)}#ke(e,t){const r=Buffer.alloc(4);return r.writeUInt16BE(e,0),r.writeUInt16BE(t.length,2),Buffer.concat([r,t])}#Ne(e,t){switch(e){case K.HELLO_VERIFY_REQUEST:{const e=t.readUInt8(2);this.#Q=t.slice(3,3+e),this.#Ce(),this.#pe();break}case K.SERVER_HELLO:this.#we(e,t),this.#Le(t);break;case K.CERTIFICATE:this.#we(e,t),this.#ee=this.#Pe(t);break;case K.SERVER_KEY_EXCHANGE:this.#we(e,t),this.#_e(t);break;case K.CERTIFICATE_REQUEST:this.#ue=!0,this.#we(e,t);break;case K.SERVER_HELLO_DONE:this.#we(e,t),this.#Ce(),this.#xe();break;case K.FINISHED:this.#He(t,Q.SERVER),this.#we(e,t),this.#Me()}}#Le(e){let t=2;this.#X=e.slice(t,t+32),t+=32,t+=1+e.readUInt8(t);const r=e.readUInt16BE(t);if(t+=2,r!==$)throw new Error(`Server chose unsupported cipher suite 0x${r.toString(16)}`);if(t+=1,t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===X.EXTENDED_MASTER_SECRET&&(this.#re=!0),t+=s}}}#xe(){this.#Z=a.createECDH("prime256v1"),this.#Z.generateKeys();const e=this.#Z.getPublicKey(),t=this.#Z.computeSecret(this.#te),r=ee(e),s=this.#ue;let i=null,n=Buffer.alloc(0);const o=s?this.#z+1:this.#z;s&&(i=this.#Fe(),n=se(K.CERTIFICATE,this.#z,i));const c=se(K.CLIENT_KEY_EXCHANGE,o,r);if(this.#re){const e=a.createHash("sha256");for(const t of this.#se)e.update(t);s&&e.update(n),e.update(c);const r=e.digest();this.#J=ae(t,r)}else this.#J=ne(t,this.#Y,this.#X);this.#Ke();const h=[];if(s&&h.push({type:K.CERTIFICATE,body:i}),h.push({type:K.CLIENT_KEY_EXCHANGE,body:r}),s){const e=Buffer.concat([...this.#se,n,c]),t=a.sign("sha256",e,{key:this.#m,dsaEncoding:"der"}),r=Buffer.concat([Buffer.from([V.sha256,W.ecdsa]),te(t)]);h.push({type:K.CERTIFICATE_VERIFY,body:r})}this.#me(h),this.#Te(),this.#qe(Q.CLIENT)}#be(e,t){switch(e){case K.CLIENT_HELLO:this.#Ge(t);break;case K.CERTIFICATE:this.#we(e,t),this.#ee=this.#Pe(t);break;case K.CLIENT_KEY_EXCHANGE:{this.#we(e,t);const r=t.readUInt8(0);this.#te=t.slice(1,1+r);const s=this.#Z.computeSecret(this.#te);this.#re?this.#J=ae(s,this.#Oe()):this.#J=ne(s,this.#Y,this.#X),this.#Ke();break}case K.CERTIFICATE_VERIFY:this.#$e(t),this.#we(e,t);break;case K.FINISHED:this.#He(t,Q.CLIENT),this.#we(e,t),this.#Te(),this.#qe(Q.SERVER),this.#Me()}}#Ge(e){let t=2;const r=e.slice(t,t+32);t+=32,t+=1+e.readUInt8(t);const s=e.readUInt8(t),i=e.slice(t+1,t+1+s);t+=1+s;const n=e.readUInt16BE(t),a=e.slice(t+2,t+2+n);t+=2+n,t+=1+e.readUInt8(t);let o=!1,c=!1;for(let e=0;e+1<a.length;e+=2)255===a.readUInt16BE(e)&&(c=!0);if(t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===X.EXTENDED_MASTER_SECRET&&(o=!0),r===X.RENEGOTIATION_INFO&&(c=!0),t+=s}}if(this.#le=c,0===i.length)return this.#Y=r,this.#ze(this.#je(r)),this.#ie.clear(),void(this.#ne=1);const h=this.#je(r);if(!i.equals(h))return this.#ze(h),this.#ie.clear(),void(this.#ne=1);this.#Y=r,this.#re=o,this.#we(K.CLIENT_HELLO,e),this.#Ve()}#je(e){return this.#de||(this.#de=a.randomBytes(32)),a.createHmac("sha256",this.#de).update(e).digest().slice(0,20)}#ze(e){const t=Buffer.concat([Buffer.from([254,255]),ee(e)]),r=se(K.HELLO_VERIFY_REQUEST,0,t);this.#Ie(F.HANDSHAKE,r),this.#z=1}#Ve(){this.#X=this.#fe(),this.#Z=a.createECDH("prime256v1"),this.#Z.generateKeys();const e=this.#Z.getPublicKey(),t=this.#We(),r=this.#Fe(),s=Buffer.concat([Buffer.from([3]),(()=>{const e=Buffer.alloc(2);return e.writeUInt16BE(z.secp256r1,0),e})(),ee(e)]),i=Buffer.concat([this.#Y,this.#X,s]),n=a.sign("sha256",i,{key:this.#m,dsaEncoding:"der"}),o=Buffer.concat([s,Buffer.from([V.sha256,W.ecdsa]),te(n)]),c=ee(Buffer.from([Y.ecdsa_sign,Y.rsa_sign])),h=te(Buffer.from([V.sha256,W.ecdsa])),d=te(Buffer.alloc(0)),l=Buffer.concat([c,h,d]),u=Buffer.alloc(0);this.#me([{type:K.SERVER_HELLO,body:t},{type:K.CERTIFICATE,body:r},{type:K.SERVER_KEY_EXCHANGE,body:o},{type:K.CERTIFICATE_REQUEST,body:l},{type:K.SERVER_HELLO_DONE,body:u}])}#We(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#X),e.push(ee(Buffer.alloc(0)));const t=Buffer.alloc(2);t.writeUInt16BE($,0),e.push(t),e.push(Buffer.from([0]));const r=[];return this.#re&&r.push(this.#ke(X.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),r.push(this.#ke(X.EC_POINT_FORMATS,ee(Buffer.from([j.uncompressed])))),this.#le&&r.push(this.#ke(X.RENEGOTIATION_INFO,ee(Buffer.alloc(0)))),e.push(te(Buffer.concat(r))),Buffer.concat(e)}#$e(e){const t=e.readUInt16BE(2),r=e.slice(4,4+t),s=this.#De(),i=this.#Ye(this.#ee);if(!a.verify("sha256",s,{key:i,dsaEncoding:"der"},r))throw new Error("Client CertificateVerify signature invalid")}#Fe(){const e=re(this.#p);return re(e)}#Pe(e){let t=3;if(t+3>3+J(e,0))return null;const r=J(e,t);t+=3;const s=e.slice(t,t+r);if(this.#K){const e={algorithm:"sha-256",value:R(s,"sha-256")};if(!this.#K(e,s))throw new Error("Remote certificate fingerprint mismatch")}return s}#_e(e){let t=0;const r=e.readUInt8(t);t+=1;const s=e.readUInt16BE(t);if(t+=2,3!==r||s!==z.secp256r1)throw new Error("Unsupported ECDHE curve from server");const i=e.readUInt8(t);t+=1;const n=e.slice(t,t+i);t+=i,this.#te=n;const o=e.slice(0,t);t+=2;const c=e.readUInt16BE(t);t+=2;const h=e.slice(t,t+c),d=Buffer.concat([this.#Y,this.#X,o]),l=this.#Ye(this.#ee);if(!a.verify("sha256",d,{key:l,dsaEncoding:"der"},h))throw new Error("ServerKeyExchange signature invalid")}#Ye(e){return new a.X509Certificate(e).publicKey}#Ke(){const{clientKey:e,serverKey:t,clientIV:r,serverIV:s}=function(e,t,r){const s=ie(e,"key expansion",Buffer.concat([r,t]),40);let i=0;return{clientKey:s.slice(i,i+=16),serverKey:s.slice(i,i+=16),clientIV:s.slice(i,i+=4),serverIV:s.slice(i,i+=4)}}(this.#J,this.#Y,this.#X);this.role===he.CLIENT?(this.#j=new ce(e,r),this.#V=new ce(t,s)):(this.#j=new ce(t,s),this.#V=new ce(e,r))}#qe(e){const t=ie(this.#J,e,this.#Oe(),12),r=this.#z++,s=se(K.FINISHED,r,t);this.#se.push(s),this.#Ie(F.HANDSHAKE,s)}#He(e,t){const r=ie(this.#J,t,this.#Oe(),12);if(!a.timingSafeEqual(e,r))throw new Error("Peer Finished verify_data mismatch")}#Me(){this.#he||(this.#he=!0,this.#Ce(),this.state=de.CONNECTED,this.emit("connect"))}send(e){if(this.state!==de.CONNECTED)throw new Error("DTLS connection not established");this.#Ie(F.APPLICATION_DATA,e)}close(){if(this.state!==de.CLOSED&&this.state!==de.FAILED){try{this.#W&&this.#Ie(F.ALERT,Buffer.from([q.WARNING,G.CLOSE_NOTIFY]))}catch(e){}this.#Ce(),this.state=de.CLOSED,this.emit("close")}}#Se(e){this.state!==de.FAILED&&this.state!==de.CLOSED&&(this.#Ce(),this.state=de.FAILED,this.emit("error",e))}getRemoteCertificate(){return this.#ee}}const ue=554869826;class fe extends t.EventEmitter{#Xe;#Qe;#Ze;#Je;#et;#tt;#rt;#st;#it;#nt;#at;#ot;#ct;constructor(e){super(),this.#Xe=e.server,this.#Qe=e.port,this.#Ze=e.username,this.#Je=e.credential,this.#et=null,this.#tt=new Map,this.#rt=null,this.#st=null,this.#it=!0===e.secure,this.#nt=(e.transport||"udp").toLowerCase(),this.#at=null,this.#ot=null,this.#ct=Buffer.alloc(0)}async connect(){if(!this.#et&&!this.#ot)return this.#it&&"tcp"===this.#nt?this.#ht():new Promise((e,t)=>{const r=o.createSocket("udp4");if(this.#et=r,r.on("error",e=>{console.error("STUN socket error:",e),t(e)}),this.#it){const s=B({commonName:"nodertc-turn-client"}),i=new le({role:he.CLIENT,certDer:s.certDer,privateKey:s.privateKey,verifyFingerprint:()=>!0,output:e=>{r.send(e,this.#Qe,this.#Xe,()=>{})}});this.#at=i,r.on("message",e=>i.handlePacket(e)),i.on("data",e=>this.#dt(e,this.#lt())),i.on("connect",()=>e()),i.on("error",e=>t(e)),r.bind(()=>i.start())}else r.on("message",(e,t)=>{this.#dt(e,t)}),r.bind(()=>e())})}#ht(){return new Promise((e,t)=>{const r=h.connect({host:this.#Xe,port:this.#Qe,rejectUnauthorized:!1},()=>e());this.#ot=r,r.on("data",e=>this.#ut(e)),r.on("error",e=>t(e))})}#ut(e){for(this.#ct=this.#ct.length?Buffer.concat([this.#ct,e]):e;this.#ct.length>=20;){const e=20+this.#ct.readUInt16BE(2);if(this.#ct.length<e)break;const t=this.#ct.subarray(0,e);this.#ct=this.#ct.subarray(e),this.#dt(t,this.#lt())}}#lt(){return{address:this.#Xe,family:"IPv4",port:this.#Qe,size:0}}#ft(e,t){if(this.#ot)this.#ot.write(e,e=>{e&&t(e)});else if(this.#at)try{this.#at.send(e)}catch(e){t(e instanceof Error?e:new Error(String(e)))}else this.#et.send(e,this.#Qe,this.#Xe,e=>{e&&t(e)})}async getReflexiveAddress(){await this.connect();const e=a.randomBytes(12),t=this.#pt(e);return new Promise((r,s)=>{const i=setTimeout(()=>{this.#tt.delete(e.toString("hex")),s(new Error("STUN request timeout"))},5e3);this.#tt.set(e.toString("hex"),{resolve:e=>{clearTimeout(i),r(e)},reject:e=>{clearTimeout(i),s(e)}}),this.#ft(t,t=>{clearTimeout(i),this.#tt.delete(e.toString("hex")),s(t)})})}async allocateRelay(e=600){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");await this.connect();let t=a.randomBytes(12),r=this.#mt(t,e);try{return await this.#Et(r,t,"allocate")}catch(s){if(s instanceof Error&&s.message.includes("401")&&this.#rt&&this.#st)return t=a.randomBytes(12),r=this.#mt(t,e,!0),await this.#Et(r,t,"allocate");throw s}}async refreshAllocation(e=600){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");return this.#gt("refresh",()=>{const t=a.randomBytes(12);return{transactionId:t,request:this.#It(t,e)}})}async#gt(e,t){const r=t();try{return await this.#Et(r.request,r.transactionId,e)}catch(r){if(r instanceof Error&&r.message.includes("401")&&this.#rt&&this.#st){const r=t();return this.#Et(r.request,r.transactionId,e)}throw r}}async createPermission(e){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");await this.#gt("createPermission",()=>{const t=a.randomBytes(12);return{transactionId:t,request:this.#Tt(t,e)}})}async sendIndication(e,t,r){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");const s=a.randomBytes(12),i=this.#Ct(s,e,t,r);return new Promise((e,t)=>{this.#ft(i,t),e()})}#Et(e,t,r){return new Promise((s,i)=>{const n=setTimeout(()=>{this.#tt.delete(t.toString("hex")),i(new Error(`${r} request timeout`))},5e3);this.#tt.set(t.toString("hex"),{type:r,resolve:e=>{clearTimeout(n),s(e)},reject:e=>{clearTimeout(n),i(e)}}),this.#ft(e,e=>{clearTimeout(n),this.#tt.delete(t.toString("hex")),i(e)})})}#pt(e){const t=Buffer.alloc(20);return t.writeUInt16BE(1,0),t.writeUInt16BE(0,2),t.writeUInt32BE(ue,4),e.copy(t,8),t}#mt(e,t,r=!1){const s=[],i=Buffer.alloc(8);i.writeUInt16BE(25,0),i.writeUInt16BE(4,2),i.writeUInt8(17,4),s.push(i);const n=Buffer.alloc(8);if(n.writeUInt16BE(13,0),n.writeUInt16BE(4,2),n.writeUInt32BE(t,4),s.push(n),r&&this.#rt&&this.#st){const e=this.#St(6,this.#Ze);s.push(e);const t=this.#St(20,this.#rt);s.push(t);const r=this.#St(21,this.#st);s.push(r)}return this.#yt(3,e,s,r)}#Tt(e,t){const r=[],s=this.#Bt(t,0,e);return r.push(s),this.#rt&&this.#st&&(r.push(this.#St(6,this.#Ze)),r.push(this.#St(20,this.#rt)),r.push(this.#St(21,this.#st))),this.#yt(8,e,r,!0)}#Ct(e,t,r,s){const i=[],n=this.#Bt(t,r,e);i.push(n);const a=Buffer.alloc(4+s.length+(4-s.length%4)%4);return a.writeUInt16BE(19,0),a.writeUInt16BE(s.length,2),s.copy(a,4),i.push(a),this.#yt(22,e,i,!1)}#Bt(e,t,r){const s=Buffer.alloc(12);s.writeUInt16BE(18,0),s.writeUInt16BE(8,2),s.writeUInt8(0,4),s.writeUInt8(1,5);const i=8466^t;s.writeUInt16BE(i,6);const n=e.split(".").map(Number),a=(n[0]<<24|n[1]<<16|n[2]<<8|n[3])^ue;return s.writeUInt32BE(a>>>0,8),s}#It(e,t){const r=[],s=Buffer.alloc(8);s.writeUInt16BE(13,0),s.writeUInt16BE(4,2),s.writeUInt32BE(t,4),r.push(s);const i=this.#St(6,this.#Ze);if(r.push(i),this.#rt){const e=this.#St(20,this.#rt);r.push(e)}if(this.#st){const e=this.#St(21,this.#st);r.push(e)}return this.#yt(4,e,r,!0)}#yt(e,t,r,s=!1){let i=Buffer.concat(r);if(s&&this.#Je){const r=Buffer.alloc(20);r.writeUInt16BE(e,0),r.writeUInt16BE(i.length+24,2),r.writeUInt32BE(ue,4),t.copy(r,8);const s=Buffer.concat([r,i]);let n=this.#Je;if(this.#Ze&&this.#rt){const e=`${this.#Ze}:${this.#rt}:${this.#Je}`;n=a.createHash("md5").update(e).digest()}const o=a.createHmac("sha1",n);o.update(s);const c=o.digest(),h=Buffer.alloc(4+c.length);h.writeUInt16BE(8,0),h.writeUInt16BE(c.length,2),c.copy(h,4),i=Buffer.concat([i,h])}const n=Buffer.alloc(20);return n.writeUInt16BE(e,0),n.writeUInt16BE(i.length,2),n.writeUInt32BE(ue,4),t.copy(n,8),Buffer.concat([n,i])}#St(e,t){const r=Buffer.from(t,"utf8"),s=r.length,i=(4-s%4)%4,n=Buffer.alloc(4+s+i);return n.writeUInt16BE(e,0),n.writeUInt16BE(s,2),r.copy(n,4),n}#dt(e,t){if(e.length<20)return;const r=e.readUInt16BE(0),s=e.readUInt16BE(2),i=e.readUInt32BE(4),n=e.slice(8,20);if(i!==ue)return;if(23===r){const t=this.#Rt(e.slice(20,20+s),n);if(t.xorPeerAddress&&t.data){const e={address:t.xorPeerAddress.address,port:t.xorPeerAddress.port,family:t.xorPeerAddress.family||"IPv4"};this.emit("data",t.data,e)}return}const a=n.toString("hex"),o=this.#tt.get(a);if(!o)return;const c=this.#Rt(e.slice(20,20+s),n);if(257===r)c.xorMappedAddress?o.resolve({address:c.xorMappedAddress.address,port:c.xorMappedAddress.port,family:c.xorMappedAddress.family}):c.mappedAddress?o.resolve({address:c.mappedAddress.address,port:c.mappedAddress.port,family:c.mappedAddress.family}):o.reject(new Error("No mapped address in STUN response")),this.#tt.delete(a);else if(259===r)c.xorRelayedAddress?o.resolve({relayedAddress:c.xorRelayedAddress.address,relayedPort:c.xorRelayedAddress.port,lifetime:c.lifetime||600,type:"relay"}):o.reject(new Error("No relayed address in ALLOCATE response")),this.#tt.delete(a);else if(260===r)o.resolve({lifetime:c.lifetime||600}),this.#tt.delete(a);else if(264===r||265===r)o.resolve({ok:!0}),this.#tt.delete(a);else if(!(272&~r)){c.realm&&(this.#rt=c.realm),c.nonce&&(this.#st=c.nonce);const e=c.errorCode||"Unknown error";o.reject(new Error(`STUN error: ${e}`)),this.#tt.delete(a)}}#Rt(e,t){const r={};let s=0;for(;s<e.length&&!(s+4>e.length);){const i=e.readUInt16BE(s),n=e.readUInt16BE(s+2);if(s+=4,s+n>e.length)break;const a=e.slice(s,s+n);switch(i){case 32:r.xorMappedAddress=this.#At(a,t);break;case 22:r.xorRelayedAddress=this.#At(a,t);break;case 18:r.xorPeerAddress=this.#At(a,t);break;case 19:r.data=a;break;case 1:r.mappedAddress=this.#wt(a);break;case 13:r.lifetime=a.readUInt32BE(0);break;case 9:r.errorCode=this.#Nt(a);break;case 20:r.realm=a.toString("utf8"),this.#rt=r.realm;break;case 21:r.nonce=a.toString("utf8"),this.#st=r.nonce}s+=n,s+=(4-n%4)%4}return r}#At(e,t){const r=e.readUInt8(1),s=8466^e.readUInt16BE(2);if(1===r){const t=e.readUInt32BE(4)^ue;return{family:"IPv4",port:s,address:[t>>24&255,t>>16&255,t>>8&255,255&t].join(".")}}return null}#wt(e){const t=e.readUInt8(1),r=e.readUInt16BE(2);if(1===t){const t=e.slice(4,8);return{family:"IPv4",port:r,address:Array.from(t).join(".")}}return null}#Nt(e){return`${100*(7&e.readUInt8(2))+e.readUInt8(3)} ${e.slice(4).toString("utf8")}`}close(){if(this.#at){try{this.#at.close()}catch(e){}this.#at=null}if(this.#ot){try{this.#ot.destroy()}catch(e){}this.#ot=null}this.#et&&(this.#et.close(),this.#et=null),this.#tt.clear()}}const pe={host:126,srflx:100,prflx:110,relay:0};function me(e){const t=e.match(/^(stuns?|turns?):\/?\/?([^:?]+):?(\d+)?(?:\?(.+))?$/);if(!t)return null;const r=t[1],s=t[2],i={};if(t[4])for(const e of t[4].split("&")){if(!e)continue;const t=e.indexOf("=");-1===t?i[e]=!0:i[e.slice(0,t)]=e.slice(t+1)}const n="turns"===r||"stuns"===r?5349:3478;return{scheme:r,protocol:r,host:s,port:parseInt(t[3]||String(n),10),transport:"string"==typeof i.transport?i.transport:"udp",params:i}}class Ee{kind;#et;onMessage;constructor(e){this.kind="host",this.#et=e,this.onMessage=null,e.on("message",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){this.#et.send(e,r,t)}close(){try{this.#et.close()}catch(e){}}}class ge{kind;#bt;onMessage;#Ot;constructor(e){this.kind="relay",this.#bt=e,this.onMessage=null,this.#Ot=new Set,e.on("data",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){const s=`${t}:${r}`;this.#Ot.has(s)?this.#bt.sendIndication(t,r,e).catch(()=>{}):(this.#Ot.add(s),this.#bt.createPermission(t).then(()=>this.#bt.sendIndication(t,r,e)).catch(()=>{}))}close(){try{this.#bt.close()}catch(e){}}}class Ie extends t.EventEmitter{role;localUfrag;localPwd;remoteUfrag;remotePwd;#Dt;#Ut;#vt;#kt;#Lt;#Pt;#_t;#xt;#Ht;#U;#Mt;constructor(e){super(),this.role=e.role,this.localUfrag=e.localUfrag,this.localPwd=e.localPwd,this.remoteUfrag=null,this.remotePwd=null,this.#Dt=a.randomBytes(8),this.#Ut=[],this.#vt=[],this.#kt=[],this.#Lt=[],this.#Pt=null,this.#_t=!1,this.#xt=null,this.#Ht=null,this.#U=!1,this.#Mt=new Map}async gather(e={}){const t=e.iceServers||[],r="relay"===e.iceTransportPolicy,s=await this.#Ft();for(const e of t){const t=Array.isArray(e.urls)?e.urls:[e.urls];for(const i of t){const t=me(i);if(!t)continue;const n="turns"===t.scheme&&"tcp"===t.transport;if("udp"===t.transport||n)try{"stun"!==t.scheme||r?"turn"!==t.scheme&&"turns"!==t.scheme||await this.#Kt(t,e):await this.#qt(t,s[0])}catch(e){this.emit("gathererror",{url:i,error:e instanceof Error?e.message:String(e)})}}}r&&(this.#vt=this.#vt.filter(e=>"relay"===e.type)),this.emit("gatheringcomplete")}async#Ft(){const e=c.networkInterfaces(),t=[];for(const r of Object.values(e))if(r)for(const e of r)"IPv4"!==e.family||e.internal||t.push(e.address);0===t.length&&t.push("127.0.0.1");const r=[];for(const e of t)r.push(await this.#Gt(e));return r}#Gt(e){return new Promise((t,r)=>{const s=o.createSocket("udp4");s.on("error",e=>this.emit("error",e)),s.bind(0,e,()=>{const{port:r}=s.address(),i=new Ee(s);i.onMessage=(e,t)=>this.#$t(i,e,t),this.#Ut.push(i);const n=this.#zt("host",e,r,i);t({socket:s,address:e,port:r,transport:i,candidate:n})})})}async#qt(e,t){if(!t)return;const r=new fe({server:e.host,port:e.port});try{const e=await r.getReflexiveAddress();this.#zt("srflx",e.address,e.port,t.transport,{relatedAddress:t.address,relatedPort:t.port})}finally{r.close()}}async#Kt(e,t){if(!t.username||!t.credential)throw new Error("TURN server requires username and credential");const r=new fe({server:e.host,port:e.port,username:t.username,credential:t.credential,transport:e.transport,secure:"turns"===e.scheme}),s=await r.allocateRelay(600),i=new ge(r);i.onMessage=(e,t)=>this.#$t(i,e,t),this.#Ut.push(i),this.#zt("relay",s.relayedAddress,s.relayedPort,i,{relatedAddress:e.host,relatedPort:e.port})}#zt(e,t,r,s,i={}){const n=a.createHash("md5").update(`${e}:${t}:${s.kind}`).digest("hex").slice(0,8),o=function(e,t=65535,r=1){return(pe[e]<<24)+(t<<8)+(256-r)>>>0}(e);let c=`candidate:${n} 1 udp ${o} ${t} ${r} typ ${e}`;i.relatedAddress&&(c+=` raddr ${i.relatedAddress} rport ${i.relatedPort}`);const h={foundation:n,component:1,protocol:"udp",priority:o,address:t,port:r,type:e,transport:s,sdp:c};return this.#vt.push(h),this.emit("candidate",h),h}getLocalCandidates(){return this.#vt.slice()}setRemoteCredentials(e,t){this.remoteUfrag=e,this.remotePwd=t}addRemoteCandidate(e){e&&e.address&&e.port&&("string"==typeof e.address&&e.address.endsWith(".local")||(this.#kt.push(e),this.#jt(),!this.#xt&&this.remotePwd&&this.#Vt()))}start(){this.remotePwd&&this.#kt.length>0&&this.#Vt()}#jt(){for(const e of this.#vt)for(const t of this.#kt){const r=`${e.type}:${e.address}:${e.port}->${t.address}:${t.port}`;this.#Lt.find(e=>e.key===r)||this.#Lt.push({key:r,local:e,remote:t,state:"frozen",nominated:!1})}}#Vt(){this.#xt||this.#_t||(this.#xt=setInterval(()=>this.#Wt(),50),this.#xt.unref&&this.#xt.unref(),this.#Ht=setTimeout(()=>{this.#U||this.emit("failed"),this.#Yt()},1e4),this.#Ht.unref&&this.#Ht.unref(),this.#Wt())}#Yt(){this.#xt&&(clearInterval(this.#xt),this.#xt=null),this.#Ht&&(clearTimeout(this.#Ht),this.#Ht=null)}#Wt(){if(!this.#_t)for(const e of this.#Lt)"succeeded"!==e.state&&this.#Xt(e)}#Xt(e){const t=a.randomBytes(12),r=`${this.remoteUfrag}:${this.localUfrag}`,s=new M(P.BINDING_REQUEST,t).addUsername(r).addPriority(e.local.priority);"controlling"===this.role?(s.addIceControlling(this.#Dt),s.addUseCandidate()):s.addIceControlled(this.#Dt);const i=s.build(this.remotePwd??void 0);this.#Mt.set(t.toString("hex"),e),e.state="in-progress",e.local.transport.send(i,e.remote.address,e.remote.port)}#$t(e,t,r){0!==t.length&&(t[0]<=3?this.#Qt(e,t,r):this.emit("data",t,{transport:e,address:r.address,port:r.port}))}#Qt(e,t,r){const s=function(e){if(e.length<20)return null;if(e.readUInt32BE(4)!==L)return null;const t=e.readUInt16BE(0),r=e.readUInt16BE(2);if(20+r>e.length)return null;const s=e.slice(8,20),i=new Map;let n=20;const a=20+r;for(;n+4<=a;){const t=e.readUInt16BE(n),r=e.readUInt16BE(n+2);if(n+=4,n+r>a)break;i.set(t,e.slice(n,n+r)),n+=x(r)}return{type:t,transactionId:s,attrs:i,raw:e}}(t);s&&(s.type===P.BINDING_REQUEST?this.#Zt(e,s,r):s.type===P.BINDING_SUCCESS&&this.#Jt(e,s,r))}#Zt(e,t,r){if(this.localPwd&&!function(e,t){let r=20;const s=20+e.readUInt16BE(2);let i=-1;for(;r+4<=s;){const t=e.readUInt16BE(r),s=e.readUInt16BE(r+2);if(t===_.MESSAGE_INTEGRITY){i=r;break}r+=4+x(s)}if(i<0)return!1;const n=e.slice(i+4,i+4+20),o=i+24-20,c=Buffer.from(e.slice(0,20));c.writeUInt16BE(o,2);const h=a.createHmac("sha1",Buffer.from(t,"utf8")).update(Buffer.concat([c,e.slice(20,i)])).digest();return n.length===h.length&&a.timingSafeEqual(n,h)}(t.raw,this.localPwd))return;const s=new M(P.BINDING_SUCCESS,t.transactionId).addXorMappedAddress(r.address,r.port).build(this.localPwd);e.send(s,r.address,r.port),this.#kt.find(e=>e.address===r.address&&e.port===r.port)||this.addRemoteCandidate({address:r.address,port:r.port,type:"prflx",priority:0});const i=t.attrs.has(_.USE_CANDIDATE),n=this.#er(e,r);i&&"controlled"===this.role&&this.#tr(n||this.#rr(e,r))}#Jt(e,t,r){const s=this.#Mt.get(t.transactionId.toString("hex"));s&&(this.#Mt.delete(t.transactionId.toString("hex")),s.state="succeeded","controlling"===this.role&&this.#tr(s))}#er(e,t){return this.#Lt.find(r=>r.remote.address===t.address&&r.remote.port===t.port&&r.local.transport===e)}#rr(e,t){return{local:{transport:e},remote:{address:t.address,port:t.port}}}#tr(e){!this.#Pt&&e&&(this.#Pt=e,this.#U=!0,this.#Yt(),this.emit("selected",{transport:e.local.transport,candidateType:e.local.type,remoteAddress:e.remote.address,remotePort:e.remote.port}),this.emit("connected"))}send(e){if(!this.#Pt)throw new Error("ICE not connected");this.#Pt.local.transport.send(e,this.#Pt.remote.address,this.#Pt.remote.port)}getSelectedPair(){return this.#Pt}getSelectedCandidateType(){return this.#Pt?this.#Pt.local.type:null}close(){if(!this.#_t){this.#_t=!0,this.#Yt();for(const e of this.#Ut)try{e.close()}catch(e){}this.#Ut=[],this.emit("closed")}}}const Te=Object.freeze({DATA:0,INIT:1,INIT_ACK:2,SACK:3,HEARTBEAT:4,HEARTBEAT_ACK:5,ABORT:6,SHUTDOWN:7,SHUTDOWN_ACK:8,ERROR:9,COOKIE_ECHO:10,COOKIE_ACK:11,SHUTDOWN_COMPLETE:14,FORWARD_TSN:192}),Ce=Object.freeze({HEARTBEAT_INFO:1,STATE_COOKIE:7,UNRECOGNIZED_PARAM:8,COOKIE_PRESERVATIVE:9,SUPPORTED_ADDR_TYPES:11,FORWARD_TSN_SUPPORTED:49152,SUPPORTED_EXTENSIONS:32776}),Se=Object.freeze({DCEP:50,STRING:51,BINARY:53,STRING_EMPTY:56,BINARY_EMPTY:57,STRING_PARTIAL:54,BINARY_PARTIAL:52});function ye(e){return e+3&-4}function Be(e,t,r){const s=4+r.length,i=Buffer.alloc(ye(s));return i.writeUInt8(e,0),i.writeUInt8(t,1),i.writeUInt16BE(s,2),r.copy(i,4),i}function Re(e,t){const r=4+t.length,s=Buffer.alloc(ye(r));return s.writeUInt16BE(e,0),s.writeUInt16BE(r,2),t.copy(s,4),s}function Ae(e){const t=[];let r=0;for(;r+4<=e.length;){const s=e.readUInt16BE(r),i=e.readUInt16BE(r+2);if(i<4||r+i>e.length)break;t.push({type:s,length:i,value:e.slice(r+4,r+i)}),r+=ye(i)}return t}function we({initiateTag:e,a_rwnd:t,outStreams:r,inStreams:s,initialTSN:i}){const n=Buffer.alloc(16);return n.writeUInt32BE(e>>>0,0),n.writeUInt32BE(t>>>0,4),n.writeUInt16BE(r,8),n.writeUInt16BE(s,10),n.writeUInt32BE(i>>>0,12),n}function Ne(e){return{initiateTag:e.readUInt32BE(0),a_rwnd:e.readUInt32BE(4),outStreams:e.readUInt16BE(8),inStreams:e.readUInt16BE(10),initialTSN:e.readUInt32BE(12),params:Ae(e.slice(16))}}function be({tsn:e,streamId:t,streamSeq:r,ppid:s,userData:i,unordered:n=!1,beginning:a=!0,ending:o=!0}){const c=Buffer.alloc(12);c.writeUInt32BE(e>>>0,0),c.writeUInt16BE(t,4),c.writeUInt16BE(r,6),c.writeUInt32BE(s>>>0,8);let h=0;return o&&(h|=1),a&&(h|=2),n&&(h|=4),{flags:h,body:Buffer.concat([c,i])}}const Oe=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?2197175160^r>>>1:r>>>1;e[t]=r>>>0}return e})();function De(e){let t=4294967295;for(let r=0;r<e.length;r++)t=Oe[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}const Ue=1048576,ve=Object.freeze({CLOSED:"closed",COOKIE_WAIT:"cookie-wait",COOKIE_ECHOED:"cookie-echoed",ESTABLISHED:"established"});function ke(e,t){return(e-t&4294967295)>2147483648}function Le(e,t){return e===t||ke(e,t)}class Pe extends t.EventEmitter{isClient;state;#sr;#ir;#nr;#ar;#or;#cr;#hr;#dr;#lr;#ur;#fr;#de;constructor(e={}){super(),this.isClient=!!e.isClient,this.state=ve.CLOSED,this.#sr=5e3,this.#ir=5e3,this.#nr=a.randomBytes(4).readUInt32BE(0)>>>0||1,this.#ar=0,this.#or=a.randomBytes(4).readUInt32BE(0)>>>0,this.#cr=new Map,this.#hr=new Map,this.#dr=null,this.#lr=new Map,this.#ur=new Map,this.#fr=null}start(){this.state===ve.CLOSED&&this.isClient&&(this.#pr(),this.state=ve.COOKIE_WAIT)}#mr(e,t){const r=function(e,t,r){const s=Buffer.alloc(12);return s.writeUInt16BE(e,0),s.writeUInt16BE(t,2),s.writeUInt32BE(r>>>0,4),s.writeUInt32BE(0,8),s}(this.#sr,this.#ir,e),s=Buffer.concat([r,...t]);!function(e){e.writeUInt32LE(0,8);const t=De(e);e.writeUInt32LE(t,8)}(s),this.emit("output",s)}receivePacket(e){if(e.length<12)return;if(!function(e){const t=e.readUInt32LE(8);e.writeUInt32LE(0,8);const r=De(e);return e.writeUInt32LE(t,8),r===t}(e))return;const t=function(e){return{srcPort:e.readUInt16BE(0),dstPort:e.readUInt16BE(2),verificationTag:e.readUInt32BE(4),checksum:e.readUInt32LE(8)}}(e),r=function(e){const t=[];let r=12;for(;r+4<=e.length;){const s=e.readUInt8(r),i=e.readUInt8(r+1),n=e.readUInt16BE(r+2);if(n<4||r+n>e.length)break;const a=e.slice(r+4,r+n);t.push({type:s,flags:i,length:n,body:a}),r+=ye(n)}return t}(e);for(const e of r)this.#Er(e,t)}#Er(e,t){switch(e.type){case Te.INIT:this.#gr(e);break;case Te.INIT_ACK:this.#Ir(e);break;case Te.COOKIE_ECHO:this.#Tr(e);break;case Te.COOKIE_ACK:this.#Cr();break;case Te.DATA:this.#Sr(e);break;case Te.SACK:this.#yr(e);break;case Te.HEARTBEAT:this.#Br(e);break;case Te.ABORT:this.#Rr("peer sent ABORT");break;case Te.SHUTDOWN:this.#Ar()}}#wr(){return[Re(Ce.FORWARD_TSN_SUPPORTED,Buffer.alloc(0))]}#pr(){const e=we({initiateTag:this.#nr,a_rwnd:Ue,outStreams:65535,inStreams:65535,initialTSN:this.#or}),t=Be(Te.INIT,0,Buffer.concat([e,...this.#wr()]));this.#mr(0,[t]),this.#Nr([t])}#Nr(e){this.#br();let t=500,r=0;const s=()=>{this.state!==ve.ESTABLISHED&&this.state!==ve.CLOSED&&(r>=8?this.#Rr("SCTP setup timed out"):(r++,this.#mr(this.state===ve.COOKIE_ECHOED?this.#ar:0,e),t=Math.min(2*t,5e3),this.#fr=setTimeout(s,t),this.#fr.unref&&this.#fr.unref()))};this.#fr=setTimeout(s,t),this.#fr.unref&&this.#fr.unref()}#br(){this.#fr&&(clearTimeout(this.#fr),this.#fr=null)}#gr(e){const t=Ne(e.body);this.#ar=t.initiateTag,this.#dr=t.initialTSN-1>>>0,this.#de||(this.#de=a.randomBytes(32));const r=Buffer.alloc(16);r.writeUInt32BE(this.#nr,0),r.writeUInt32BE(this.#ar,4),r.writeUInt32BE(this.#or,8),r.writeUInt32BE(t.initialTSN,12);const s=a.createHmac("sha256",this.#de).update(r).digest(),i=Buffer.concat([r,s]),n=we({initiateTag:this.#nr,a_rwnd:Ue,outStreams:65535,inStreams:65535,initialTSN:this.#or}),o=Buffer.concat([Re(Ce.STATE_COOKIE,i),...this.#wr()]),c=Be(Te.INIT_ACK,0,Buffer.concat([n,o]));this.#mr(this.#ar,[c])}#Ir(e){if(this.state!==ve.COOKIE_WAIT)return;this.#br();const t=Ne(e.body);this.#ar=t.initiateTag,this.#dr=t.initialTSN-1>>>0;const r=t.params.find(e=>e.type===Ce.STATE_COOKIE);if(!r)return void this.#Rr("INIT_ACK missing state cookie");const s=Be(Te.COOKIE_ECHO,0,r.value);this.state=ve.COOKIE_ECHOED,this.#mr(this.#ar,[s]),this.#Nr([s])}#Tr(e){const t=e.body;if(t.length>=48&&this.#de){const e=t.slice(0,16),r=t.slice(16,48),s=a.createHmac("sha256",this.#de).update(e).digest();if(!a.timingSafeEqual(r,s))return}const r=Be(Te.COOKIE_ACK,0,Buffer.alloc(0));this.#mr(this.#ar,[r]),this.#Or()}#Cr(){this.state===ve.COOKIE_ECHOED&&(this.#br(),this.#Or())}#Or(){this.state!==ve.ESTABLISHED&&(this.state=ve.ESTABLISHED,this.emit("established"))}sendData(e,t,r,s={}){if(this.state!==ve.ESTABLISHED)throw new Error("SCTP association not established");const i=!!s.unordered;let n=0;i||(n=this.#cr.get(e)||0,this.#cr.set(e,n+1&65535));const a=r.length;let o=0;const c=[];do{const s=r.slice(o,o+1200),h=0===o,d=o+s.length>=a,l=this.#or;this.#or=this.#or+1>>>0;const{flags:u,body:f}=be({tsn:l,streamId:e,streamSeq:n,ppid:t,userData:s,unordered:i,beginning:h,ending:d}),p=Be(Te.DATA,u,f);this.#hr.set(l,{chunk:p}),c.push(p),o+=s.length}while(o<a);for(const e of c)this.#mr(this.#ar,[e])}#Sr(e){const t={unordered:!!(4&(r=e.flags)),beginning:!!(2&r),ending:!!(1&r),tsn:(s=e.body).readUInt32BE(0),streamId:s.readUInt16BE(4),streamSeq:s.readUInt16BE(6),ppid:s.readUInt32BE(8),userData:s.slice(12)};var r,s;this.#Dr(t),this.#Ur()}#Dr(e){const t=this.#dr+1>>>0;if(!ke(e.tsn,t))if(e.tsn===t){this.#dr=e.tsn,this.#vr(e);let t=this.#dr+1>>>0;for(;this.#lr.has(t);){const e=this.#lr.get(t);this.#lr.delete(t),this.#dr=t,this.#vr(e),t=this.#dr+1>>>0}}else this.#lr.has(e.tsn)||this.#lr.set(e.tsn,e)}#vr(e){const t=`${e.streamId}:${e.unordered?"u":"o"}`;if(e.beginning&&e.ending)return void this.emit("message",{streamId:e.streamId,ppid:e.ppid,data:e.userData});let r=this.#ur.get(t);if(e.beginning)r={ppid:e.ppid,parts:[e.userData]},this.#ur.set(t,r);else{if(!r)return;r.parts.push(e.userData)}e.ending&&r&&(this.#ur.delete(t),this.emit("message",{streamId:e.streamId,ppid:r.ppid,data:Buffer.concat(r.parts)}))}#Ur(){const e=[];if(this.#lr.size>0){const t=[...this.#lr.keys()].sort((e,t)=>ke(e,t)?-1:1),r=this.#dr+1>>>0;let s=null,i=null;for(const n of t)null!==s?n!==i+1>>>0?(e.push([1+(s-r&65535),1+(i-r&65535)]),s=n,i=n):i=n:(s=n,i=n);null!==s&&e.push([1+(s-r&65535),1+(i-r&65535)])}const t=function({cumulativeTSNAck:e,a_rwnd:t,gapBlocks:r=[],dupTSNs:s=[]}){const i=Buffer.alloc(12+4*r.length+4*s.length);i.writeUInt32BE(e>>>0,0),i.writeUInt32BE(t>>>0,4),i.writeUInt16BE(r.length,8),i.writeUInt16BE(s.length,10);let n=12;for(const[e,t]of r)i.writeUInt16BE(e,n),i.writeUInt16BE(t,n+2),n+=4;for(const e of s)i.writeUInt32BE(e>>>0,n),n+=4;return i}({cumulativeTSNAck:this.#dr>>>0,a_rwnd:Ue,gapBlocks:e}),r=Be(Te.SACK,0,t);this.#mr(this.#ar,[r])}#yr(e){const t=function(e){const t=e.readUInt32BE(0),r=e.readUInt32BE(4),s=e.readUInt16BE(8),i=e.readUInt16BE(10),n=[];let a=12;for(let t=0;t<s;t++)n.push([e.readUInt16BE(a),e.readUInt16BE(a+2)]),a+=4;const o=[];for(let t=0;t<i;t++)o.push(e.readUInt32BE(a)),a+=4;return{cumulativeTSNAck:t,a_rwnd:r,gapBlocks:n,dupTSNs:o}}(e.body);for(const e of[...this.#hr.keys()])Le(e,t.cumulativeTSNAck)&&this.#hr.delete(e);const r=t.cumulativeTSNAck+1>>>0;for(const[e,s]of t.gapBlocks)for(let t=e;t<=s;t++)this.#hr.delete(r+t-1>>>0)}#Br(e){const t=Be(Te.HEARTBEAT_ACK,0,e.body);this.#mr(this.#ar,[t])}#Ar(){const e=Be(Te.SHUTDOWN_ACK,0,Buffer.alloc(0));this.#mr(this.#ar,[e]),this.#kr()}#Rr(e){this.#br(),this.state!==ve.CLOSED&&(this.state=ve.CLOSED,this.emit("error",new Error(e||"SCTP abort")),this.emit("close"))}shutdown(){if(this.state!==ve.ESTABLISHED)return void this.#kr();const e=Be(Te.SHUTDOWN,0,(()=>{const e=Buffer.alloc(4);return e.writeUInt32BE(this.#dr>>>0,0),e})());this.#mr(this.#ar,[e]),this.#kr()}#kr(){this.#br(),this.state!==ve.CLOSED&&(this.state=ve.CLOSED,this.emit("close"))}}const _e=Object.freeze({DATA_CHANNEL_ACK:2,DATA_CHANNEL_OPEN:3}),xe=Object.freeze({RELIABLE:0,RELIABLE_UNORDERED:128,PARTIAL_RELIABLE_REXMIT:1,PARTIAL_RELIABLE_REXMIT_UNORDERED:129,PARTIAL_RELIABLE_TIMED:2,PARTIAL_RELIABLE_TIMED_UNORDERED:130});class He extends t.EventEmitter{#Lr;#Pr;#_r;constructor(e,t){super(),this.#Lr=e,this.#Pr=new Map,this.#_r=t?0:1,this.#Lr.on("message",e=>this.#xr(e))}openChannel(e,t={}){let r=e.id;if(null==r&&(r=this.#Hr(),e.emit(b.SET_ID,r)),this.#Pr.set(r,{channel:e,acked:!1}),this.#Mr(e,r,t),e.negotiated)this.#Pr.get(r).acked=!0,e.emit(b.OPEN);else{const s=function({channelType:e,priority:t=0,reliabilityParameter:r=0,label:s="",protocol:i=""}){const n=Buffer.from(s,"utf8"),a=Buffer.from(i,"utf8"),o=Buffer.alloc(12+n.length+a.length);return o.writeUInt8(_e.DATA_CHANNEL_OPEN,0),o.writeUInt8(e,1),o.writeUInt16BE(t,2),o.writeUInt32BE(r>>>0,4),o.writeUInt16BE(n.length,8),o.writeUInt16BE(a.length,10),n.copy(o,12),a.copy(o,12+n.length),o}({channelType:this.#Fr(t),priority:0,reliabilityParameter:this.#Kr(t),label:e.label,protocol:t.protocol||e.protocol||""});this.#Lr.sendData(r,Se.DCEP,s)}}#Hr(){let e=this.#_r;for(;this.#Pr.has(e);)e+=2;return this.#_r=e+2,e}#Fr(e){const t=!1===e.ordered;return null!=e.maxRetransmits?t?xe.PARTIAL_RELIABLE_REXMIT_UNORDERED:xe.PARTIAL_RELIABLE_REXMIT:null!=e.maxPacketLifeTime?t?xe.PARTIAL_RELIABLE_TIMED_UNORDERED:xe.PARTIAL_RELIABLE_TIMED:t?xe.RELIABLE_UNORDERED:xe.RELIABLE}#Kr(e){return null!=e.maxRetransmits?e.maxRetransmits>>>0:null!=e.maxPacketLifeTime?e.maxPacketLifeTime>>>0:0}#Mr(e,t,r){const s=!1===r.ordered;e.on(b.SEND,(e,r)=>{let i;i=r?0===e.length?Se.BINARY_EMPTY:Se.BINARY:0===e.length?Se.STRING_EMPTY:Se.STRING;const n=0===e.length?Buffer.from([0]):e;this.#Lr.sendData(t,i,n,{unordered:s})})}#xr(e){if(e.ppid===Se.DCEP)return void this.#qr(e);const t=this.#Pr.get(e.streamId);if(!t)return;const r=e.ppid===Se.BINARY||e.ppid===Se.BINARY_EMPTY||e.ppid===Se.BINARY_PARTIAL,s=e.ppid===Se.STRING_EMPTY||e.ppid===Se.BINARY_EMPTY?Buffer.alloc(0):e.data;t.channel.emit(b.RECEIVE,s,r)}#qr(e){const t=(r=e.data).length>0?r.readUInt8(0):-1;var r;if(t===_e.DATA_CHANNEL_OPEN){const t=function(e){const t=e.readUInt8(1),r=e.readUInt16BE(2),s=e.readUInt32BE(4),i=e.readUInt16BE(8),n=e.readUInt16BE(10);return{channelType:t,priority:r,reliabilityParameter:s,label:e.slice(12,12+i).toString("utf8"),protocol:e.slice(12+i,12+i+n).toString("utf8"),unordered:!!(128&t)}}(e.data);this.#Lr.sendData(e.streamId,Se.DCEP,Buffer.from([_e.DATA_CHANNEL_ACK])),this.emit("open-request",{streamId:e.streamId,label:t.label,protocol:t.protocol,ordered:!t.unordered,channelType:t.channelType,reliabilityParameter:t.reliabilityParameter})}else if(t===_e.DATA_CHANNEL_ACK){const t=this.#Pr.get(e.streamId);t&&!t.acked&&(t.acked=!0,t.channel.emit(b.OPEN))}}acceptChannel(e,t){e.emit(b.SET_ID,t.streamId),this.#Pr.set(t.streamId,{channel:e,acked:!0}),this.#Mr(e,t.streamId,{ordered:t.ordered}),e.emit(b.OPEN)}}class Me extends t.EventEmitter{#Gr;ice;dtls;sctp;dcm;#$r;constructor(e){super(),this.#Gr=e,this.ice=new Ie({role:e.iceRole,localUfrag:e.localUfrag,localPwd:e.localPwd}),this.dtls=null,this.sctp=null,this.dcm=null,this.#$r=!1,this.ice.on("candidate",e=>this.emit("candidate",e)),this.ice.on("error",e=>this.emit("error",e)),this.ice.on("failed",()=>this.emit("error",new Error("ICE failed"))),this.ice.on("data",e=>{this.dtls&&this.dtls.handlePacket(e)}),this.ice.on("connected",()=>{this.emit("iceconnected"),this.#zr()})}async gather(e={}){await this.ice.gather(e)}getLocalCandidates(){return this.ice.getLocalCandidates()}setRemote(e,t){this.ice.setRemoteCredentials(e,t),this.ice.start()}addRemoteCandidate(e){this.ice.addRemoteCandidate(e)}#zr(){this.#$r||(this.#$r=!0,this.dtls=new le({role:"client"===this.#Gr.dtlsRole?he.CLIENT:he.SERVER,certDer:this.#Gr.certDer,privateKey:this.#Gr.privateKey,verifyFingerprint:this.#Gr.verifyFingerprint,output:e=>{try{this.ice.send(e)}catch(e){this.emit("error",e)}}}),this.dtls.on("connect",()=>{this.emit("dtlsconnected"),this.#jr()}),this.dtls.on("data",e=>{this.sctp&&this.sctp.receivePacket(e)}),this.dtls.on("error",e=>this.emit("error",e)),this.dtls.on("close",()=>this.emit("close")),this.dtls.start())}#jr(){const e="client"===this.#Gr.dtlsRole,t=new Pe({isClient:e});this.sctp=t,t.on("output",e=>{try{this.dtls&&this.dtls.send(e)}catch(e){this.emit("error",e)}}),t.on("error",e=>this.emit("error",e)),t.on("close",()=>this.emit("close")),this.dcm=new He(t,e),this.dcm.on("open-request",e=>this.emit("datachannel-request",e)),t.on("established",()=>{this.emit("sctpconnected"),this.emit("ready")}),t.start()}openChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.openChannel(e,t)}acceptChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.acceptChannel(e,t)}isReady(){return!!this.sctp&&"established"===this.sctp.state}close(){if(this.sctp)try{this.sctp.shutdown()}catch{}if(this.dtls)try{this.dtls.close()}catch{}if(this.ice)try{this.ice.close()}catch{}}}const Fe=Object.freeze({STABLE:"stable",HAVE_LOCAL_OFFER:"have-local-offer",HAVE_REMOTE_OFFER:"have-remote-offer",HAVE_LOCAL_PRANSWER:"have-local-pranswer",HAVE_REMOTE_PRANSWER:"have-remote-pranswer",CLOSED:"closed"}),Ke=Object.freeze({NEW:"new",GATHERING:"gathering",COMPLETE:"complete"}),qe=Object.freeze({NEW:"new",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"});class Ge extends t.EventEmitter{#Vr;#Wr;#Yr;#Xr;#Qr;#Zr;#Jr;#es;#ts;#rs;#ss;#is;#ns;#as;#os;#Pr;#vt;constructor(e={}){super(),this.#Vr=e,this.#Wr=Fe.STABLE,this.#Yr=Ke.NEW,this.#Xr=qe.NEW,this.#Qr=null,this.#Zr=null,this.#Jr=null,this.#es={usernameFragment:a.randomBytes(3).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,4).padEnd(4,"x"),password:a.randomBytes(18).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,24).padEnd(24,"x")},this.#ts=null,this.#rs=[],this.#ss=null,this.#is=null,this.#ns=!1,this.#as=!1,this.#os=[],this.#Pr=new Set,this.#vt=[]}async#cs(){return this.#Jr||(this.#Vr.certificates&&this.#Vr.certificates[0]?this.#Jr=this.#Vr.certificates[0]:this.#Jr=await w.generateCertificate()),this.#Jr}#hs(e,t){if(this.#is)return this.#is;const r=this.#Jr;if(!r)throw new Error("Certificate not initialized");const s=r.getCertificateDer();if(!s)throw new Error("Certificate has no DER encoding");const i=new Me({iceRole:e,dtlsRole:t,localUfrag:this.#es.usernameFragment,localPwd:this.#es.password,certDer:s,privateKey:r.getPrivateKeyObject(),verifyFingerprint:e=>this.#ds(e)});return i.on("candidate",e=>{const t={candidate:e.sdp,sdpMid:"0",sdpMLineIndex:0,usernameFragment:this.#es.usernameFragment};this.#vt.push(t),this.emit("icecandidate",{candidate:t})}),i.on("iceconnected",()=>this.#ls(qe.CONNECTING)),i.on("sctpconnected",()=>this.#ls(qe.CONNECTED)),i.on("error",e=>{this.emit("error",e),this.#ls(qe.FAILED)}),i.on("close",()=>this.#ls(qe.DISCONNECTED)),i.on("datachannel-request",e=>{const t=new O(e.label,{ordered:e.ordered,protocol:e.protocol,id:e.streamId});i.acceptChannel(t,e),this.#Pr.add(t),this.emit("datachannel",{channel:t})}),i.on("ready",()=>{for(const{channel:e,init:t}of this.#os)i.openChannel(e,t);this.#os=[]}),this.#is=i,i}#ds(e){return 0===this.#rs.length||this.#rs.some(t=>t.algorithm===e.algorithm&&t.value.toUpperCase()===e.value.toUpperCase())}createDataChannel(e,t={}){if(this.#as)throw new Error("RTCPeerConnection is closed");const r=new O(e,t);this.#Pr.add(r);const s={ordered:!1!==t.ordered,maxRetransmits:t.maxRetransmits,maxPacketLifeTime:t.maxPacketLifeTime,protocol:t.protocol||"",negotiated:t.negotiated||!1};return this.#is&&this.#is.isReady()?this.#is.openChannel(r,s):this.#os.push({channel:r,init:s}),setImmediate(()=>{this.#as||this.emit("negotiationneeded")}),r}async createOffer(){if(this.#as)throw new Error("RTCPeerConnection is closed");await this.#cs(),this.#ns=!0;const e=this.#us(),t=(r={iceUfrag:this.#es.usernameFragment,icePwd:this.#es.password,fingerprint:e,setup:"actpass",candidates:[]},v({...r,setup:r.setup||"actpass"}));var r;return new U({type:D.OFFER,sdp:t})}async createAnswer(){if(this.#as)throw new Error("RTCPeerConnection is closed");if(!this.#Zr||"offer"!==this.#Zr.type)throw new Error("Cannot create answer without remote offer");await this.#cs();const e=this.#us(),t=(r={iceUfrag:this.#es.usernameFragment,icePwd:this.#es.password,fingerprint:e,setup:"active",candidates:[]},v({...r,setup:r.setup||"active"}));var r;return new U({type:D.ANSWER,sdp:t})}#us(){const e=this.#Jr;if(!e)throw new Error("Certificate not initialized");const t=e.getFingerprints();return t.find(e=>"sha-256"===e.algorithm)||t[0]}async setLocalDescription(e){if(this.#as)throw new Error("RTCPeerConnection is closed");const t=e||(this.#Wr===Fe.HAVE_REMOTE_OFFER?await this.createAnswer():await this.createOffer());await this.#cs(),this.#Qr=new U({type:t.type??void 0,sdp:t.sdp??void 0}),"offer"===t.type?this.#Wr=Fe.HAVE_LOCAL_OFFER:"answer"===t.type&&(this.#Wr=Fe.STABLE),this.#fs(t,!0),this.#Yr=Ke.GATHERING,this.emit("icegatheringstatechange"),this.#is&&(await this.#is.gather({iceServers:this.#Vr.iceServers||[],iceTransportPolicy:this.#Vr.iceTransportPolicy||"all"}),this.#Yr=Ke.COMPLETE,this.emit("icegatheringstatechange"),this.emit("icecandidate",{candidate:null}),this.#ps()),this.emit("signalingstatechange")}async setRemoteDescription(e){if(this.#as)throw new Error("RTCPeerConnection is closed");if(!e||!e.sdp)throw new Error("Invalid session description");await this.#cs(),this.#Zr=new U(e),"offer"===e.type?this.#Wr=Fe.HAVE_REMOTE_OFFER:"answer"===e.type&&(this.#Wr=Fe.STABLE),this.#ts=function(e){const t={usernameFragment:null,password:null};for(const r of e.split(/\r?\n/))r.startsWith("a=ice-ufrag:")?t.usernameFragment=r.slice(12).trim():r.startsWith("a=ice-pwd:")&&(t.password=r.slice(10).trim());return t}(e.sdp);const t=function(e){const t={role:"auto",fingerprints:[]};for(const r of e.split(/\r?\n/))if(r.startsWith("a=setup:")){const e=r.slice(8).trim();t.role="active"===e?"client":"passive"===e?"server":"actpass",t.setup=e}else if(r.startsWith("a=fingerprint:")){const e=r.slice(14).trim().split(/\s+/);2===e.length&&t.fingerprints.push({algorithm:e[0].toLowerCase(),value:e[1].toUpperCase()})}return t}(e.sdp);if(this.#rs=t.fingerprints,this.#ss=t.setup??null,this.#fs(e,!1),this.#is&&this.#ts.usernameFragment){this.#is.setRemote(this.#ts.usernameFragment,this.#ts.password??"");for(const t of function(e){const t=[];for(const r of e.split(/\r?\n/)){if(!r.startsWith("a=candidate:"))continue;const e=k(r.slice(2));e&&t.push(e)}return t}(e.sdp))this.#is.addRemoteCandidate(t)}this.#ps(),this.emit("signalingstatechange")}#fs(e,t){if(this.#is)return;const r=this.#ns?"controlling":"controlled";let s;s=this.#ns?"active"===this.#ss?"server":"passive"===this.#ss?"client":"server":"client",this.#hs(r,s)}#ps(){this.#is&&this.#ts&&this.#ts.usernameFragment&&this.#is.setRemote(this.#ts.usernameFragment,this.#ts.password??"")}async addIceCandidate(e){if(this.#as)throw new Error("RTCPeerConnection is closed");if(!e||"string"!=typeof e&&""===e.candidate)return;const t=k("string"==typeof e?e:e.candidate||"");t&&this.#is&&this.#is.addRemoteCandidate(t)}#ls(e){this.#Xr!==e&&(this.#Xr=e,this.emit("connectionstatechange"),this.emit("iceconnectionstatechange"))}getConfiguration(){return{...this.#Vr}}setConfiguration(e){if(this.#as)throw new Error("RTCPeerConnection is closed");this.#Vr={...e}}close(){if(!this.#as){this.#as=!0,this.#Wr=Fe.CLOSED;for(const e of this.#Pr)try{e.close()}catch(e){}if(this.#is)try{this.#is.close()}catch(e){}this.#ls(qe.CLOSED),this.emit("signalingstatechange")}}get signalingState(){return this.#Wr}get iceGatheringState(){return this.#Yr}get iceConnectionState(){return this.#Xr===qe.CONNECTED?"connected":this.#Xr===qe.CONNECTING?"checking":this.#Xr===qe.FAILED?"failed":"new"}get connectionState(){return this.#Xr}get localDescription(){return this.#Qr}get remoteDescription(){return this.#Zr}get currentLocalDescription(){return this.#Qr}get currentRemoteDescription(){return this.#Zr}get pendingLocalDescription(){return this.#Wr===Fe.STABLE?null:this.#Qr}get pendingRemoteDescription(){return this.#Wr===Fe.STABLE?null:this.#Zr}get canTrickleIceCandidates(){return!0}get sctp(){return this.#is?this.#is.sctp:null}}exports.ByteBufferQueue=class{#ms;#Es;#gs;constructor(){this.#ms=0,this.#Es=[],this.#gs=0}get size(){return this.#ms}get empty(){return 0===this.#ms}readInto(e){if(!Buffer.isBuffer(e))throw new TypeError("bufferOut must be a Buffer");let t=0,r=0;for(;r<e.length&&this.#Es.length>0;){const s=this.#Es[0],i=s.length-this.#gs,n=e.length-r,a=Math.min(i,n);s.copy(e,r,this.#gs,this.#gs+a),t+=a,r+=a,a<i?this.#gs+=a:(this.#Es.shift(),this.#gs=0)}return this.#ms-=t,this.#Is(),t}append(e){if(!Buffer.isBuffer(e))throw new TypeError("buffer must be a Buffer");0!==e.length&&(this.#ms+=e.length,this.#Es.push(e),this.#Is())}clear(){this.#Es=[],this.#gs=0,this.#ms=0,this.#Is()}read(e){if(e>this.#ms)throw new RangeError(`Cannot read ${e} bytes, only ${this.#ms} available`);if(0===e)return Buffer.allocUnsafe(0);const t=Buffer.allocUnsafe(e),r=this.readInto(t);if(r!==e)throw new Error(`Internal error: read ${r} bytes, expected ${e}`);return t}peek(e=this.#ms){const t=Math.min(e,this.#ms);if(0===t)return Buffer.allocUnsafe(0);const r=Buffer.allocUnsafe(t);let s=0,i=0,n=this.#gs;for(;s<t&&i<this.#Es.length;){const e=this.#Es[i],a=e.length-n,o=Math.min(a,t-s);e.copy(r,s,n,n+o),s+=o,i++,n=0}return r}#Is(){if("production"!==process.env.NODE_ENV){let e=0;for(const t of this.#Es){if(0===t.length)throw new Error("Invariant violation: empty buffer in queue");e+=t.length}const t=e-this.#gs;if(this.#ms!==t)throw new Error(`Invariant violation: size=${this.#ms}, expected=${t}`);if(0===this.#Es.length){if(0!==this.#gs)throw new Error("Invariant violation: offset non-zero with empty queue")}else if(this.#gs>=this.#Es[0].length)throw new Error("Invariant violation: offset >= front buffer size")}}},exports.RTCCertificate=w,exports.RTCDataChannel=O,exports.RTCDataChannelState=N,exports.RTCError=l,exports.RTCIceCandidate=u,exports.RTCIceGatheringState=Ke,exports.RTCPeerConnection=Ge,exports.RTCPeerConnectionState=qe,exports.RTCSdpType=D,exports.RTCSessionDescription=U,exports.RTCSignalingState=Fe,exports.version="2.0.8";
1
+ "use strict";var e=require("crypto"),t=require("events"),r=require("dgram"),s=require("os"),i=require("tls");function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var a=n(e),o=n(r),c=n(s),h=n(i);const d=Object.freeze({NONE:"none",DATA_CHANNEL_FAILURE:"data-channel-failure",DTLS_FAILURE:"dtls-failure",FINGERPRINT_FAILURE:"fingerprint-failure",SCTP_FAILURE:"sctp-failure",SDP_SYNTAX_ERROR:"sdp-syntax-error",HARDWARE_ENCODER_NOT_AVAILABLE:"hardware-encoder-not-available",HARDWARE_ENCODER_ERROR:"hardware-encoder-error",INVALID_STATE:"invalid-state",INVALID_MODIFICATION:"invalid-modification",INVALID_ACCESS_ERROR:"invalid-access-error",OPERATION_ERROR:"operation-error"});class l extends Error{static DetailType=d;#e;#t;#r;#s;#i;#n;constructor(e={},t=""){super(t),this.name="RTCError",Error.captureStackTrace&&Error.captureStackTrace(this,l);const r=e.errorDetail||d.NONE;if("string"!=typeof r)throw new TypeError("errorDetail must be a string");this.#e=r,this.#t=this.#a(e.sdpLineNumber,"sdpLineNumber"),this.#r=this.#a(e.httpRequestStatusCode,"httpRequestStatusCode"),this.#s=this.#a(e.sctpCauseCode,"sctpCauseCode"),this.#i=this.#o(e.receivedAlert,"receivedAlert"),this.#n=this.#o(e.sentAlert,"sentAlert")}#a(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r))throw new TypeError(`${t} must be an integer`);return r}#o(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r)||r<0)throw new TypeError(`${t} must be an unsigned integer`);return r}get errorDetail(){return this.#e}get sdpLineNumber(){return this.#t}get httpRequestStatusCode(){return this.#r}get sctpCauseCode(){return this.#s}get receivedAlert(){return this.#i}get sentAlert(){return this.#n}toJSON(){const e={name:this.name,message:this.message,errorDetail:this.#e};return null!==this.#t&&(e.sdpLineNumber=this.#t),null!==this.#r&&(e.httpRequestStatusCode=this.#r),null!==this.#s&&(e.sctpCauseCode=this.#s),null!==this.#i&&(e.receivedAlert=this.#i),null!==this.#n&&(e.sentAlert=this.#n),e}static fromNative(e){const t={errorDetail:e.error_detail||d.NONE};return void 0!==e.sctp_cause_code&&(t.sctpCauseCode=e.sctp_cause_code),new l(t,e.message||"Unknown error")}}class u{#c;#h;#d;#l;#u;constructor(e={}){if(null===e.sdpMid&&null===e.sdpMLineIndex)throw new TypeError("sdpMid and sdpMLineIndex are both null");this.#c=e.candidate||"",this.#h=void 0!==e.sdpMid?e.sdpMid:null,this.#d=void 0!==e.sdpMLineIndex?e.sdpMLineIndex:null,this.#l=e.usernameFragment||null,this.#u=this.#f(this.#c)}#f(e){const t={foundation:null,component:null,protocol:null,priority:null,address:null,port:null,type:null,tcpType:null,relatedAddress:null,relatedPort:null};if(!e||!e.startsWith("candidate:"))return t;const r=e.substring(10).trim().split(/\s+/);if(r.length<8)return t;t.foundation=r[0],t.component=r[1],t.protocol=r[2].toLowerCase(),t.priority=parseInt(r[3],10),t.address=r[4],t.port=parseInt(r[5],10),"typ"===r[6]&&(t.type=r[7]);for(let e=8;e<r.length;e+=2){const s=r[e],i=r[e+1];"raddr"===s?t.relatedAddress=i:"rport"===s?t.relatedPort=parseInt(i,10):"tcptype"===s&&(t.tcpType=i)}return t}get candidate(){return this.#c}get sdpMid(){return this.#h}get sdpMLineIndex(){return this.#d}get usernameFragment(){return this.#l}get foundation(){return this.#u.foundation}get component(){return this.#u.component}get priority(){return this.#u.priority}get address(){return this.#u.address}get protocol(){return this.#u.protocol}get port(){return this.#u.port}get type(){return this.#u.type}get tcpType(){return this.#u.tcpType}get relatedAddress(){return this.#u.relatedAddress}get relatedPort(){return this.#u.relatedPort}toJSON(){const e={candidate:this.#c,sdpMid:this.#h,sdpMLineIndex:this.#d};return this.#l&&(e.usernameFragment=this.#l),e}static fromString(e,t=null,r=0){return new u({candidate:e,sdpMid:t,sdpMLineIndex:r})}static isValid(e){return!(!e||"string"!=typeof e)&&(!!e.startsWith("candidate:")&&e.substring(10).trim().split(/\s+/).length>=8)}}const f=Object.freeze({BOOLEAN:1,INTEGER:2,BIT_STRING:3,OCTET_STRING:4,NULL:5,OID:6,UTF8_STRING:12,PRINTABLE_STRING:19,IA5_STRING:22,UTC_TIME:23,GENERALIZED_TIME:24,SEQUENCE:48,SET:49});function p(e){if(e<128)return Buffer.from([e]);const t=[];let r=e;for(;r>0;)t.unshift(255&r),r>>>=8;return Buffer.from([128|t.length,...t])}function E(e,t){return Buffer.concat([Buffer.from([e]),p(t.length),t])}function m(e){let t=0;for(;t<e.length-1&&0===e[t];)t++;let r=e.slice(t);return 128&r[0]&&(r=Buffer.concat([Buffer.from([0]),r])),E(f.INTEGER,r)}function g(e){const t=[];let r=e;for(;r>0;)t.unshift(255&r),r=Math.floor(r/256);return 128&t[0]&&t.unshift(0),E(f.INTEGER,Buffer.from(t))}function I(e){const t=e.split(".").map(Number);if(t.length<2)throw new Error(`Invalid OID: ${e}`);const r=[40*t[0]+t[1]];for(let e=2;e<t.length;e++){let s=t[e];const i=[127&s];for(s=Math.floor(s/128);s>0;)i.unshift(127&s|128),s=Math.floor(s/128);r.push(...i)}return E(f.OID,Buffer.from(r))}function T(e){return E(f.SEQUENCE,Buffer.concat(e))}function C(e){const t=e.getUTCFullYear(),r=(e,t=2)=>String(e).padStart(t,"0"),s=r(e.getUTCMonth()+1),i=r(e.getUTCDate()),n=r(e.getUTCHours()),a=r(e.getUTCMinutes()),o=r(e.getUTCSeconds());if(t<2050){const e=r(t%100);return E(f.UTC_TIME,Buffer.from(`${e}${s}${i}${n}${a}${o}Z`,"ascii"))}return E(f.GENERALIZED_TIME,Buffer.from(`${t}${s}${i}${n}${a}${o}Z`,"ascii"))}const S=Object.freeze({ecPublicKey:"1.2.840.10045.2.1",prime256v1:"1.2.840.10045.3.1.7",ecdsaWithSHA256:"1.2.840.10045.4.3.2",commonName:"2.5.4.3"});function y(){return T([I(S.ecdsaWithSHA256)])}function B(e={}){const t=e.commonName||`WebRTC-${a.randomBytes(8).toString("hex")}`,r=e.days||30,{publicKey:s,privateKey:i}=a.generateKeyPairSync("ec",{namedCurve:"prime256v1"}),n=s.export({type:"spki",format:"der"}),o=e.notBefore||new Date(Date.now()-864e5),c=new Date(o.getTime()+24*r*60*60*1e3),h=a.randomBytes(20);h[0]&=127,0===h[0]&&(h[0]=1);const d=function(e){const t=T([I(S.commonName),(r=e,E(f.UTF8_STRING,Buffer.from(r,"utf8")))]);var r,s;return T([(s=[t],E(f.SET,Buffer.concat(s)))])}(t),l=T([(u=g(2),E(160,u)),m(h),y(),d,T([C(o),C(c)]),d,n]);var u;const p=a.sign("sha256",l,i);var B;return{certDer:T([l,y(),(B=p,E(f.BIT_STRING,Buffer.concat([Buffer.from([0]),B])))]),privateKey:i,publicKey:s,notBefore:o,notAfter:c}}function R(e,t="sha-256"){const r=t.replace("-","").toLowerCase();return a.createHash(r).update(e).digest("hex").toUpperCase().match(/.{2}/g).join(":")}function A(e,t="sha-256"){return R(e,t)}class w{#p;#E;#m;#g;#I;constructor(e){this.#p=e.certDer||null,this.#E=e.privateKey,this.#m=e.publicKey,this.#g=e.expires,this.#I=null}getCertificateDer(){return this.#p}get expires(){return this.#g}getFingerprints(){if(!this.#p)throw new Error("Certificate has no DER encoding; cannot compute fingerprint");if(!this.#I){const e=this.#p,t=["sha-256","sha-384","sha-512"];this.#I=t.map(t=>({algorithm:t,value:A(e,t)}))}return this.#I.map(e=>({...e}))}getPrivateKeyObject(){return this.#T(this.#E,"private")}#T(e,t){return e&&"object"==typeof e&&e.type?e:"private"===t?a.createPrivateKey(e):a.createPublicKey(e)}getPrivateKey(){return this.#T(this.#E,"private").export({type:"pkcs8",format:"pem"})}getPublicKey(){return this.#T(this.#m,"public").export({type:"spki",format:"pem"})}toPEM(){const e=this.#p?`-----BEGIN CERTIFICATE-----\n${this.#p.toString("base64").match(/.{1,64}/g).join("\n")}\n-----END CERTIFICATE-----\n`:this.getPublicKey();return{pemPrivateKey:this.getPrivateKey(),pemCertificate:e}}isExpired(){return Date.now()>this.#g}static async generateCertificate(e={}){return new Promise((t,r)=>{try{let s;if(e.expires)s=e.expires;else{const t=e.days||30;s=Date.now()+24*t*60*60*1e3}setImmediate(()=>{try{const r=function(e={}){const{name:t,days:r=30}=e,{certDer:s,privateKey:i,publicKey:n,notAfter:a}=B({commonName:t,days:r});return{certDer:s,privateKey:i,publicKey:n,expires:a.getTime(),hash:"sha256"}}({name:e.name||"webrtc",days:Math.ceil((s-Date.now())/864e5),hash:e.hash||"sha256"});r.expires=s;const i=new w(r);t(i)}catch(e){r(e)}})}catch(e){r(e)}})}static fromPEM(e,t,r){if("string"!=typeof e||0===e.length)throw new TypeError("pemPrivateKey must be a non-empty string");if("string"!=typeof t||0===t.length)throw new TypeError("pemCertificate must be a non-empty string");const s=r||Date.now()+2592e6;let i=null,n=t;const o=t.match(/-----BEGIN CERTIFICATE-----([\s\S]+?)-----END CERTIFICATE-----/);return o&&(i=Buffer.from(o[1].replace(/\s/g,""),"base64"),n=a.createPublicKey(a.createPrivateKey(e))),new w({certDer:i,privateKey:e,publicKey:n,expires:s,hash:"sha256"})}static isSupportedKeyParams(e){if(!e||"object"!=typeof e)return!1;if("RSA"===e.type){const t=e.rsaModulusLength||2048;return t>=1024&&t<=4096}if("ECDSA"===e.type){const t=e.namedCurve;return["P-256","P-384","P-521"].includes(t)}return!1}}const N=Object.freeze({CONNECTING:"connecting",OPEN:"open",CLOSING:"closing",CLOSED:"closed"}),b=Object.freeze({SEND:Symbol("rtcdatachannel:send"),RECEIVE:Symbol("rtcdatachannel:receive"),OPEN:Symbol("rtcdatachannel:open"),SET_ID:Symbol("rtcdatachannel:setId")});class O extends t.EventEmitter{#C;#S;#y;#B;#R;#A;#w;#N;#b;#O;#U;#D;constructor(e,t={}){if(super(),"string"!=typeof e)throw new TypeError("label must be a string");this.#C=e,this.#S=void 0===t.ordered||t.ordered,this.#y=t.maxPacketLifeTime||null,this.#B=t.maxRetransmits||null,this.#R=t.protocol||"",this.#A=t.negotiated||!1,this.#w=void 0!==t.id?t.id:null,this.#N=N.CONNECTING,this.#b=0,this.#O=0,this.#U="arraybuffer",this.#D=!1,this.on(b.SET_ID,e=>{this.#w=e}),this.on(b.OPEN,()=>{this.#D=!0,this.#v(N.OPEN)}),this.on(b.RECEIVE,(e,t)=>{this.#k(e,t)})}get label(){return this.#C}get ordered(){return this.#S}get maxPacketLifeTime(){return this.#y}get maxRetransmits(){return this.#B}get protocol(){return this.#R}get negotiated(){return this.#A}get id(){return this.#w}get readyState(){return this.#N}get bufferedAmount(){return this.#b}get bufferedAmountLowThreshold(){return this.#O}set bufferedAmountLowThreshold(e){this.#O=e}get binaryType(){return this.#U}set binaryType(e){if("arraybuffer"!==e&&"blob"!==e)throw new TypeError('binaryType must be "arraybuffer" or "blob"');this.#U=e}get reliable(){return this.#S&&null===this.#y&&null===this.#B}send(e){if(this.#N!==N.OPEN)throw new Error('RTCDataChannel.readyState is not "open"');let t,r,s=0;if("string"==typeof e)t=Buffer.from(e,"utf8"),s=t.length,r=!1;else if(e instanceof ArrayBuffer)t=Buffer.from(e),s=e.byteLength,r=!0;else if(ArrayBuffer.isView(e))t=Buffer.from(e.buffer,e.byteOffset,e.byteLength),s=e.byteLength,r=!0;else{if(!Buffer.isBuffer(e))throw e&&"function"==typeof e.arrayBuffer?new Error("Blob sending not yet implemented"):new TypeError("Invalid data type");t=e,s=e.length,r=!0}if(!this.#D)throw new Error("Data channel not connected to a transport");this.#b+=s;try{this.emit(b.SEND,t,r),this.#b=Math.max(0,this.#b-s),this.#L()}catch(e){throw this.#b=Math.max(0,this.#b-s),this.emit("error",e),e}}#L(){this.#b<=this.#O&&this.emit("bufferedamountlow")}close(){this.#N!==N.CLOSING&&this.#N!==N.CLOSED&&(this.#v(N.CLOSING),setImmediate(()=>{this.#N===N.CLOSING&&this.#v(N.CLOSED)}))}#v(e){this.#N!==e&&(this.#N=e,e===N.OPEN?this.emit("open"):e===N.CLOSING?this.emit("closing"):e===N.CLOSED&&this.emit("close"))}#k(e,t){let r;r=t?"arraybuffer"===this.#U?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e:e.toString("utf8"),this.emit("message",{data:r})}}const U=Object.freeze({OFFER:"offer",PRANSWER:"pranswer",ANSWER:"answer",ROLLBACK:"rollback"});class D{#P;#_;constructor(e={}){if(this.#P=e.type||null,this.#_=e.sdp||null,this.#P&&!Object.values(U).includes(this.#P))throw new TypeError(`Invalid SDP type: ${this.#P}`)}get type(){return this.#P}set type(e){if(e&&!Object.values(U).includes(e))throw new TypeError(`Invalid SDP type: ${e}`);this.#P=e}get sdp(){return this.#_}set sdp(e){this.#_=e}toJSON(){return{type:this.#P,sdp:this.#_}}}function v(e){const{iceUfrag:t,icePwd:r,fingerprint:s,setup:i="actpass",candidates:n=[],sctpPort:o=5e3,maxMessageSize:c=262144}=e,h=[];h.push("v=0");const d=a.randomBytes(4).readUInt32BE(0);h.push(`o=- ${d} 2 IN IP4 127.0.0.1`),h.push("s=-"),h.push("t=0 0"),h.push("a=group:BUNDLE 0"),h.push("a=msid-semantic: WMS"),h.push("m=application 9 UDP/DTLS/SCTP webrtc-datachannel"),h.push("c=IN IP4 0.0.0.0"),h.push("a=ice-ufrag:"+t),h.push("a=ice-pwd:"+r),h.push("a=ice-options:trickle"),s&&h.push(`a=fingerprint:${s.algorithm} ${s.value}`),h.push(`a=setup:${i}`),h.push("a=mid:0"),h.push("a=sctp-port:"+o),h.push("a=max-message-size:"+c);for(const e of n){const t=e.sdp||e.candidate;t&&h.push("a="+(t.startsWith("candidate:")?t:"candidate:"+t))}return h.join("\r\n")+"\r\n"}function k(e){const t=(e.startsWith("candidate:")?e.slice(10):e).split(/\s+/);return t.length<8?null:{candidate:e.startsWith("candidate:")?e:"candidate:"+e,foundation:t[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10)>>>0,address:t[4],port:parseInt(t[5],10),type:t[7]}}const L=554869826,P=Object.freeze({BINDING_REQUEST:1,BINDING_SUCCESS:257,BINDING_ERROR:273}),_=Object.freeze({MAPPED_ADDRESS:1,USERNAME:6,MESSAGE_INTEGRITY:8,ERROR_CODE:9,XOR_MAPPED_ADDRESS:32,PRIORITY:36,USE_CANDIDATE:37,FINGERPRINT:32808,ICE_CONTROLLED:32809,ICE_CONTROLLING:32810});function x(e){return e+3&-4}const H=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})();class M{type;transactionId;attrs;constructor(e,t){this.type=e,this.transactionId=t||a.randomBytes(12),this.attrs=[]}addAttr(e,t){return this.attrs.push({type:e,value:t}),this}addUsername(e){return this.addAttr(_.USERNAME,Buffer.from(e,"utf8"))}addPriority(e){const t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),this.addAttr(_.PRIORITY,t)}addIceControlling(e){return this.addAttr(_.ICE_CONTROLLING,e)}addIceControlled(e){return this.addAttr(_.ICE_CONTROLLED,e)}addUseCandidate(){return this.addAttr(_.USE_CANDIDATE,Buffer.alloc(0))}addXorMappedAddress(e,t){return this.addAttr(_.XOR_MAPPED_ADDRESS,function(e,t){const r=Buffer.alloc(8);r.writeUInt8(0,0),r.writeUInt8(1,1),r.writeUInt16BE(8466^t,2);const s=e.split(".").map(Number),i=(s[0]<<24|s[1]<<16|s[2]<<8|s[3])>>>0;return r.writeUInt32BE((i^L)>>>0,4),r}(e,t,this.transactionId))}#x(){const e=[];for(const t of this.attrs){const r=Buffer.alloc(4);r.writeUInt16BE(t.type,0),r.writeUInt16BE(t.value.length,2);const s=Buffer.alloc(x(t.value.length));t.value.copy(s,0),e.push(r,s)}return Buffer.concat(e)}#H(e){const t=Buffer.alloc(20);return t.writeUInt16BE(this.type,0),t.writeUInt16BE(e,2),t.writeUInt32BE(L,4),this.transactionId.copy(t,8),t}build(e){let t=this.#x();if(e){const r=t.length+24,s=this.#H(r),i=a.createHmac("sha1",Buffer.from(e,"utf8")).update(Buffer.concat([s,t])).digest(),n=Buffer.alloc(4);n.writeUInt16BE(_.MESSAGE_INTEGRITY,0),n.writeUInt16BE(20,2),t=Buffer.concat([t,n,i])}const r=t.length+8,s=this.#H(r),i=(1398035790^function(e){let t=4294967295;for(let r=0;r<e.length;r++)t=H[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}(Buffer.concat([s,t])))>>>0,n=Buffer.alloc(8);return n.writeUInt16BE(_.FINGERPRINT,0),n.writeUInt16BE(4,2),n.writeUInt32BE(i,4),t=Buffer.concat([t,n]),Buffer.concat([this.#H(t.length),t])}}const F=Object.freeze({CHANGE_CIPHER_SPEC:20,ALERT:21,HANDSHAKE:22,APPLICATION_DATA:23}),K=Object.freeze({HELLO_REQUEST:0,CLIENT_HELLO:1,SERVER_HELLO:2,HELLO_VERIFY_REQUEST:3,CERTIFICATE:11,SERVER_KEY_EXCHANGE:12,CERTIFICATE_REQUEST:13,SERVER_HELLO_DONE:14,CERTIFICATE_VERIFY:15,CLIENT_KEY_EXCHANGE:16,FINISHED:20}),q=Object.freeze({WARNING:1,FATAL:2}),G=Object.freeze({CLOSE_NOTIFY:0,HANDSHAKE_FAILURE:40,BAD_CERTIFICATE:42,DECRYPT_ERROR:51,INTERNAL_ERROR:80}),z=49195,j=Object.freeze({secp256r1:23}),$=Object.freeze({uncompressed:0}),V=Object.freeze({sha256:4,sha384:5,sha512:6}),W=Object.freeze({rsa:1,ecdsa:3}),Y=Object.freeze({ecdsa_sign:64,rsa_sign:1}),X=Object.freeze({SUPPORTED_GROUPS:10,EC_POINT_FORMATS:11,SIGNATURE_ALGORITHMS:13,EXTENDED_MASTER_SECRET:23,RENEGOTIATION_INFO:65281}),Q=Object.freeze({CLIENT:"client finished",SERVER:"server finished"});function Z(e){return Buffer.from([e>>16&255,e>>8&255,255&e])}function J(e,t){return e[t]<<16|e[t+1]<<8|e[t+2]}function ee(e){return Buffer.concat([Buffer.from([e.length]),e])}function te(e){const t=Buffer.alloc(2);return t.writeUInt16BE(e.length,0),Buffer.concat([t,e])}function re(e){return Buffer.concat([Z(e.length),e])}function se(e,t,r){const s=Buffer.alloc(12);return s.writeUInt8(e,0),Z(r.length).copy(s,1),s.writeUInt16BE(t,4),Z(0).copy(s,6),Z(r.length).copy(s,9),Buffer.concat([s,r])}function ie(e,t,r,s){return function(e,t,r,s){const i=[];let n=0,o=r;for(;n<s;){o=a.createHmac(e,t).update(o).digest();const s=a.createHmac(e,t).update(Buffer.concat([o,r])).digest();i.push(s),n+=s.length}return Buffer.concat(i).slice(0,s)}("sha256",e,Buffer.concat([Buffer.from(t,"ascii"),r]),s)}function ne(e,t,r){return ie(e,"master secret",Buffer.concat([t,r]),48)}function ae(e,t){return ie(e,"extended master secret",t,48)}function oe(e,t,r,s,i){const n=Buffer.alloc(13);return n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6),n.writeUInt8(r,8),n.writeUInt16BE(s,9),n.writeUInt16BE(i,11),n}class ce{#M;#F;constructor(e,t){this.#M=e,this.#F=t}encrypt(e,t,r,s,i){const n=Buffer.alloc(8);n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6);const o=Buffer.concat([this.#F,n]),c=oe(e,t,r,s,i.length),h=a.createCipheriv("aes-128-gcm",this.#M,o);h.setAAD(c);const d=Buffer.concat([h.update(i),h.final()]),l=h.getAuthTag();return Buffer.concat([n,d,l])}decrypt(e,t,r,s,i){const n=i.slice(0,8),o=i.slice(i.length-16),c=i.slice(8,i.length-16),h=Buffer.concat([this.#F,n]),d=oe(e,t,r,s,c.length),l=a.createDecipheriv("aes-128-gcm",this.#M,h);return l.setAAD(d),l.setAuthTag(o),Buffer.concat([l.update(c),l.final()])}}const he=Object.freeze({CLIENT:"client",SERVER:"server"}),de=Object.freeze({NEW:"new",HANDSHAKING:"handshaking",CONNECTED:"connected",CLOSED:"closed",FAILED:"failed"});class le extends t.EventEmitter{role;state;#p;#E;#K;#q;#G;#z;#j;#$;#V;#W;#Y;#X;#Q;#Z;#J;#ee;#te;#re;#se;#ie;#ne;#ae;#oe;#ce;#he;#de;#le;#ue;constructor(e){super(),this.role=e.role,this.#p=e.certDer,this.#E=e.privateKey,this.#K=e.verifyFingerprint||null,this.#q=e.output,this.state=de.NEW,this.#G=0,this.#z=0,this.#j=0,this.#$=null,this.#V=null,this.#W=!1,this.#Y=null,this.#X=null,this.#Q=Buffer.alloc(0),this.#Z=null,this.#J=null,this.#ee=null,this.#te=null,this.#re=!1,this.#se=[],this.#ie=new Map,this.#ne=0,this.#ae=[],this.#oe=null,this.#ce=0,this.#he=!1,this.#ue=!1}start(){this.state===de.NEW&&(this.state=de.HANDSHAKING,this.role===he.CLIENT&&(this.#Y=this.#fe(),this.#pe()))}#fe(){const e=a.randomBytes(32);return e.writeUInt32BE(Math.floor(Date.now()/1e3),0),e}#Ee(e){const t=[];for(const r of e){const e=this.#j++,s=se(r.type,e,r.body);this.#se.push(s);const i=r.body.length;let n=0;do{const s=r.body.slice(n,n+1200),a=Buffer.alloc(12);a.writeUInt8(r.type,0),Z(i).copy(a,1),a.writeUInt16BE(e,4),Z(n).copy(a,6),Z(s.length).copy(a,9);const o=Buffer.concat([a,s]);t.push({type:F.HANDSHAKE,payload:o}),n+=s.length}while(n<i)}this.#ae=t,this.#ce=0,this.#me(),this.#ge()}#me(){for(const e of this.#ae)this.#Ie(e.type,e.payload)}#Te(){this.#Ie(F.CHANGE_CIPHER_SPEC,Buffer.from([1])),this.#G=1,this.#z=0,this.#W=!0}#Ie(e,t){let r=t;const s=this.#z++;this.#W&&this.#$&&(r=this.#$.encrypt(this.#G,s,e,65277,t));const i=function(e,t,r,s,i=65277){const n=Buffer.alloc(13);return n.writeUInt8(e,0),n.writeUInt16BE(i,1),n.writeUInt16BE(t,3),n.writeUIntBE(r,5,6),n.writeUInt16BE(s.length,11),Buffer.concat([n,s])}(e,this.#G,s,r,65277);this.#q(i)}#ge(){this.#Ce(),this.#oe=setTimeout(()=>{this.#he||this.state!==de.HANDSHAKING||(this.#ce>=10?this.#Se(new Error("DTLS handshake timed out")):(this.#ce++,this.#me(),this.#ge()))},1e3*Math.pow(2,this.#ce)),this.#oe.unref&&this.#oe.unref()}#Ce(){this.#oe&&(clearTimeout(this.#oe),this.#oe=null)}handlePacket(e){if(this.state===de.CLOSED||this.state===de.FAILED)return;let t;try{t=function(e){const t=[];let r=0;for(;r+13<=e.length;){const s=e.readUInt8(r),i=e.readUInt16BE(r+1),n=e.readUInt16BE(r+3),a=e.readUIntBE(r+5,6),o=e.readUInt16BE(r+11),c=r+13;if(c+o>e.length)break;t.push({type:s,version:i,epoch:n,seq:a,fragment:e.slice(c,c+o)}),r=c+o}return t}(e)}catch(e){return}for(const e of t)try{this.#ye(e)}catch(e){return void this.#Se(e instanceof Error?e:new Error(String(e)))}}#ye(e){let t=e.fragment;if(e.epoch>=1){if(!this.#V)return;t=this.#V.decrypt(e.epoch,e.seq,e.type,e.version,e.fragment)}switch(e.type){case F.HANDSHAKE:this.#Be(t);break;case F.CHANGE_CIPHER_SPEC:break;case F.APPLICATION_DATA:this.state===de.CONNECTED&&this.emit("data",t);break;case F.ALERT:this.#Re(t)}}#Re(e){if(e.length<2)return;const t=e[0],r=e[1];r===G.CLOSE_NOTIFY?this.close():t===q.FATAL&&this.#Se(new Error(`DTLS fatal alert: ${r}`))}#Be(e){const t=function(e){const t=e.readUInt8(0),r=J(e,1),s=e.readUInt16BE(4),i=J(e,6),n=J(e,9);return{msgType:t,length:r,messageSeq:s,fragmentOffset:i,fragmentLength:n,body:e.slice(12,12+n)}}(e);let r=this.#ie.get(t.messageSeq);for(r||(r={type:t.msgType,length:t.length,data:Buffer.alloc(t.length),received:0,ranges:[]},this.#ie.set(t.messageSeq,r)),t.body.copy(r.data,t.fragmentOffset),r.received=Math.max(r.received,t.fragmentOffset+t.fragmentLength);;){const e=this.#ie.get(this.#ne);if(!e||e.received<e.length)break;this.#ie.delete(this.#ne),this.#ne++,this.#Ae(e.type,e.data)}}#we(e,t){const r=this.#ne-1;this.#se.push(se(e,r,t))}#Ae(e,t){this.role===he.CLIENT?this.#Ne(e,t):this.#be(e,t)}#Oe(){const e=a.createHash("sha256");for(const t of this.#se)e.update(t);return e.digest()}#Ue(){return Buffer.concat(this.#se)}#pe(){const e=this.#De();if(0===this.#Q.length){const t=this.#j++,r=se(K.CLIENT_HELLO,t,e);this.#ae=[{type:F.HANDSHAKE,payload:r}],this.#me(),this.#ge()}else{const t=this.#j++,r=se(K.CLIENT_HELLO,t,e);this.#se.push(r),this.#ae=[{type:F.HANDSHAKE,payload:r}],this.#ce=0,this.#me(),this.#ge()}}#De(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#Y),e.push(ee(Buffer.alloc(0))),e.push(ee(this.#Q));const t=Buffer.alloc(2);return t.writeUInt16BE(z,0),e.push(te(t)),e.push(ee(Buffer.from([0]))),e.push(te(this.#ve())),Buffer.concat(e)}#ve(){const e=[],t=Buffer.alloc(2);t.writeUInt16BE(j.secp256r1,0),e.push(this.#ke(X.SUPPORTED_GROUPS,te(t))),e.push(this.#ke(X.EC_POINT_FORMATS,ee(Buffer.from([$.uncompressed]))));const r=Buffer.from([V.sha256,W.ecdsa]);return e.push(this.#ke(X.SIGNATURE_ALGORITHMS,te(r))),e.push(this.#ke(X.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),Buffer.concat(e)}#ke(e,t){const r=Buffer.alloc(4);return r.writeUInt16BE(e,0),r.writeUInt16BE(t.length,2),Buffer.concat([r,t])}#Ne(e,t){switch(e){case K.HELLO_VERIFY_REQUEST:{const e=t.readUInt8(2);this.#Q=t.slice(3,3+e),this.#Ce(),this.#pe();break}case K.SERVER_HELLO:this.#we(e,t),this.#Le(t);break;case K.CERTIFICATE:this.#we(e,t),this.#ee=this.#Pe(t);break;case K.SERVER_KEY_EXCHANGE:this.#we(e,t),this.#_e(t);break;case K.CERTIFICATE_REQUEST:this.#ue=!0,this.#we(e,t);break;case K.SERVER_HELLO_DONE:this.#we(e,t),this.#Ce(),this.#xe();break;case K.FINISHED:this.#He(t,Q.SERVER),this.#we(e,t),this.#Me()}}#Le(e){let t=2;this.#X=e.slice(t,t+32),t+=32,t+=1+e.readUInt8(t);const r=e.readUInt16BE(t);if(t+=2,r!==z)throw new Error(`Server chose unsupported cipher suite 0x${r.toString(16)}`);if(t+=1,t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===X.EXTENDED_MASTER_SECRET&&(this.#re=!0),t+=s}}}#xe(){this.#Z=a.createECDH("prime256v1"),this.#Z.generateKeys();const e=this.#Z.getPublicKey(),t=this.#Z.computeSecret(this.#te),r=ee(e),s=this.#ue;let i=null,n=Buffer.alloc(0);const o=s?this.#j+1:this.#j;s&&(i=this.#Fe(),n=se(K.CERTIFICATE,this.#j,i));const c=se(K.CLIENT_KEY_EXCHANGE,o,r);if(this.#re){const e=a.createHash("sha256");for(const t of this.#se)e.update(t);s&&e.update(n),e.update(c);const r=e.digest();this.#J=ae(t,r)}else this.#J=ne(t,this.#Y,this.#X);this.#Ke();const h=[];if(s&&h.push({type:K.CERTIFICATE,body:i}),h.push({type:K.CLIENT_KEY_EXCHANGE,body:r}),s){const e=Buffer.concat([...this.#se,n,c]),t=a.sign("sha256",e,{key:this.#E,dsaEncoding:"der"}),r=Buffer.concat([Buffer.from([V.sha256,W.ecdsa]),te(t)]);h.push({type:K.CERTIFICATE_VERIFY,body:r})}this.#Ee(h),this.#Te(),this.#qe(Q.CLIENT)}#be(e,t){switch(e){case K.CLIENT_HELLO:this.#Ge(t);break;case K.CERTIFICATE:this.#we(e,t),this.#ee=this.#Pe(t);break;case K.CLIENT_KEY_EXCHANGE:{this.#we(e,t);const r=t.readUInt8(0);this.#te=t.slice(1,1+r);const s=this.#Z.computeSecret(this.#te);this.#re?this.#J=ae(s,this.#Oe()):this.#J=ne(s,this.#Y,this.#X),this.#Ke();break}case K.CERTIFICATE_VERIFY:this.#ze(t),this.#we(e,t);break;case K.FINISHED:this.#He(t,Q.CLIENT),this.#we(e,t),this.#Te(),this.#qe(Q.SERVER),this.#Me()}}#Ge(e){let t=2;const r=e.slice(t,t+32);t+=32,t+=1+e.readUInt8(t);const s=e.readUInt8(t),i=e.slice(t+1,t+1+s);t+=1+s;const n=e.readUInt16BE(t),a=e.slice(t+2,t+2+n);t+=2+n,t+=1+e.readUInt8(t);let o=!1,c=!1;for(let e=0;e+1<a.length;e+=2)255===a.readUInt16BE(e)&&(c=!0);if(t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===X.EXTENDED_MASTER_SECRET&&(o=!0),r===X.RENEGOTIATION_INFO&&(c=!0),t+=s}}if(this.#le=c,0===i.length)return this.#Y=r,this.#je(this.#$e(r)),this.#ie.clear(),void(this.#ne=1);const h=this.#$e(r);if(!i.equals(h))return this.#je(h),this.#ie.clear(),void(this.#ne=1);this.#Y=r,this.#re=o,this.#we(K.CLIENT_HELLO,e),this.#Ve()}#$e(e){return this.#de||(this.#de=a.randomBytes(32)),a.createHmac("sha256",this.#de).update(e).digest().slice(0,20)}#je(e){const t=Buffer.concat([Buffer.from([254,255]),ee(e)]),r=se(K.HELLO_VERIFY_REQUEST,0,t);this.#Ie(F.HANDSHAKE,r),this.#j=1}#Ve(){this.#X=this.#fe(),this.#Z=a.createECDH("prime256v1"),this.#Z.generateKeys();const e=this.#Z.getPublicKey(),t=this.#We(),r=this.#Fe(),s=Buffer.concat([Buffer.from([3]),(()=>{const e=Buffer.alloc(2);return e.writeUInt16BE(j.secp256r1,0),e})(),ee(e)]),i=Buffer.concat([this.#Y,this.#X,s]),n=a.sign("sha256",i,{key:this.#E,dsaEncoding:"der"}),o=Buffer.concat([s,Buffer.from([V.sha256,W.ecdsa]),te(n)]),c=ee(Buffer.from([Y.ecdsa_sign,Y.rsa_sign])),h=te(Buffer.from([V.sha256,W.ecdsa])),d=te(Buffer.alloc(0)),l=Buffer.concat([c,h,d]),u=Buffer.alloc(0);this.#Ee([{type:K.SERVER_HELLO,body:t},{type:K.CERTIFICATE,body:r},{type:K.SERVER_KEY_EXCHANGE,body:o},{type:K.CERTIFICATE_REQUEST,body:l},{type:K.SERVER_HELLO_DONE,body:u}])}#We(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#X),e.push(ee(Buffer.alloc(0)));const t=Buffer.alloc(2);t.writeUInt16BE(z,0),e.push(t),e.push(Buffer.from([0]));const r=[];return this.#re&&r.push(this.#ke(X.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),r.push(this.#ke(X.EC_POINT_FORMATS,ee(Buffer.from([$.uncompressed])))),this.#le&&r.push(this.#ke(X.RENEGOTIATION_INFO,ee(Buffer.alloc(0)))),e.push(te(Buffer.concat(r))),Buffer.concat(e)}#ze(e){const t=e.readUInt16BE(2),r=e.slice(4,4+t),s=this.#Ue(),i=this.#Ye(this.#ee);if(!a.verify("sha256",s,{key:i,dsaEncoding:"der"},r))throw new Error("Client CertificateVerify signature invalid")}#Fe(){const e=re(this.#p);return re(e)}#Pe(e){let t=3;if(t+3>3+J(e,0))return null;const r=J(e,t);t+=3;const s=e.slice(t,t+r);if(this.#K){const e={algorithm:"sha-256",value:R(s,"sha-256")};if(!this.#K(e,s))throw new Error("Remote certificate fingerprint mismatch")}return s}#_e(e){let t=0;const r=e.readUInt8(t);t+=1;const s=e.readUInt16BE(t);if(t+=2,3!==r||s!==j.secp256r1)throw new Error("Unsupported ECDHE curve from server");const i=e.readUInt8(t);t+=1;const n=e.slice(t,t+i);t+=i,this.#te=n;const o=e.slice(0,t);t+=2;const c=e.readUInt16BE(t);t+=2;const h=e.slice(t,t+c),d=Buffer.concat([this.#Y,this.#X,o]),l=this.#Ye(this.#ee);if(!a.verify("sha256",d,{key:l,dsaEncoding:"der"},h))throw new Error("ServerKeyExchange signature invalid")}#Ye(e){return new a.X509Certificate(e).publicKey}#Ke(){const{clientKey:e,serverKey:t,clientIV:r,serverIV:s}=function(e,t,r){const s=ie(e,"key expansion",Buffer.concat([r,t]),40);let i=0;return{clientKey:s.slice(i,i+=16),serverKey:s.slice(i,i+=16),clientIV:s.slice(i,i+=4),serverIV:s.slice(i,i+=4)}}(this.#J,this.#Y,this.#X);this.role===he.CLIENT?(this.#$=new ce(e,r),this.#V=new ce(t,s)):(this.#$=new ce(t,s),this.#V=new ce(e,r))}#qe(e){const t=ie(this.#J,e,this.#Oe(),12),r=this.#j++,s=se(K.FINISHED,r,t);this.#se.push(s),this.#Ie(F.HANDSHAKE,s)}#He(e,t){const r=ie(this.#J,t,this.#Oe(),12);if(!a.timingSafeEqual(e,r))throw new Error("Peer Finished verify_data mismatch")}#Me(){this.#he||(this.#he=!0,this.#Ce(),this.state=de.CONNECTED,this.emit("connect"))}send(e){if(this.state!==de.CONNECTED)throw new Error("DTLS connection not established");this.#Ie(F.APPLICATION_DATA,e)}close(){if(this.state!==de.CLOSED&&this.state!==de.FAILED){try{this.#W&&this.#Ie(F.ALERT,Buffer.from([q.WARNING,G.CLOSE_NOTIFY]))}catch(e){}this.#Ce(),this.state=de.CLOSED,this.emit("close")}}#Se(e){this.state!==de.FAILED&&this.state!==de.CLOSED&&(this.#Ce(),this.state=de.FAILED,this.emit("error",e))}getRemoteCertificate(){return this.#ee}}const ue=554869826;class fe extends t.EventEmitter{#Xe;#Qe;#Ze;#Je;#et;#tt;#rt;#st;#it;#nt;#at;#ot;#ct;#ht;constructor(e){super(),this.#Xe=e.server,this.#Qe=e.port,this.#Ze=e.username,this.#Je=e.credential,this.#et=null,this.#tt=new Map,this.#rt=null,this.#st=null,this.#it=!0===e.secure,this.#nt=(e.transport||"udp").toLowerCase(),this.#at=!1!==e.rejectUnauthorized,this.#ot=null,this.#ct=null,this.#ht=Buffer.alloc(0)}async connect(){if(!this.#et&&!this.#ct)return this.#it&&"tcp"===this.#nt?this.#dt():new Promise((e,t)=>{const r=o.createSocket("udp4");if(this.#et=r,r.on("error",e=>{console.error("STUN socket error:",e),t(e)}),this.#it){const s=B({commonName:"nodertc-turn-client"}),i=new le({role:he.CLIENT,certDer:s.certDer,privateKey:s.privateKey,verifyFingerprint:()=>!0,output:e=>{r.send(e,this.#Qe,this.#Xe,()=>{})}});this.#ot=i,r.on("message",e=>i.handlePacket(e)),i.on("data",e=>this.#lt(e,this.#ut())),i.on("connect",()=>e()),i.on("error",e=>t(e)),r.bind(()=>i.start())}else r.on("message",(e,t)=>{this.#lt(e,t)}),r.bind(()=>e())})}#dt(){return new Promise((e,t)=>{const r=h.connect({host:this.#Xe,port:this.#Qe,rejectUnauthorized:this.#at},()=>e());this.#ct=r,r.on("data",e=>this.#ft(e)),r.on("error",e=>t(e))})}#ft(e){for(this.#ht=this.#ht.length?Buffer.concat([this.#ht,e]):e;this.#ht.length>=20;){const e=20+this.#ht.readUInt16BE(2);if(this.#ht.length<e)break;const t=this.#ht.subarray(0,e);this.#ht=this.#ht.subarray(e),this.#lt(t,this.#ut())}}#ut(){return{address:this.#Xe,family:"IPv4",port:this.#Qe,size:0}}#pt(e,t){if(this.#ct)this.#ct.write(e,e=>{e&&t(e)});else if(this.#ot)try{this.#ot.send(e)}catch(e){t(e instanceof Error?e:new Error(String(e)))}else this.#et.send(e,this.#Qe,this.#Xe,e=>{e&&t(e)})}async getReflexiveAddress(){await this.connect();const e=a.randomBytes(12),t=this.#Et(e);return new Promise((r,s)=>{const i=setTimeout(()=>{this.#tt.delete(e.toString("hex")),s(new Error("STUN request timeout"))},5e3);this.#tt.set(e.toString("hex"),{resolve:e=>{clearTimeout(i),r(e)},reject:e=>{clearTimeout(i),s(e)}}),this.#pt(t,t=>{clearTimeout(i),this.#tt.delete(e.toString("hex")),s(t)})})}async allocateRelay(e=600){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");await this.connect();let t=a.randomBytes(12),r=this.#mt(t,e);try{return await this.#gt(r,t,"allocate")}catch(s){if(s instanceof Error&&s.message.includes("401")&&this.#rt&&this.#st)return t=a.randomBytes(12),r=this.#mt(t,e,!0),await this.#gt(r,t,"allocate");throw s}}async refreshAllocation(e=600){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");return this.#It("refresh",()=>{const t=a.randomBytes(12);return{transactionId:t,request:this.#Tt(t,e)}})}async#It(e,t){const r=t();try{return await this.#gt(r.request,r.transactionId,e)}catch(r){if(r instanceof Error&&r.message.includes("401")&&this.#rt&&this.#st){const r=t();return this.#gt(r.request,r.transactionId,e)}throw r}}async createPermission(e){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");await this.#It("createPermission",()=>{const t=a.randomBytes(12);return{transactionId:t,request:this.#Ct(t,e)}})}async sendIndication(e,t,r){if(!this.#Ze||!this.#Je)throw new Error("TURN requires username and credential");const s=a.randomBytes(12),i=this.#St(s,e,t,r);return new Promise((e,t)=>{this.#pt(i,t),e()})}#gt(e,t,r){return new Promise((s,i)=>{const n=setTimeout(()=>{this.#tt.delete(t.toString("hex")),i(new Error(`${r} request timeout`))},5e3);this.#tt.set(t.toString("hex"),{type:r,resolve:e=>{clearTimeout(n),s(e)},reject:e=>{clearTimeout(n),i(e)}}),this.#pt(e,e=>{clearTimeout(n),this.#tt.delete(t.toString("hex")),i(e)})})}#Et(e){const t=Buffer.alloc(20);return t.writeUInt16BE(1,0),t.writeUInt16BE(0,2),t.writeUInt32BE(ue,4),e.copy(t,8),t}#mt(e,t,r=!1){const s=[],i=Buffer.alloc(8);i.writeUInt16BE(25,0),i.writeUInt16BE(4,2),i.writeUInt8(17,4),s.push(i);const n=Buffer.alloc(8);if(n.writeUInt16BE(13,0),n.writeUInt16BE(4,2),n.writeUInt32BE(t,4),s.push(n),r&&this.#rt&&this.#st){const e=this.#yt(6,this.#Ze);s.push(e);const t=this.#yt(20,this.#rt);s.push(t);const r=this.#yt(21,this.#st);s.push(r)}return this.#Bt(3,e,s,r)}#Ct(e,t){const r=[],s=this.#Rt(t,0,e);return r.push(s),this.#rt&&this.#st&&(r.push(this.#yt(6,this.#Ze)),r.push(this.#yt(20,this.#rt)),r.push(this.#yt(21,this.#st))),this.#Bt(8,e,r,!0)}#St(e,t,r,s){const i=[],n=this.#Rt(t,r,e);i.push(n);const a=Buffer.alloc(4+s.length+(4-s.length%4)%4);return a.writeUInt16BE(19,0),a.writeUInt16BE(s.length,2),s.copy(a,4),i.push(a),this.#Bt(22,e,i,!1)}#Rt(e,t,r){const s=Buffer.alloc(12);s.writeUInt16BE(18,0),s.writeUInt16BE(8,2),s.writeUInt8(0,4),s.writeUInt8(1,5);const i=8466^t;s.writeUInt16BE(i,6);const n=e.split(".").map(Number),a=(n[0]<<24|n[1]<<16|n[2]<<8|n[3])^ue;return s.writeUInt32BE(a>>>0,8),s}#Tt(e,t){const r=[],s=Buffer.alloc(8);s.writeUInt16BE(13,0),s.writeUInt16BE(4,2),s.writeUInt32BE(t,4),r.push(s);const i=this.#yt(6,this.#Ze);if(r.push(i),this.#rt){const e=this.#yt(20,this.#rt);r.push(e)}if(this.#st){const e=this.#yt(21,this.#st);r.push(e)}return this.#Bt(4,e,r,!0)}#Bt(e,t,r,s=!1){let i=Buffer.concat(r);if(s&&this.#Je){const r=Buffer.alloc(20);r.writeUInt16BE(e,0),r.writeUInt16BE(i.length+24,2),r.writeUInt32BE(ue,4),t.copy(r,8);const s=Buffer.concat([r,i]);let n=this.#Je;if(this.#Ze&&this.#rt){const e=`${this.#Ze}:${this.#rt}:${this.#Je}`;n=a.createHash("sha256").update(e).digest()}const o=a.createHmac("sha256",n);o.update(s);const c=o.digest(),h=Buffer.alloc(4+c.length);h.writeUInt16BE(8,0),h.writeUInt16BE(c.length,2),c.copy(h,4),i=Buffer.concat([i,h])}const n=Buffer.alloc(20);return n.writeUInt16BE(e,0),n.writeUInt16BE(i.length,2),n.writeUInt32BE(ue,4),t.copy(n,8),Buffer.concat([n,i])}#yt(e,t){const r=Buffer.from(t,"utf8"),s=r.length,i=(4-s%4)%4,n=Buffer.alloc(4+s+i);return n.writeUInt16BE(e,0),n.writeUInt16BE(s,2),r.copy(n,4),n}#lt(e,t){if(e.length<20)return;const r=e.readUInt16BE(0),s=e.readUInt16BE(2),i=e.readUInt32BE(4),n=e.slice(8,20);if(i!==ue)return;if(23===r){const t=this.#At(e.slice(20,20+s),n);if(t.xorPeerAddress&&t.data){const e={address:t.xorPeerAddress.address,port:t.xorPeerAddress.port,family:t.xorPeerAddress.family||"IPv4"};this.emit("data",t.data,e)}return}const a=n.toString("hex"),o=this.#tt.get(a);if(!o)return;const c=this.#At(e.slice(20,20+s),n);if(257===r)c.xorMappedAddress?o.resolve({address:c.xorMappedAddress.address,port:c.xorMappedAddress.port,family:c.xorMappedAddress.family}):c.mappedAddress?o.resolve({address:c.mappedAddress.address,port:c.mappedAddress.port,family:c.mappedAddress.family}):o.reject(new Error("No mapped address in STUN response")),this.#tt.delete(a);else if(259===r)c.xorRelayedAddress?o.resolve({relayedAddress:c.xorRelayedAddress.address,relayedPort:c.xorRelayedAddress.port,lifetime:c.lifetime||600,type:"relay"}):o.reject(new Error("No relayed address in ALLOCATE response")),this.#tt.delete(a);else if(260===r)o.resolve({lifetime:c.lifetime||600}),this.#tt.delete(a);else if(264===r||265===r)o.resolve({ok:!0}),this.#tt.delete(a);else if(!(272&~r)){c.realm&&(this.#rt=c.realm),c.nonce&&(this.#st=c.nonce);const e=c.errorCode||"Unknown error";o.reject(new Error(`STUN error: ${e}`)),this.#tt.delete(a)}}#At(e,t){const r={};let s=0;for(;s<e.length&&!(s+4>e.length);){const i=e.readUInt16BE(s),n=e.readUInt16BE(s+2);if(s+=4,s+n>e.length)break;const a=e.slice(s,s+n);switch(i){case 32:r.xorMappedAddress=this.#wt(a,t);break;case 22:r.xorRelayedAddress=this.#wt(a,t);break;case 18:r.xorPeerAddress=this.#wt(a,t);break;case 19:r.data=a;break;case 1:r.mappedAddress=this.#Nt(a);break;case 13:r.lifetime=a.readUInt32BE(0);break;case 9:r.errorCode=this.#bt(a);break;case 20:r.realm=a.toString("utf8"),this.#rt=r.realm;break;case 21:r.nonce=a.toString("utf8"),this.#st=r.nonce}s+=n,s+=(4-n%4)%4}return r}#wt(e,t){const r=e.readUInt8(1),s=8466^e.readUInt16BE(2);if(1===r){const t=e.readUInt32BE(4)^ue;return{family:"IPv4",port:s,address:[t>>24&255,t>>16&255,t>>8&255,255&t].join(".")}}return null}#Nt(e){const t=e.readUInt8(1),r=e.readUInt16BE(2);if(1===t){const t=e.slice(4,8);return{family:"IPv4",port:r,address:Array.from(t).join(".")}}return null}#bt(e){return`${100*(7&e.readUInt8(2))+e.readUInt8(3)} ${e.slice(4).toString("utf8")}`}close(){if(this.#ot){try{this.#ot.close()}catch(e){}this.#ot=null}if(this.#ct){try{this.#ct.destroy()}catch(e){}this.#ct=null}this.#et&&(this.#et.close(),this.#et=null),this.#tt.clear()}}const pe={host:126,srflx:100,prflx:110,relay:0};function Ee(e){const t=e.match(/^(stuns?|turns?):\/?\/?([^:?]+):?(\d+)?(?:\?(.+))?$/);if(!t)return null;const r=t[1],s=t[2],i={};if(t[4])for(const e of t[4].split("&")){if(!e)continue;const t=e.indexOf("=");-1===t?i[e]=!0:i[e.slice(0,t)]=e.slice(t+1)}const n="turns"===r||"stuns"===r?5349:3478;return{scheme:r,protocol:r,host:s,port:parseInt(t[3]||String(n),10),transport:"string"==typeof i.transport?i.transport:"udp",params:i}}class me{kind;#et;onMessage;constructor(e){this.kind="host",this.#et=e,this.onMessage=null,e.on("message",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){this.#et.send(e,r,t)}close(){try{this.#et.close()}catch(e){}}}class ge{kind;#Ot;onMessage;#Ut;constructor(e){this.kind="relay",this.#Ot=e,this.onMessage=null,this.#Ut=new Set,e.on("data",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){const s=`${t}:${r}`;this.#Ut.has(s)?this.#Ot.sendIndication(t,r,e).catch(()=>{}):(this.#Ut.add(s),this.#Ot.createPermission(t).then(()=>this.#Ot.sendIndication(t,r,e)).catch(()=>{}))}close(){try{this.#Ot.close()}catch(e){}}}class Ie extends t.EventEmitter{role;localUfrag;localPwd;remoteUfrag;remotePwd;#Dt;#vt;#kt;#Lt;#Pt;#_t;#xt;#Ht;#Mt;#D;#Ft;constructor(e){super(),this.role=e.role,this.localUfrag=e.localUfrag,this.localPwd=e.localPwd,this.remoteUfrag=null,this.remotePwd=null,this.#Dt=a.randomBytes(8),this.#vt=[],this.#kt=[],this.#Lt=[],this.#Pt=[],this.#_t=null,this.#xt=!1,this.#Ht=null,this.#Mt=null,this.#D=!1,this.#Ft=new Map}async gather(e={}){const t=e.iceServers||[],r="relay"===e.iceTransportPolicy,s=await this.#Kt();for(const e of t){const t=Array.isArray(e.urls)?e.urls:[e.urls];for(const i of t){const t=Ee(i);if(!t)continue;const n="turns"===t.scheme&&"tcp"===t.transport;if("udp"===t.transport||n)try{"stun"!==t.scheme||r?"turn"!==t.scheme&&"turns"!==t.scheme||await this.#qt(t,e):await this.#Gt(t,s[0])}catch(e){this.emit("gathererror",{url:i,error:e instanceof Error?e.message:String(e)})}}}r&&(this.#kt=this.#kt.filter(e=>"relay"===e.type)),this.emit("gatheringcomplete")}async#Kt(){const e=c.networkInterfaces(),t=[];for(const r of Object.values(e))if(r)for(const e of r)"IPv4"!==e.family||e.internal||t.push(e.address);0===t.length&&t.push("127.0.0.1");const r=[];for(const e of t)r.push(await this.#zt(e));return r}#zt(e){return new Promise((t,r)=>{const s=o.createSocket("udp4");s.on("error",e=>this.emit("error",e)),s.bind(0,e,()=>{const{port:r}=s.address(),i=new me(s);i.onMessage=(e,t)=>this.#jt(i,e,t),this.#vt.push(i);const n=this.#$t("host",e,r,i);t({socket:s,address:e,port:r,transport:i,candidate:n})})})}async#Gt(e,t){if(!t)return;const r=new fe({server:e.host,port:e.port});try{const e=await r.getReflexiveAddress();this.#$t("srflx",e.address,e.port,t.transport,{relatedAddress:t.address,relatedPort:t.port})}finally{r.close()}}async#qt(e,t){if(!t.username||!t.credential)throw new Error("TURN server requires username and credential");const r=new fe({server:e.host,port:e.port,username:t.username,credential:t.credential,transport:e.transport,secure:"turns"===e.scheme,rejectUnauthorized:t.rejectUnauthorized}),s=await r.allocateRelay(600),i=new ge(r);i.onMessage=(e,t)=>this.#jt(i,e,t),this.#vt.push(i),this.#$t("relay",s.relayedAddress,s.relayedPort,i,{relatedAddress:e.host,relatedPort:e.port})}#$t(e,t,r,s,i={}){const n=a.createHash("md5").update(`${e}:${t}:${s.kind}`).digest("hex").slice(0,8),o=function(e,t=65535,r=1){return(pe[e]<<24)+(t<<8)+(256-r)>>>0}(e);let c=`candidate:${n} 1 udp ${o} ${t} ${r} typ ${e}`;i.relatedAddress&&(c+=` raddr ${i.relatedAddress} rport ${i.relatedPort}`);const h={foundation:n,component:1,protocol:"udp",priority:o,address:t,port:r,type:e,transport:s,sdp:c};return this.#kt.push(h),this.emit("candidate",h),h}getLocalCandidates(){return this.#kt.slice()}setRemoteCredentials(e,t){this.remoteUfrag=e,this.remotePwd=t}addRemoteCandidate(e){e&&e.address&&e.port&&("string"==typeof e.address&&e.address.endsWith(".local")||(this.#Lt.push(e),this.#Vt(),!this.#Ht&&this.remotePwd&&this.#Wt()))}start(){this.remotePwd&&this.#Lt.length>0&&this.#Wt()}#Vt(){for(const e of this.#kt)for(const t of this.#Lt){const r=`${e.type}:${e.address}:${e.port}->${t.address}:${t.port}`;this.#Pt.find(e=>e.key===r)||this.#Pt.push({key:r,local:e,remote:t,state:"frozen",nominated:!1})}}#Wt(){this.#Ht||this.#xt||(this.#Ht=setInterval(()=>this.#Yt(),50),this.#Ht.unref&&this.#Ht.unref(),this.#Mt=setTimeout(()=>{this.#D||this.emit("failed"),this.#Xt()},1e4),this.#Mt.unref&&this.#Mt.unref(),this.#Yt())}#Xt(){this.#Ht&&(clearInterval(this.#Ht),this.#Ht=null),this.#Mt&&(clearTimeout(this.#Mt),this.#Mt=null)}#Yt(){if(!this.#xt)for(const e of this.#Pt)"succeeded"!==e.state&&this.#Qt(e)}#Qt(e){const t=a.randomBytes(12),r=`${this.remoteUfrag}:${this.localUfrag}`,s=new M(P.BINDING_REQUEST,t).addUsername(r).addPriority(e.local.priority);"controlling"===this.role?(s.addIceControlling(this.#Dt),s.addUseCandidate()):s.addIceControlled(this.#Dt);const i=s.build(this.remotePwd??void 0);this.#Ft.set(t.toString("hex"),e),e.state="in-progress",e.local.transport.send(i,e.remote.address,e.remote.port)}#jt(e,t,r){0!==t.length&&(t[0]<=3?this.#Zt(e,t,r):this.emit("data",t,{transport:e,address:r.address,port:r.port}))}#Zt(e,t,r){const s=function(e){if(e.length<20)return null;if(e.readUInt32BE(4)!==L)return null;const t=e.readUInt16BE(0),r=e.readUInt16BE(2);if(20+r>e.length)return null;const s=e.slice(8,20),i=new Map;let n=20;const a=20+r;for(;n+4<=a;){const t=e.readUInt16BE(n),r=e.readUInt16BE(n+2);if(n+=4,n+r>a)break;i.set(t,e.slice(n,n+r)),n+=x(r)}return{type:t,transactionId:s,attrs:i,raw:e}}(t);s&&(s.type===P.BINDING_REQUEST?this.#Jt(e,s,r):s.type===P.BINDING_SUCCESS&&this.#er(e,s,r))}#Jt(e,t,r){if(this.localPwd&&!function(e,t){let r=20;const s=20+e.readUInt16BE(2);let i=-1;for(;r+4<=s;){const t=e.readUInt16BE(r),s=e.readUInt16BE(r+2);if(t===_.MESSAGE_INTEGRITY){i=r;break}r+=4+x(s)}if(i<0)return!1;const n=e.slice(i+4,i+4+20),o=i+24-20,c=Buffer.from(e.slice(0,20));c.writeUInt16BE(o,2);const h=a.createHmac("sha1",Buffer.from(t,"utf8")).update(Buffer.concat([c,e.slice(20,i)])).digest();return n.length===h.length&&a.timingSafeEqual(n,h)}(t.raw,this.localPwd))return;const s=new M(P.BINDING_SUCCESS,t.transactionId).addXorMappedAddress(r.address,r.port).build(this.localPwd);e.send(s,r.address,r.port),this.#Lt.find(e=>e.address===r.address&&e.port===r.port)||this.addRemoteCandidate({address:r.address,port:r.port,type:"prflx",priority:0});const i=t.attrs.has(_.USE_CANDIDATE),n=this.#tr(e,r);i&&"controlled"===this.role&&this.#rr(n||this.#sr(e,r))}#er(e,t,r){const s=this.#Ft.get(t.transactionId.toString("hex"));s&&(this.#Ft.delete(t.transactionId.toString("hex")),s.state="succeeded","controlling"===this.role&&this.#rr(s))}#tr(e,t){return this.#Pt.find(r=>r.remote.address===t.address&&r.remote.port===t.port&&r.local.transport===e)}#sr(e,t){return{local:{transport:e},remote:{address:t.address,port:t.port}}}#rr(e){!this.#_t&&e&&(this.#_t=e,this.#D=!0,this.#Xt(),this.emit("selected",{transport:e.local.transport,candidateType:e.local.type,remoteAddress:e.remote.address,remotePort:e.remote.port}),this.emit("connected"))}send(e){if(!this.#_t)throw new Error("ICE not connected");this.#_t.local.transport.send(e,this.#_t.remote.address,this.#_t.remote.port)}getSelectedPair(){return this.#_t}getSelectedCandidateType(){return this.#_t?this.#_t.local.type:null}close(){if(!this.#xt){this.#xt=!0,this.#Xt();for(const e of this.#vt)try{e.close()}catch(e){}this.#vt=[],this.emit("closed")}}}const Te=Object.freeze({DATA:0,INIT:1,INIT_ACK:2,SACK:3,HEARTBEAT:4,HEARTBEAT_ACK:5,ABORT:6,SHUTDOWN:7,SHUTDOWN_ACK:8,ERROR:9,COOKIE_ECHO:10,COOKIE_ACK:11,SHUTDOWN_COMPLETE:14,FORWARD_TSN:192}),Ce=Object.freeze({HEARTBEAT_INFO:1,STATE_COOKIE:7,UNRECOGNIZED_PARAM:8,COOKIE_PRESERVATIVE:9,SUPPORTED_ADDR_TYPES:11,FORWARD_TSN_SUPPORTED:49152,SUPPORTED_EXTENSIONS:32776}),Se=Object.freeze({DCEP:50,STRING:51,BINARY:53,STRING_EMPTY:56,BINARY_EMPTY:57,STRING_PARTIAL:54,BINARY_PARTIAL:52});function ye(e){return e+3&-4}function Be(e,t,r){const s=4+r.length,i=Buffer.alloc(ye(s));return i.writeUInt8(e,0),i.writeUInt8(t,1),i.writeUInt16BE(s,2),r.copy(i,4),i}function Re(e,t){const r=4+t.length,s=Buffer.alloc(ye(r));return s.writeUInt16BE(e,0),s.writeUInt16BE(r,2),t.copy(s,4),s}function Ae(e){const t=[];let r=0;for(;r+4<=e.length;){const s=e.readUInt16BE(r),i=e.readUInt16BE(r+2);if(i<4||r+i>e.length)break;t.push({type:s,length:i,value:e.slice(r+4,r+i)}),r+=ye(i)}return t}function we({initiateTag:e,a_rwnd:t,outStreams:r,inStreams:s,initialTSN:i}){const n=Buffer.alloc(16);return n.writeUInt32BE(e>>>0,0),n.writeUInt32BE(t>>>0,4),n.writeUInt16BE(r,8),n.writeUInt16BE(s,10),n.writeUInt32BE(i>>>0,12),n}function Ne(e){return{initiateTag:e.readUInt32BE(0),a_rwnd:e.readUInt32BE(4),outStreams:e.readUInt16BE(8),inStreams:e.readUInt16BE(10),initialTSN:e.readUInt32BE(12),params:Ae(e.slice(16))}}function be({tsn:e,streamId:t,streamSeq:r,ppid:s,userData:i,unordered:n=!1,beginning:a=!0,ending:o=!0}){const c=Buffer.alloc(12);c.writeUInt32BE(e>>>0,0),c.writeUInt16BE(t,4),c.writeUInt16BE(r,6),c.writeUInt32BE(s>>>0,8);let h=0;return o&&(h|=1),a&&(h|=2),n&&(h|=4),{flags:h,body:Buffer.concat([c,i])}}const Oe=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?2197175160^r>>>1:r>>>1;e[t]=r>>>0}return e})();function Ue(e){let t=4294967295;for(let r=0;r<e.length;r++)t=Oe[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}const De=1048576,ve=Object.freeze({CLOSED:"closed",COOKIE_WAIT:"cookie-wait",COOKIE_ECHOED:"cookie-echoed",ESTABLISHED:"established"});function ke(e,t){return(e-t&4294967295)>2147483648}function Le(e,t){return e===t||ke(e,t)}class Pe extends t.EventEmitter{isClient;state;#ir;#nr;#ar;#or;#cr;#hr;#dr;#lr;#ur;#fr;#pr;#de;constructor(e={}){super(),this.isClient=!!e.isClient,this.state=ve.CLOSED,this.#ir=5e3,this.#nr=5e3,this.#ar=a.randomBytes(4).readUInt32BE(0)>>>0||1,this.#or=0,this.#cr=a.randomBytes(4).readUInt32BE(0)>>>0,this.#hr=new Map,this.#dr=new Map,this.#lr=null,this.#ur=new Map,this.#fr=new Map,this.#pr=null}start(){this.state===ve.CLOSED&&this.isClient&&(this.#Er(),this.state=ve.COOKIE_WAIT)}#mr(e,t){const r=function(e,t,r){const s=Buffer.alloc(12);return s.writeUInt16BE(e,0),s.writeUInt16BE(t,2),s.writeUInt32BE(r>>>0,4),s.writeUInt32BE(0,8),s}(this.#ir,this.#nr,e),s=Buffer.concat([r,...t]);!function(e){e.writeUInt32LE(0,8);const t=Ue(e);e.writeUInt32LE(t,8)}(s),this.emit("output",s)}receivePacket(e){if(e.length<12)return;if(!function(e){const t=e.readUInt32LE(8);e.writeUInt32LE(0,8);const r=Ue(e);return e.writeUInt32LE(t,8),r===t}(e))return;const t=function(e){return{srcPort:e.readUInt16BE(0),dstPort:e.readUInt16BE(2),verificationTag:e.readUInt32BE(4),checksum:e.readUInt32LE(8)}}(e),r=function(e){const t=[];let r=12;for(;r+4<=e.length;){const s=e.readUInt8(r),i=e.readUInt8(r+1),n=e.readUInt16BE(r+2);if(n<4||r+n>e.length)break;const a=e.slice(r+4,r+n);t.push({type:s,flags:i,length:n,body:a}),r+=ye(n)}return t}(e);for(const e of r)this.#gr(e,t)}#gr(e,t){switch(e.type){case Te.INIT:this.#Ir(e);break;case Te.INIT_ACK:this.#Tr(e);break;case Te.COOKIE_ECHO:this.#Cr(e);break;case Te.COOKIE_ACK:this.#Sr();break;case Te.DATA:this.#yr(e);break;case Te.SACK:this.#Br(e);break;case Te.HEARTBEAT:this.#Rr(e);break;case Te.ABORT:this.#Ar("peer sent ABORT");break;case Te.SHUTDOWN:this.#wr()}}#Nr(){return[Re(Ce.FORWARD_TSN_SUPPORTED,Buffer.alloc(0))]}#Er(){const e=we({initiateTag:this.#ar,a_rwnd:De,outStreams:65535,inStreams:65535,initialTSN:this.#cr}),t=Be(Te.INIT,0,Buffer.concat([e,...this.#Nr()]));this.#mr(0,[t]),this.#br([t])}#br(e){this.#Or();let t=500,r=0;const s=()=>{this.state!==ve.ESTABLISHED&&this.state!==ve.CLOSED&&(r>=8?this.#Ar("SCTP setup timed out"):(r++,this.#mr(this.state===ve.COOKIE_ECHOED?this.#or:0,e),t=Math.min(2*t,5e3),this.#pr=setTimeout(s,t),this.#pr.unref&&this.#pr.unref()))};this.#pr=setTimeout(s,t),this.#pr.unref&&this.#pr.unref()}#Or(){this.#pr&&(clearTimeout(this.#pr),this.#pr=null)}#Ir(e){const t=Ne(e.body);this.#or=t.initiateTag,this.#lr=t.initialTSN-1>>>0,this.#de||(this.#de=a.randomBytes(32));const r=Buffer.alloc(16);r.writeUInt32BE(this.#ar,0),r.writeUInt32BE(this.#or,4),r.writeUInt32BE(this.#cr,8),r.writeUInt32BE(t.initialTSN,12);const s=a.createHmac("sha256",this.#de).update(r).digest(),i=Buffer.concat([r,s]),n=we({initiateTag:this.#ar,a_rwnd:De,outStreams:65535,inStreams:65535,initialTSN:this.#cr}),o=Buffer.concat([Re(Ce.STATE_COOKIE,i),...this.#Nr()]),c=Be(Te.INIT_ACK,0,Buffer.concat([n,o]));this.#mr(this.#or,[c])}#Tr(e){if(this.state!==ve.COOKIE_WAIT)return;this.#Or();const t=Ne(e.body);this.#or=t.initiateTag,this.#lr=t.initialTSN-1>>>0;const r=t.params.find(e=>e.type===Ce.STATE_COOKIE);if(!r)return void this.#Ar("INIT_ACK missing state cookie");const s=Be(Te.COOKIE_ECHO,0,r.value);this.state=ve.COOKIE_ECHOED,this.#mr(this.#or,[s]),this.#br([s])}#Cr(e){const t=e.body;if(t.length>=48&&this.#de){const e=t.slice(0,16),r=t.slice(16,48),s=a.createHmac("sha256",this.#de).update(e).digest();if(!a.timingSafeEqual(r,s))return}const r=Be(Te.COOKIE_ACK,0,Buffer.alloc(0));this.#mr(this.#or,[r]),this.#Ur()}#Sr(){this.state===ve.COOKIE_ECHOED&&(this.#Or(),this.#Ur())}#Ur(){this.state!==ve.ESTABLISHED&&(this.state=ve.ESTABLISHED,this.emit("established"))}sendData(e,t,r,s={}){if(this.state!==ve.ESTABLISHED)throw new Error("SCTP association not established");const i=!!s.unordered;let n=0;i||(n=this.#hr.get(e)||0,this.#hr.set(e,n+1&65535));const a=r.length;let o=0;const c=[];do{const s=r.slice(o,o+1200),h=0===o,d=o+s.length>=a,l=this.#cr;this.#cr=this.#cr+1>>>0;const{flags:u,body:f}=be({tsn:l,streamId:e,streamSeq:n,ppid:t,userData:s,unordered:i,beginning:h,ending:d}),p=Be(Te.DATA,u,f);this.#dr.set(l,{chunk:p}),c.push(p),o+=s.length}while(o<a);for(const e of c)this.#mr(this.#or,[e])}#yr(e){const t={unordered:!!(4&(r=e.flags)),beginning:!!(2&r),ending:!!(1&r),tsn:(s=e.body).readUInt32BE(0),streamId:s.readUInt16BE(4),streamSeq:s.readUInt16BE(6),ppid:s.readUInt32BE(8),userData:s.slice(12)};var r,s;this.#Dr(t),this.#vr()}#Dr(e){const t=this.#lr+1>>>0;if(!ke(e.tsn,t))if(e.tsn===t){this.#lr=e.tsn,this.#kr(e);let t=this.#lr+1>>>0;for(;this.#ur.has(t);){const e=this.#ur.get(t);this.#ur.delete(t),this.#lr=t,this.#kr(e),t=this.#lr+1>>>0}}else this.#ur.has(e.tsn)||this.#ur.set(e.tsn,e)}#kr(e){const t=`${e.streamId}:${e.unordered?"u":"o"}`;if(e.beginning&&e.ending)return void this.emit("message",{streamId:e.streamId,ppid:e.ppid,data:e.userData});let r=this.#fr.get(t);if(e.beginning)r={ppid:e.ppid,parts:[e.userData]},this.#fr.set(t,r);else{if(!r)return;r.parts.push(e.userData)}e.ending&&r&&(this.#fr.delete(t),this.emit("message",{streamId:e.streamId,ppid:r.ppid,data:Buffer.concat(r.parts)}))}#vr(){const e=[];if(this.#ur.size>0){const t=this.#lr,r=e=>e-t>>>0,s=(t,s)=>{const i=r(t),n=r(s);n<=65535&&e.push([i,n])},i=[...this.#ur.keys()].sort((e,t)=>ke(e,t)?-1:1);let n=null,a=null;for(const e of i)null!==n?e!==a+1>>>0?(s(n,a),n=e,a=e):a=e:(n=e,a=e);null!==n&&s(n,a)}const t=function({cumulativeTSNAck:e,a_rwnd:t,gapBlocks:r=[],dupTSNs:s=[]}){const i=Buffer.alloc(12+4*r.length+4*s.length);i.writeUInt32BE(e>>>0,0),i.writeUInt32BE(t>>>0,4),i.writeUInt16BE(r.length,8),i.writeUInt16BE(s.length,10);let n=12;for(const[e,t]of r)i.writeUInt16BE(e,n),i.writeUInt16BE(t,n+2),n+=4;for(const e of s)i.writeUInt32BE(e>>>0,n),n+=4;return i}({cumulativeTSNAck:this.#lr>>>0,a_rwnd:De,gapBlocks:e}),r=Be(Te.SACK,0,t);this.#mr(this.#or,[r])}#Br(e){const t=function(e){const t=e.readUInt32BE(0),r=e.readUInt32BE(4),s=e.readUInt16BE(8),i=e.readUInt16BE(10),n=[];let a=12;for(let t=0;t<s;t++)n.push([e.readUInt16BE(a),e.readUInt16BE(a+2)]),a+=4;const o=[];for(let t=0;t<i;t++)o.push(e.readUInt32BE(a)),a+=4;return{cumulativeTSNAck:t,a_rwnd:r,gapBlocks:n,dupTSNs:o}}(e.body);for(const e of[...this.#dr.keys()])Le(e,t.cumulativeTSNAck)&&this.#dr.delete(e);const r=t.cumulativeTSNAck+1>>>0;for(const[e,s]of t.gapBlocks)for(let t=e;t<=s;t++)this.#dr.delete(r+t-1>>>0)}#Rr(e){const t=Be(Te.HEARTBEAT_ACK,0,e.body);this.#mr(this.#or,[t])}#wr(){const e=Be(Te.SHUTDOWN_ACK,0,Buffer.alloc(0));this.#mr(this.#or,[e]),this.#Lr()}#Ar(e){this.#Or(),this.state!==ve.CLOSED&&(this.state=ve.CLOSED,this.emit("error",new Error(e||"SCTP abort")),this.emit("close"))}shutdown(){if(this.state!==ve.ESTABLISHED)return void this.#Lr();const e=Be(Te.SHUTDOWN,0,(()=>{const e=Buffer.alloc(4);return e.writeUInt32BE(this.#lr>>>0,0),e})());this.#mr(this.#or,[e]),this.#Lr()}#Lr(){this.#Or(),this.state!==ve.CLOSED&&(this.state=ve.CLOSED,this.emit("close"))}}const _e=Object.freeze({DATA_CHANNEL_ACK:2,DATA_CHANNEL_OPEN:3}),xe=Object.freeze({RELIABLE:0,RELIABLE_UNORDERED:128,PARTIAL_RELIABLE_REXMIT:1,PARTIAL_RELIABLE_REXMIT_UNORDERED:129,PARTIAL_RELIABLE_TIMED:2,PARTIAL_RELIABLE_TIMED_UNORDERED:130});class He extends t.EventEmitter{#Pr;#_r;#xr;constructor(e,t){super(),this.#Pr=e,this.#_r=new Map,this.#xr=t?0:1,this.#Pr.on("message",e=>this.#Hr(e))}openChannel(e,t={}){let r=e.id;if(null==r&&(r=this.#Mr(),e.emit(b.SET_ID,r)),this.#_r.set(r,{channel:e,acked:!1}),this.#Fr(e,r,t),e.negotiated)this.#_r.get(r).acked=!0,e.emit(b.OPEN);else{const s=function({channelType:e,priority:t=0,reliabilityParameter:r=0,label:s="",protocol:i=""}){const n=Buffer.from(s,"utf8"),a=Buffer.from(i,"utf8"),o=Buffer.alloc(12+n.length+a.length);return o.writeUInt8(_e.DATA_CHANNEL_OPEN,0),o.writeUInt8(e,1),o.writeUInt16BE(t,2),o.writeUInt32BE(r>>>0,4),o.writeUInt16BE(n.length,8),o.writeUInt16BE(a.length,10),n.copy(o,12),a.copy(o,12+n.length),o}({channelType:this.#Kr(t),priority:0,reliabilityParameter:this.#qr(t),label:e.label,protocol:t.protocol||e.protocol||""});this.#Pr.sendData(r,Se.DCEP,s)}}#Mr(){let e=this.#xr;for(;this.#_r.has(e);)e+=2;return this.#xr=e+2,e}#Kr(e){const t=!1===e.ordered;return null!=e.maxRetransmits?t?xe.PARTIAL_RELIABLE_REXMIT_UNORDERED:xe.PARTIAL_RELIABLE_REXMIT:null!=e.maxPacketLifeTime?t?xe.PARTIAL_RELIABLE_TIMED_UNORDERED:xe.PARTIAL_RELIABLE_TIMED:t?xe.RELIABLE_UNORDERED:xe.RELIABLE}#qr(e){return null!=e.maxRetransmits?e.maxRetransmits>>>0:null!=e.maxPacketLifeTime?e.maxPacketLifeTime>>>0:0}#Fr(e,t,r){const s=!1===r.ordered;e.on(b.SEND,(e,r)=>{let i;i=r?0===e.length?Se.BINARY_EMPTY:Se.BINARY:0===e.length?Se.STRING_EMPTY:Se.STRING;const n=0===e.length?Buffer.from([0]):e;this.#Pr.sendData(t,i,n,{unordered:s})})}#Hr(e){if(e.ppid===Se.DCEP)return void this.#Gr(e);const t=this.#_r.get(e.streamId);if(!t)return;const r=e.ppid===Se.BINARY||e.ppid===Se.BINARY_EMPTY||e.ppid===Se.BINARY_PARTIAL,s=e.ppid===Se.STRING_EMPTY||e.ppid===Se.BINARY_EMPTY?Buffer.alloc(0):e.data;t.channel.emit(b.RECEIVE,s,r)}#Gr(e){const t=(r=e.data).length>0?r.readUInt8(0):-1;var r;if(t===_e.DATA_CHANNEL_OPEN){const t=function(e){const t=e.readUInt8(1),r=e.readUInt16BE(2),s=e.readUInt32BE(4),i=e.readUInt16BE(8),n=e.readUInt16BE(10);return{channelType:t,priority:r,reliabilityParameter:s,label:e.slice(12,12+i).toString("utf8"),protocol:e.slice(12+i,12+i+n).toString("utf8"),unordered:!!(128&t)}}(e.data);this.#Pr.sendData(e.streamId,Se.DCEP,Buffer.from([_e.DATA_CHANNEL_ACK])),this.emit("open-request",{streamId:e.streamId,label:t.label,protocol:t.protocol,ordered:!t.unordered,channelType:t.channelType,reliabilityParameter:t.reliabilityParameter})}else if(t===_e.DATA_CHANNEL_ACK){const t=this.#_r.get(e.streamId);t&&!t.acked&&(t.acked=!0,t.channel.emit(b.OPEN))}}acceptChannel(e,t){e.emit(b.SET_ID,t.streamId),this.#_r.set(t.streamId,{channel:e,acked:!0}),this.#Fr(e,t.streamId,{ordered:t.ordered}),e.emit(b.OPEN)}}class Me extends t.EventEmitter{#zr;ice;dtls;sctp;dcm;#jr;constructor(e){super(),this.#zr=e,this.ice=new Ie({role:e.iceRole,localUfrag:e.localUfrag,localPwd:e.localPwd}),this.dtls=null,this.sctp=null,this.dcm=null,this.#jr=!1,this.ice.on("candidate",e=>this.emit("candidate",e)),this.ice.on("error",e=>this.#$r(e)),this.ice.on("failed",()=>this.#$r(new Error("ICE failed"))),this.ice.on("data",e=>{this.dtls&&this.dtls.handlePacket(e)}),this.ice.on("connected",()=>{this.emit("iceconnected"),this.#Vr()})}async gather(e={}){await this.ice.gather(e)}getLocalCandidates(){return this.ice.getLocalCandidates()}setRemote(e,t){this.ice.setRemoteCredentials(e,t),this.ice.start()}addRemoteCandidate(e){this.ice.addRemoteCandidate(e)}#Vr(){this.#jr||(this.#jr=!0,this.dtls=new le({role:"client"===this.#zr.dtlsRole?he.CLIENT:he.SERVER,certDer:this.#zr.certDer,privateKey:this.#zr.privateKey,verifyFingerprint:this.#zr.verifyFingerprint,output:e=>{try{this.ice.send(e)}catch(e){this.#$r(e)}}}),this.dtls.on("connect",()=>{this.emit("dtlsconnected"),this.#Wr()}),this.dtls.on("data",e=>{this.sctp&&this.sctp.receivePacket(e)}),this.dtls.on("error",e=>this.#$r(e)),this.dtls.on("close",()=>this.emit("close")),this.dtls.start())}#Wr(){const e="client"===this.#zr.dtlsRole,t=new Pe({isClient:e});this.sctp=t,t.on("output",e=>{try{this.dtls&&this.dtls.send(e)}catch(e){this.#$r(e)}}),t.on("error",e=>this.#$r(e)),t.on("close",()=>this.emit("close")),this.dcm=new He(t,e),this.dcm.on("open-request",e=>this.emit("datachannel-request",e)),t.on("established",()=>{this.emit("sctpconnected"),this.emit("ready")}),t.start()}openChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.openChannel(e,t)}acceptChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.acceptChannel(e,t)}#$r(e){this.listenerCount("error")>0&&this.emit("error",e)}isReady(){return!!this.sctp&&"established"===this.sctp.state}close(){if(this.sctp)try{this.sctp.shutdown()}catch{}if(this.dtls)try{this.dtls.close()}catch{}if(this.ice)try{this.ice.close()}catch{}}}const Fe=Object.freeze({STABLE:"stable",HAVE_LOCAL_OFFER:"have-local-offer",HAVE_REMOTE_OFFER:"have-remote-offer",HAVE_LOCAL_PRANSWER:"have-local-pranswer",HAVE_REMOTE_PRANSWER:"have-remote-pranswer",CLOSED:"closed"}),Ke=Object.freeze({NEW:"new",GATHERING:"gathering",COMPLETE:"complete"}),qe=Object.freeze({NEW:"new",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"});class Ge extends t.EventEmitter{#Yr;#Xr;#Qr;#Zr;#Jr;#es;#ts;#rs;#ss;#is;#ns;#as;#os;#cs;#hs;#_r;#kt;constructor(e={}){super(),this.#Yr=e,this.#Xr=Fe.STABLE,this.#Qr=Ke.NEW,this.#Zr=qe.NEW,this.#Jr=null,this.#es=null,this.#ts=null,this.#rs={usernameFragment:a.randomBytes(3).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,4).padEnd(4,"x"),password:a.randomBytes(18).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,24).padEnd(24,"x")},this.#ss=null,this.#is=[],this.#ns=null,this.#as=null,this.#os=!1,this.#cs=!1,this.#hs=[],this.#_r=new Set,this.#kt=[]}async#ds(){return this.#ts||(this.#Yr.certificates&&this.#Yr.certificates[0]?this.#ts=this.#Yr.certificates[0]:this.#ts=await w.generateCertificate()),this.#ts}#ls(e,t){if(this.#as)return this.#as;const r=this.#ts;if(!r)throw new Error("Certificate not initialized");const s=r.getCertificateDer();if(!s)throw new Error("Certificate has no DER encoding");const i=new Me({iceRole:e,dtlsRole:t,localUfrag:this.#rs.usernameFragment,localPwd:this.#rs.password,certDer:s,privateKey:r.getPrivateKeyObject(),verifyFingerprint:e=>this.#us(e)});return i.on("candidate",e=>{const t={candidate:e.sdp,sdpMid:"0",sdpMLineIndex:0,usernameFragment:this.#rs.usernameFragment};this.#kt.push(t),this.emit("icecandidate",{candidate:t})}),i.on("iceconnected",()=>this.#fs(qe.CONNECTING)),i.on("sctpconnected",()=>this.#fs(qe.CONNECTED)),i.on("error",e=>{this.listenerCount("error")>0&&this.emit("error",e),this.#fs(qe.FAILED)}),i.on("close",()=>this.#fs(qe.DISCONNECTED)),i.on("datachannel-request",e=>{const t=new O(e.label,{ordered:e.ordered,protocol:e.protocol,id:e.streamId});i.acceptChannel(t,e),this.#_r.add(t),this.emit("datachannel",{channel:t})}),i.on("ready",()=>{for(const{channel:e,init:t}of this.#hs)i.openChannel(e,t);this.#hs=[]}),this.#as=i,i}#us(e){return 0===this.#is.length||this.#is.some(t=>t.algorithm===e.algorithm&&t.value.toUpperCase()===e.value.toUpperCase())}createDataChannel(e,t={}){if(this.#cs)throw new Error("RTCPeerConnection is closed");const r=new O(e,t);this.#_r.add(r);const s={ordered:!1!==t.ordered,maxRetransmits:t.maxRetransmits,maxPacketLifeTime:t.maxPacketLifeTime,protocol:t.protocol||"",negotiated:t.negotiated||!1};return this.#as&&this.#as.isReady()?this.#as.openChannel(r,s):this.#hs.push({channel:r,init:s}),setImmediate(()=>{this.#cs||this.emit("negotiationneeded")}),r}async createOffer(){if(this.#cs)throw new Error("RTCPeerConnection is closed");await this.#ds(),this.#os=!0;const e=this.#ps(),t=(r={iceUfrag:this.#rs.usernameFragment,icePwd:this.#rs.password,fingerprint:e,setup:"actpass",candidates:[]},v({...r,setup:r.setup||"actpass"}));var r;return new D({type:U.OFFER,sdp:t})}async createAnswer(){if(this.#cs)throw new Error("RTCPeerConnection is closed");if(!this.#es||"offer"!==this.#es.type)throw new Error("Cannot create answer without remote offer");await this.#ds();const e=this.#ps(),t=(r={iceUfrag:this.#rs.usernameFragment,icePwd:this.#rs.password,fingerprint:e,setup:"active",candidates:[]},v({...r,setup:r.setup||"active"}));var r;return new D({type:U.ANSWER,sdp:t})}#ps(){const e=this.#ts;if(!e)throw new Error("Certificate not initialized");const t=e.getFingerprints();return t.find(e=>"sha-256"===e.algorithm)||t[0]}async setLocalDescription(e){if(this.#cs)throw new Error("RTCPeerConnection is closed");const t=e||(this.#Xr===Fe.HAVE_REMOTE_OFFER?await this.createAnswer():await this.createOffer());await this.#ds(),this.#Jr=new D({type:t.type??void 0,sdp:t.sdp??void 0}),"offer"===t.type?this.#Xr=Fe.HAVE_LOCAL_OFFER:"answer"===t.type&&(this.#Xr=Fe.STABLE),this.#Es(t,!0),this.#Qr=Ke.GATHERING,this.emit("icegatheringstatechange"),this.#as&&(await this.#as.gather({iceServers:this.#Yr.iceServers||[],iceTransportPolicy:this.#Yr.iceTransportPolicy||"all"}),this.#Qr=Ke.COMPLETE,this.emit("icegatheringstatechange"),this.emit("icecandidate",{candidate:null}),this.#ms()),this.emit("signalingstatechange")}async setRemoteDescription(e){if(this.#cs)throw new Error("RTCPeerConnection is closed");if(!e||!e.sdp)throw new Error("Invalid session description");await this.#ds(),this.#es=new D(e),"offer"===e.type?this.#Xr=Fe.HAVE_REMOTE_OFFER:"answer"===e.type&&(this.#Xr=Fe.STABLE),this.#ss=function(e){const t={usernameFragment:null,password:null};for(const r of e.split(/\r?\n/))r.startsWith("a=ice-ufrag:")?t.usernameFragment=r.slice(12).trim():r.startsWith("a=ice-pwd:")&&(t.password=r.slice(10).trim());return t}(e.sdp);const t=function(e){const t={role:"auto",fingerprints:[]};for(const r of e.split(/\r?\n/))if(r.startsWith("a=setup:")){const e=r.slice(8).trim();t.role="active"===e?"client":"passive"===e?"server":"actpass",t.setup=e}else if(r.startsWith("a=fingerprint:")){const e=r.slice(14).trim().split(/\s+/);2===e.length&&t.fingerprints.push({algorithm:e[0].toLowerCase(),value:e[1].toUpperCase()})}return t}(e.sdp);if(this.#is=t.fingerprints,this.#ns=t.setup??null,this.#Es(e,!1),this.#as&&this.#ss.usernameFragment){this.#as.setRemote(this.#ss.usernameFragment,this.#ss.password??"");for(const t of function(e){const t=[];for(const r of e.split(/\r?\n/)){if(!r.startsWith("a=candidate:"))continue;const e=k(r.slice(2));e&&t.push(e)}return t}(e.sdp))this.#as.addRemoteCandidate(t)}this.#ms(),this.emit("signalingstatechange")}#Es(e,t){if(this.#as)return;const r=this.#os?"controlling":"controlled";let s;s=this.#os?"active"===this.#ns?"server":"passive"===this.#ns?"client":"server":"client",this.#ls(r,s)}#ms(){this.#as&&this.#ss&&this.#ss.usernameFragment&&this.#as.setRemote(this.#ss.usernameFragment,this.#ss.password??"")}async addIceCandidate(e){if(this.#cs)throw new Error("RTCPeerConnection is closed");if(!e||"string"!=typeof e&&""===e.candidate)return;const t=k("string"==typeof e?e:e.candidate||"");t&&this.#as&&this.#as.addRemoteCandidate(t)}#fs(e){this.#Zr!==e&&(this.#Zr=e,this.emit("connectionstatechange"),this.emit("iceconnectionstatechange"))}getConfiguration(){return{...this.#Yr}}setConfiguration(e){if(this.#cs)throw new Error("RTCPeerConnection is closed");this.#Yr={...e}}close(){if(!this.#cs){this.#cs=!0,this.#Xr=Fe.CLOSED;for(const e of this.#_r)try{e.close()}catch(e){}if(this.#as)try{this.#as.close()}catch(e){}this.#fs(qe.CLOSED),this.emit("signalingstatechange")}}get signalingState(){return this.#Xr}get iceGatheringState(){return this.#Qr}get iceConnectionState(){return this.#Zr===qe.CONNECTED?"connected":this.#Zr===qe.CONNECTING?"checking":this.#Zr===qe.FAILED?"failed":"new"}get connectionState(){return this.#Zr}get localDescription(){return this.#Jr}get remoteDescription(){return this.#es}get currentLocalDescription(){return this.#Jr}get currentRemoteDescription(){return this.#es}get pendingLocalDescription(){return this.#Xr===Fe.STABLE?null:this.#Jr}get pendingRemoteDescription(){return this.#Xr===Fe.STABLE?null:this.#es}get canTrickleIceCandidates(){return!0}get sctp(){return this.#as?this.#as.sctp:null}}exports.ByteBufferQueue=class{#gs;#Is;#Ts;constructor(){this.#gs=0,this.#Is=[],this.#Ts=0}get size(){return this.#gs}get empty(){return 0===this.#gs}readInto(e){if(!Buffer.isBuffer(e))throw new TypeError("bufferOut must be a Buffer");let t=0,r=0;for(;r<e.length&&this.#Is.length>0;){const s=this.#Is[0],i=s.length-this.#Ts,n=e.length-r,a=Math.min(i,n);s.copy(e,r,this.#Ts,this.#Ts+a),t+=a,r+=a,a<i?this.#Ts+=a:(this.#Is.shift(),this.#Ts=0)}return this.#gs-=t,this.#Cs(),t}append(e){if(!Buffer.isBuffer(e))throw new TypeError("buffer must be a Buffer");0!==e.length&&(this.#gs+=e.length,this.#Is.push(e),this.#Cs())}clear(){this.#Is=[],this.#Ts=0,this.#gs=0,this.#Cs()}read(e){if(e>this.#gs)throw new RangeError(`Cannot read ${e} bytes, only ${this.#gs} available`);if(0===e)return Buffer.allocUnsafe(0);const t=Buffer.allocUnsafe(e),r=this.readInto(t);if(r!==e)throw new Error(`Internal error: read ${r} bytes, expected ${e}`);return t}peek(e=this.#gs){const t=Math.min(e,this.#gs);if(0===t)return Buffer.allocUnsafe(0);const r=Buffer.allocUnsafe(t);let s=0,i=0,n=this.#Ts;for(;s<t&&i<this.#Is.length;){const e=this.#Is[i],a=e.length-n,o=Math.min(a,t-s);e.copy(r,s,n,n+o),s+=o,i++,n=0}return r}#Cs(){if("production"!==process.env.NODE_ENV){let e=0;for(const t of this.#Is){if(0===t.length)throw new Error("Invariant violation: empty buffer in queue");e+=t.length}const t=e-this.#Ts;if(this.#gs!==t)throw new Error(`Invariant violation: size=${this.#gs}, expected=${t}`);if(0===this.#Is.length){if(0!==this.#Ts)throw new Error("Invariant violation: offset non-zero with empty queue")}else if(this.#Ts>=this.#Is[0].length)throw new Error("Invariant violation: offset >= front buffer size")}}},exports.RTCCertificate=w,exports.RTCDataChannel=O,exports.RTCDataChannelState=N,exports.RTCError=l,exports.RTCIceCandidate=u,exports.RTCIceGatheringState=Ke,exports.RTCPeerConnection=Ge,exports.RTCPeerConnectionState=qe,exports.RTCSdpType=U,exports.RTCSessionDescription=D,exports.RTCSignalingState=Fe,exports.version="2.0.9";
package/index.mjs CHANGED
@@ -1 +1 @@
1
- import*as e from"crypto";import{EventEmitter as t}from"events";import*as r from"dgram";import*as s from"os";import*as i from"tls";class n{#e;#t;#r;constructor(){this.#e=0,this.#t=[],this.#r=0}get size(){return this.#e}get empty(){return 0===this.#e}readInto(e){if(!Buffer.isBuffer(e))throw new TypeError("bufferOut must be a Buffer");let t=0,r=0;for(;r<e.length&&this.#t.length>0;){const s=this.#t[0],i=s.length-this.#r,n=e.length-r,a=Math.min(i,n);s.copy(e,r,this.#r,this.#r+a),t+=a,r+=a,a<i?this.#r+=a:(this.#t.shift(),this.#r=0)}return this.#e-=t,this.#s(),t}append(e){if(!Buffer.isBuffer(e))throw new TypeError("buffer must be a Buffer");0!==e.length&&(this.#e+=e.length,this.#t.push(e),this.#s())}clear(){this.#t=[],this.#r=0,this.#e=0,this.#s()}read(e){if(e>this.#e)throw new RangeError(`Cannot read ${e} bytes, only ${this.#e} available`);if(0===e)return Buffer.allocUnsafe(0);const t=Buffer.allocUnsafe(e),r=this.readInto(t);if(r!==e)throw new Error(`Internal error: read ${r} bytes, expected ${e}`);return t}peek(e=this.#e){const t=Math.min(e,this.#e);if(0===t)return Buffer.allocUnsafe(0);const r=Buffer.allocUnsafe(t);let s=0,i=0,n=this.#r;for(;s<t&&i<this.#t.length;){const e=this.#t[i],a=e.length-n,o=Math.min(a,t-s);e.copy(r,s,n,n+o),s+=o,i++,n=0}return r}#s(){if("production"!==process.env.NODE_ENV){let e=0;for(const t of this.#t){if(0===t.length)throw new Error("Invariant violation: empty buffer in queue");e+=t.length}const t=e-this.#r;if(this.#e!==t)throw new Error(`Invariant violation: size=${this.#e}, expected=${t}`);if(0===this.#t.length){if(0!==this.#r)throw new Error("Invariant violation: offset non-zero with empty queue")}else if(this.#r>=this.#t[0].length)throw new Error("Invariant violation: offset >= front buffer size")}}}const a=Object.freeze({NONE:"none",DATA_CHANNEL_FAILURE:"data-channel-failure",DTLS_FAILURE:"dtls-failure",FINGERPRINT_FAILURE:"fingerprint-failure",SCTP_FAILURE:"sctp-failure",SDP_SYNTAX_ERROR:"sdp-syntax-error",HARDWARE_ENCODER_NOT_AVAILABLE:"hardware-encoder-not-available",HARDWARE_ENCODER_ERROR:"hardware-encoder-error",INVALID_STATE:"invalid-state",INVALID_MODIFICATION:"invalid-modification",INVALID_ACCESS_ERROR:"invalid-access-error",OPERATION_ERROR:"operation-error"});class o extends Error{static DetailType=a;#i;#n;#a;#o;#c;#h;constructor(e={},t=""){super(t),this.name="RTCError",Error.captureStackTrace&&Error.captureStackTrace(this,o);const r=e.errorDetail||a.NONE;if("string"!=typeof r)throw new TypeError("errorDetail must be a string");this.#i=r,this.#n=this.#d(e.sdpLineNumber,"sdpLineNumber"),this.#a=this.#d(e.httpRequestStatusCode,"httpRequestStatusCode"),this.#o=this.#d(e.sctpCauseCode,"sctpCauseCode"),this.#c=this.#l(e.receivedAlert,"receivedAlert"),this.#h=this.#l(e.sentAlert,"sentAlert")}#d(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r))throw new TypeError(`${t} must be an integer`);return r}#l(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r)||r<0)throw new TypeError(`${t} must be an unsigned integer`);return r}get errorDetail(){return this.#i}get sdpLineNumber(){return this.#n}get httpRequestStatusCode(){return this.#a}get sctpCauseCode(){return this.#o}get receivedAlert(){return this.#c}get sentAlert(){return this.#h}toJSON(){const e={name:this.name,message:this.message,errorDetail:this.#i};return null!==this.#n&&(e.sdpLineNumber=this.#n),null!==this.#a&&(e.httpRequestStatusCode=this.#a),null!==this.#o&&(e.sctpCauseCode=this.#o),null!==this.#c&&(e.receivedAlert=this.#c),null!==this.#h&&(e.sentAlert=this.#h),e}static fromNative(e){const t={errorDetail:e.error_detail||a.NONE};return void 0!==e.sctp_cause_code&&(t.sctpCauseCode=e.sctp_cause_code),new o(t,e.message||"Unknown error")}}class c{#u;#f;#p;#m;#E;constructor(e={}){if(null===e.sdpMid&&null===e.sdpMLineIndex)throw new TypeError("sdpMid and sdpMLineIndex are both null");this.#u=e.candidate||"",this.#f=void 0!==e.sdpMid?e.sdpMid:null,this.#p=void 0!==e.sdpMLineIndex?e.sdpMLineIndex:null,this.#m=e.usernameFragment||null,this.#E=this.#g(this.#u)}#g(e){const t={foundation:null,component:null,protocol:null,priority:null,address:null,port:null,type:null,tcpType:null,relatedAddress:null,relatedPort:null};if(!e||!e.startsWith("candidate:"))return t;const r=e.substring(10).trim().split(/\s+/);if(r.length<8)return t;t.foundation=r[0],t.component=r[1],t.protocol=r[2].toLowerCase(),t.priority=parseInt(r[3],10),t.address=r[4],t.port=parseInt(r[5],10),"typ"===r[6]&&(t.type=r[7]);for(let e=8;e<r.length;e+=2){const s=r[e],i=r[e+1];"raddr"===s?t.relatedAddress=i:"rport"===s?t.relatedPort=parseInt(i,10):"tcptype"===s&&(t.tcpType=i)}return t}get candidate(){return this.#u}get sdpMid(){return this.#f}get sdpMLineIndex(){return this.#p}get usernameFragment(){return this.#m}get foundation(){return this.#E.foundation}get component(){return this.#E.component}get priority(){return this.#E.priority}get address(){return this.#E.address}get protocol(){return this.#E.protocol}get port(){return this.#E.port}get type(){return this.#E.type}get tcpType(){return this.#E.tcpType}get relatedAddress(){return this.#E.relatedAddress}get relatedPort(){return this.#E.relatedPort}toJSON(){const e={candidate:this.#u,sdpMid:this.#f,sdpMLineIndex:this.#p};return this.#m&&(e.usernameFragment=this.#m),e}static fromString(e,t=null,r=0){return new c({candidate:e,sdpMid:t,sdpMLineIndex:r})}static isValid(e){return!(!e||"string"!=typeof e)&&(!!e.startsWith("candidate:")&&e.substring(10).trim().split(/\s+/).length>=8)}}const h=Object.freeze({BOOLEAN:1,INTEGER:2,BIT_STRING:3,OCTET_STRING:4,NULL:5,OID:6,UTF8_STRING:12,PRINTABLE_STRING:19,IA5_STRING:22,UTC_TIME:23,GENERALIZED_TIME:24,SEQUENCE:48,SET:49});function d(e){if(e<128)return Buffer.from([e]);const t=[];let r=e;for(;r>0;)t.unshift(255&r),r>>>=8;return Buffer.from([128|t.length,...t])}function l(e,t){return Buffer.concat([Buffer.from([e]),d(t.length),t])}function u(e){let t=0;for(;t<e.length-1&&0===e[t];)t++;let r=e.slice(t);return 128&r[0]&&(r=Buffer.concat([Buffer.from([0]),r])),l(h.INTEGER,r)}function f(e){const t=[];let r=e;for(;r>0;)t.unshift(255&r),r=Math.floor(r/256);return 128&t[0]&&t.unshift(0),l(h.INTEGER,Buffer.from(t))}function p(e){const t=e.split(".").map(Number);if(t.length<2)throw new Error(`Invalid OID: ${e}`);const r=[40*t[0]+t[1]];for(let e=2;e<t.length;e++){let s=t[e];const i=[127&s];for(s=Math.floor(s/128);s>0;)i.unshift(127&s|128),s=Math.floor(s/128);r.push(...i)}return l(h.OID,Buffer.from(r))}function m(e){return l(h.SEQUENCE,Buffer.concat(e))}function E(e){const t=e.getUTCFullYear(),r=(e,t=2)=>String(e).padStart(t,"0"),s=r(e.getUTCMonth()+1),i=r(e.getUTCDate()),n=r(e.getUTCHours()),a=r(e.getUTCMinutes()),o=r(e.getUTCSeconds());if(t<2050){const e=r(t%100);return l(h.UTC_TIME,Buffer.from(`${e}${s}${i}${n}${a}${o}Z`,"ascii"))}return l(h.GENERALIZED_TIME,Buffer.from(`${t}${s}${i}${n}${a}${o}Z`,"ascii"))}const g=Object.freeze({ecPublicKey:"1.2.840.10045.2.1",prime256v1:"1.2.840.10045.3.1.7",ecdsaWithSHA256:"1.2.840.10045.4.3.2",commonName:"2.5.4.3"});function I(){return m([p(g.ecdsaWithSHA256)])}function T(t={}){const r=t.commonName||`WebRTC-${e.randomBytes(8).toString("hex")}`,s=t.days||30,{publicKey:i,privateKey:n}=e.generateKeyPairSync("ec",{namedCurve:"prime256v1"}),a=i.export({type:"spki",format:"der"}),o=t.notBefore||new Date(Date.now()-864e5),c=new Date(o.getTime()+24*s*60*60*1e3),d=e.randomBytes(20);d[0]&=127,0===d[0]&&(d[0]=1);const T=function(e){const t=m([p(g.commonName),(r=e,l(h.UTF8_STRING,Buffer.from(r,"utf8")))]);var r,s;return m([(s=[t],l(h.SET,Buffer.concat(s)))])}(r),C=m([(S=f(2),l(160,S)),u(d),I(),T,m([E(o),E(c)]),T,a]);var S;const y=e.sign("sha256",C,n);var B;return{certDer:m([C,I(),(B=y,l(h.BIT_STRING,Buffer.concat([Buffer.from([0]),B])))]),privateKey:n,publicKey:i,notBefore:o,notAfter:c}}function C(t,r="sha-256"){const s=r.replace("-","").toLowerCase();return e.createHash(s).update(t).digest("hex").toUpperCase().match(/.{2}/g).join(":")}function S(e,t="sha-256"){return C(e,t)}class y{#I;#T;#C;#S;#y;constructor(e){this.#I=e.certDer||null,this.#T=e.privateKey,this.#C=e.publicKey,this.#S=e.expires,this.#y=null}getCertificateDer(){return this.#I}get expires(){return this.#S}getFingerprints(){if(!this.#I)throw new Error("Certificate has no DER encoding; cannot compute fingerprint");if(!this.#y){const e=this.#I,t=["sha-256","sha-384","sha-512"];this.#y=t.map(t=>({algorithm:t,value:S(e,t)}))}return this.#y.map(e=>({...e}))}getPrivateKeyObject(){return this.#B(this.#T,"private")}#B(t,r){return t&&"object"==typeof t&&t.type?t:"private"===r?e.createPrivateKey(t):e.createPublicKey(t)}getPrivateKey(){return this.#B(this.#T,"private").export({type:"pkcs8",format:"pem"})}getPublicKey(){return this.#B(this.#C,"public").export({type:"spki",format:"pem"})}toPEM(){const e=this.#I?`-----BEGIN CERTIFICATE-----\n${this.#I.toString("base64").match(/.{1,64}/g).join("\n")}\n-----END CERTIFICATE-----\n`:this.getPublicKey();return{pemPrivateKey:this.getPrivateKey(),pemCertificate:e}}isExpired(){return Date.now()>this.#S}static async generateCertificate(e={}){return new Promise((t,r)=>{try{let s;if(e.expires)s=e.expires;else{const t=e.days||30;s=Date.now()+24*t*60*60*1e3}setImmediate(()=>{try{const r=function(e={}){const{name:t,days:r=30}=e,{certDer:s,privateKey:i,publicKey:n,notAfter:a}=T({commonName:t,days:r});return{certDer:s,privateKey:i,publicKey:n,expires:a.getTime(),hash:"sha256"}}({name:e.name||"webrtc",days:Math.ceil((s-Date.now())/864e5),hash:e.hash||"sha256"});r.expires=s;const i=new y(r);t(i)}catch(e){r(e)}})}catch(e){r(e)}})}static fromPEM(t,r,s){if("string"!=typeof t||0===t.length)throw new TypeError("pemPrivateKey must be a non-empty string");if("string"!=typeof r||0===r.length)throw new TypeError("pemCertificate must be a non-empty string");const i=s||Date.now()+2592e6;let n=null,a=r;const o=r.match(/-----BEGIN CERTIFICATE-----([\s\S]+?)-----END CERTIFICATE-----/);return o&&(n=Buffer.from(o[1].replace(/\s/g,""),"base64"),a=e.createPublicKey(e.createPrivateKey(t))),new y({certDer:n,privateKey:t,publicKey:a,expires:i,hash:"sha256"})}static isSupportedKeyParams(e){if(!e||"object"!=typeof e)return!1;if("RSA"===e.type){const t=e.rsaModulusLength||2048;return t>=1024&&t<=4096}if("ECDSA"===e.type){const t=e.namedCurve;return["P-256","P-384","P-521"].includes(t)}return!1}}const B=Object.freeze({CONNECTING:"connecting",OPEN:"open",CLOSING:"closing",CLOSED:"closed"}),A=Object.freeze({SEND:Symbol("rtcdatachannel:send"),RECEIVE:Symbol("rtcdatachannel:receive"),OPEN:Symbol("rtcdatachannel:open"),SET_ID:Symbol("rtcdatachannel:setId")});class R extends t{#A;#R;#w;#N;#b;#O;#D;#U;#k;#v;#L;#P;constructor(e,t={}){if(super(),"string"!=typeof e)throw new TypeError("label must be a string");this.#A=e,this.#R=void 0===t.ordered||t.ordered,this.#w=t.maxPacketLifeTime||null,this.#N=t.maxRetransmits||null,this.#b=t.protocol||"",this.#O=t.negotiated||!1,this.#D=void 0!==t.id?t.id:null,this.#U=B.CONNECTING,this.#k=0,this.#v=0,this.#L="arraybuffer",this.#P=!1,this.on(A.SET_ID,e=>{this.#D=e}),this.on(A.OPEN,()=>{this.#P=!0,this.#_(B.OPEN)}),this.on(A.RECEIVE,(e,t)=>{this.#H(e,t)})}get label(){return this.#A}get ordered(){return this.#R}get maxPacketLifeTime(){return this.#w}get maxRetransmits(){return this.#N}get protocol(){return this.#b}get negotiated(){return this.#O}get id(){return this.#D}get readyState(){return this.#U}get bufferedAmount(){return this.#k}get bufferedAmountLowThreshold(){return this.#v}set bufferedAmountLowThreshold(e){this.#v=e}get binaryType(){return this.#L}set binaryType(e){if("arraybuffer"!==e&&"blob"!==e)throw new TypeError('binaryType must be "arraybuffer" or "blob"');this.#L=e}get reliable(){return this.#R&&null===this.#w&&null===this.#N}send(e){if(this.#U!==B.OPEN)throw new Error('RTCDataChannel.readyState is not "open"');let t,r,s=0;if("string"==typeof e)t=Buffer.from(e,"utf8"),s=t.length,r=!1;else if(e instanceof ArrayBuffer)t=Buffer.from(e),s=e.byteLength,r=!0;else if(ArrayBuffer.isView(e))t=Buffer.from(e.buffer,e.byteOffset,e.byteLength),s=e.byteLength,r=!0;else{if(!Buffer.isBuffer(e))throw e&&"function"==typeof e.arrayBuffer?new Error("Blob sending not yet implemented"):new TypeError("Invalid data type");t=e,s=e.length,r=!0}if(!this.#P)throw new Error("Data channel not connected to a transport");this.#k+=s;try{this.emit(A.SEND,t,r),this.#k=Math.max(0,this.#k-s),this.#x()}catch(e){throw this.#k=Math.max(0,this.#k-s),this.emit("error",e),e}}#x(){this.#k<=this.#v&&this.emit("bufferedamountlow")}close(){this.#U!==B.CLOSING&&this.#U!==B.CLOSED&&(this.#_(B.CLOSING),setImmediate(()=>{this.#U===B.CLOSING&&this.#_(B.CLOSED)}))}#_(e){this.#U!==e&&(this.#U=e,e===B.OPEN?this.emit("open"):e===B.CLOSING?this.emit("closing"):e===B.CLOSED&&this.emit("close"))}#H(e,t){let r;r=t?"arraybuffer"===this.#L?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e:e.toString("utf8"),this.emit("message",{data:r})}}const w=Object.freeze({OFFER:"offer",PRANSWER:"pranswer",ANSWER:"answer",ROLLBACK:"rollback"});class N{#M;#F;constructor(e={}){if(this.#M=e.type||null,this.#F=e.sdp||null,this.#M&&!Object.values(w).includes(this.#M))throw new TypeError(`Invalid SDP type: ${this.#M}`)}get type(){return this.#M}set type(e){if(e&&!Object.values(w).includes(e))throw new TypeError(`Invalid SDP type: ${e}`);this.#M=e}get sdp(){return this.#F}set sdp(e){this.#F=e}toJSON(){return{type:this.#M,sdp:this.#F}}}function b(t){const{iceUfrag:r,icePwd:s,fingerprint:i,setup:n="actpass",candidates:a=[],sctpPort:o=5e3,maxMessageSize:c=262144}=t,h=[];h.push("v=0");const d=e.randomBytes(4).readUInt32BE(0);h.push(`o=- ${d} 2 IN IP4 127.0.0.1`),h.push("s=-"),h.push("t=0 0"),h.push("a=group:BUNDLE 0"),h.push("a=msid-semantic: WMS"),h.push("m=application 9 UDP/DTLS/SCTP webrtc-datachannel"),h.push("c=IN IP4 0.0.0.0"),h.push("a=ice-ufrag:"+r),h.push("a=ice-pwd:"+s),h.push("a=ice-options:trickle"),i&&h.push(`a=fingerprint:${i.algorithm} ${i.value}`),h.push(`a=setup:${n}`),h.push("a=mid:0"),h.push("a=sctp-port:"+o),h.push("a=max-message-size:"+c);for(const e of a){const t=e.sdp||e.candidate;t&&h.push("a="+(t.startsWith("candidate:")?t:"candidate:"+t))}return h.join("\r\n")+"\r\n"}function O(e){const t=(e.startsWith("candidate:")?e.slice(10):e).split(/\s+/);return t.length<8?null:{candidate:e.startsWith("candidate:")?e:"candidate:"+e,foundation:t[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10)>>>0,address:t[4],port:parseInt(t[5],10),type:t[7]}}const D=554869826,U=Object.freeze({BINDING_REQUEST:1,BINDING_SUCCESS:257,BINDING_ERROR:273}),k=Object.freeze({MAPPED_ADDRESS:1,USERNAME:6,MESSAGE_INTEGRITY:8,ERROR_CODE:9,XOR_MAPPED_ADDRESS:32,PRIORITY:36,USE_CANDIDATE:37,FINGERPRINT:32808,ICE_CONTROLLED:32809,ICE_CONTROLLING:32810});function v(e){return e+3&-4}const L=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})();class P{type;transactionId;attrs;constructor(t,r){this.type=t,this.transactionId=r||e.randomBytes(12),this.attrs=[]}addAttr(e,t){return this.attrs.push({type:e,value:t}),this}addUsername(e){return this.addAttr(k.USERNAME,Buffer.from(e,"utf8"))}addPriority(e){const t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),this.addAttr(k.PRIORITY,t)}addIceControlling(e){return this.addAttr(k.ICE_CONTROLLING,e)}addIceControlled(e){return this.addAttr(k.ICE_CONTROLLED,e)}addUseCandidate(){return this.addAttr(k.USE_CANDIDATE,Buffer.alloc(0))}addXorMappedAddress(e,t){return this.addAttr(k.XOR_MAPPED_ADDRESS,function(e,t){const r=Buffer.alloc(8);r.writeUInt8(0,0),r.writeUInt8(1,1),r.writeUInt16BE(8466^t,2);const s=e.split(".").map(Number),i=(s[0]<<24|s[1]<<16|s[2]<<8|s[3])>>>0;return r.writeUInt32BE((i^D)>>>0,4),r}(e,t,this.transactionId))}#K(){const e=[];for(const t of this.attrs){const r=Buffer.alloc(4);r.writeUInt16BE(t.type,0),r.writeUInt16BE(t.value.length,2);const s=Buffer.alloc(v(t.value.length));t.value.copy(s,0),e.push(r,s)}return Buffer.concat(e)}#q(e){const t=Buffer.alloc(20);return t.writeUInt16BE(this.type,0),t.writeUInt16BE(e,2),t.writeUInt32BE(D,4),this.transactionId.copy(t,8),t}build(t){let r=this.#K();if(t){const s=r.length+24,i=this.#q(s),n=e.createHmac("sha1",Buffer.from(t,"utf8")).update(Buffer.concat([i,r])).digest(),a=Buffer.alloc(4);a.writeUInt16BE(k.MESSAGE_INTEGRITY,0),a.writeUInt16BE(20,2),r=Buffer.concat([r,a,n])}const s=r.length+8,i=this.#q(s),n=(1398035790^function(e){let t=4294967295;for(let r=0;r<e.length;r++)t=L[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}(Buffer.concat([i,r])))>>>0,a=Buffer.alloc(8);return a.writeUInt16BE(k.FINGERPRINT,0),a.writeUInt16BE(4,2),a.writeUInt32BE(n,4),r=Buffer.concat([r,a]),Buffer.concat([this.#q(r.length),r])}}const _=Object.freeze({CHANGE_CIPHER_SPEC:20,ALERT:21,HANDSHAKE:22,APPLICATION_DATA:23}),H=Object.freeze({HELLO_REQUEST:0,CLIENT_HELLO:1,SERVER_HELLO:2,HELLO_VERIFY_REQUEST:3,CERTIFICATE:11,SERVER_KEY_EXCHANGE:12,CERTIFICATE_REQUEST:13,SERVER_HELLO_DONE:14,CERTIFICATE_VERIFY:15,CLIENT_KEY_EXCHANGE:16,FINISHED:20}),x=Object.freeze({WARNING:1,FATAL:2}),M=Object.freeze({CLOSE_NOTIFY:0,HANDSHAKE_FAILURE:40,BAD_CERTIFICATE:42,DECRYPT_ERROR:51,INTERNAL_ERROR:80}),F=49195,K=Object.freeze({secp256r1:23}),q=Object.freeze({uncompressed:0}),G=Object.freeze({sha256:4,sha384:5,sha512:6}),$=Object.freeze({rsa:1,ecdsa:3}),z=Object.freeze({ecdsa_sign:64,rsa_sign:1}),j=Object.freeze({SUPPORTED_GROUPS:10,EC_POINT_FORMATS:11,SIGNATURE_ALGORITHMS:13,EXTENDED_MASTER_SECRET:23,RENEGOTIATION_INFO:65281}),V=Object.freeze({CLIENT:"client finished",SERVER:"server finished"});function W(e){return Buffer.from([e>>16&255,e>>8&255,255&e])}function Y(e,t){return e[t]<<16|e[t+1]<<8|e[t+2]}function X(e){return Buffer.concat([Buffer.from([e.length]),e])}function Q(e){const t=Buffer.alloc(2);return t.writeUInt16BE(e.length,0),Buffer.concat([t,e])}function Z(e){return Buffer.concat([W(e.length),e])}function J(e,t,r){const s=Buffer.alloc(12);return s.writeUInt8(e,0),W(r.length).copy(s,1),s.writeUInt16BE(t,4),W(0).copy(s,6),W(r.length).copy(s,9),Buffer.concat([s,r])}function ee(t,r,s,i){return function(t,r,s,i){const n=[];let a=0,o=s;for(;a<i;){o=e.createHmac(t,r).update(o).digest();const i=e.createHmac(t,r).update(Buffer.concat([o,s])).digest();n.push(i),a+=i.length}return Buffer.concat(n).slice(0,i)}("sha256",t,Buffer.concat([Buffer.from(r,"ascii"),s]),i)}function te(e,t,r){return ee(e,"master secret",Buffer.concat([t,r]),48)}function re(e,t){return ee(e,"extended master secret",t,48)}function se(e,t,r,s,i){const n=Buffer.alloc(13);return n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6),n.writeUInt8(r,8),n.writeUInt16BE(s,9),n.writeUInt16BE(i,11),n}class ie{#G;#$;constructor(e,t){this.#G=e,this.#$=t}encrypt(t,r,s,i,n){const a=Buffer.alloc(8);a.writeUInt16BE(t,0),a.writeUIntBE(r,2,6);const o=Buffer.concat([this.#$,a]),c=se(t,r,s,i,n.length),h=e.createCipheriv("aes-128-gcm",this.#G,o);h.setAAD(c);const d=Buffer.concat([h.update(n),h.final()]),l=h.getAuthTag();return Buffer.concat([a,d,l])}decrypt(t,r,s,i,n){const a=n.slice(0,8),o=n.slice(n.length-16),c=n.slice(8,n.length-16),h=Buffer.concat([this.#$,a]),d=se(t,r,s,i,c.length),l=e.createDecipheriv("aes-128-gcm",this.#G,h);return l.setAAD(d),l.setAuthTag(o),Buffer.concat([l.update(c),l.final()])}}const ne=Object.freeze({CLIENT:"client",SERVER:"server"}),ae=Object.freeze({NEW:"new",HANDSHAKING:"handshaking",CONNECTED:"connected",CLOSED:"closed",FAILED:"failed"});class oe extends t{role;state;#I;#T;#z;#j;#V;#W;#Y;#X;#Q;#Z;#J;#ee;#te;#re;#se;#ie;#ne;#ae;#oe;#ce;#he;#de;#le;#ue;#fe;#pe;#me;#Ee;constructor(e){super(),this.role=e.role,this.#I=e.certDer,this.#T=e.privateKey,this.#z=e.verifyFingerprint||null,this.#j=e.output,this.state=ae.NEW,this.#V=0,this.#W=0,this.#Y=0,this.#X=null,this.#Q=null,this.#Z=!1,this.#J=null,this.#ee=null,this.#te=Buffer.alloc(0),this.#re=null,this.#se=null,this.#ie=null,this.#ne=null,this.#ae=!1,this.#oe=[],this.#ce=new Map,this.#he=0,this.#de=[],this.#le=null,this.#ue=0,this.#fe=!1,this.#Ee=!1}start(){this.state===ae.NEW&&(this.state=ae.HANDSHAKING,this.role===ne.CLIENT&&(this.#J=this.#ge(),this.#Ie()))}#ge(){const t=e.randomBytes(32);return t.writeUInt32BE(Math.floor(Date.now()/1e3),0),t}#Te(e){const t=[];for(const r of e){const e=this.#Y++,s=J(r.type,e,r.body);this.#oe.push(s);const i=r.body.length;let n=0;do{const s=r.body.slice(n,n+1200),a=Buffer.alloc(12);a.writeUInt8(r.type,0),W(i).copy(a,1),a.writeUInt16BE(e,4),W(n).copy(a,6),W(s.length).copy(a,9);const o=Buffer.concat([a,s]);t.push({type:_.HANDSHAKE,payload:o}),n+=s.length}while(n<i)}this.#de=t,this.#ue=0,this.#Ce(),this.#Se()}#Ce(){for(const e of this.#de)this.#ye(e.type,e.payload)}#Be(){this.#ye(_.CHANGE_CIPHER_SPEC,Buffer.from([1])),this.#V=1,this.#W=0,this.#Z=!0}#ye(e,t){let r=t;const s=this.#W++;this.#Z&&this.#X&&(r=this.#X.encrypt(this.#V,s,e,65277,t));const i=function(e,t,r,s,i=65277){const n=Buffer.alloc(13);return n.writeUInt8(e,0),n.writeUInt16BE(i,1),n.writeUInt16BE(t,3),n.writeUIntBE(r,5,6),n.writeUInt16BE(s.length,11),Buffer.concat([n,s])}(e,this.#V,s,r,65277);this.#j(i)}#Se(){this.#Ae(),this.#le=setTimeout(()=>{this.#fe||this.state!==ae.HANDSHAKING||(this.#ue>=10?this.#Re(new Error("DTLS handshake timed out")):(this.#ue++,this.#Ce(),this.#Se()))},1e3*Math.pow(2,this.#ue)),this.#le.unref&&this.#le.unref()}#Ae(){this.#le&&(clearTimeout(this.#le),this.#le=null)}handlePacket(e){if(this.state===ae.CLOSED||this.state===ae.FAILED)return;let t;try{t=function(e){const t=[];let r=0;for(;r+13<=e.length;){const s=e.readUInt8(r),i=e.readUInt16BE(r+1),n=e.readUInt16BE(r+3),a=e.readUIntBE(r+5,6),o=e.readUInt16BE(r+11),c=r+13;if(c+o>e.length)break;t.push({type:s,version:i,epoch:n,seq:a,fragment:e.slice(c,c+o)}),r=c+o}return t}(e)}catch(e){return}for(const e of t)try{this.#we(e)}catch(e){return void this.#Re(e instanceof Error?e:new Error(String(e)))}}#we(e){let t=e.fragment;if(e.epoch>=1){if(!this.#Q)return;t=this.#Q.decrypt(e.epoch,e.seq,e.type,e.version,e.fragment)}switch(e.type){case _.HANDSHAKE:this.#Ne(t);break;case _.CHANGE_CIPHER_SPEC:break;case _.APPLICATION_DATA:this.state===ae.CONNECTED&&this.emit("data",t);break;case _.ALERT:this.#be(t)}}#be(e){if(e.length<2)return;const t=e[0],r=e[1];r===M.CLOSE_NOTIFY?this.close():t===x.FATAL&&this.#Re(new Error(`DTLS fatal alert: ${r}`))}#Ne(e){const t=function(e){const t=e.readUInt8(0),r=Y(e,1),s=e.readUInt16BE(4),i=Y(e,6),n=Y(e,9);return{msgType:t,length:r,messageSeq:s,fragmentOffset:i,fragmentLength:n,body:e.slice(12,12+n)}}(e);let r=this.#ce.get(t.messageSeq);for(r||(r={type:t.msgType,length:t.length,data:Buffer.alloc(t.length),received:0,ranges:[]},this.#ce.set(t.messageSeq,r)),t.body.copy(r.data,t.fragmentOffset),r.received=Math.max(r.received,t.fragmentOffset+t.fragmentLength);;){const e=this.#ce.get(this.#he);if(!e||e.received<e.length)break;this.#ce.delete(this.#he),this.#he++,this.#Oe(e.type,e.data)}}#De(e,t){const r=this.#he-1;this.#oe.push(J(e,r,t))}#Oe(e,t){this.role===ne.CLIENT?this.#Ue(e,t):this.#ke(e,t)}#ve(){const t=e.createHash("sha256");for(const e of this.#oe)t.update(e);return t.digest()}#Le(){return Buffer.concat(this.#oe)}#Ie(){const e=this.#Pe();if(0===this.#te.length){const t=this.#Y++,r=J(H.CLIENT_HELLO,t,e);this.#de=[{type:_.HANDSHAKE,payload:r}],this.#Ce(),this.#Se()}else{const t=this.#Y++,r=J(H.CLIENT_HELLO,t,e);this.#oe.push(r),this.#de=[{type:_.HANDSHAKE,payload:r}],this.#ue=0,this.#Ce(),this.#Se()}}#Pe(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#J),e.push(X(Buffer.alloc(0))),e.push(X(this.#te));const t=Buffer.alloc(2);return t.writeUInt16BE(F,0),e.push(Q(t)),e.push(X(Buffer.from([0]))),e.push(Q(this.#_e())),Buffer.concat(e)}#_e(){const e=[],t=Buffer.alloc(2);t.writeUInt16BE(K.secp256r1,0),e.push(this.#He(j.SUPPORTED_GROUPS,Q(t))),e.push(this.#He(j.EC_POINT_FORMATS,X(Buffer.from([q.uncompressed]))));const r=Buffer.from([G.sha256,$.ecdsa]);return e.push(this.#He(j.SIGNATURE_ALGORITHMS,Q(r))),e.push(this.#He(j.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),Buffer.concat(e)}#He(e,t){const r=Buffer.alloc(4);return r.writeUInt16BE(e,0),r.writeUInt16BE(t.length,2),Buffer.concat([r,t])}#Ue(e,t){switch(e){case H.HELLO_VERIFY_REQUEST:{const e=t.readUInt8(2);this.#te=t.slice(3,3+e),this.#Ae(),this.#Ie();break}case H.SERVER_HELLO:this.#De(e,t),this.#xe(t);break;case H.CERTIFICATE:this.#De(e,t),this.#ie=this.#Me(t);break;case H.SERVER_KEY_EXCHANGE:this.#De(e,t),this.#Fe(t);break;case H.CERTIFICATE_REQUEST:this.#Ee=!0,this.#De(e,t);break;case H.SERVER_HELLO_DONE:this.#De(e,t),this.#Ae(),this.#Ke();break;case H.FINISHED:this.#qe(t,V.SERVER),this.#De(e,t),this.#Ge()}}#xe(e){let t=2;this.#ee=e.slice(t,t+32),t+=32,t+=1+e.readUInt8(t);const r=e.readUInt16BE(t);if(t+=2,r!==F)throw new Error(`Server chose unsupported cipher suite 0x${r.toString(16)}`);if(t+=1,t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===j.EXTENDED_MASTER_SECRET&&(this.#ae=!0),t+=s}}}#Ke(){this.#re=e.createECDH("prime256v1"),this.#re.generateKeys();const t=this.#re.getPublicKey(),r=this.#re.computeSecret(this.#ne),s=X(t),i=this.#Ee;let n=null,a=Buffer.alloc(0);const o=i?this.#Y+1:this.#Y;i&&(n=this.#$e(),a=J(H.CERTIFICATE,this.#Y,n));const c=J(H.CLIENT_KEY_EXCHANGE,o,s);if(this.#ae){const t=e.createHash("sha256");for(const e of this.#oe)t.update(e);i&&t.update(a),t.update(c);const s=t.digest();this.#se=re(r,s)}else this.#se=te(r,this.#J,this.#ee);this.#ze();const h=[];if(i&&h.push({type:H.CERTIFICATE,body:n}),h.push({type:H.CLIENT_KEY_EXCHANGE,body:s}),i){const t=Buffer.concat([...this.#oe,a,c]),r=e.sign("sha256",t,{key:this.#T,dsaEncoding:"der"}),s=Buffer.concat([Buffer.from([G.sha256,$.ecdsa]),Q(r)]);h.push({type:H.CERTIFICATE_VERIFY,body:s})}this.#Te(h),this.#Be(),this.#je(V.CLIENT)}#ke(e,t){switch(e){case H.CLIENT_HELLO:this.#Ve(t);break;case H.CERTIFICATE:this.#De(e,t),this.#ie=this.#Me(t);break;case H.CLIENT_KEY_EXCHANGE:{this.#De(e,t);const r=t.readUInt8(0);this.#ne=t.slice(1,1+r);const s=this.#re.computeSecret(this.#ne);this.#ae?this.#se=re(s,this.#ve()):this.#se=te(s,this.#J,this.#ee),this.#ze();break}case H.CERTIFICATE_VERIFY:this.#We(t),this.#De(e,t);break;case H.FINISHED:this.#qe(t,V.CLIENT),this.#De(e,t),this.#Be(),this.#je(V.SERVER),this.#Ge()}}#Ve(e){let t=2;const r=e.slice(t,t+32);t+=32,t+=1+e.readUInt8(t);const s=e.readUInt8(t),i=e.slice(t+1,t+1+s);t+=1+s;const n=e.readUInt16BE(t),a=e.slice(t+2,t+2+n);t+=2+n,t+=1+e.readUInt8(t);let o=!1,c=!1;for(let e=0;e+1<a.length;e+=2)255===a.readUInt16BE(e)&&(c=!0);if(t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===j.EXTENDED_MASTER_SECRET&&(o=!0),r===j.RENEGOTIATION_INFO&&(c=!0),t+=s}}if(this.#me=c,0===i.length)return this.#J=r,this.#Ye(this.#Xe(r)),this.#ce.clear(),void(this.#he=1);const h=this.#Xe(r);if(!i.equals(h))return this.#Ye(h),this.#ce.clear(),void(this.#he=1);this.#J=r,this.#ae=o,this.#De(H.CLIENT_HELLO,e),this.#Qe()}#Xe(t){return this.#pe||(this.#pe=e.randomBytes(32)),e.createHmac("sha256",this.#pe).update(t).digest().slice(0,20)}#Ye(e){const t=Buffer.concat([Buffer.from([254,255]),X(e)]),r=J(H.HELLO_VERIFY_REQUEST,0,t);this.#ye(_.HANDSHAKE,r),this.#Y=1}#Qe(){this.#ee=this.#ge(),this.#re=e.createECDH("prime256v1"),this.#re.generateKeys();const t=this.#re.getPublicKey(),r=this.#Ze(),s=this.#$e(),i=Buffer.concat([Buffer.from([3]),(()=>{const e=Buffer.alloc(2);return e.writeUInt16BE(K.secp256r1,0),e})(),X(t)]),n=Buffer.concat([this.#J,this.#ee,i]),a=e.sign("sha256",n,{key:this.#T,dsaEncoding:"der"}),o=Buffer.concat([i,Buffer.from([G.sha256,$.ecdsa]),Q(a)]),c=X(Buffer.from([z.ecdsa_sign,z.rsa_sign])),h=Q(Buffer.from([G.sha256,$.ecdsa])),d=Q(Buffer.alloc(0)),l=Buffer.concat([c,h,d]),u=Buffer.alloc(0);this.#Te([{type:H.SERVER_HELLO,body:r},{type:H.CERTIFICATE,body:s},{type:H.SERVER_KEY_EXCHANGE,body:o},{type:H.CERTIFICATE_REQUEST,body:l},{type:H.SERVER_HELLO_DONE,body:u}])}#Ze(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#ee),e.push(X(Buffer.alloc(0)));const t=Buffer.alloc(2);t.writeUInt16BE(F,0),e.push(t),e.push(Buffer.from([0]));const r=[];return this.#ae&&r.push(this.#He(j.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),r.push(this.#He(j.EC_POINT_FORMATS,X(Buffer.from([q.uncompressed])))),this.#me&&r.push(this.#He(j.RENEGOTIATION_INFO,X(Buffer.alloc(0)))),e.push(Q(Buffer.concat(r))),Buffer.concat(e)}#We(t){const r=t.readUInt16BE(2),s=t.slice(4,4+r),i=this.#Le(),n=this.#Je(this.#ie);if(!e.verify("sha256",i,{key:n,dsaEncoding:"der"},s))throw new Error("Client CertificateVerify signature invalid")}#$e(){const e=Z(this.#I);return Z(e)}#Me(e){let t=3;if(t+3>3+Y(e,0))return null;const r=Y(e,t);t+=3;const s=e.slice(t,t+r);if(this.#z){const e={algorithm:"sha-256",value:C(s,"sha-256")};if(!this.#z(e,s))throw new Error("Remote certificate fingerprint mismatch")}return s}#Fe(t){let r=0;const s=t.readUInt8(r);r+=1;const i=t.readUInt16BE(r);if(r+=2,3!==s||i!==K.secp256r1)throw new Error("Unsupported ECDHE curve from server");const n=t.readUInt8(r);r+=1;const a=t.slice(r,r+n);r+=n,this.#ne=a;const o=t.slice(0,r);r+=2;const c=t.readUInt16BE(r);r+=2;const h=t.slice(r,r+c),d=Buffer.concat([this.#J,this.#ee,o]),l=this.#Je(this.#ie);if(!e.verify("sha256",d,{key:l,dsaEncoding:"der"},h))throw new Error("ServerKeyExchange signature invalid")}#Je(t){return new e.X509Certificate(t).publicKey}#ze(){const{clientKey:e,serverKey:t,clientIV:r,serverIV:s}=function(e,t,r){const s=ee(e,"key expansion",Buffer.concat([r,t]),40);let i=0;return{clientKey:s.slice(i,i+=16),serverKey:s.slice(i,i+=16),clientIV:s.slice(i,i+=4),serverIV:s.slice(i,i+=4)}}(this.#se,this.#J,this.#ee);this.role===ne.CLIENT?(this.#X=new ie(e,r),this.#Q=new ie(t,s)):(this.#X=new ie(t,s),this.#Q=new ie(e,r))}#je(e){const t=ee(this.#se,e,this.#ve(),12),r=this.#Y++,s=J(H.FINISHED,r,t);this.#oe.push(s),this.#ye(_.HANDSHAKE,s)}#qe(t,r){const s=ee(this.#se,r,this.#ve(),12);if(!e.timingSafeEqual(t,s))throw new Error("Peer Finished verify_data mismatch")}#Ge(){this.#fe||(this.#fe=!0,this.#Ae(),this.state=ae.CONNECTED,this.emit("connect"))}send(e){if(this.state!==ae.CONNECTED)throw new Error("DTLS connection not established");this.#ye(_.APPLICATION_DATA,e)}close(){if(this.state!==ae.CLOSED&&this.state!==ae.FAILED){try{this.#Z&&this.#ye(_.ALERT,Buffer.from([x.WARNING,M.CLOSE_NOTIFY]))}catch(e){}this.#Ae(),this.state=ae.CLOSED,this.emit("close")}}#Re(e){this.state!==ae.FAILED&&this.state!==ae.CLOSED&&(this.#Ae(),this.state=ae.FAILED,this.emit("error",e))}getRemoteCertificate(){return this.#ie}}const ce=554869826;class he extends t{#et;#tt;#rt;#st;#it;#nt;#at;#ot;#ct;#ht;#dt;#lt;#ut;constructor(e){super(),this.#et=e.server,this.#tt=e.port,this.#rt=e.username,this.#st=e.credential,this.#it=null,this.#nt=new Map,this.#at=null,this.#ot=null,this.#ct=!0===e.secure,this.#ht=(e.transport||"udp").toLowerCase(),this.#dt=null,this.#lt=null,this.#ut=Buffer.alloc(0)}async connect(){if(!this.#it&&!this.#lt)return this.#ct&&"tcp"===this.#ht?this.#ft():new Promise((e,t)=>{const s=r.createSocket("udp4");if(this.#it=s,s.on("error",e=>{console.error("STUN socket error:",e),t(e)}),this.#ct){const r=T({commonName:"nodertc-turn-client"}),i=new oe({role:ne.CLIENT,certDer:r.certDer,privateKey:r.privateKey,verifyFingerprint:()=>!0,output:e=>{s.send(e,this.#tt,this.#et,()=>{})}});this.#dt=i,s.on("message",e=>i.handlePacket(e)),i.on("data",e=>this.#pt(e,this.#mt())),i.on("connect",()=>e()),i.on("error",e=>t(e)),s.bind(()=>i.start())}else s.on("message",(e,t)=>{this.#pt(e,t)}),s.bind(()=>e())})}#ft(){return new Promise((e,t)=>{const r=i.connect({host:this.#et,port:this.#tt,rejectUnauthorized:!1},()=>e());this.#lt=r,r.on("data",e=>this.#Et(e)),r.on("error",e=>t(e))})}#Et(e){for(this.#ut=this.#ut.length?Buffer.concat([this.#ut,e]):e;this.#ut.length>=20;){const e=20+this.#ut.readUInt16BE(2);if(this.#ut.length<e)break;const t=this.#ut.subarray(0,e);this.#ut=this.#ut.subarray(e),this.#pt(t,this.#mt())}}#mt(){return{address:this.#et,family:"IPv4",port:this.#tt,size:0}}#gt(e,t){if(this.#lt)this.#lt.write(e,e=>{e&&t(e)});else if(this.#dt)try{this.#dt.send(e)}catch(e){t(e instanceof Error?e:new Error(String(e)))}else this.#it.send(e,this.#tt,this.#et,e=>{e&&t(e)})}async getReflexiveAddress(){await this.connect();const t=e.randomBytes(12),r=this.#It(t);return new Promise((e,s)=>{const i=setTimeout(()=>{this.#nt.delete(t.toString("hex")),s(new Error("STUN request timeout"))},5e3);this.#nt.set(t.toString("hex"),{resolve:t=>{clearTimeout(i),e(t)},reject:e=>{clearTimeout(i),s(e)}}),this.#gt(r,e=>{clearTimeout(i),this.#nt.delete(t.toString("hex")),s(e)})})}async allocateRelay(t=600){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");await this.connect();let r=e.randomBytes(12),s=this.#Tt(r,t);try{return await this.#Ct(s,r,"allocate")}catch(i){if(i instanceof Error&&i.message.includes("401")&&this.#at&&this.#ot)return r=e.randomBytes(12),s=this.#Tt(r,t,!0),await this.#Ct(s,r,"allocate");throw i}}async refreshAllocation(t=600){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");return this.#St("refresh",()=>{const r=e.randomBytes(12);return{transactionId:r,request:this.#yt(r,t)}})}async#St(e,t){const r=t();try{return await this.#Ct(r.request,r.transactionId,e)}catch(r){if(r instanceof Error&&r.message.includes("401")&&this.#at&&this.#ot){const r=t();return this.#Ct(r.request,r.transactionId,e)}throw r}}async createPermission(t){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");await this.#St("createPermission",()=>{const r=e.randomBytes(12);return{transactionId:r,request:this.#Bt(r,t)}})}async sendIndication(t,r,s){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");const i=e.randomBytes(12),n=this.#At(i,t,r,s);return new Promise((e,t)=>{this.#gt(n,t),e()})}#Ct(e,t,r){return new Promise((s,i)=>{const n=setTimeout(()=>{this.#nt.delete(t.toString("hex")),i(new Error(`${r} request timeout`))},5e3);this.#nt.set(t.toString("hex"),{type:r,resolve:e=>{clearTimeout(n),s(e)},reject:e=>{clearTimeout(n),i(e)}}),this.#gt(e,e=>{clearTimeout(n),this.#nt.delete(t.toString("hex")),i(e)})})}#It(e){const t=Buffer.alloc(20);return t.writeUInt16BE(1,0),t.writeUInt16BE(0,2),t.writeUInt32BE(ce,4),e.copy(t,8),t}#Tt(e,t,r=!1){const s=[],i=Buffer.alloc(8);i.writeUInt16BE(25,0),i.writeUInt16BE(4,2),i.writeUInt8(17,4),s.push(i);const n=Buffer.alloc(8);if(n.writeUInt16BE(13,0),n.writeUInt16BE(4,2),n.writeUInt32BE(t,4),s.push(n),r&&this.#at&&this.#ot){const e=this.#Rt(6,this.#rt);s.push(e);const t=this.#Rt(20,this.#at);s.push(t);const r=this.#Rt(21,this.#ot);s.push(r)}return this.#wt(3,e,s,r)}#Bt(e,t){const r=[],s=this.#Nt(t,0,e);return r.push(s),this.#at&&this.#ot&&(r.push(this.#Rt(6,this.#rt)),r.push(this.#Rt(20,this.#at)),r.push(this.#Rt(21,this.#ot))),this.#wt(8,e,r,!0)}#At(e,t,r,s){const i=[],n=this.#Nt(t,r,e);i.push(n);const a=Buffer.alloc(4+s.length+(4-s.length%4)%4);return a.writeUInt16BE(19,0),a.writeUInt16BE(s.length,2),s.copy(a,4),i.push(a),this.#wt(22,e,i,!1)}#Nt(e,t,r){const s=Buffer.alloc(12);s.writeUInt16BE(18,0),s.writeUInt16BE(8,2),s.writeUInt8(0,4),s.writeUInt8(1,5);const i=8466^t;s.writeUInt16BE(i,6);const n=e.split(".").map(Number),a=(n[0]<<24|n[1]<<16|n[2]<<8|n[3])^ce;return s.writeUInt32BE(a>>>0,8),s}#yt(e,t){const r=[],s=Buffer.alloc(8);s.writeUInt16BE(13,0),s.writeUInt16BE(4,2),s.writeUInt32BE(t,4),r.push(s);const i=this.#Rt(6,this.#rt);if(r.push(i),this.#at){const e=this.#Rt(20,this.#at);r.push(e)}if(this.#ot){const e=this.#Rt(21,this.#ot);r.push(e)}return this.#wt(4,e,r,!0)}#wt(t,r,s,i=!1){let n=Buffer.concat(s);if(i&&this.#st){const s=Buffer.alloc(20);s.writeUInt16BE(t,0),s.writeUInt16BE(n.length+24,2),s.writeUInt32BE(ce,4),r.copy(s,8);const i=Buffer.concat([s,n]);let a=this.#st;if(this.#rt&&this.#at){const t=`${this.#rt}:${this.#at}:${this.#st}`;a=e.createHash("md5").update(t).digest()}const o=e.createHmac("sha1",a);o.update(i);const c=o.digest(),h=Buffer.alloc(4+c.length);h.writeUInt16BE(8,0),h.writeUInt16BE(c.length,2),c.copy(h,4),n=Buffer.concat([n,h])}const a=Buffer.alloc(20);return a.writeUInt16BE(t,0),a.writeUInt16BE(n.length,2),a.writeUInt32BE(ce,4),r.copy(a,8),Buffer.concat([a,n])}#Rt(e,t){const r=Buffer.from(t,"utf8"),s=r.length,i=(4-s%4)%4,n=Buffer.alloc(4+s+i);return n.writeUInt16BE(e,0),n.writeUInt16BE(s,2),r.copy(n,4),n}#pt(e,t){if(e.length<20)return;const r=e.readUInt16BE(0),s=e.readUInt16BE(2),i=e.readUInt32BE(4),n=e.slice(8,20);if(i!==ce)return;if(23===r){const t=this.#bt(e.slice(20,20+s),n);if(t.xorPeerAddress&&t.data){const e={address:t.xorPeerAddress.address,port:t.xorPeerAddress.port,family:t.xorPeerAddress.family||"IPv4"};this.emit("data",t.data,e)}return}const a=n.toString("hex"),o=this.#nt.get(a);if(!o)return;const c=this.#bt(e.slice(20,20+s),n);if(257===r)c.xorMappedAddress?o.resolve({address:c.xorMappedAddress.address,port:c.xorMappedAddress.port,family:c.xorMappedAddress.family}):c.mappedAddress?o.resolve({address:c.mappedAddress.address,port:c.mappedAddress.port,family:c.mappedAddress.family}):o.reject(new Error("No mapped address in STUN response")),this.#nt.delete(a);else if(259===r)c.xorRelayedAddress?o.resolve({relayedAddress:c.xorRelayedAddress.address,relayedPort:c.xorRelayedAddress.port,lifetime:c.lifetime||600,type:"relay"}):o.reject(new Error("No relayed address in ALLOCATE response")),this.#nt.delete(a);else if(260===r)o.resolve({lifetime:c.lifetime||600}),this.#nt.delete(a);else if(264===r||265===r)o.resolve({ok:!0}),this.#nt.delete(a);else if(!(272&~r)){c.realm&&(this.#at=c.realm),c.nonce&&(this.#ot=c.nonce);const e=c.errorCode||"Unknown error";o.reject(new Error(`STUN error: ${e}`)),this.#nt.delete(a)}}#bt(e,t){const r={};let s=0;for(;s<e.length&&!(s+4>e.length);){const i=e.readUInt16BE(s),n=e.readUInt16BE(s+2);if(s+=4,s+n>e.length)break;const a=e.slice(s,s+n);switch(i){case 32:r.xorMappedAddress=this.#Ot(a,t);break;case 22:r.xorRelayedAddress=this.#Ot(a,t);break;case 18:r.xorPeerAddress=this.#Ot(a,t);break;case 19:r.data=a;break;case 1:r.mappedAddress=this.#Dt(a);break;case 13:r.lifetime=a.readUInt32BE(0);break;case 9:r.errorCode=this.#Ut(a);break;case 20:r.realm=a.toString("utf8"),this.#at=r.realm;break;case 21:r.nonce=a.toString("utf8"),this.#ot=r.nonce}s+=n,s+=(4-n%4)%4}return r}#Ot(e,t){const r=e.readUInt8(1),s=8466^e.readUInt16BE(2);if(1===r){const t=e.readUInt32BE(4)^ce;return{family:"IPv4",port:s,address:[t>>24&255,t>>16&255,t>>8&255,255&t].join(".")}}return null}#Dt(e){const t=e.readUInt8(1),r=e.readUInt16BE(2);if(1===t){const t=e.slice(4,8);return{family:"IPv4",port:r,address:Array.from(t).join(".")}}return null}#Ut(e){return`${100*(7&e.readUInt8(2))+e.readUInt8(3)} ${e.slice(4).toString("utf8")}`}close(){if(this.#dt){try{this.#dt.close()}catch(e){}this.#dt=null}if(this.#lt){try{this.#lt.destroy()}catch(e){}this.#lt=null}this.#it&&(this.#it.close(),this.#it=null),this.#nt.clear()}}const de={host:126,srflx:100,prflx:110,relay:0};function le(e){const t=e.match(/^(stuns?|turns?):\/?\/?([^:?]+):?(\d+)?(?:\?(.+))?$/);if(!t)return null;const r=t[1],s=t[2],i={};if(t[4])for(const e of t[4].split("&")){if(!e)continue;const t=e.indexOf("=");-1===t?i[e]=!0:i[e.slice(0,t)]=e.slice(t+1)}const n="turns"===r||"stuns"===r?5349:3478;return{scheme:r,protocol:r,host:s,port:parseInt(t[3]||String(n),10),transport:"string"==typeof i.transport?i.transport:"udp",params:i}}class ue{kind;#it;onMessage;constructor(e){this.kind="host",this.#it=e,this.onMessage=null,e.on("message",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){this.#it.send(e,r,t)}close(){try{this.#it.close()}catch(e){}}}class fe{kind;#kt;onMessage;#vt;constructor(e){this.kind="relay",this.#kt=e,this.onMessage=null,this.#vt=new Set,e.on("data",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){const s=`${t}:${r}`;this.#vt.has(s)?this.#kt.sendIndication(t,r,e).catch(()=>{}):(this.#vt.add(s),this.#kt.createPermission(t).then(()=>this.#kt.sendIndication(t,r,e)).catch(()=>{}))}close(){try{this.#kt.close()}catch(e){}}}class pe extends t{role;localUfrag;localPwd;remoteUfrag;remotePwd;#Lt;#Pt;#_t;#Ht;#xt;#Mt;#Ft;#Kt;#qt;#P;#Gt;constructor(t){super(),this.role=t.role,this.localUfrag=t.localUfrag,this.localPwd=t.localPwd,this.remoteUfrag=null,this.remotePwd=null,this.#Lt=e.randomBytes(8),this.#Pt=[],this.#_t=[],this.#Ht=[],this.#xt=[],this.#Mt=null,this.#Ft=!1,this.#Kt=null,this.#qt=null,this.#P=!1,this.#Gt=new Map}async gather(e={}){const t=e.iceServers||[],r="relay"===e.iceTransportPolicy,s=await this.#$t();for(const e of t){const t=Array.isArray(e.urls)?e.urls:[e.urls];for(const i of t){const t=le(i);if(!t)continue;const n="turns"===t.scheme&&"tcp"===t.transport;if("udp"===t.transport||n)try{"stun"!==t.scheme||r?"turn"!==t.scheme&&"turns"!==t.scheme||await this.#zt(t,e):await this.#jt(t,s[0])}catch(e){this.emit("gathererror",{url:i,error:e instanceof Error?e.message:String(e)})}}}r&&(this.#_t=this.#_t.filter(e=>"relay"===e.type)),this.emit("gatheringcomplete")}async#$t(){const e=s.networkInterfaces(),t=[];for(const r of Object.values(e))if(r)for(const e of r)"IPv4"!==e.family||e.internal||t.push(e.address);0===t.length&&t.push("127.0.0.1");const r=[];for(const e of t)r.push(await this.#Vt(e));return r}#Vt(e){return new Promise((t,s)=>{const i=r.createSocket("udp4");i.on("error",e=>this.emit("error",e)),i.bind(0,e,()=>{const{port:r}=i.address(),s=new ue(i);s.onMessage=(e,t)=>this.#Wt(s,e,t),this.#Pt.push(s);const n=this.#Yt("host",e,r,s);t({socket:i,address:e,port:r,transport:s,candidate:n})})})}async#jt(e,t){if(!t)return;const r=new he({server:e.host,port:e.port});try{const e=await r.getReflexiveAddress();this.#Yt("srflx",e.address,e.port,t.transport,{relatedAddress:t.address,relatedPort:t.port})}finally{r.close()}}async#zt(e,t){if(!t.username||!t.credential)throw new Error("TURN server requires username and credential");const r=new he({server:e.host,port:e.port,username:t.username,credential:t.credential,transport:e.transport,secure:"turns"===e.scheme}),s=await r.allocateRelay(600),i=new fe(r);i.onMessage=(e,t)=>this.#Wt(i,e,t),this.#Pt.push(i),this.#Yt("relay",s.relayedAddress,s.relayedPort,i,{relatedAddress:e.host,relatedPort:e.port})}#Yt(t,r,s,i,n={}){const a=e.createHash("md5").update(`${t}:${r}:${i.kind}`).digest("hex").slice(0,8),o=function(e,t=65535,r=1){return(de[e]<<24)+(t<<8)+(256-r)>>>0}(t);let c=`candidate:${a} 1 udp ${o} ${r} ${s} typ ${t}`;n.relatedAddress&&(c+=` raddr ${n.relatedAddress} rport ${n.relatedPort}`);const h={foundation:a,component:1,protocol:"udp",priority:o,address:r,port:s,type:t,transport:i,sdp:c};return this.#_t.push(h),this.emit("candidate",h),h}getLocalCandidates(){return this.#_t.slice()}setRemoteCredentials(e,t){this.remoteUfrag=e,this.remotePwd=t}addRemoteCandidate(e){e&&e.address&&e.port&&("string"==typeof e.address&&e.address.endsWith(".local")||(this.#Ht.push(e),this.#Xt(),!this.#Kt&&this.remotePwd&&this.#Qt()))}start(){this.remotePwd&&this.#Ht.length>0&&this.#Qt()}#Xt(){for(const e of this.#_t)for(const t of this.#Ht){const r=`${e.type}:${e.address}:${e.port}->${t.address}:${t.port}`;this.#xt.find(e=>e.key===r)||this.#xt.push({key:r,local:e,remote:t,state:"frozen",nominated:!1})}}#Qt(){this.#Kt||this.#Ft||(this.#Kt=setInterval(()=>this.#Zt(),50),this.#Kt.unref&&this.#Kt.unref(),this.#qt=setTimeout(()=>{this.#P||this.emit("failed"),this.#Jt()},1e4),this.#qt.unref&&this.#qt.unref(),this.#Zt())}#Jt(){this.#Kt&&(clearInterval(this.#Kt),this.#Kt=null),this.#qt&&(clearTimeout(this.#qt),this.#qt=null)}#Zt(){if(!this.#Ft)for(const e of this.#xt)"succeeded"!==e.state&&this.#er(e)}#er(t){const r=e.randomBytes(12),s=`${this.remoteUfrag}:${this.localUfrag}`,i=new P(U.BINDING_REQUEST,r).addUsername(s).addPriority(t.local.priority);"controlling"===this.role?(i.addIceControlling(this.#Lt),i.addUseCandidate()):i.addIceControlled(this.#Lt);const n=i.build(this.remotePwd??void 0);this.#Gt.set(r.toString("hex"),t),t.state="in-progress",t.local.transport.send(n,t.remote.address,t.remote.port)}#Wt(e,t,r){0!==t.length&&(t[0]<=3?this.#tr(e,t,r):this.emit("data",t,{transport:e,address:r.address,port:r.port}))}#tr(e,t,r){const s=function(e){if(e.length<20)return null;if(e.readUInt32BE(4)!==D)return null;const t=e.readUInt16BE(0),r=e.readUInt16BE(2);if(20+r>e.length)return null;const s=e.slice(8,20),i=new Map;let n=20;const a=20+r;for(;n+4<=a;){const t=e.readUInt16BE(n),r=e.readUInt16BE(n+2);if(n+=4,n+r>a)break;i.set(t,e.slice(n,n+r)),n+=v(r)}return{type:t,transactionId:s,attrs:i,raw:e}}(t);s&&(s.type===U.BINDING_REQUEST?this.#rr(e,s,r):s.type===U.BINDING_SUCCESS&&this.#sr(e,s,r))}#rr(t,r,s){if(this.localPwd&&!function(t,r){let s=20;const i=20+t.readUInt16BE(2);let n=-1;for(;s+4<=i;){const e=t.readUInt16BE(s),r=t.readUInt16BE(s+2);if(e===k.MESSAGE_INTEGRITY){n=s;break}s+=4+v(r)}if(n<0)return!1;const a=t.slice(n+4,n+4+20),o=n+24-20,c=Buffer.from(t.slice(0,20));c.writeUInt16BE(o,2);const h=e.createHmac("sha1",Buffer.from(r,"utf8")).update(Buffer.concat([c,t.slice(20,n)])).digest();return a.length===h.length&&e.timingSafeEqual(a,h)}(r.raw,this.localPwd))return;const i=new P(U.BINDING_SUCCESS,r.transactionId).addXorMappedAddress(s.address,s.port).build(this.localPwd);t.send(i,s.address,s.port),this.#Ht.find(e=>e.address===s.address&&e.port===s.port)||this.addRemoteCandidate({address:s.address,port:s.port,type:"prflx",priority:0});const n=r.attrs.has(k.USE_CANDIDATE),a=this.#ir(t,s);n&&"controlled"===this.role&&this.#nr(a||this.#ar(t,s))}#sr(e,t,r){const s=this.#Gt.get(t.transactionId.toString("hex"));s&&(this.#Gt.delete(t.transactionId.toString("hex")),s.state="succeeded","controlling"===this.role&&this.#nr(s))}#ir(e,t){return this.#xt.find(r=>r.remote.address===t.address&&r.remote.port===t.port&&r.local.transport===e)}#ar(e,t){return{local:{transport:e},remote:{address:t.address,port:t.port}}}#nr(e){!this.#Mt&&e&&(this.#Mt=e,this.#P=!0,this.#Jt(),this.emit("selected",{transport:e.local.transport,candidateType:e.local.type,remoteAddress:e.remote.address,remotePort:e.remote.port}),this.emit("connected"))}send(e){if(!this.#Mt)throw new Error("ICE not connected");this.#Mt.local.transport.send(e,this.#Mt.remote.address,this.#Mt.remote.port)}getSelectedPair(){return this.#Mt}getSelectedCandidateType(){return this.#Mt?this.#Mt.local.type:null}close(){if(!this.#Ft){this.#Ft=!0,this.#Jt();for(const e of this.#Pt)try{e.close()}catch(e){}this.#Pt=[],this.emit("closed")}}}const me=Object.freeze({DATA:0,INIT:1,INIT_ACK:2,SACK:3,HEARTBEAT:4,HEARTBEAT_ACK:5,ABORT:6,SHUTDOWN:7,SHUTDOWN_ACK:8,ERROR:9,COOKIE_ECHO:10,COOKIE_ACK:11,SHUTDOWN_COMPLETE:14,FORWARD_TSN:192}),Ee=Object.freeze({HEARTBEAT_INFO:1,STATE_COOKIE:7,UNRECOGNIZED_PARAM:8,COOKIE_PRESERVATIVE:9,SUPPORTED_ADDR_TYPES:11,FORWARD_TSN_SUPPORTED:49152,SUPPORTED_EXTENSIONS:32776}),ge=Object.freeze({DCEP:50,STRING:51,BINARY:53,STRING_EMPTY:56,BINARY_EMPTY:57,STRING_PARTIAL:54,BINARY_PARTIAL:52});function Ie(e){return e+3&-4}function Te(e,t,r){const s=4+r.length,i=Buffer.alloc(Ie(s));return i.writeUInt8(e,0),i.writeUInt8(t,1),i.writeUInt16BE(s,2),r.copy(i,4),i}function Ce(e,t){const r=4+t.length,s=Buffer.alloc(Ie(r));return s.writeUInt16BE(e,0),s.writeUInt16BE(r,2),t.copy(s,4),s}function Se(e){const t=[];let r=0;for(;r+4<=e.length;){const s=e.readUInt16BE(r),i=e.readUInt16BE(r+2);if(i<4||r+i>e.length)break;t.push({type:s,length:i,value:e.slice(r+4,r+i)}),r+=Ie(i)}return t}function ye({initiateTag:e,a_rwnd:t,outStreams:r,inStreams:s,initialTSN:i}){const n=Buffer.alloc(16);return n.writeUInt32BE(e>>>0,0),n.writeUInt32BE(t>>>0,4),n.writeUInt16BE(r,8),n.writeUInt16BE(s,10),n.writeUInt32BE(i>>>0,12),n}function Be(e){return{initiateTag:e.readUInt32BE(0),a_rwnd:e.readUInt32BE(4),outStreams:e.readUInt16BE(8),inStreams:e.readUInt16BE(10),initialTSN:e.readUInt32BE(12),params:Se(e.slice(16))}}function Ae({tsn:e,streamId:t,streamSeq:r,ppid:s,userData:i,unordered:n=!1,beginning:a=!0,ending:o=!0}){const c=Buffer.alloc(12);c.writeUInt32BE(e>>>0,0),c.writeUInt16BE(t,4),c.writeUInt16BE(r,6),c.writeUInt32BE(s>>>0,8);let h=0;return o&&(h|=1),a&&(h|=2),n&&(h|=4),{flags:h,body:Buffer.concat([c,i])}}const Re=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?2197175160^r>>>1:r>>>1;e[t]=r>>>0}return e})();function we(e){let t=4294967295;for(let r=0;r<e.length;r++)t=Re[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}const Ne=1048576,be=Object.freeze({CLOSED:"closed",COOKIE_WAIT:"cookie-wait",COOKIE_ECHOED:"cookie-echoed",ESTABLISHED:"established"});function Oe(e,t){return(e-t&4294967295)>2147483648}function De(e,t){return e===t||Oe(e,t)}class Ue extends t{isClient;state;#or;#cr;#hr;#dr;#lr;#ur;#fr;#pr;#mr;#Er;#gr;#pe;constructor(t={}){super(),this.isClient=!!t.isClient,this.state=be.CLOSED,this.#or=5e3,this.#cr=5e3,this.#hr=e.randomBytes(4).readUInt32BE(0)>>>0||1,this.#dr=0,this.#lr=e.randomBytes(4).readUInt32BE(0)>>>0,this.#ur=new Map,this.#fr=new Map,this.#pr=null,this.#mr=new Map,this.#Er=new Map,this.#gr=null}start(){this.state===be.CLOSED&&this.isClient&&(this.#Ir(),this.state=be.COOKIE_WAIT)}#Tr(e,t){const r=function(e,t,r){const s=Buffer.alloc(12);return s.writeUInt16BE(e,0),s.writeUInt16BE(t,2),s.writeUInt32BE(r>>>0,4),s.writeUInt32BE(0,8),s}(this.#or,this.#cr,e),s=Buffer.concat([r,...t]);!function(e){e.writeUInt32LE(0,8);const t=we(e);e.writeUInt32LE(t,8)}(s),this.emit("output",s)}receivePacket(e){if(e.length<12)return;if(!function(e){const t=e.readUInt32LE(8);e.writeUInt32LE(0,8);const r=we(e);return e.writeUInt32LE(t,8),r===t}(e))return;const t=function(e){return{srcPort:e.readUInt16BE(0),dstPort:e.readUInt16BE(2),verificationTag:e.readUInt32BE(4),checksum:e.readUInt32LE(8)}}(e),r=function(e){const t=[];let r=12;for(;r+4<=e.length;){const s=e.readUInt8(r),i=e.readUInt8(r+1),n=e.readUInt16BE(r+2);if(n<4||r+n>e.length)break;const a=e.slice(r+4,r+n);t.push({type:s,flags:i,length:n,body:a}),r+=Ie(n)}return t}(e);for(const e of r)this.#Cr(e,t)}#Cr(e,t){switch(e.type){case me.INIT:this.#Sr(e);break;case me.INIT_ACK:this.#yr(e);break;case me.COOKIE_ECHO:this.#Br(e);break;case me.COOKIE_ACK:this.#Ar();break;case me.DATA:this.#Rr(e);break;case me.SACK:this.#wr(e);break;case me.HEARTBEAT:this.#Nr(e);break;case me.ABORT:this.#br("peer sent ABORT");break;case me.SHUTDOWN:this.#Or()}}#Dr(){return[Ce(Ee.FORWARD_TSN_SUPPORTED,Buffer.alloc(0))]}#Ir(){const e=ye({initiateTag:this.#hr,a_rwnd:Ne,outStreams:65535,inStreams:65535,initialTSN:this.#lr}),t=Te(me.INIT,0,Buffer.concat([e,...this.#Dr()]));this.#Tr(0,[t]),this.#Ur([t])}#Ur(e){this.#kr();let t=500,r=0;const s=()=>{this.state!==be.ESTABLISHED&&this.state!==be.CLOSED&&(r>=8?this.#br("SCTP setup timed out"):(r++,this.#Tr(this.state===be.COOKIE_ECHOED?this.#dr:0,e),t=Math.min(2*t,5e3),this.#gr=setTimeout(s,t),this.#gr.unref&&this.#gr.unref()))};this.#gr=setTimeout(s,t),this.#gr.unref&&this.#gr.unref()}#kr(){this.#gr&&(clearTimeout(this.#gr),this.#gr=null)}#Sr(t){const r=Be(t.body);this.#dr=r.initiateTag,this.#pr=r.initialTSN-1>>>0,this.#pe||(this.#pe=e.randomBytes(32));const s=Buffer.alloc(16);s.writeUInt32BE(this.#hr,0),s.writeUInt32BE(this.#dr,4),s.writeUInt32BE(this.#lr,8),s.writeUInt32BE(r.initialTSN,12);const i=e.createHmac("sha256",this.#pe).update(s).digest(),n=Buffer.concat([s,i]),a=ye({initiateTag:this.#hr,a_rwnd:Ne,outStreams:65535,inStreams:65535,initialTSN:this.#lr}),o=Buffer.concat([Ce(Ee.STATE_COOKIE,n),...this.#Dr()]),c=Te(me.INIT_ACK,0,Buffer.concat([a,o]));this.#Tr(this.#dr,[c])}#yr(e){if(this.state!==be.COOKIE_WAIT)return;this.#kr();const t=Be(e.body);this.#dr=t.initiateTag,this.#pr=t.initialTSN-1>>>0;const r=t.params.find(e=>e.type===Ee.STATE_COOKIE);if(!r)return void this.#br("INIT_ACK missing state cookie");const s=Te(me.COOKIE_ECHO,0,r.value);this.state=be.COOKIE_ECHOED,this.#Tr(this.#dr,[s]),this.#Ur([s])}#Br(t){const r=t.body;if(r.length>=48&&this.#pe){const t=r.slice(0,16),s=r.slice(16,48),i=e.createHmac("sha256",this.#pe).update(t).digest();if(!e.timingSafeEqual(s,i))return}const s=Te(me.COOKIE_ACK,0,Buffer.alloc(0));this.#Tr(this.#dr,[s]),this.#vr()}#Ar(){this.state===be.COOKIE_ECHOED&&(this.#kr(),this.#vr())}#vr(){this.state!==be.ESTABLISHED&&(this.state=be.ESTABLISHED,this.emit("established"))}sendData(e,t,r,s={}){if(this.state!==be.ESTABLISHED)throw new Error("SCTP association not established");const i=!!s.unordered;let n=0;i||(n=this.#ur.get(e)||0,this.#ur.set(e,n+1&65535));const a=r.length;let o=0;const c=[];do{const s=r.slice(o,o+1200),h=0===o,d=o+s.length>=a,l=this.#lr;this.#lr=this.#lr+1>>>0;const{flags:u,body:f}=Ae({tsn:l,streamId:e,streamSeq:n,ppid:t,userData:s,unordered:i,beginning:h,ending:d}),p=Te(me.DATA,u,f);this.#fr.set(l,{chunk:p}),c.push(p),o+=s.length}while(o<a);for(const e of c)this.#Tr(this.#dr,[e])}#Rr(e){const t={unordered:!!(4&(r=e.flags)),beginning:!!(2&r),ending:!!(1&r),tsn:(s=e.body).readUInt32BE(0),streamId:s.readUInt16BE(4),streamSeq:s.readUInt16BE(6),ppid:s.readUInt32BE(8),userData:s.slice(12)};var r,s;this.#Lr(t),this.#Pr()}#Lr(e){const t=this.#pr+1>>>0;if(!Oe(e.tsn,t))if(e.tsn===t){this.#pr=e.tsn,this.#_r(e);let t=this.#pr+1>>>0;for(;this.#mr.has(t);){const e=this.#mr.get(t);this.#mr.delete(t),this.#pr=t,this.#_r(e),t=this.#pr+1>>>0}}else this.#mr.has(e.tsn)||this.#mr.set(e.tsn,e)}#_r(e){const t=`${e.streamId}:${e.unordered?"u":"o"}`;if(e.beginning&&e.ending)return void this.emit("message",{streamId:e.streamId,ppid:e.ppid,data:e.userData});let r=this.#Er.get(t);if(e.beginning)r={ppid:e.ppid,parts:[e.userData]},this.#Er.set(t,r);else{if(!r)return;r.parts.push(e.userData)}e.ending&&r&&(this.#Er.delete(t),this.emit("message",{streamId:e.streamId,ppid:r.ppid,data:Buffer.concat(r.parts)}))}#Pr(){const e=[];if(this.#mr.size>0){const t=[...this.#mr.keys()].sort((e,t)=>Oe(e,t)?-1:1),r=this.#pr+1>>>0;let s=null,i=null;for(const n of t)null!==s?n!==i+1>>>0?(e.push([1+(s-r&65535),1+(i-r&65535)]),s=n,i=n):i=n:(s=n,i=n);null!==s&&e.push([1+(s-r&65535),1+(i-r&65535)])}const t=function({cumulativeTSNAck:e,a_rwnd:t,gapBlocks:r=[],dupTSNs:s=[]}){const i=Buffer.alloc(12+4*r.length+4*s.length);i.writeUInt32BE(e>>>0,0),i.writeUInt32BE(t>>>0,4),i.writeUInt16BE(r.length,8),i.writeUInt16BE(s.length,10);let n=12;for(const[e,t]of r)i.writeUInt16BE(e,n),i.writeUInt16BE(t,n+2),n+=4;for(const e of s)i.writeUInt32BE(e>>>0,n),n+=4;return i}({cumulativeTSNAck:this.#pr>>>0,a_rwnd:Ne,gapBlocks:e}),r=Te(me.SACK,0,t);this.#Tr(this.#dr,[r])}#wr(e){const t=function(e){const t=e.readUInt32BE(0),r=e.readUInt32BE(4),s=e.readUInt16BE(8),i=e.readUInt16BE(10),n=[];let a=12;for(let t=0;t<s;t++)n.push([e.readUInt16BE(a),e.readUInt16BE(a+2)]),a+=4;const o=[];for(let t=0;t<i;t++)o.push(e.readUInt32BE(a)),a+=4;return{cumulativeTSNAck:t,a_rwnd:r,gapBlocks:n,dupTSNs:o}}(e.body);for(const e of[...this.#fr.keys()])De(e,t.cumulativeTSNAck)&&this.#fr.delete(e);const r=t.cumulativeTSNAck+1>>>0;for(const[e,s]of t.gapBlocks)for(let t=e;t<=s;t++)this.#fr.delete(r+t-1>>>0)}#Nr(e){const t=Te(me.HEARTBEAT_ACK,0,e.body);this.#Tr(this.#dr,[t])}#Or(){const e=Te(me.SHUTDOWN_ACK,0,Buffer.alloc(0));this.#Tr(this.#dr,[e]),this.#Hr()}#br(e){this.#kr(),this.state!==be.CLOSED&&(this.state=be.CLOSED,this.emit("error",new Error(e||"SCTP abort")),this.emit("close"))}shutdown(){if(this.state!==be.ESTABLISHED)return void this.#Hr();const e=Te(me.SHUTDOWN,0,(()=>{const e=Buffer.alloc(4);return e.writeUInt32BE(this.#pr>>>0,0),e})());this.#Tr(this.#dr,[e]),this.#Hr()}#Hr(){this.#kr(),this.state!==be.CLOSED&&(this.state=be.CLOSED,this.emit("close"))}}const ke=Object.freeze({DATA_CHANNEL_ACK:2,DATA_CHANNEL_OPEN:3}),ve=Object.freeze({RELIABLE:0,RELIABLE_UNORDERED:128,PARTIAL_RELIABLE_REXMIT:1,PARTIAL_RELIABLE_REXMIT_UNORDERED:129,PARTIAL_RELIABLE_TIMED:2,PARTIAL_RELIABLE_TIMED_UNORDERED:130});class Le extends t{#xr;#Mr;#Fr;constructor(e,t){super(),this.#xr=e,this.#Mr=new Map,this.#Fr=t?0:1,this.#xr.on("message",e=>this.#Kr(e))}openChannel(e,t={}){let r=e.id;if(null==r&&(r=this.#qr(),e.emit(A.SET_ID,r)),this.#Mr.set(r,{channel:e,acked:!1}),this.#Gr(e,r,t),e.negotiated)this.#Mr.get(r).acked=!0,e.emit(A.OPEN);else{const s=function({channelType:e,priority:t=0,reliabilityParameter:r=0,label:s="",protocol:i=""}){const n=Buffer.from(s,"utf8"),a=Buffer.from(i,"utf8"),o=Buffer.alloc(12+n.length+a.length);return o.writeUInt8(ke.DATA_CHANNEL_OPEN,0),o.writeUInt8(e,1),o.writeUInt16BE(t,2),o.writeUInt32BE(r>>>0,4),o.writeUInt16BE(n.length,8),o.writeUInt16BE(a.length,10),n.copy(o,12),a.copy(o,12+n.length),o}({channelType:this.#$r(t),priority:0,reliabilityParameter:this.#zr(t),label:e.label,protocol:t.protocol||e.protocol||""});this.#xr.sendData(r,ge.DCEP,s)}}#qr(){let e=this.#Fr;for(;this.#Mr.has(e);)e+=2;return this.#Fr=e+2,e}#$r(e){const t=!1===e.ordered;return null!=e.maxRetransmits?t?ve.PARTIAL_RELIABLE_REXMIT_UNORDERED:ve.PARTIAL_RELIABLE_REXMIT:null!=e.maxPacketLifeTime?t?ve.PARTIAL_RELIABLE_TIMED_UNORDERED:ve.PARTIAL_RELIABLE_TIMED:t?ve.RELIABLE_UNORDERED:ve.RELIABLE}#zr(e){return null!=e.maxRetransmits?e.maxRetransmits>>>0:null!=e.maxPacketLifeTime?e.maxPacketLifeTime>>>0:0}#Gr(e,t,r){const s=!1===r.ordered;e.on(A.SEND,(e,r)=>{let i;i=r?0===e.length?ge.BINARY_EMPTY:ge.BINARY:0===e.length?ge.STRING_EMPTY:ge.STRING;const n=0===e.length?Buffer.from([0]):e;this.#xr.sendData(t,i,n,{unordered:s})})}#Kr(e){if(e.ppid===ge.DCEP)return void this.#jr(e);const t=this.#Mr.get(e.streamId);if(!t)return;const r=e.ppid===ge.BINARY||e.ppid===ge.BINARY_EMPTY||e.ppid===ge.BINARY_PARTIAL,s=e.ppid===ge.STRING_EMPTY||e.ppid===ge.BINARY_EMPTY?Buffer.alloc(0):e.data;t.channel.emit(A.RECEIVE,s,r)}#jr(e){const t=(r=e.data).length>0?r.readUInt8(0):-1;var r;if(t===ke.DATA_CHANNEL_OPEN){const t=function(e){const t=e.readUInt8(1),r=e.readUInt16BE(2),s=e.readUInt32BE(4),i=e.readUInt16BE(8),n=e.readUInt16BE(10);return{channelType:t,priority:r,reliabilityParameter:s,label:e.slice(12,12+i).toString("utf8"),protocol:e.slice(12+i,12+i+n).toString("utf8"),unordered:!!(128&t)}}(e.data);this.#xr.sendData(e.streamId,ge.DCEP,Buffer.from([ke.DATA_CHANNEL_ACK])),this.emit("open-request",{streamId:e.streamId,label:t.label,protocol:t.protocol,ordered:!t.unordered,channelType:t.channelType,reliabilityParameter:t.reliabilityParameter})}else if(t===ke.DATA_CHANNEL_ACK){const t=this.#Mr.get(e.streamId);t&&!t.acked&&(t.acked=!0,t.channel.emit(A.OPEN))}}acceptChannel(e,t){e.emit(A.SET_ID,t.streamId),this.#Mr.set(t.streamId,{channel:e,acked:!0}),this.#Gr(e,t.streamId,{ordered:t.ordered}),e.emit(A.OPEN)}}class Pe extends t{#Vr;ice;dtls;sctp;dcm;#Wr;constructor(e){super(),this.#Vr=e,this.ice=new pe({role:e.iceRole,localUfrag:e.localUfrag,localPwd:e.localPwd}),this.dtls=null,this.sctp=null,this.dcm=null,this.#Wr=!1,this.ice.on("candidate",e=>this.emit("candidate",e)),this.ice.on("error",e=>this.emit("error",e)),this.ice.on("failed",()=>this.emit("error",new Error("ICE failed"))),this.ice.on("data",e=>{this.dtls&&this.dtls.handlePacket(e)}),this.ice.on("connected",()=>{this.emit("iceconnected"),this.#Yr()})}async gather(e={}){await this.ice.gather(e)}getLocalCandidates(){return this.ice.getLocalCandidates()}setRemote(e,t){this.ice.setRemoteCredentials(e,t),this.ice.start()}addRemoteCandidate(e){this.ice.addRemoteCandidate(e)}#Yr(){this.#Wr||(this.#Wr=!0,this.dtls=new oe({role:"client"===this.#Vr.dtlsRole?ne.CLIENT:ne.SERVER,certDer:this.#Vr.certDer,privateKey:this.#Vr.privateKey,verifyFingerprint:this.#Vr.verifyFingerprint,output:e=>{try{this.ice.send(e)}catch(e){this.emit("error",e)}}}),this.dtls.on("connect",()=>{this.emit("dtlsconnected"),this.#Xr()}),this.dtls.on("data",e=>{this.sctp&&this.sctp.receivePacket(e)}),this.dtls.on("error",e=>this.emit("error",e)),this.dtls.on("close",()=>this.emit("close")),this.dtls.start())}#Xr(){const e="client"===this.#Vr.dtlsRole,t=new Ue({isClient:e});this.sctp=t,t.on("output",e=>{try{this.dtls&&this.dtls.send(e)}catch(e){this.emit("error",e)}}),t.on("error",e=>this.emit("error",e)),t.on("close",()=>this.emit("close")),this.dcm=new Le(t,e),this.dcm.on("open-request",e=>this.emit("datachannel-request",e)),t.on("established",()=>{this.emit("sctpconnected"),this.emit("ready")}),t.start()}openChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.openChannel(e,t)}acceptChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.acceptChannel(e,t)}isReady(){return!!this.sctp&&"established"===this.sctp.state}close(){if(this.sctp)try{this.sctp.shutdown()}catch{}if(this.dtls)try{this.dtls.close()}catch{}if(this.ice)try{this.ice.close()}catch{}}}const _e=Object.freeze({STABLE:"stable",HAVE_LOCAL_OFFER:"have-local-offer",HAVE_REMOTE_OFFER:"have-remote-offer",HAVE_LOCAL_PRANSWER:"have-local-pranswer",HAVE_REMOTE_PRANSWER:"have-remote-pranswer",CLOSED:"closed"}),He=Object.freeze({NEW:"new",GATHERING:"gathering",COMPLETE:"complete"}),xe=Object.freeze({NEW:"new",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"});class Me extends t{#Qr;#Zr;#Jr;#es;#ts;#rs;#ss;#is;#ns;#as;#os;#cs;#hs;#ds;#ls;#Mr;#_t;constructor(t={}){super(),this.#Qr=t,this.#Zr=_e.STABLE,this.#Jr=He.NEW,this.#es=xe.NEW,this.#ts=null,this.#rs=null,this.#ss=null,this.#is={usernameFragment:e.randomBytes(3).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,4).padEnd(4,"x"),password:e.randomBytes(18).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,24).padEnd(24,"x")},this.#ns=null,this.#as=[],this.#os=null,this.#cs=null,this.#hs=!1,this.#ds=!1,this.#ls=[],this.#Mr=new Set,this.#_t=[]}async#us(){return this.#ss||(this.#Qr.certificates&&this.#Qr.certificates[0]?this.#ss=this.#Qr.certificates[0]:this.#ss=await y.generateCertificate()),this.#ss}#fs(e,t){if(this.#cs)return this.#cs;const r=this.#ss;if(!r)throw new Error("Certificate not initialized");const s=r.getCertificateDer();if(!s)throw new Error("Certificate has no DER encoding");const i=new Pe({iceRole:e,dtlsRole:t,localUfrag:this.#is.usernameFragment,localPwd:this.#is.password,certDer:s,privateKey:r.getPrivateKeyObject(),verifyFingerprint:e=>this.#ps(e)});return i.on("candidate",e=>{const t={candidate:e.sdp,sdpMid:"0",sdpMLineIndex:0,usernameFragment:this.#is.usernameFragment};this.#_t.push(t),this.emit("icecandidate",{candidate:t})}),i.on("iceconnected",()=>this.#ms(xe.CONNECTING)),i.on("sctpconnected",()=>this.#ms(xe.CONNECTED)),i.on("error",e=>{this.emit("error",e),this.#ms(xe.FAILED)}),i.on("close",()=>this.#ms(xe.DISCONNECTED)),i.on("datachannel-request",e=>{const t=new R(e.label,{ordered:e.ordered,protocol:e.protocol,id:e.streamId});i.acceptChannel(t,e),this.#Mr.add(t),this.emit("datachannel",{channel:t})}),i.on("ready",()=>{for(const{channel:e,init:t}of this.#ls)i.openChannel(e,t);this.#ls=[]}),this.#cs=i,i}#ps(e){return 0===this.#as.length||this.#as.some(t=>t.algorithm===e.algorithm&&t.value.toUpperCase()===e.value.toUpperCase())}createDataChannel(e,t={}){if(this.#ds)throw new Error("RTCPeerConnection is closed");const r=new R(e,t);this.#Mr.add(r);const s={ordered:!1!==t.ordered,maxRetransmits:t.maxRetransmits,maxPacketLifeTime:t.maxPacketLifeTime,protocol:t.protocol||"",negotiated:t.negotiated||!1};return this.#cs&&this.#cs.isReady()?this.#cs.openChannel(r,s):this.#ls.push({channel:r,init:s}),setImmediate(()=>{this.#ds||this.emit("negotiationneeded")}),r}async createOffer(){if(this.#ds)throw new Error("RTCPeerConnection is closed");await this.#us(),this.#hs=!0;const e=this.#Es(),t=(r={iceUfrag:this.#is.usernameFragment,icePwd:this.#is.password,fingerprint:e,setup:"actpass",candidates:[]},b({...r,setup:r.setup||"actpass"}));var r;return new N({type:w.OFFER,sdp:t})}async createAnswer(){if(this.#ds)throw new Error("RTCPeerConnection is closed");if(!this.#rs||"offer"!==this.#rs.type)throw new Error("Cannot create answer without remote offer");await this.#us();const e=this.#Es(),t=(r={iceUfrag:this.#is.usernameFragment,icePwd:this.#is.password,fingerprint:e,setup:"active",candidates:[]},b({...r,setup:r.setup||"active"}));var r;return new N({type:w.ANSWER,sdp:t})}#Es(){const e=this.#ss;if(!e)throw new Error("Certificate not initialized");const t=e.getFingerprints();return t.find(e=>"sha-256"===e.algorithm)||t[0]}async setLocalDescription(e){if(this.#ds)throw new Error("RTCPeerConnection is closed");const t=e||(this.#Zr===_e.HAVE_REMOTE_OFFER?await this.createAnswer():await this.createOffer());await this.#us(),this.#ts=new N({type:t.type??void 0,sdp:t.sdp??void 0}),"offer"===t.type?this.#Zr=_e.HAVE_LOCAL_OFFER:"answer"===t.type&&(this.#Zr=_e.STABLE),this.#gs(t,!0),this.#Jr=He.GATHERING,this.emit("icegatheringstatechange"),this.#cs&&(await this.#cs.gather({iceServers:this.#Qr.iceServers||[],iceTransportPolicy:this.#Qr.iceTransportPolicy||"all"}),this.#Jr=He.COMPLETE,this.emit("icegatheringstatechange"),this.emit("icecandidate",{candidate:null}),this.#Is()),this.emit("signalingstatechange")}async setRemoteDescription(e){if(this.#ds)throw new Error("RTCPeerConnection is closed");if(!e||!e.sdp)throw new Error("Invalid session description");await this.#us(),this.#rs=new N(e),"offer"===e.type?this.#Zr=_e.HAVE_REMOTE_OFFER:"answer"===e.type&&(this.#Zr=_e.STABLE),this.#ns=function(e){const t={usernameFragment:null,password:null};for(const r of e.split(/\r?\n/))r.startsWith("a=ice-ufrag:")?t.usernameFragment=r.slice(12).trim():r.startsWith("a=ice-pwd:")&&(t.password=r.slice(10).trim());return t}(e.sdp);const t=function(e){const t={role:"auto",fingerprints:[]};for(const r of e.split(/\r?\n/))if(r.startsWith("a=setup:")){const e=r.slice(8).trim();t.role="active"===e?"client":"passive"===e?"server":"actpass",t.setup=e}else if(r.startsWith("a=fingerprint:")){const e=r.slice(14).trim().split(/\s+/);2===e.length&&t.fingerprints.push({algorithm:e[0].toLowerCase(),value:e[1].toUpperCase()})}return t}(e.sdp);if(this.#as=t.fingerprints,this.#os=t.setup??null,this.#gs(e,!1),this.#cs&&this.#ns.usernameFragment){this.#cs.setRemote(this.#ns.usernameFragment,this.#ns.password??"");for(const t of function(e){const t=[];for(const r of e.split(/\r?\n/)){if(!r.startsWith("a=candidate:"))continue;const e=O(r.slice(2));e&&t.push(e)}return t}(e.sdp))this.#cs.addRemoteCandidate(t)}this.#Is(),this.emit("signalingstatechange")}#gs(e,t){if(this.#cs)return;const r=this.#hs?"controlling":"controlled";let s;s=this.#hs?"active"===this.#os?"server":"passive"===this.#os?"client":"server":"client",this.#fs(r,s)}#Is(){this.#cs&&this.#ns&&this.#ns.usernameFragment&&this.#cs.setRemote(this.#ns.usernameFragment,this.#ns.password??"")}async addIceCandidate(e){if(this.#ds)throw new Error("RTCPeerConnection is closed");if(!e||"string"!=typeof e&&""===e.candidate)return;const t=O("string"==typeof e?e:e.candidate||"");t&&this.#cs&&this.#cs.addRemoteCandidate(t)}#ms(e){this.#es!==e&&(this.#es=e,this.emit("connectionstatechange"),this.emit("iceconnectionstatechange"))}getConfiguration(){return{...this.#Qr}}setConfiguration(e){if(this.#ds)throw new Error("RTCPeerConnection is closed");this.#Qr={...e}}close(){if(!this.#ds){this.#ds=!0,this.#Zr=_e.CLOSED;for(const e of this.#Mr)try{e.close()}catch(e){}if(this.#cs)try{this.#cs.close()}catch(e){}this.#ms(xe.CLOSED),this.emit("signalingstatechange")}}get signalingState(){return this.#Zr}get iceGatheringState(){return this.#Jr}get iceConnectionState(){return this.#es===xe.CONNECTED?"connected":this.#es===xe.CONNECTING?"checking":this.#es===xe.FAILED?"failed":"new"}get connectionState(){return this.#es}get localDescription(){return this.#ts}get remoteDescription(){return this.#rs}get currentLocalDescription(){return this.#ts}get currentRemoteDescription(){return this.#rs}get pendingLocalDescription(){return this.#Zr===_e.STABLE?null:this.#ts}get pendingRemoteDescription(){return this.#Zr===_e.STABLE?null:this.#rs}get canTrickleIceCandidates(){return!0}get sctp(){return this.#cs?this.#cs.sctp:null}}const Fe="2.0.8";export{n as ByteBufferQueue,y as RTCCertificate,R as RTCDataChannel,B as RTCDataChannelState,o as RTCError,c as RTCIceCandidate,He as RTCIceGatheringState,Me as RTCPeerConnection,xe as RTCPeerConnectionState,w as RTCSdpType,N as RTCSessionDescription,_e as RTCSignalingState,Fe as version};
1
+ import*as e from"crypto";import{EventEmitter as t}from"events";import*as r from"dgram";import*as s from"os";import*as i from"tls";class n{#e;#t;#r;constructor(){this.#e=0,this.#t=[],this.#r=0}get size(){return this.#e}get empty(){return 0===this.#e}readInto(e){if(!Buffer.isBuffer(e))throw new TypeError("bufferOut must be a Buffer");let t=0,r=0;for(;r<e.length&&this.#t.length>0;){const s=this.#t[0],i=s.length-this.#r,n=e.length-r,a=Math.min(i,n);s.copy(e,r,this.#r,this.#r+a),t+=a,r+=a,a<i?this.#r+=a:(this.#t.shift(),this.#r=0)}return this.#e-=t,this.#s(),t}append(e){if(!Buffer.isBuffer(e))throw new TypeError("buffer must be a Buffer");0!==e.length&&(this.#e+=e.length,this.#t.push(e),this.#s())}clear(){this.#t=[],this.#r=0,this.#e=0,this.#s()}read(e){if(e>this.#e)throw new RangeError(`Cannot read ${e} bytes, only ${this.#e} available`);if(0===e)return Buffer.allocUnsafe(0);const t=Buffer.allocUnsafe(e),r=this.readInto(t);if(r!==e)throw new Error(`Internal error: read ${r} bytes, expected ${e}`);return t}peek(e=this.#e){const t=Math.min(e,this.#e);if(0===t)return Buffer.allocUnsafe(0);const r=Buffer.allocUnsafe(t);let s=0,i=0,n=this.#r;for(;s<t&&i<this.#t.length;){const e=this.#t[i],a=e.length-n,o=Math.min(a,t-s);e.copy(r,s,n,n+o),s+=o,i++,n=0}return r}#s(){if("production"!==process.env.NODE_ENV){let e=0;for(const t of this.#t){if(0===t.length)throw new Error("Invariant violation: empty buffer in queue");e+=t.length}const t=e-this.#r;if(this.#e!==t)throw new Error(`Invariant violation: size=${this.#e}, expected=${t}`);if(0===this.#t.length){if(0!==this.#r)throw new Error("Invariant violation: offset non-zero with empty queue")}else if(this.#r>=this.#t[0].length)throw new Error("Invariant violation: offset >= front buffer size")}}}const a=Object.freeze({NONE:"none",DATA_CHANNEL_FAILURE:"data-channel-failure",DTLS_FAILURE:"dtls-failure",FINGERPRINT_FAILURE:"fingerprint-failure",SCTP_FAILURE:"sctp-failure",SDP_SYNTAX_ERROR:"sdp-syntax-error",HARDWARE_ENCODER_NOT_AVAILABLE:"hardware-encoder-not-available",HARDWARE_ENCODER_ERROR:"hardware-encoder-error",INVALID_STATE:"invalid-state",INVALID_MODIFICATION:"invalid-modification",INVALID_ACCESS_ERROR:"invalid-access-error",OPERATION_ERROR:"operation-error"});class o extends Error{static DetailType=a;#i;#n;#a;#o;#c;#h;constructor(e={},t=""){super(t),this.name="RTCError",Error.captureStackTrace&&Error.captureStackTrace(this,o);const r=e.errorDetail||a.NONE;if("string"!=typeof r)throw new TypeError("errorDetail must be a string");this.#i=r,this.#n=this.#d(e.sdpLineNumber,"sdpLineNumber"),this.#a=this.#d(e.httpRequestStatusCode,"httpRequestStatusCode"),this.#o=this.#d(e.sctpCauseCode,"sctpCauseCode"),this.#c=this.#l(e.receivedAlert,"receivedAlert"),this.#h=this.#l(e.sentAlert,"sentAlert")}#d(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r))throw new TypeError(`${t} must be an integer`);return r}#l(e,t){if(null==e)return null;const r=Number(e);if(!Number.isInteger(r)||r<0)throw new TypeError(`${t} must be an unsigned integer`);return r}get errorDetail(){return this.#i}get sdpLineNumber(){return this.#n}get httpRequestStatusCode(){return this.#a}get sctpCauseCode(){return this.#o}get receivedAlert(){return this.#c}get sentAlert(){return this.#h}toJSON(){const e={name:this.name,message:this.message,errorDetail:this.#i};return null!==this.#n&&(e.sdpLineNumber=this.#n),null!==this.#a&&(e.httpRequestStatusCode=this.#a),null!==this.#o&&(e.sctpCauseCode=this.#o),null!==this.#c&&(e.receivedAlert=this.#c),null!==this.#h&&(e.sentAlert=this.#h),e}static fromNative(e){const t={errorDetail:e.error_detail||a.NONE};return void 0!==e.sctp_cause_code&&(t.sctpCauseCode=e.sctp_cause_code),new o(t,e.message||"Unknown error")}}class c{#u;#f;#p;#m;#E;constructor(e={}){if(null===e.sdpMid&&null===e.sdpMLineIndex)throw new TypeError("sdpMid and sdpMLineIndex are both null");this.#u=e.candidate||"",this.#f=void 0!==e.sdpMid?e.sdpMid:null,this.#p=void 0!==e.sdpMLineIndex?e.sdpMLineIndex:null,this.#m=e.usernameFragment||null,this.#E=this.#g(this.#u)}#g(e){const t={foundation:null,component:null,protocol:null,priority:null,address:null,port:null,type:null,tcpType:null,relatedAddress:null,relatedPort:null};if(!e||!e.startsWith("candidate:"))return t;const r=e.substring(10).trim().split(/\s+/);if(r.length<8)return t;t.foundation=r[0],t.component=r[1],t.protocol=r[2].toLowerCase(),t.priority=parseInt(r[3],10),t.address=r[4],t.port=parseInt(r[5],10),"typ"===r[6]&&(t.type=r[7]);for(let e=8;e<r.length;e+=2){const s=r[e],i=r[e+1];"raddr"===s?t.relatedAddress=i:"rport"===s?t.relatedPort=parseInt(i,10):"tcptype"===s&&(t.tcpType=i)}return t}get candidate(){return this.#u}get sdpMid(){return this.#f}get sdpMLineIndex(){return this.#p}get usernameFragment(){return this.#m}get foundation(){return this.#E.foundation}get component(){return this.#E.component}get priority(){return this.#E.priority}get address(){return this.#E.address}get protocol(){return this.#E.protocol}get port(){return this.#E.port}get type(){return this.#E.type}get tcpType(){return this.#E.tcpType}get relatedAddress(){return this.#E.relatedAddress}get relatedPort(){return this.#E.relatedPort}toJSON(){const e={candidate:this.#u,sdpMid:this.#f,sdpMLineIndex:this.#p};return this.#m&&(e.usernameFragment=this.#m),e}static fromString(e,t=null,r=0){return new c({candidate:e,sdpMid:t,sdpMLineIndex:r})}static isValid(e){return!(!e||"string"!=typeof e)&&(!!e.startsWith("candidate:")&&e.substring(10).trim().split(/\s+/).length>=8)}}const h=Object.freeze({BOOLEAN:1,INTEGER:2,BIT_STRING:3,OCTET_STRING:4,NULL:5,OID:6,UTF8_STRING:12,PRINTABLE_STRING:19,IA5_STRING:22,UTC_TIME:23,GENERALIZED_TIME:24,SEQUENCE:48,SET:49});function d(e){if(e<128)return Buffer.from([e]);const t=[];let r=e;for(;r>0;)t.unshift(255&r),r>>>=8;return Buffer.from([128|t.length,...t])}function l(e,t){return Buffer.concat([Buffer.from([e]),d(t.length),t])}function u(e){let t=0;for(;t<e.length-1&&0===e[t];)t++;let r=e.slice(t);return 128&r[0]&&(r=Buffer.concat([Buffer.from([0]),r])),l(h.INTEGER,r)}function f(e){const t=[];let r=e;for(;r>0;)t.unshift(255&r),r=Math.floor(r/256);return 128&t[0]&&t.unshift(0),l(h.INTEGER,Buffer.from(t))}function p(e){const t=e.split(".").map(Number);if(t.length<2)throw new Error(`Invalid OID: ${e}`);const r=[40*t[0]+t[1]];for(let e=2;e<t.length;e++){let s=t[e];const i=[127&s];for(s=Math.floor(s/128);s>0;)i.unshift(127&s|128),s=Math.floor(s/128);r.push(...i)}return l(h.OID,Buffer.from(r))}function m(e){return l(h.SEQUENCE,Buffer.concat(e))}function E(e){const t=e.getUTCFullYear(),r=(e,t=2)=>String(e).padStart(t,"0"),s=r(e.getUTCMonth()+1),i=r(e.getUTCDate()),n=r(e.getUTCHours()),a=r(e.getUTCMinutes()),o=r(e.getUTCSeconds());if(t<2050){const e=r(t%100);return l(h.UTC_TIME,Buffer.from(`${e}${s}${i}${n}${a}${o}Z`,"ascii"))}return l(h.GENERALIZED_TIME,Buffer.from(`${t}${s}${i}${n}${a}${o}Z`,"ascii"))}const g=Object.freeze({ecPublicKey:"1.2.840.10045.2.1",prime256v1:"1.2.840.10045.3.1.7",ecdsaWithSHA256:"1.2.840.10045.4.3.2",commonName:"2.5.4.3"});function I(){return m([p(g.ecdsaWithSHA256)])}function T(t={}){const r=t.commonName||`WebRTC-${e.randomBytes(8).toString("hex")}`,s=t.days||30,{publicKey:i,privateKey:n}=e.generateKeyPairSync("ec",{namedCurve:"prime256v1"}),a=i.export({type:"spki",format:"der"}),o=t.notBefore||new Date(Date.now()-864e5),c=new Date(o.getTime()+24*s*60*60*1e3),d=e.randomBytes(20);d[0]&=127,0===d[0]&&(d[0]=1);const T=function(e){const t=m([p(g.commonName),(r=e,l(h.UTF8_STRING,Buffer.from(r,"utf8")))]);var r,s;return m([(s=[t],l(h.SET,Buffer.concat(s)))])}(r),C=m([(S=f(2),l(160,S)),u(d),I(),T,m([E(o),E(c)]),T,a]);var S;const y=e.sign("sha256",C,n);var B;return{certDer:m([C,I(),(B=y,l(h.BIT_STRING,Buffer.concat([Buffer.from([0]),B])))]),privateKey:n,publicKey:i,notBefore:o,notAfter:c}}function C(t,r="sha-256"){const s=r.replace("-","").toLowerCase();return e.createHash(s).update(t).digest("hex").toUpperCase().match(/.{2}/g).join(":")}function S(e,t="sha-256"){return C(e,t)}class y{#I;#T;#C;#S;#y;constructor(e){this.#I=e.certDer||null,this.#T=e.privateKey,this.#C=e.publicKey,this.#S=e.expires,this.#y=null}getCertificateDer(){return this.#I}get expires(){return this.#S}getFingerprints(){if(!this.#I)throw new Error("Certificate has no DER encoding; cannot compute fingerprint");if(!this.#y){const e=this.#I,t=["sha-256","sha-384","sha-512"];this.#y=t.map(t=>({algorithm:t,value:S(e,t)}))}return this.#y.map(e=>({...e}))}getPrivateKeyObject(){return this.#B(this.#T,"private")}#B(t,r){return t&&"object"==typeof t&&t.type?t:"private"===r?e.createPrivateKey(t):e.createPublicKey(t)}getPrivateKey(){return this.#B(this.#T,"private").export({type:"pkcs8",format:"pem"})}getPublicKey(){return this.#B(this.#C,"public").export({type:"spki",format:"pem"})}toPEM(){const e=this.#I?`-----BEGIN CERTIFICATE-----\n${this.#I.toString("base64").match(/.{1,64}/g).join("\n")}\n-----END CERTIFICATE-----\n`:this.getPublicKey();return{pemPrivateKey:this.getPrivateKey(),pemCertificate:e}}isExpired(){return Date.now()>this.#S}static async generateCertificate(e={}){return new Promise((t,r)=>{try{let s;if(e.expires)s=e.expires;else{const t=e.days||30;s=Date.now()+24*t*60*60*1e3}setImmediate(()=>{try{const r=function(e={}){const{name:t,days:r=30}=e,{certDer:s,privateKey:i,publicKey:n,notAfter:a}=T({commonName:t,days:r});return{certDer:s,privateKey:i,publicKey:n,expires:a.getTime(),hash:"sha256"}}({name:e.name||"webrtc",days:Math.ceil((s-Date.now())/864e5),hash:e.hash||"sha256"});r.expires=s;const i=new y(r);t(i)}catch(e){r(e)}})}catch(e){r(e)}})}static fromPEM(t,r,s){if("string"!=typeof t||0===t.length)throw new TypeError("pemPrivateKey must be a non-empty string");if("string"!=typeof r||0===r.length)throw new TypeError("pemCertificate must be a non-empty string");const i=s||Date.now()+2592e6;let n=null,a=r;const o=r.match(/-----BEGIN CERTIFICATE-----([\s\S]+?)-----END CERTIFICATE-----/);return o&&(n=Buffer.from(o[1].replace(/\s/g,""),"base64"),a=e.createPublicKey(e.createPrivateKey(t))),new y({certDer:n,privateKey:t,publicKey:a,expires:i,hash:"sha256"})}static isSupportedKeyParams(e){if(!e||"object"!=typeof e)return!1;if("RSA"===e.type){const t=e.rsaModulusLength||2048;return t>=1024&&t<=4096}if("ECDSA"===e.type){const t=e.namedCurve;return["P-256","P-384","P-521"].includes(t)}return!1}}const B=Object.freeze({CONNECTING:"connecting",OPEN:"open",CLOSING:"closing",CLOSED:"closed"}),A=Object.freeze({SEND:Symbol("rtcdatachannel:send"),RECEIVE:Symbol("rtcdatachannel:receive"),OPEN:Symbol("rtcdatachannel:open"),SET_ID:Symbol("rtcdatachannel:setId")});class R extends t{#A;#R;#w;#N;#b;#O;#U;#D;#k;#v;#L;#P;constructor(e,t={}){if(super(),"string"!=typeof e)throw new TypeError("label must be a string");this.#A=e,this.#R=void 0===t.ordered||t.ordered,this.#w=t.maxPacketLifeTime||null,this.#N=t.maxRetransmits||null,this.#b=t.protocol||"",this.#O=t.negotiated||!1,this.#U=void 0!==t.id?t.id:null,this.#D=B.CONNECTING,this.#k=0,this.#v=0,this.#L="arraybuffer",this.#P=!1,this.on(A.SET_ID,e=>{this.#U=e}),this.on(A.OPEN,()=>{this.#P=!0,this.#_(B.OPEN)}),this.on(A.RECEIVE,(e,t)=>{this.#H(e,t)})}get label(){return this.#A}get ordered(){return this.#R}get maxPacketLifeTime(){return this.#w}get maxRetransmits(){return this.#N}get protocol(){return this.#b}get negotiated(){return this.#O}get id(){return this.#U}get readyState(){return this.#D}get bufferedAmount(){return this.#k}get bufferedAmountLowThreshold(){return this.#v}set bufferedAmountLowThreshold(e){this.#v=e}get binaryType(){return this.#L}set binaryType(e){if("arraybuffer"!==e&&"blob"!==e)throw new TypeError('binaryType must be "arraybuffer" or "blob"');this.#L=e}get reliable(){return this.#R&&null===this.#w&&null===this.#N}send(e){if(this.#D!==B.OPEN)throw new Error('RTCDataChannel.readyState is not "open"');let t,r,s=0;if("string"==typeof e)t=Buffer.from(e,"utf8"),s=t.length,r=!1;else if(e instanceof ArrayBuffer)t=Buffer.from(e),s=e.byteLength,r=!0;else if(ArrayBuffer.isView(e))t=Buffer.from(e.buffer,e.byteOffset,e.byteLength),s=e.byteLength,r=!0;else{if(!Buffer.isBuffer(e))throw e&&"function"==typeof e.arrayBuffer?new Error("Blob sending not yet implemented"):new TypeError("Invalid data type");t=e,s=e.length,r=!0}if(!this.#P)throw new Error("Data channel not connected to a transport");this.#k+=s;try{this.emit(A.SEND,t,r),this.#k=Math.max(0,this.#k-s),this.#x()}catch(e){throw this.#k=Math.max(0,this.#k-s),this.emit("error",e),e}}#x(){this.#k<=this.#v&&this.emit("bufferedamountlow")}close(){this.#D!==B.CLOSING&&this.#D!==B.CLOSED&&(this.#_(B.CLOSING),setImmediate(()=>{this.#D===B.CLOSING&&this.#_(B.CLOSED)}))}#_(e){this.#D!==e&&(this.#D=e,e===B.OPEN?this.emit("open"):e===B.CLOSING?this.emit("closing"):e===B.CLOSED&&this.emit("close"))}#H(e,t){let r;r=t?"arraybuffer"===this.#L?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e:e.toString("utf8"),this.emit("message",{data:r})}}const w=Object.freeze({OFFER:"offer",PRANSWER:"pranswer",ANSWER:"answer",ROLLBACK:"rollback"});class N{#M;#F;constructor(e={}){if(this.#M=e.type||null,this.#F=e.sdp||null,this.#M&&!Object.values(w).includes(this.#M))throw new TypeError(`Invalid SDP type: ${this.#M}`)}get type(){return this.#M}set type(e){if(e&&!Object.values(w).includes(e))throw new TypeError(`Invalid SDP type: ${e}`);this.#M=e}get sdp(){return this.#F}set sdp(e){this.#F=e}toJSON(){return{type:this.#M,sdp:this.#F}}}function b(t){const{iceUfrag:r,icePwd:s,fingerprint:i,setup:n="actpass",candidates:a=[],sctpPort:o=5e3,maxMessageSize:c=262144}=t,h=[];h.push("v=0");const d=e.randomBytes(4).readUInt32BE(0);h.push(`o=- ${d} 2 IN IP4 127.0.0.1`),h.push("s=-"),h.push("t=0 0"),h.push("a=group:BUNDLE 0"),h.push("a=msid-semantic: WMS"),h.push("m=application 9 UDP/DTLS/SCTP webrtc-datachannel"),h.push("c=IN IP4 0.0.0.0"),h.push("a=ice-ufrag:"+r),h.push("a=ice-pwd:"+s),h.push("a=ice-options:trickle"),i&&h.push(`a=fingerprint:${i.algorithm} ${i.value}`),h.push(`a=setup:${n}`),h.push("a=mid:0"),h.push("a=sctp-port:"+o),h.push("a=max-message-size:"+c);for(const e of a){const t=e.sdp||e.candidate;t&&h.push("a="+(t.startsWith("candidate:")?t:"candidate:"+t))}return h.join("\r\n")+"\r\n"}function O(e){const t=(e.startsWith("candidate:")?e.slice(10):e).split(/\s+/);return t.length<8?null:{candidate:e.startsWith("candidate:")?e:"candidate:"+e,foundation:t[0],component:parseInt(t[1],10),protocol:t[2].toLowerCase(),priority:parseInt(t[3],10)>>>0,address:t[4],port:parseInt(t[5],10),type:t[7]}}const U=554869826,D=Object.freeze({BINDING_REQUEST:1,BINDING_SUCCESS:257,BINDING_ERROR:273}),k=Object.freeze({MAPPED_ADDRESS:1,USERNAME:6,MESSAGE_INTEGRITY:8,ERROR_CODE:9,XOR_MAPPED_ADDRESS:32,PRIORITY:36,USE_CANDIDATE:37,FINGERPRINT:32808,ICE_CONTROLLED:32809,ICE_CONTROLLING:32810});function v(e){return e+3&-4}const L=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})();class P{type;transactionId;attrs;constructor(t,r){this.type=t,this.transactionId=r||e.randomBytes(12),this.attrs=[]}addAttr(e,t){return this.attrs.push({type:e,value:t}),this}addUsername(e){return this.addAttr(k.USERNAME,Buffer.from(e,"utf8"))}addPriority(e){const t=Buffer.alloc(4);return t.writeUInt32BE(e>>>0,0),this.addAttr(k.PRIORITY,t)}addIceControlling(e){return this.addAttr(k.ICE_CONTROLLING,e)}addIceControlled(e){return this.addAttr(k.ICE_CONTROLLED,e)}addUseCandidate(){return this.addAttr(k.USE_CANDIDATE,Buffer.alloc(0))}addXorMappedAddress(e,t){return this.addAttr(k.XOR_MAPPED_ADDRESS,function(e,t){const r=Buffer.alloc(8);r.writeUInt8(0,0),r.writeUInt8(1,1),r.writeUInt16BE(8466^t,2);const s=e.split(".").map(Number),i=(s[0]<<24|s[1]<<16|s[2]<<8|s[3])>>>0;return r.writeUInt32BE((i^U)>>>0,4),r}(e,t,this.transactionId))}#K(){const e=[];for(const t of this.attrs){const r=Buffer.alloc(4);r.writeUInt16BE(t.type,0),r.writeUInt16BE(t.value.length,2);const s=Buffer.alloc(v(t.value.length));t.value.copy(s,0),e.push(r,s)}return Buffer.concat(e)}#q(e){const t=Buffer.alloc(20);return t.writeUInt16BE(this.type,0),t.writeUInt16BE(e,2),t.writeUInt32BE(U,4),this.transactionId.copy(t,8),t}build(t){let r=this.#K();if(t){const s=r.length+24,i=this.#q(s),n=e.createHmac("sha1",Buffer.from(t,"utf8")).update(Buffer.concat([i,r])).digest(),a=Buffer.alloc(4);a.writeUInt16BE(k.MESSAGE_INTEGRITY,0),a.writeUInt16BE(20,2),r=Buffer.concat([r,a,n])}const s=r.length+8,i=this.#q(s),n=(1398035790^function(e){let t=4294967295;for(let r=0;r<e.length;r++)t=L[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}(Buffer.concat([i,r])))>>>0,a=Buffer.alloc(8);return a.writeUInt16BE(k.FINGERPRINT,0),a.writeUInt16BE(4,2),a.writeUInt32BE(n,4),r=Buffer.concat([r,a]),Buffer.concat([this.#q(r.length),r])}}const _=Object.freeze({CHANGE_CIPHER_SPEC:20,ALERT:21,HANDSHAKE:22,APPLICATION_DATA:23}),H=Object.freeze({HELLO_REQUEST:0,CLIENT_HELLO:1,SERVER_HELLO:2,HELLO_VERIFY_REQUEST:3,CERTIFICATE:11,SERVER_KEY_EXCHANGE:12,CERTIFICATE_REQUEST:13,SERVER_HELLO_DONE:14,CERTIFICATE_VERIFY:15,CLIENT_KEY_EXCHANGE:16,FINISHED:20}),x=Object.freeze({WARNING:1,FATAL:2}),M=Object.freeze({CLOSE_NOTIFY:0,HANDSHAKE_FAILURE:40,BAD_CERTIFICATE:42,DECRYPT_ERROR:51,INTERNAL_ERROR:80}),F=49195,K=Object.freeze({secp256r1:23}),q=Object.freeze({uncompressed:0}),G=Object.freeze({sha256:4,sha384:5,sha512:6}),z=Object.freeze({rsa:1,ecdsa:3}),$=Object.freeze({ecdsa_sign:64,rsa_sign:1}),j=Object.freeze({SUPPORTED_GROUPS:10,EC_POINT_FORMATS:11,SIGNATURE_ALGORITHMS:13,EXTENDED_MASTER_SECRET:23,RENEGOTIATION_INFO:65281}),V=Object.freeze({CLIENT:"client finished",SERVER:"server finished"});function W(e){return Buffer.from([e>>16&255,e>>8&255,255&e])}function Y(e,t){return e[t]<<16|e[t+1]<<8|e[t+2]}function X(e){return Buffer.concat([Buffer.from([e.length]),e])}function Q(e){const t=Buffer.alloc(2);return t.writeUInt16BE(e.length,0),Buffer.concat([t,e])}function Z(e){return Buffer.concat([W(e.length),e])}function J(e,t,r){const s=Buffer.alloc(12);return s.writeUInt8(e,0),W(r.length).copy(s,1),s.writeUInt16BE(t,4),W(0).copy(s,6),W(r.length).copy(s,9),Buffer.concat([s,r])}function ee(t,r,s,i){return function(t,r,s,i){const n=[];let a=0,o=s;for(;a<i;){o=e.createHmac(t,r).update(o).digest();const i=e.createHmac(t,r).update(Buffer.concat([o,s])).digest();n.push(i),a+=i.length}return Buffer.concat(n).slice(0,i)}("sha256",t,Buffer.concat([Buffer.from(r,"ascii"),s]),i)}function te(e,t,r){return ee(e,"master secret",Buffer.concat([t,r]),48)}function re(e,t){return ee(e,"extended master secret",t,48)}function se(e,t,r,s,i){const n=Buffer.alloc(13);return n.writeUInt16BE(e,0),n.writeUIntBE(t,2,6),n.writeUInt8(r,8),n.writeUInt16BE(s,9),n.writeUInt16BE(i,11),n}class ie{#G;#z;constructor(e,t){this.#G=e,this.#z=t}encrypt(t,r,s,i,n){const a=Buffer.alloc(8);a.writeUInt16BE(t,0),a.writeUIntBE(r,2,6);const o=Buffer.concat([this.#z,a]),c=se(t,r,s,i,n.length),h=e.createCipheriv("aes-128-gcm",this.#G,o);h.setAAD(c);const d=Buffer.concat([h.update(n),h.final()]),l=h.getAuthTag();return Buffer.concat([a,d,l])}decrypt(t,r,s,i,n){const a=n.slice(0,8),o=n.slice(n.length-16),c=n.slice(8,n.length-16),h=Buffer.concat([this.#z,a]),d=se(t,r,s,i,c.length),l=e.createDecipheriv("aes-128-gcm",this.#G,h);return l.setAAD(d),l.setAuthTag(o),Buffer.concat([l.update(c),l.final()])}}const ne=Object.freeze({CLIENT:"client",SERVER:"server"}),ae=Object.freeze({NEW:"new",HANDSHAKING:"handshaking",CONNECTED:"connected",CLOSED:"closed",FAILED:"failed"});class oe extends t{role;state;#I;#T;#$;#j;#V;#W;#Y;#X;#Q;#Z;#J;#ee;#te;#re;#se;#ie;#ne;#ae;#oe;#ce;#he;#de;#le;#ue;#fe;#pe;#me;#Ee;constructor(e){super(),this.role=e.role,this.#I=e.certDer,this.#T=e.privateKey,this.#$=e.verifyFingerprint||null,this.#j=e.output,this.state=ae.NEW,this.#V=0,this.#W=0,this.#Y=0,this.#X=null,this.#Q=null,this.#Z=!1,this.#J=null,this.#ee=null,this.#te=Buffer.alloc(0),this.#re=null,this.#se=null,this.#ie=null,this.#ne=null,this.#ae=!1,this.#oe=[],this.#ce=new Map,this.#he=0,this.#de=[],this.#le=null,this.#ue=0,this.#fe=!1,this.#Ee=!1}start(){this.state===ae.NEW&&(this.state=ae.HANDSHAKING,this.role===ne.CLIENT&&(this.#J=this.#ge(),this.#Ie()))}#ge(){const t=e.randomBytes(32);return t.writeUInt32BE(Math.floor(Date.now()/1e3),0),t}#Te(e){const t=[];for(const r of e){const e=this.#Y++,s=J(r.type,e,r.body);this.#oe.push(s);const i=r.body.length;let n=0;do{const s=r.body.slice(n,n+1200),a=Buffer.alloc(12);a.writeUInt8(r.type,0),W(i).copy(a,1),a.writeUInt16BE(e,4),W(n).copy(a,6),W(s.length).copy(a,9);const o=Buffer.concat([a,s]);t.push({type:_.HANDSHAKE,payload:o}),n+=s.length}while(n<i)}this.#de=t,this.#ue=0,this.#Ce(),this.#Se()}#Ce(){for(const e of this.#de)this.#ye(e.type,e.payload)}#Be(){this.#ye(_.CHANGE_CIPHER_SPEC,Buffer.from([1])),this.#V=1,this.#W=0,this.#Z=!0}#ye(e,t){let r=t;const s=this.#W++;this.#Z&&this.#X&&(r=this.#X.encrypt(this.#V,s,e,65277,t));const i=function(e,t,r,s,i=65277){const n=Buffer.alloc(13);return n.writeUInt8(e,0),n.writeUInt16BE(i,1),n.writeUInt16BE(t,3),n.writeUIntBE(r,5,6),n.writeUInt16BE(s.length,11),Buffer.concat([n,s])}(e,this.#V,s,r,65277);this.#j(i)}#Se(){this.#Ae(),this.#le=setTimeout(()=>{this.#fe||this.state!==ae.HANDSHAKING||(this.#ue>=10?this.#Re(new Error("DTLS handshake timed out")):(this.#ue++,this.#Ce(),this.#Se()))},1e3*Math.pow(2,this.#ue)),this.#le.unref&&this.#le.unref()}#Ae(){this.#le&&(clearTimeout(this.#le),this.#le=null)}handlePacket(e){if(this.state===ae.CLOSED||this.state===ae.FAILED)return;let t;try{t=function(e){const t=[];let r=0;for(;r+13<=e.length;){const s=e.readUInt8(r),i=e.readUInt16BE(r+1),n=e.readUInt16BE(r+3),a=e.readUIntBE(r+5,6),o=e.readUInt16BE(r+11),c=r+13;if(c+o>e.length)break;t.push({type:s,version:i,epoch:n,seq:a,fragment:e.slice(c,c+o)}),r=c+o}return t}(e)}catch(e){return}for(const e of t)try{this.#we(e)}catch(e){return void this.#Re(e instanceof Error?e:new Error(String(e)))}}#we(e){let t=e.fragment;if(e.epoch>=1){if(!this.#Q)return;t=this.#Q.decrypt(e.epoch,e.seq,e.type,e.version,e.fragment)}switch(e.type){case _.HANDSHAKE:this.#Ne(t);break;case _.CHANGE_CIPHER_SPEC:break;case _.APPLICATION_DATA:this.state===ae.CONNECTED&&this.emit("data",t);break;case _.ALERT:this.#be(t)}}#be(e){if(e.length<2)return;const t=e[0],r=e[1];r===M.CLOSE_NOTIFY?this.close():t===x.FATAL&&this.#Re(new Error(`DTLS fatal alert: ${r}`))}#Ne(e){const t=function(e){const t=e.readUInt8(0),r=Y(e,1),s=e.readUInt16BE(4),i=Y(e,6),n=Y(e,9);return{msgType:t,length:r,messageSeq:s,fragmentOffset:i,fragmentLength:n,body:e.slice(12,12+n)}}(e);let r=this.#ce.get(t.messageSeq);for(r||(r={type:t.msgType,length:t.length,data:Buffer.alloc(t.length),received:0,ranges:[]},this.#ce.set(t.messageSeq,r)),t.body.copy(r.data,t.fragmentOffset),r.received=Math.max(r.received,t.fragmentOffset+t.fragmentLength);;){const e=this.#ce.get(this.#he);if(!e||e.received<e.length)break;this.#ce.delete(this.#he),this.#he++,this.#Oe(e.type,e.data)}}#Ue(e,t){const r=this.#he-1;this.#oe.push(J(e,r,t))}#Oe(e,t){this.role===ne.CLIENT?this.#De(e,t):this.#ke(e,t)}#ve(){const t=e.createHash("sha256");for(const e of this.#oe)t.update(e);return t.digest()}#Le(){return Buffer.concat(this.#oe)}#Ie(){const e=this.#Pe();if(0===this.#te.length){const t=this.#Y++,r=J(H.CLIENT_HELLO,t,e);this.#de=[{type:_.HANDSHAKE,payload:r}],this.#Ce(),this.#Se()}else{const t=this.#Y++,r=J(H.CLIENT_HELLO,t,e);this.#oe.push(r),this.#de=[{type:_.HANDSHAKE,payload:r}],this.#ue=0,this.#Ce(),this.#Se()}}#Pe(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#J),e.push(X(Buffer.alloc(0))),e.push(X(this.#te));const t=Buffer.alloc(2);return t.writeUInt16BE(F,0),e.push(Q(t)),e.push(X(Buffer.from([0]))),e.push(Q(this.#_e())),Buffer.concat(e)}#_e(){const e=[],t=Buffer.alloc(2);t.writeUInt16BE(K.secp256r1,0),e.push(this.#He(j.SUPPORTED_GROUPS,Q(t))),e.push(this.#He(j.EC_POINT_FORMATS,X(Buffer.from([q.uncompressed]))));const r=Buffer.from([G.sha256,z.ecdsa]);return e.push(this.#He(j.SIGNATURE_ALGORITHMS,Q(r))),e.push(this.#He(j.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),Buffer.concat(e)}#He(e,t){const r=Buffer.alloc(4);return r.writeUInt16BE(e,0),r.writeUInt16BE(t.length,2),Buffer.concat([r,t])}#De(e,t){switch(e){case H.HELLO_VERIFY_REQUEST:{const e=t.readUInt8(2);this.#te=t.slice(3,3+e),this.#Ae(),this.#Ie();break}case H.SERVER_HELLO:this.#Ue(e,t),this.#xe(t);break;case H.CERTIFICATE:this.#Ue(e,t),this.#ie=this.#Me(t);break;case H.SERVER_KEY_EXCHANGE:this.#Ue(e,t),this.#Fe(t);break;case H.CERTIFICATE_REQUEST:this.#Ee=!0,this.#Ue(e,t);break;case H.SERVER_HELLO_DONE:this.#Ue(e,t),this.#Ae(),this.#Ke();break;case H.FINISHED:this.#qe(t,V.SERVER),this.#Ue(e,t),this.#Ge()}}#xe(e){let t=2;this.#ee=e.slice(t,t+32),t+=32,t+=1+e.readUInt8(t);const r=e.readUInt16BE(t);if(t+=2,r!==F)throw new Error(`Server chose unsupported cipher suite 0x${r.toString(16)}`);if(t+=1,t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===j.EXTENDED_MASTER_SECRET&&(this.#ae=!0),t+=s}}}#Ke(){this.#re=e.createECDH("prime256v1"),this.#re.generateKeys();const t=this.#re.getPublicKey(),r=this.#re.computeSecret(this.#ne),s=X(t),i=this.#Ee;let n=null,a=Buffer.alloc(0);const o=i?this.#Y+1:this.#Y;i&&(n=this.#ze(),a=J(H.CERTIFICATE,this.#Y,n));const c=J(H.CLIENT_KEY_EXCHANGE,o,s);if(this.#ae){const t=e.createHash("sha256");for(const e of this.#oe)t.update(e);i&&t.update(a),t.update(c);const s=t.digest();this.#se=re(r,s)}else this.#se=te(r,this.#J,this.#ee);this.#$e();const h=[];if(i&&h.push({type:H.CERTIFICATE,body:n}),h.push({type:H.CLIENT_KEY_EXCHANGE,body:s}),i){const t=Buffer.concat([...this.#oe,a,c]),r=e.sign("sha256",t,{key:this.#T,dsaEncoding:"der"}),s=Buffer.concat([Buffer.from([G.sha256,z.ecdsa]),Q(r)]);h.push({type:H.CERTIFICATE_VERIFY,body:s})}this.#Te(h),this.#Be(),this.#je(V.CLIENT)}#ke(e,t){switch(e){case H.CLIENT_HELLO:this.#Ve(t);break;case H.CERTIFICATE:this.#Ue(e,t),this.#ie=this.#Me(t);break;case H.CLIENT_KEY_EXCHANGE:{this.#Ue(e,t);const r=t.readUInt8(0);this.#ne=t.slice(1,1+r);const s=this.#re.computeSecret(this.#ne);this.#ae?this.#se=re(s,this.#ve()):this.#se=te(s,this.#J,this.#ee),this.#$e();break}case H.CERTIFICATE_VERIFY:this.#We(t),this.#Ue(e,t);break;case H.FINISHED:this.#qe(t,V.CLIENT),this.#Ue(e,t),this.#Be(),this.#je(V.SERVER),this.#Ge()}}#Ve(e){let t=2;const r=e.slice(t,t+32);t+=32,t+=1+e.readUInt8(t);const s=e.readUInt8(t),i=e.slice(t+1,t+1+s);t+=1+s;const n=e.readUInt16BE(t),a=e.slice(t+2,t+2+n);t+=2+n,t+=1+e.readUInt8(t);let o=!1,c=!1;for(let e=0;e+1<a.length;e+=2)255===a.readUInt16BE(e)&&(c=!0);if(t+2<=e.length){const r=e.readUInt16BE(t);t+=2;const s=t+r;for(;t+4<=s;){const r=e.readUInt16BE(t),s=e.readUInt16BE(t+2);t+=4,r===j.EXTENDED_MASTER_SECRET&&(o=!0),r===j.RENEGOTIATION_INFO&&(c=!0),t+=s}}if(this.#me=c,0===i.length)return this.#J=r,this.#Ye(this.#Xe(r)),this.#ce.clear(),void(this.#he=1);const h=this.#Xe(r);if(!i.equals(h))return this.#Ye(h),this.#ce.clear(),void(this.#he=1);this.#J=r,this.#ae=o,this.#Ue(H.CLIENT_HELLO,e),this.#Qe()}#Xe(t){return this.#pe||(this.#pe=e.randomBytes(32)),e.createHmac("sha256",this.#pe).update(t).digest().slice(0,20)}#Ye(e){const t=Buffer.concat([Buffer.from([254,255]),X(e)]),r=J(H.HELLO_VERIFY_REQUEST,0,t);this.#ye(_.HANDSHAKE,r),this.#Y=1}#Qe(){this.#ee=this.#ge(),this.#re=e.createECDH("prime256v1"),this.#re.generateKeys();const t=this.#re.getPublicKey(),r=this.#Ze(),s=this.#ze(),i=Buffer.concat([Buffer.from([3]),(()=>{const e=Buffer.alloc(2);return e.writeUInt16BE(K.secp256r1,0),e})(),X(t)]),n=Buffer.concat([this.#J,this.#ee,i]),a=e.sign("sha256",n,{key:this.#T,dsaEncoding:"der"}),o=Buffer.concat([i,Buffer.from([G.sha256,z.ecdsa]),Q(a)]),c=X(Buffer.from([$.ecdsa_sign,$.rsa_sign])),h=Q(Buffer.from([G.sha256,z.ecdsa])),d=Q(Buffer.alloc(0)),l=Buffer.concat([c,h,d]),u=Buffer.alloc(0);this.#Te([{type:H.SERVER_HELLO,body:r},{type:H.CERTIFICATE,body:s},{type:H.SERVER_KEY_EXCHANGE,body:o},{type:H.CERTIFICATE_REQUEST,body:l},{type:H.SERVER_HELLO_DONE,body:u}])}#Ze(){const e=[];e.push(Buffer.from([254,253])),e.push(this.#ee),e.push(X(Buffer.alloc(0)));const t=Buffer.alloc(2);t.writeUInt16BE(F,0),e.push(t),e.push(Buffer.from([0]));const r=[];return this.#ae&&r.push(this.#He(j.EXTENDED_MASTER_SECRET,Buffer.alloc(0))),r.push(this.#He(j.EC_POINT_FORMATS,X(Buffer.from([q.uncompressed])))),this.#me&&r.push(this.#He(j.RENEGOTIATION_INFO,X(Buffer.alloc(0)))),e.push(Q(Buffer.concat(r))),Buffer.concat(e)}#We(t){const r=t.readUInt16BE(2),s=t.slice(4,4+r),i=this.#Le(),n=this.#Je(this.#ie);if(!e.verify("sha256",i,{key:n,dsaEncoding:"der"},s))throw new Error("Client CertificateVerify signature invalid")}#ze(){const e=Z(this.#I);return Z(e)}#Me(e){let t=3;if(t+3>3+Y(e,0))return null;const r=Y(e,t);t+=3;const s=e.slice(t,t+r);if(this.#$){const e={algorithm:"sha-256",value:C(s,"sha-256")};if(!this.#$(e,s))throw new Error("Remote certificate fingerprint mismatch")}return s}#Fe(t){let r=0;const s=t.readUInt8(r);r+=1;const i=t.readUInt16BE(r);if(r+=2,3!==s||i!==K.secp256r1)throw new Error("Unsupported ECDHE curve from server");const n=t.readUInt8(r);r+=1;const a=t.slice(r,r+n);r+=n,this.#ne=a;const o=t.slice(0,r);r+=2;const c=t.readUInt16BE(r);r+=2;const h=t.slice(r,r+c),d=Buffer.concat([this.#J,this.#ee,o]),l=this.#Je(this.#ie);if(!e.verify("sha256",d,{key:l,dsaEncoding:"der"},h))throw new Error("ServerKeyExchange signature invalid")}#Je(t){return new e.X509Certificate(t).publicKey}#$e(){const{clientKey:e,serverKey:t,clientIV:r,serverIV:s}=function(e,t,r){const s=ee(e,"key expansion",Buffer.concat([r,t]),40);let i=0;return{clientKey:s.slice(i,i+=16),serverKey:s.slice(i,i+=16),clientIV:s.slice(i,i+=4),serverIV:s.slice(i,i+=4)}}(this.#se,this.#J,this.#ee);this.role===ne.CLIENT?(this.#X=new ie(e,r),this.#Q=new ie(t,s)):(this.#X=new ie(t,s),this.#Q=new ie(e,r))}#je(e){const t=ee(this.#se,e,this.#ve(),12),r=this.#Y++,s=J(H.FINISHED,r,t);this.#oe.push(s),this.#ye(_.HANDSHAKE,s)}#qe(t,r){const s=ee(this.#se,r,this.#ve(),12);if(!e.timingSafeEqual(t,s))throw new Error("Peer Finished verify_data mismatch")}#Ge(){this.#fe||(this.#fe=!0,this.#Ae(),this.state=ae.CONNECTED,this.emit("connect"))}send(e){if(this.state!==ae.CONNECTED)throw new Error("DTLS connection not established");this.#ye(_.APPLICATION_DATA,e)}close(){if(this.state!==ae.CLOSED&&this.state!==ae.FAILED){try{this.#Z&&this.#ye(_.ALERT,Buffer.from([x.WARNING,M.CLOSE_NOTIFY]))}catch(e){}this.#Ae(),this.state=ae.CLOSED,this.emit("close")}}#Re(e){this.state!==ae.FAILED&&this.state!==ae.CLOSED&&(this.#Ae(),this.state=ae.FAILED,this.emit("error",e))}getRemoteCertificate(){return this.#ie}}const ce=554869826;class he extends t{#et;#tt;#rt;#st;#it;#nt;#at;#ot;#ct;#ht;#dt;#lt;#ut;#ft;constructor(e){super(),this.#et=e.server,this.#tt=e.port,this.#rt=e.username,this.#st=e.credential,this.#it=null,this.#nt=new Map,this.#at=null,this.#ot=null,this.#ct=!0===e.secure,this.#ht=(e.transport||"udp").toLowerCase(),this.#dt=!1!==e.rejectUnauthorized,this.#lt=null,this.#ut=null,this.#ft=Buffer.alloc(0)}async connect(){if(!this.#it&&!this.#ut)return this.#ct&&"tcp"===this.#ht?this.#pt():new Promise((e,t)=>{const s=r.createSocket("udp4");if(this.#it=s,s.on("error",e=>{console.error("STUN socket error:",e),t(e)}),this.#ct){const r=T({commonName:"nodertc-turn-client"}),i=new oe({role:ne.CLIENT,certDer:r.certDer,privateKey:r.privateKey,verifyFingerprint:()=>!0,output:e=>{s.send(e,this.#tt,this.#et,()=>{})}});this.#lt=i,s.on("message",e=>i.handlePacket(e)),i.on("data",e=>this.#mt(e,this.#Et())),i.on("connect",()=>e()),i.on("error",e=>t(e)),s.bind(()=>i.start())}else s.on("message",(e,t)=>{this.#mt(e,t)}),s.bind(()=>e())})}#pt(){return new Promise((e,t)=>{const r=i.connect({host:this.#et,port:this.#tt,rejectUnauthorized:this.#dt},()=>e());this.#ut=r,r.on("data",e=>this.#gt(e)),r.on("error",e=>t(e))})}#gt(e){for(this.#ft=this.#ft.length?Buffer.concat([this.#ft,e]):e;this.#ft.length>=20;){const e=20+this.#ft.readUInt16BE(2);if(this.#ft.length<e)break;const t=this.#ft.subarray(0,e);this.#ft=this.#ft.subarray(e),this.#mt(t,this.#Et())}}#Et(){return{address:this.#et,family:"IPv4",port:this.#tt,size:0}}#It(e,t){if(this.#ut)this.#ut.write(e,e=>{e&&t(e)});else if(this.#lt)try{this.#lt.send(e)}catch(e){t(e instanceof Error?e:new Error(String(e)))}else this.#it.send(e,this.#tt,this.#et,e=>{e&&t(e)})}async getReflexiveAddress(){await this.connect();const t=e.randomBytes(12),r=this.#Tt(t);return new Promise((e,s)=>{const i=setTimeout(()=>{this.#nt.delete(t.toString("hex")),s(new Error("STUN request timeout"))},5e3);this.#nt.set(t.toString("hex"),{resolve:t=>{clearTimeout(i),e(t)},reject:e=>{clearTimeout(i),s(e)}}),this.#It(r,e=>{clearTimeout(i),this.#nt.delete(t.toString("hex")),s(e)})})}async allocateRelay(t=600){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");await this.connect();let r=e.randomBytes(12),s=this.#Ct(r,t);try{return await this.#St(s,r,"allocate")}catch(i){if(i instanceof Error&&i.message.includes("401")&&this.#at&&this.#ot)return r=e.randomBytes(12),s=this.#Ct(r,t,!0),await this.#St(s,r,"allocate");throw i}}async refreshAllocation(t=600){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");return this.#yt("refresh",()=>{const r=e.randomBytes(12);return{transactionId:r,request:this.#Bt(r,t)}})}async#yt(e,t){const r=t();try{return await this.#St(r.request,r.transactionId,e)}catch(r){if(r instanceof Error&&r.message.includes("401")&&this.#at&&this.#ot){const r=t();return this.#St(r.request,r.transactionId,e)}throw r}}async createPermission(t){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");await this.#yt("createPermission",()=>{const r=e.randomBytes(12);return{transactionId:r,request:this.#At(r,t)}})}async sendIndication(t,r,s){if(!this.#rt||!this.#st)throw new Error("TURN requires username and credential");const i=e.randomBytes(12),n=this.#Rt(i,t,r,s);return new Promise((e,t)=>{this.#It(n,t),e()})}#St(e,t,r){return new Promise((s,i)=>{const n=setTimeout(()=>{this.#nt.delete(t.toString("hex")),i(new Error(`${r} request timeout`))},5e3);this.#nt.set(t.toString("hex"),{type:r,resolve:e=>{clearTimeout(n),s(e)},reject:e=>{clearTimeout(n),i(e)}}),this.#It(e,e=>{clearTimeout(n),this.#nt.delete(t.toString("hex")),i(e)})})}#Tt(e){const t=Buffer.alloc(20);return t.writeUInt16BE(1,0),t.writeUInt16BE(0,2),t.writeUInt32BE(ce,4),e.copy(t,8),t}#Ct(e,t,r=!1){const s=[],i=Buffer.alloc(8);i.writeUInt16BE(25,0),i.writeUInt16BE(4,2),i.writeUInt8(17,4),s.push(i);const n=Buffer.alloc(8);if(n.writeUInt16BE(13,0),n.writeUInt16BE(4,2),n.writeUInt32BE(t,4),s.push(n),r&&this.#at&&this.#ot){const e=this.#wt(6,this.#rt);s.push(e);const t=this.#wt(20,this.#at);s.push(t);const r=this.#wt(21,this.#ot);s.push(r)}return this.#Nt(3,e,s,r)}#At(e,t){const r=[],s=this.#bt(t,0,e);return r.push(s),this.#at&&this.#ot&&(r.push(this.#wt(6,this.#rt)),r.push(this.#wt(20,this.#at)),r.push(this.#wt(21,this.#ot))),this.#Nt(8,e,r,!0)}#Rt(e,t,r,s){const i=[],n=this.#bt(t,r,e);i.push(n);const a=Buffer.alloc(4+s.length+(4-s.length%4)%4);return a.writeUInt16BE(19,0),a.writeUInt16BE(s.length,2),s.copy(a,4),i.push(a),this.#Nt(22,e,i,!1)}#bt(e,t,r){const s=Buffer.alloc(12);s.writeUInt16BE(18,0),s.writeUInt16BE(8,2),s.writeUInt8(0,4),s.writeUInt8(1,5);const i=8466^t;s.writeUInt16BE(i,6);const n=e.split(".").map(Number),a=(n[0]<<24|n[1]<<16|n[2]<<8|n[3])^ce;return s.writeUInt32BE(a>>>0,8),s}#Bt(e,t){const r=[],s=Buffer.alloc(8);s.writeUInt16BE(13,0),s.writeUInt16BE(4,2),s.writeUInt32BE(t,4),r.push(s);const i=this.#wt(6,this.#rt);if(r.push(i),this.#at){const e=this.#wt(20,this.#at);r.push(e)}if(this.#ot){const e=this.#wt(21,this.#ot);r.push(e)}return this.#Nt(4,e,r,!0)}#Nt(t,r,s,i=!1){let n=Buffer.concat(s);if(i&&this.#st){const s=Buffer.alloc(20);s.writeUInt16BE(t,0),s.writeUInt16BE(n.length+24,2),s.writeUInt32BE(ce,4),r.copy(s,8);const i=Buffer.concat([s,n]);let a=this.#st;if(this.#rt&&this.#at){const t=`${this.#rt}:${this.#at}:${this.#st}`;a=e.createHash("sha256").update(t).digest()}const o=e.createHmac("sha256",a);o.update(i);const c=o.digest(),h=Buffer.alloc(4+c.length);h.writeUInt16BE(8,0),h.writeUInt16BE(c.length,2),c.copy(h,4),n=Buffer.concat([n,h])}const a=Buffer.alloc(20);return a.writeUInt16BE(t,0),a.writeUInt16BE(n.length,2),a.writeUInt32BE(ce,4),r.copy(a,8),Buffer.concat([a,n])}#wt(e,t){const r=Buffer.from(t,"utf8"),s=r.length,i=(4-s%4)%4,n=Buffer.alloc(4+s+i);return n.writeUInt16BE(e,0),n.writeUInt16BE(s,2),r.copy(n,4),n}#mt(e,t){if(e.length<20)return;const r=e.readUInt16BE(0),s=e.readUInt16BE(2),i=e.readUInt32BE(4),n=e.slice(8,20);if(i!==ce)return;if(23===r){const t=this.#Ot(e.slice(20,20+s),n);if(t.xorPeerAddress&&t.data){const e={address:t.xorPeerAddress.address,port:t.xorPeerAddress.port,family:t.xorPeerAddress.family||"IPv4"};this.emit("data",t.data,e)}return}const a=n.toString("hex"),o=this.#nt.get(a);if(!o)return;const c=this.#Ot(e.slice(20,20+s),n);if(257===r)c.xorMappedAddress?o.resolve({address:c.xorMappedAddress.address,port:c.xorMappedAddress.port,family:c.xorMappedAddress.family}):c.mappedAddress?o.resolve({address:c.mappedAddress.address,port:c.mappedAddress.port,family:c.mappedAddress.family}):o.reject(new Error("No mapped address in STUN response")),this.#nt.delete(a);else if(259===r)c.xorRelayedAddress?o.resolve({relayedAddress:c.xorRelayedAddress.address,relayedPort:c.xorRelayedAddress.port,lifetime:c.lifetime||600,type:"relay"}):o.reject(new Error("No relayed address in ALLOCATE response")),this.#nt.delete(a);else if(260===r)o.resolve({lifetime:c.lifetime||600}),this.#nt.delete(a);else if(264===r||265===r)o.resolve({ok:!0}),this.#nt.delete(a);else if(!(272&~r)){c.realm&&(this.#at=c.realm),c.nonce&&(this.#ot=c.nonce);const e=c.errorCode||"Unknown error";o.reject(new Error(`STUN error: ${e}`)),this.#nt.delete(a)}}#Ot(e,t){const r={};let s=0;for(;s<e.length&&!(s+4>e.length);){const i=e.readUInt16BE(s),n=e.readUInt16BE(s+2);if(s+=4,s+n>e.length)break;const a=e.slice(s,s+n);switch(i){case 32:r.xorMappedAddress=this.#Ut(a,t);break;case 22:r.xorRelayedAddress=this.#Ut(a,t);break;case 18:r.xorPeerAddress=this.#Ut(a,t);break;case 19:r.data=a;break;case 1:r.mappedAddress=this.#Dt(a);break;case 13:r.lifetime=a.readUInt32BE(0);break;case 9:r.errorCode=this.#kt(a);break;case 20:r.realm=a.toString("utf8"),this.#at=r.realm;break;case 21:r.nonce=a.toString("utf8"),this.#ot=r.nonce}s+=n,s+=(4-n%4)%4}return r}#Ut(e,t){const r=e.readUInt8(1),s=8466^e.readUInt16BE(2);if(1===r){const t=e.readUInt32BE(4)^ce;return{family:"IPv4",port:s,address:[t>>24&255,t>>16&255,t>>8&255,255&t].join(".")}}return null}#Dt(e){const t=e.readUInt8(1),r=e.readUInt16BE(2);if(1===t){const t=e.slice(4,8);return{family:"IPv4",port:r,address:Array.from(t).join(".")}}return null}#kt(e){return`${100*(7&e.readUInt8(2))+e.readUInt8(3)} ${e.slice(4).toString("utf8")}`}close(){if(this.#lt){try{this.#lt.close()}catch(e){}this.#lt=null}if(this.#ut){try{this.#ut.destroy()}catch(e){}this.#ut=null}this.#it&&(this.#it.close(),this.#it=null),this.#nt.clear()}}const de={host:126,srflx:100,prflx:110,relay:0};function le(e){const t=e.match(/^(stuns?|turns?):\/?\/?([^:?]+):?(\d+)?(?:\?(.+))?$/);if(!t)return null;const r=t[1],s=t[2],i={};if(t[4])for(const e of t[4].split("&")){if(!e)continue;const t=e.indexOf("=");-1===t?i[e]=!0:i[e.slice(0,t)]=e.slice(t+1)}const n="turns"===r||"stuns"===r?5349:3478;return{scheme:r,protocol:r,host:s,port:parseInt(t[3]||String(n),10),transport:"string"==typeof i.transport?i.transport:"udp",params:i}}class ue{kind;#it;onMessage;constructor(e){this.kind="host",this.#it=e,this.onMessage=null,e.on("message",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){this.#it.send(e,r,t)}close(){try{this.#it.close()}catch(e){}}}class fe{kind;#vt;onMessage;#Lt;constructor(e){this.kind="relay",this.#vt=e,this.onMessage=null,this.#Lt=new Set,e.on("data",(e,t)=>{this.onMessage&&this.onMessage(e,{address:t.address,port:t.port})})}send(e,t,r){const s=`${t}:${r}`;this.#Lt.has(s)?this.#vt.sendIndication(t,r,e).catch(()=>{}):(this.#Lt.add(s),this.#vt.createPermission(t).then(()=>this.#vt.sendIndication(t,r,e)).catch(()=>{}))}close(){try{this.#vt.close()}catch(e){}}}class pe extends t{role;localUfrag;localPwd;remoteUfrag;remotePwd;#Pt;#_t;#Ht;#xt;#Mt;#Ft;#Kt;#qt;#Gt;#P;#zt;constructor(t){super(),this.role=t.role,this.localUfrag=t.localUfrag,this.localPwd=t.localPwd,this.remoteUfrag=null,this.remotePwd=null,this.#Pt=e.randomBytes(8),this.#_t=[],this.#Ht=[],this.#xt=[],this.#Mt=[],this.#Ft=null,this.#Kt=!1,this.#qt=null,this.#Gt=null,this.#P=!1,this.#zt=new Map}async gather(e={}){const t=e.iceServers||[],r="relay"===e.iceTransportPolicy,s=await this.#$t();for(const e of t){const t=Array.isArray(e.urls)?e.urls:[e.urls];for(const i of t){const t=le(i);if(!t)continue;const n="turns"===t.scheme&&"tcp"===t.transport;if("udp"===t.transport||n)try{"stun"!==t.scheme||r?"turn"!==t.scheme&&"turns"!==t.scheme||await this.#jt(t,e):await this.#Vt(t,s[0])}catch(e){this.emit("gathererror",{url:i,error:e instanceof Error?e.message:String(e)})}}}r&&(this.#Ht=this.#Ht.filter(e=>"relay"===e.type)),this.emit("gatheringcomplete")}async#$t(){const e=s.networkInterfaces(),t=[];for(const r of Object.values(e))if(r)for(const e of r)"IPv4"!==e.family||e.internal||t.push(e.address);0===t.length&&t.push("127.0.0.1");const r=[];for(const e of t)r.push(await this.#Wt(e));return r}#Wt(e){return new Promise((t,s)=>{const i=r.createSocket("udp4");i.on("error",e=>this.emit("error",e)),i.bind(0,e,()=>{const{port:r}=i.address(),s=new ue(i);s.onMessage=(e,t)=>this.#Yt(s,e,t),this.#_t.push(s);const n=this.#Xt("host",e,r,s);t({socket:i,address:e,port:r,transport:s,candidate:n})})})}async#Vt(e,t){if(!t)return;const r=new he({server:e.host,port:e.port});try{const e=await r.getReflexiveAddress();this.#Xt("srflx",e.address,e.port,t.transport,{relatedAddress:t.address,relatedPort:t.port})}finally{r.close()}}async#jt(e,t){if(!t.username||!t.credential)throw new Error("TURN server requires username and credential");const r=new he({server:e.host,port:e.port,username:t.username,credential:t.credential,transport:e.transport,secure:"turns"===e.scheme,rejectUnauthorized:t.rejectUnauthorized}),s=await r.allocateRelay(600),i=new fe(r);i.onMessage=(e,t)=>this.#Yt(i,e,t),this.#_t.push(i),this.#Xt("relay",s.relayedAddress,s.relayedPort,i,{relatedAddress:e.host,relatedPort:e.port})}#Xt(t,r,s,i,n={}){const a=e.createHash("md5").update(`${t}:${r}:${i.kind}`).digest("hex").slice(0,8),o=function(e,t=65535,r=1){return(de[e]<<24)+(t<<8)+(256-r)>>>0}(t);let c=`candidate:${a} 1 udp ${o} ${r} ${s} typ ${t}`;n.relatedAddress&&(c+=` raddr ${n.relatedAddress} rport ${n.relatedPort}`);const h={foundation:a,component:1,protocol:"udp",priority:o,address:r,port:s,type:t,transport:i,sdp:c};return this.#Ht.push(h),this.emit("candidate",h),h}getLocalCandidates(){return this.#Ht.slice()}setRemoteCredentials(e,t){this.remoteUfrag=e,this.remotePwd=t}addRemoteCandidate(e){e&&e.address&&e.port&&("string"==typeof e.address&&e.address.endsWith(".local")||(this.#xt.push(e),this.#Qt(),!this.#qt&&this.remotePwd&&this.#Zt()))}start(){this.remotePwd&&this.#xt.length>0&&this.#Zt()}#Qt(){for(const e of this.#Ht)for(const t of this.#xt){const r=`${e.type}:${e.address}:${e.port}->${t.address}:${t.port}`;this.#Mt.find(e=>e.key===r)||this.#Mt.push({key:r,local:e,remote:t,state:"frozen",nominated:!1})}}#Zt(){this.#qt||this.#Kt||(this.#qt=setInterval(()=>this.#Jt(),50),this.#qt.unref&&this.#qt.unref(),this.#Gt=setTimeout(()=>{this.#P||this.emit("failed"),this.#er()},1e4),this.#Gt.unref&&this.#Gt.unref(),this.#Jt())}#er(){this.#qt&&(clearInterval(this.#qt),this.#qt=null),this.#Gt&&(clearTimeout(this.#Gt),this.#Gt=null)}#Jt(){if(!this.#Kt)for(const e of this.#Mt)"succeeded"!==e.state&&this.#tr(e)}#tr(t){const r=e.randomBytes(12),s=`${this.remoteUfrag}:${this.localUfrag}`,i=new P(D.BINDING_REQUEST,r).addUsername(s).addPriority(t.local.priority);"controlling"===this.role?(i.addIceControlling(this.#Pt),i.addUseCandidate()):i.addIceControlled(this.#Pt);const n=i.build(this.remotePwd??void 0);this.#zt.set(r.toString("hex"),t),t.state="in-progress",t.local.transport.send(n,t.remote.address,t.remote.port)}#Yt(e,t,r){0!==t.length&&(t[0]<=3?this.#rr(e,t,r):this.emit("data",t,{transport:e,address:r.address,port:r.port}))}#rr(e,t,r){const s=function(e){if(e.length<20)return null;if(e.readUInt32BE(4)!==U)return null;const t=e.readUInt16BE(0),r=e.readUInt16BE(2);if(20+r>e.length)return null;const s=e.slice(8,20),i=new Map;let n=20;const a=20+r;for(;n+4<=a;){const t=e.readUInt16BE(n),r=e.readUInt16BE(n+2);if(n+=4,n+r>a)break;i.set(t,e.slice(n,n+r)),n+=v(r)}return{type:t,transactionId:s,attrs:i,raw:e}}(t);s&&(s.type===D.BINDING_REQUEST?this.#sr(e,s,r):s.type===D.BINDING_SUCCESS&&this.#ir(e,s,r))}#sr(t,r,s){if(this.localPwd&&!function(t,r){let s=20;const i=20+t.readUInt16BE(2);let n=-1;for(;s+4<=i;){const e=t.readUInt16BE(s),r=t.readUInt16BE(s+2);if(e===k.MESSAGE_INTEGRITY){n=s;break}s+=4+v(r)}if(n<0)return!1;const a=t.slice(n+4,n+4+20),o=n+24-20,c=Buffer.from(t.slice(0,20));c.writeUInt16BE(o,2);const h=e.createHmac("sha1",Buffer.from(r,"utf8")).update(Buffer.concat([c,t.slice(20,n)])).digest();return a.length===h.length&&e.timingSafeEqual(a,h)}(r.raw,this.localPwd))return;const i=new P(D.BINDING_SUCCESS,r.transactionId).addXorMappedAddress(s.address,s.port).build(this.localPwd);t.send(i,s.address,s.port),this.#xt.find(e=>e.address===s.address&&e.port===s.port)||this.addRemoteCandidate({address:s.address,port:s.port,type:"prflx",priority:0});const n=r.attrs.has(k.USE_CANDIDATE),a=this.#nr(t,s);n&&"controlled"===this.role&&this.#ar(a||this.#or(t,s))}#ir(e,t,r){const s=this.#zt.get(t.transactionId.toString("hex"));s&&(this.#zt.delete(t.transactionId.toString("hex")),s.state="succeeded","controlling"===this.role&&this.#ar(s))}#nr(e,t){return this.#Mt.find(r=>r.remote.address===t.address&&r.remote.port===t.port&&r.local.transport===e)}#or(e,t){return{local:{transport:e},remote:{address:t.address,port:t.port}}}#ar(e){!this.#Ft&&e&&(this.#Ft=e,this.#P=!0,this.#er(),this.emit("selected",{transport:e.local.transport,candidateType:e.local.type,remoteAddress:e.remote.address,remotePort:e.remote.port}),this.emit("connected"))}send(e){if(!this.#Ft)throw new Error("ICE not connected");this.#Ft.local.transport.send(e,this.#Ft.remote.address,this.#Ft.remote.port)}getSelectedPair(){return this.#Ft}getSelectedCandidateType(){return this.#Ft?this.#Ft.local.type:null}close(){if(!this.#Kt){this.#Kt=!0,this.#er();for(const e of this.#_t)try{e.close()}catch(e){}this.#_t=[],this.emit("closed")}}}const me=Object.freeze({DATA:0,INIT:1,INIT_ACK:2,SACK:3,HEARTBEAT:4,HEARTBEAT_ACK:5,ABORT:6,SHUTDOWN:7,SHUTDOWN_ACK:8,ERROR:9,COOKIE_ECHO:10,COOKIE_ACK:11,SHUTDOWN_COMPLETE:14,FORWARD_TSN:192}),Ee=Object.freeze({HEARTBEAT_INFO:1,STATE_COOKIE:7,UNRECOGNIZED_PARAM:8,COOKIE_PRESERVATIVE:9,SUPPORTED_ADDR_TYPES:11,FORWARD_TSN_SUPPORTED:49152,SUPPORTED_EXTENSIONS:32776}),ge=Object.freeze({DCEP:50,STRING:51,BINARY:53,STRING_EMPTY:56,BINARY_EMPTY:57,STRING_PARTIAL:54,BINARY_PARTIAL:52});function Ie(e){return e+3&-4}function Te(e,t,r){const s=4+r.length,i=Buffer.alloc(Ie(s));return i.writeUInt8(e,0),i.writeUInt8(t,1),i.writeUInt16BE(s,2),r.copy(i,4),i}function Ce(e,t){const r=4+t.length,s=Buffer.alloc(Ie(r));return s.writeUInt16BE(e,0),s.writeUInt16BE(r,2),t.copy(s,4),s}function Se(e){const t=[];let r=0;for(;r+4<=e.length;){const s=e.readUInt16BE(r),i=e.readUInt16BE(r+2);if(i<4||r+i>e.length)break;t.push({type:s,length:i,value:e.slice(r+4,r+i)}),r+=Ie(i)}return t}function ye({initiateTag:e,a_rwnd:t,outStreams:r,inStreams:s,initialTSN:i}){const n=Buffer.alloc(16);return n.writeUInt32BE(e>>>0,0),n.writeUInt32BE(t>>>0,4),n.writeUInt16BE(r,8),n.writeUInt16BE(s,10),n.writeUInt32BE(i>>>0,12),n}function Be(e){return{initiateTag:e.readUInt32BE(0),a_rwnd:e.readUInt32BE(4),outStreams:e.readUInt16BE(8),inStreams:e.readUInt16BE(10),initialTSN:e.readUInt32BE(12),params:Se(e.slice(16))}}function Ae({tsn:e,streamId:t,streamSeq:r,ppid:s,userData:i,unordered:n=!1,beginning:a=!0,ending:o=!0}){const c=Buffer.alloc(12);c.writeUInt32BE(e>>>0,0),c.writeUInt16BE(t,4),c.writeUInt16BE(r,6),c.writeUInt32BE(s>>>0,8);let h=0;return o&&(h|=1),a&&(h|=2),n&&(h|=4),{flags:h,body:Buffer.concat([c,i])}}const Re=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?2197175160^r>>>1:r>>>1;e[t]=r>>>0}return e})();function we(e){let t=4294967295;for(let r=0;r<e.length;r++)t=Re[255&(t^e[r])]^t>>>8;return(4294967295^t)>>>0}const Ne=1048576,be=Object.freeze({CLOSED:"closed",COOKIE_WAIT:"cookie-wait",COOKIE_ECHOED:"cookie-echoed",ESTABLISHED:"established"});function Oe(e,t){return(e-t&4294967295)>2147483648}function Ue(e,t){return e===t||Oe(e,t)}class De extends t{isClient;state;#cr;#hr;#dr;#lr;#ur;#fr;#pr;#mr;#Er;#gr;#Ir;#pe;constructor(t={}){super(),this.isClient=!!t.isClient,this.state=be.CLOSED,this.#cr=5e3,this.#hr=5e3,this.#dr=e.randomBytes(4).readUInt32BE(0)>>>0||1,this.#lr=0,this.#ur=e.randomBytes(4).readUInt32BE(0)>>>0,this.#fr=new Map,this.#pr=new Map,this.#mr=null,this.#Er=new Map,this.#gr=new Map,this.#Ir=null}start(){this.state===be.CLOSED&&this.isClient&&(this.#Tr(),this.state=be.COOKIE_WAIT)}#Cr(e,t){const r=function(e,t,r){const s=Buffer.alloc(12);return s.writeUInt16BE(e,0),s.writeUInt16BE(t,2),s.writeUInt32BE(r>>>0,4),s.writeUInt32BE(0,8),s}(this.#cr,this.#hr,e),s=Buffer.concat([r,...t]);!function(e){e.writeUInt32LE(0,8);const t=we(e);e.writeUInt32LE(t,8)}(s),this.emit("output",s)}receivePacket(e){if(e.length<12)return;if(!function(e){const t=e.readUInt32LE(8);e.writeUInt32LE(0,8);const r=we(e);return e.writeUInt32LE(t,8),r===t}(e))return;const t=function(e){return{srcPort:e.readUInt16BE(0),dstPort:e.readUInt16BE(2),verificationTag:e.readUInt32BE(4),checksum:e.readUInt32LE(8)}}(e),r=function(e){const t=[];let r=12;for(;r+4<=e.length;){const s=e.readUInt8(r),i=e.readUInt8(r+1),n=e.readUInt16BE(r+2);if(n<4||r+n>e.length)break;const a=e.slice(r+4,r+n);t.push({type:s,flags:i,length:n,body:a}),r+=Ie(n)}return t}(e);for(const e of r)this.#Sr(e,t)}#Sr(e,t){switch(e.type){case me.INIT:this.#yr(e);break;case me.INIT_ACK:this.#Br(e);break;case me.COOKIE_ECHO:this.#Ar(e);break;case me.COOKIE_ACK:this.#Rr();break;case me.DATA:this.#wr(e);break;case me.SACK:this.#Nr(e);break;case me.HEARTBEAT:this.#br(e);break;case me.ABORT:this.#Or("peer sent ABORT");break;case me.SHUTDOWN:this.#Ur()}}#Dr(){return[Ce(Ee.FORWARD_TSN_SUPPORTED,Buffer.alloc(0))]}#Tr(){const e=ye({initiateTag:this.#dr,a_rwnd:Ne,outStreams:65535,inStreams:65535,initialTSN:this.#ur}),t=Te(me.INIT,0,Buffer.concat([e,...this.#Dr()]));this.#Cr(0,[t]),this.#kr([t])}#kr(e){this.#vr();let t=500,r=0;const s=()=>{this.state!==be.ESTABLISHED&&this.state!==be.CLOSED&&(r>=8?this.#Or("SCTP setup timed out"):(r++,this.#Cr(this.state===be.COOKIE_ECHOED?this.#lr:0,e),t=Math.min(2*t,5e3),this.#Ir=setTimeout(s,t),this.#Ir.unref&&this.#Ir.unref()))};this.#Ir=setTimeout(s,t),this.#Ir.unref&&this.#Ir.unref()}#vr(){this.#Ir&&(clearTimeout(this.#Ir),this.#Ir=null)}#yr(t){const r=Be(t.body);this.#lr=r.initiateTag,this.#mr=r.initialTSN-1>>>0,this.#pe||(this.#pe=e.randomBytes(32));const s=Buffer.alloc(16);s.writeUInt32BE(this.#dr,0),s.writeUInt32BE(this.#lr,4),s.writeUInt32BE(this.#ur,8),s.writeUInt32BE(r.initialTSN,12);const i=e.createHmac("sha256",this.#pe).update(s).digest(),n=Buffer.concat([s,i]),a=ye({initiateTag:this.#dr,a_rwnd:Ne,outStreams:65535,inStreams:65535,initialTSN:this.#ur}),o=Buffer.concat([Ce(Ee.STATE_COOKIE,n),...this.#Dr()]),c=Te(me.INIT_ACK,0,Buffer.concat([a,o]));this.#Cr(this.#lr,[c])}#Br(e){if(this.state!==be.COOKIE_WAIT)return;this.#vr();const t=Be(e.body);this.#lr=t.initiateTag,this.#mr=t.initialTSN-1>>>0;const r=t.params.find(e=>e.type===Ee.STATE_COOKIE);if(!r)return void this.#Or("INIT_ACK missing state cookie");const s=Te(me.COOKIE_ECHO,0,r.value);this.state=be.COOKIE_ECHOED,this.#Cr(this.#lr,[s]),this.#kr([s])}#Ar(t){const r=t.body;if(r.length>=48&&this.#pe){const t=r.slice(0,16),s=r.slice(16,48),i=e.createHmac("sha256",this.#pe).update(t).digest();if(!e.timingSafeEqual(s,i))return}const s=Te(me.COOKIE_ACK,0,Buffer.alloc(0));this.#Cr(this.#lr,[s]),this.#Lr()}#Rr(){this.state===be.COOKIE_ECHOED&&(this.#vr(),this.#Lr())}#Lr(){this.state!==be.ESTABLISHED&&(this.state=be.ESTABLISHED,this.emit("established"))}sendData(e,t,r,s={}){if(this.state!==be.ESTABLISHED)throw new Error("SCTP association not established");const i=!!s.unordered;let n=0;i||(n=this.#fr.get(e)||0,this.#fr.set(e,n+1&65535));const a=r.length;let o=0;const c=[];do{const s=r.slice(o,o+1200),h=0===o,d=o+s.length>=a,l=this.#ur;this.#ur=this.#ur+1>>>0;const{flags:u,body:f}=Ae({tsn:l,streamId:e,streamSeq:n,ppid:t,userData:s,unordered:i,beginning:h,ending:d}),p=Te(me.DATA,u,f);this.#pr.set(l,{chunk:p}),c.push(p),o+=s.length}while(o<a);for(const e of c)this.#Cr(this.#lr,[e])}#wr(e){const t={unordered:!!(4&(r=e.flags)),beginning:!!(2&r),ending:!!(1&r),tsn:(s=e.body).readUInt32BE(0),streamId:s.readUInt16BE(4),streamSeq:s.readUInt16BE(6),ppid:s.readUInt32BE(8),userData:s.slice(12)};var r,s;this.#Pr(t),this.#_r()}#Pr(e){const t=this.#mr+1>>>0;if(!Oe(e.tsn,t))if(e.tsn===t){this.#mr=e.tsn,this.#Hr(e);let t=this.#mr+1>>>0;for(;this.#Er.has(t);){const e=this.#Er.get(t);this.#Er.delete(t),this.#mr=t,this.#Hr(e),t=this.#mr+1>>>0}}else this.#Er.has(e.tsn)||this.#Er.set(e.tsn,e)}#Hr(e){const t=`${e.streamId}:${e.unordered?"u":"o"}`;if(e.beginning&&e.ending)return void this.emit("message",{streamId:e.streamId,ppid:e.ppid,data:e.userData});let r=this.#gr.get(t);if(e.beginning)r={ppid:e.ppid,parts:[e.userData]},this.#gr.set(t,r);else{if(!r)return;r.parts.push(e.userData)}e.ending&&r&&(this.#gr.delete(t),this.emit("message",{streamId:e.streamId,ppid:r.ppid,data:Buffer.concat(r.parts)}))}#_r(){const e=[];if(this.#Er.size>0){const t=this.#mr,r=e=>e-t>>>0,s=(t,s)=>{const i=r(t),n=r(s);n<=65535&&e.push([i,n])},i=[...this.#Er.keys()].sort((e,t)=>Oe(e,t)?-1:1);let n=null,a=null;for(const e of i)null!==n?e!==a+1>>>0?(s(n,a),n=e,a=e):a=e:(n=e,a=e);null!==n&&s(n,a)}const t=function({cumulativeTSNAck:e,a_rwnd:t,gapBlocks:r=[],dupTSNs:s=[]}){const i=Buffer.alloc(12+4*r.length+4*s.length);i.writeUInt32BE(e>>>0,0),i.writeUInt32BE(t>>>0,4),i.writeUInt16BE(r.length,8),i.writeUInt16BE(s.length,10);let n=12;for(const[e,t]of r)i.writeUInt16BE(e,n),i.writeUInt16BE(t,n+2),n+=4;for(const e of s)i.writeUInt32BE(e>>>0,n),n+=4;return i}({cumulativeTSNAck:this.#mr>>>0,a_rwnd:Ne,gapBlocks:e}),r=Te(me.SACK,0,t);this.#Cr(this.#lr,[r])}#Nr(e){const t=function(e){const t=e.readUInt32BE(0),r=e.readUInt32BE(4),s=e.readUInt16BE(8),i=e.readUInt16BE(10),n=[];let a=12;for(let t=0;t<s;t++)n.push([e.readUInt16BE(a),e.readUInt16BE(a+2)]),a+=4;const o=[];for(let t=0;t<i;t++)o.push(e.readUInt32BE(a)),a+=4;return{cumulativeTSNAck:t,a_rwnd:r,gapBlocks:n,dupTSNs:o}}(e.body);for(const e of[...this.#pr.keys()])Ue(e,t.cumulativeTSNAck)&&this.#pr.delete(e);const r=t.cumulativeTSNAck+1>>>0;for(const[e,s]of t.gapBlocks)for(let t=e;t<=s;t++)this.#pr.delete(r+t-1>>>0)}#br(e){const t=Te(me.HEARTBEAT_ACK,0,e.body);this.#Cr(this.#lr,[t])}#Ur(){const e=Te(me.SHUTDOWN_ACK,0,Buffer.alloc(0));this.#Cr(this.#lr,[e]),this.#xr()}#Or(e){this.#vr(),this.state!==be.CLOSED&&(this.state=be.CLOSED,this.emit("error",new Error(e||"SCTP abort")),this.emit("close"))}shutdown(){if(this.state!==be.ESTABLISHED)return void this.#xr();const e=Te(me.SHUTDOWN,0,(()=>{const e=Buffer.alloc(4);return e.writeUInt32BE(this.#mr>>>0,0),e})());this.#Cr(this.#lr,[e]),this.#xr()}#xr(){this.#vr(),this.state!==be.CLOSED&&(this.state=be.CLOSED,this.emit("close"))}}const ke=Object.freeze({DATA_CHANNEL_ACK:2,DATA_CHANNEL_OPEN:3}),ve=Object.freeze({RELIABLE:0,RELIABLE_UNORDERED:128,PARTIAL_RELIABLE_REXMIT:1,PARTIAL_RELIABLE_REXMIT_UNORDERED:129,PARTIAL_RELIABLE_TIMED:2,PARTIAL_RELIABLE_TIMED_UNORDERED:130});class Le extends t{#Mr;#Fr;#Kr;constructor(e,t){super(),this.#Mr=e,this.#Fr=new Map,this.#Kr=t?0:1,this.#Mr.on("message",e=>this.#qr(e))}openChannel(e,t={}){let r=e.id;if(null==r&&(r=this.#Gr(),e.emit(A.SET_ID,r)),this.#Fr.set(r,{channel:e,acked:!1}),this.#zr(e,r,t),e.negotiated)this.#Fr.get(r).acked=!0,e.emit(A.OPEN);else{const s=function({channelType:e,priority:t=0,reliabilityParameter:r=0,label:s="",protocol:i=""}){const n=Buffer.from(s,"utf8"),a=Buffer.from(i,"utf8"),o=Buffer.alloc(12+n.length+a.length);return o.writeUInt8(ke.DATA_CHANNEL_OPEN,0),o.writeUInt8(e,1),o.writeUInt16BE(t,2),o.writeUInt32BE(r>>>0,4),o.writeUInt16BE(n.length,8),o.writeUInt16BE(a.length,10),n.copy(o,12),a.copy(o,12+n.length),o}({channelType:this.#$r(t),priority:0,reliabilityParameter:this.#jr(t),label:e.label,protocol:t.protocol||e.protocol||""});this.#Mr.sendData(r,ge.DCEP,s)}}#Gr(){let e=this.#Kr;for(;this.#Fr.has(e);)e+=2;return this.#Kr=e+2,e}#$r(e){const t=!1===e.ordered;return null!=e.maxRetransmits?t?ve.PARTIAL_RELIABLE_REXMIT_UNORDERED:ve.PARTIAL_RELIABLE_REXMIT:null!=e.maxPacketLifeTime?t?ve.PARTIAL_RELIABLE_TIMED_UNORDERED:ve.PARTIAL_RELIABLE_TIMED:t?ve.RELIABLE_UNORDERED:ve.RELIABLE}#jr(e){return null!=e.maxRetransmits?e.maxRetransmits>>>0:null!=e.maxPacketLifeTime?e.maxPacketLifeTime>>>0:0}#zr(e,t,r){const s=!1===r.ordered;e.on(A.SEND,(e,r)=>{let i;i=r?0===e.length?ge.BINARY_EMPTY:ge.BINARY:0===e.length?ge.STRING_EMPTY:ge.STRING;const n=0===e.length?Buffer.from([0]):e;this.#Mr.sendData(t,i,n,{unordered:s})})}#qr(e){if(e.ppid===ge.DCEP)return void this.#Vr(e);const t=this.#Fr.get(e.streamId);if(!t)return;const r=e.ppid===ge.BINARY||e.ppid===ge.BINARY_EMPTY||e.ppid===ge.BINARY_PARTIAL,s=e.ppid===ge.STRING_EMPTY||e.ppid===ge.BINARY_EMPTY?Buffer.alloc(0):e.data;t.channel.emit(A.RECEIVE,s,r)}#Vr(e){const t=(r=e.data).length>0?r.readUInt8(0):-1;var r;if(t===ke.DATA_CHANNEL_OPEN){const t=function(e){const t=e.readUInt8(1),r=e.readUInt16BE(2),s=e.readUInt32BE(4),i=e.readUInt16BE(8),n=e.readUInt16BE(10);return{channelType:t,priority:r,reliabilityParameter:s,label:e.slice(12,12+i).toString("utf8"),protocol:e.slice(12+i,12+i+n).toString("utf8"),unordered:!!(128&t)}}(e.data);this.#Mr.sendData(e.streamId,ge.DCEP,Buffer.from([ke.DATA_CHANNEL_ACK])),this.emit("open-request",{streamId:e.streamId,label:t.label,protocol:t.protocol,ordered:!t.unordered,channelType:t.channelType,reliabilityParameter:t.reliabilityParameter})}else if(t===ke.DATA_CHANNEL_ACK){const t=this.#Fr.get(e.streamId);t&&!t.acked&&(t.acked=!0,t.channel.emit(A.OPEN))}}acceptChannel(e,t){e.emit(A.SET_ID,t.streamId),this.#Fr.set(t.streamId,{channel:e,acked:!0}),this.#zr(e,t.streamId,{ordered:t.ordered}),e.emit(A.OPEN)}}class Pe extends t{#Wr;ice;dtls;sctp;dcm;#Yr;constructor(e){super(),this.#Wr=e,this.ice=new pe({role:e.iceRole,localUfrag:e.localUfrag,localPwd:e.localPwd}),this.dtls=null,this.sctp=null,this.dcm=null,this.#Yr=!1,this.ice.on("candidate",e=>this.emit("candidate",e)),this.ice.on("error",e=>this.#Xr(e)),this.ice.on("failed",()=>this.#Xr(new Error("ICE failed"))),this.ice.on("data",e=>{this.dtls&&this.dtls.handlePacket(e)}),this.ice.on("connected",()=>{this.emit("iceconnected"),this.#Qr()})}async gather(e={}){await this.ice.gather(e)}getLocalCandidates(){return this.ice.getLocalCandidates()}setRemote(e,t){this.ice.setRemoteCredentials(e,t),this.ice.start()}addRemoteCandidate(e){this.ice.addRemoteCandidate(e)}#Qr(){this.#Yr||(this.#Yr=!0,this.dtls=new oe({role:"client"===this.#Wr.dtlsRole?ne.CLIENT:ne.SERVER,certDer:this.#Wr.certDer,privateKey:this.#Wr.privateKey,verifyFingerprint:this.#Wr.verifyFingerprint,output:e=>{try{this.ice.send(e)}catch(e){this.#Xr(e)}}}),this.dtls.on("connect",()=>{this.emit("dtlsconnected"),this.#Zr()}),this.dtls.on("data",e=>{this.sctp&&this.sctp.receivePacket(e)}),this.dtls.on("error",e=>this.#Xr(e)),this.dtls.on("close",()=>this.emit("close")),this.dtls.start())}#Zr(){const e="client"===this.#Wr.dtlsRole,t=new De({isClient:e});this.sctp=t,t.on("output",e=>{try{this.dtls&&this.dtls.send(e)}catch(e){this.#Xr(e)}}),t.on("error",e=>this.#Xr(e)),t.on("close",()=>this.emit("close")),this.dcm=new Le(t,e),this.dcm.on("open-request",e=>this.emit("datachannel-request",e)),t.on("established",()=>{this.emit("sctpconnected"),this.emit("ready")}),t.start()}openChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.openChannel(e,t)}acceptChannel(e,t){if(!this.dcm)throw new Error("SCTP not ready");this.dcm.acceptChannel(e,t)}#Xr(e){this.listenerCount("error")>0&&this.emit("error",e)}isReady(){return!!this.sctp&&"established"===this.sctp.state}close(){if(this.sctp)try{this.sctp.shutdown()}catch{}if(this.dtls)try{this.dtls.close()}catch{}if(this.ice)try{this.ice.close()}catch{}}}const _e=Object.freeze({STABLE:"stable",HAVE_LOCAL_OFFER:"have-local-offer",HAVE_REMOTE_OFFER:"have-remote-offer",HAVE_LOCAL_PRANSWER:"have-local-pranswer",HAVE_REMOTE_PRANSWER:"have-remote-pranswer",CLOSED:"closed"}),He=Object.freeze({NEW:"new",GATHERING:"gathering",COMPLETE:"complete"}),xe=Object.freeze({NEW:"new",CONNECTING:"connecting",CONNECTED:"connected",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"});class Me extends t{#Jr;#es;#ts;#rs;#ss;#is;#ns;#as;#os;#cs;#hs;#ds;#ls;#us;#fs;#Fr;#Ht;constructor(t={}){super(),this.#Jr=t,this.#es=_e.STABLE,this.#ts=He.NEW,this.#rs=xe.NEW,this.#ss=null,this.#is=null,this.#ns=null,this.#as={usernameFragment:e.randomBytes(3).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,4).padEnd(4,"x"),password:e.randomBytes(18).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,24).padEnd(24,"x")},this.#os=null,this.#cs=[],this.#hs=null,this.#ds=null,this.#ls=!1,this.#us=!1,this.#fs=[],this.#Fr=new Set,this.#Ht=[]}async#ps(){return this.#ns||(this.#Jr.certificates&&this.#Jr.certificates[0]?this.#ns=this.#Jr.certificates[0]:this.#ns=await y.generateCertificate()),this.#ns}#ms(e,t){if(this.#ds)return this.#ds;const r=this.#ns;if(!r)throw new Error("Certificate not initialized");const s=r.getCertificateDer();if(!s)throw new Error("Certificate has no DER encoding");const i=new Pe({iceRole:e,dtlsRole:t,localUfrag:this.#as.usernameFragment,localPwd:this.#as.password,certDer:s,privateKey:r.getPrivateKeyObject(),verifyFingerprint:e=>this.#Es(e)});return i.on("candidate",e=>{const t={candidate:e.sdp,sdpMid:"0",sdpMLineIndex:0,usernameFragment:this.#as.usernameFragment};this.#Ht.push(t),this.emit("icecandidate",{candidate:t})}),i.on("iceconnected",()=>this.#gs(xe.CONNECTING)),i.on("sctpconnected",()=>this.#gs(xe.CONNECTED)),i.on("error",e=>{this.listenerCount("error")>0&&this.emit("error",e),this.#gs(xe.FAILED)}),i.on("close",()=>this.#gs(xe.DISCONNECTED)),i.on("datachannel-request",e=>{const t=new R(e.label,{ordered:e.ordered,protocol:e.protocol,id:e.streamId});i.acceptChannel(t,e),this.#Fr.add(t),this.emit("datachannel",{channel:t})}),i.on("ready",()=>{for(const{channel:e,init:t}of this.#fs)i.openChannel(e,t);this.#fs=[]}),this.#ds=i,i}#Es(e){return 0===this.#cs.length||this.#cs.some(t=>t.algorithm===e.algorithm&&t.value.toUpperCase()===e.value.toUpperCase())}createDataChannel(e,t={}){if(this.#us)throw new Error("RTCPeerConnection is closed");const r=new R(e,t);this.#Fr.add(r);const s={ordered:!1!==t.ordered,maxRetransmits:t.maxRetransmits,maxPacketLifeTime:t.maxPacketLifeTime,protocol:t.protocol||"",negotiated:t.negotiated||!1};return this.#ds&&this.#ds.isReady()?this.#ds.openChannel(r,s):this.#fs.push({channel:r,init:s}),setImmediate(()=>{this.#us||this.emit("negotiationneeded")}),r}async createOffer(){if(this.#us)throw new Error("RTCPeerConnection is closed");await this.#ps(),this.#ls=!0;const e=this.#Is(),t=(r={iceUfrag:this.#as.usernameFragment,icePwd:this.#as.password,fingerprint:e,setup:"actpass",candidates:[]},b({...r,setup:r.setup||"actpass"}));var r;return new N({type:w.OFFER,sdp:t})}async createAnswer(){if(this.#us)throw new Error("RTCPeerConnection is closed");if(!this.#is||"offer"!==this.#is.type)throw new Error("Cannot create answer without remote offer");await this.#ps();const e=this.#Is(),t=(r={iceUfrag:this.#as.usernameFragment,icePwd:this.#as.password,fingerprint:e,setup:"active",candidates:[]},b({...r,setup:r.setup||"active"}));var r;return new N({type:w.ANSWER,sdp:t})}#Is(){const e=this.#ns;if(!e)throw new Error("Certificate not initialized");const t=e.getFingerprints();return t.find(e=>"sha-256"===e.algorithm)||t[0]}async setLocalDescription(e){if(this.#us)throw new Error("RTCPeerConnection is closed");const t=e||(this.#es===_e.HAVE_REMOTE_OFFER?await this.createAnswer():await this.createOffer());await this.#ps(),this.#ss=new N({type:t.type??void 0,sdp:t.sdp??void 0}),"offer"===t.type?this.#es=_e.HAVE_LOCAL_OFFER:"answer"===t.type&&(this.#es=_e.STABLE),this.#Ts(t,!0),this.#ts=He.GATHERING,this.emit("icegatheringstatechange"),this.#ds&&(await this.#ds.gather({iceServers:this.#Jr.iceServers||[],iceTransportPolicy:this.#Jr.iceTransportPolicy||"all"}),this.#ts=He.COMPLETE,this.emit("icegatheringstatechange"),this.emit("icecandidate",{candidate:null}),this.#Cs()),this.emit("signalingstatechange")}async setRemoteDescription(e){if(this.#us)throw new Error("RTCPeerConnection is closed");if(!e||!e.sdp)throw new Error("Invalid session description");await this.#ps(),this.#is=new N(e),"offer"===e.type?this.#es=_e.HAVE_REMOTE_OFFER:"answer"===e.type&&(this.#es=_e.STABLE),this.#os=function(e){const t={usernameFragment:null,password:null};for(const r of e.split(/\r?\n/))r.startsWith("a=ice-ufrag:")?t.usernameFragment=r.slice(12).trim():r.startsWith("a=ice-pwd:")&&(t.password=r.slice(10).trim());return t}(e.sdp);const t=function(e){const t={role:"auto",fingerprints:[]};for(const r of e.split(/\r?\n/))if(r.startsWith("a=setup:")){const e=r.slice(8).trim();t.role="active"===e?"client":"passive"===e?"server":"actpass",t.setup=e}else if(r.startsWith("a=fingerprint:")){const e=r.slice(14).trim().split(/\s+/);2===e.length&&t.fingerprints.push({algorithm:e[0].toLowerCase(),value:e[1].toUpperCase()})}return t}(e.sdp);if(this.#cs=t.fingerprints,this.#hs=t.setup??null,this.#Ts(e,!1),this.#ds&&this.#os.usernameFragment){this.#ds.setRemote(this.#os.usernameFragment,this.#os.password??"");for(const t of function(e){const t=[];for(const r of e.split(/\r?\n/)){if(!r.startsWith("a=candidate:"))continue;const e=O(r.slice(2));e&&t.push(e)}return t}(e.sdp))this.#ds.addRemoteCandidate(t)}this.#Cs(),this.emit("signalingstatechange")}#Ts(e,t){if(this.#ds)return;const r=this.#ls?"controlling":"controlled";let s;s=this.#ls?"active"===this.#hs?"server":"passive"===this.#hs?"client":"server":"client",this.#ms(r,s)}#Cs(){this.#ds&&this.#os&&this.#os.usernameFragment&&this.#ds.setRemote(this.#os.usernameFragment,this.#os.password??"")}async addIceCandidate(e){if(this.#us)throw new Error("RTCPeerConnection is closed");if(!e||"string"!=typeof e&&""===e.candidate)return;const t=O("string"==typeof e?e:e.candidate||"");t&&this.#ds&&this.#ds.addRemoteCandidate(t)}#gs(e){this.#rs!==e&&(this.#rs=e,this.emit("connectionstatechange"),this.emit("iceconnectionstatechange"))}getConfiguration(){return{...this.#Jr}}setConfiguration(e){if(this.#us)throw new Error("RTCPeerConnection is closed");this.#Jr={...e}}close(){if(!this.#us){this.#us=!0,this.#es=_e.CLOSED;for(const e of this.#Fr)try{e.close()}catch(e){}if(this.#ds)try{this.#ds.close()}catch(e){}this.#gs(xe.CLOSED),this.emit("signalingstatechange")}}get signalingState(){return this.#es}get iceGatheringState(){return this.#ts}get iceConnectionState(){return this.#rs===xe.CONNECTED?"connected":this.#rs===xe.CONNECTING?"checking":this.#rs===xe.FAILED?"failed":"new"}get connectionState(){return this.#rs}get localDescription(){return this.#ss}get remoteDescription(){return this.#is}get currentLocalDescription(){return this.#ss}get currentRemoteDescription(){return this.#is}get pendingLocalDescription(){return this.#es===_e.STABLE?null:this.#ss}get pendingRemoteDescription(){return this.#es===_e.STABLE?null:this.#is}get canTrickleIceCandidates(){return!0}get sctp(){return this.#ds?this.#ds.sctp:null}}const Fe="2.0.9";export{n as ByteBufferQueue,y as RTCCertificate,R as RTCDataChannel,B as RTCDataChannelState,o as RTCError,c as RTCIceCandidate,He as RTCIceGatheringState,Me as RTCPeerConnection,xe as RTCPeerConnectionState,w as RTCSdpType,N as RTCSessionDescription,_e as RTCSignalingState,Fe as version};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-rtc-connection",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "WebRTC DataChannel implementation for Node.js with STUN, TURN, NAT traversal, and encryption. Pure Node.js, no native dependencies.",
5
5
  "keywords": [
6
6
  "webrtc",
@@ -73,6 +73,11 @@ interface IceServer {
73
73
  urls: string | string[];
74
74
  username?: string;
75
75
  credential?: string;
76
+ /**
77
+ * Validate the server's TLS certificate for TURN-over-TLS (turns: + tcp).
78
+ * Defaults to true; set false to accept self-signed certs (insecure).
79
+ */
80
+ rejectUnauthorized?: boolean;
76
81
  }
77
82
  /** Options accepted by {@link IceAgent#gather}. */
78
83
  interface GatherOptions {
@@ -23,6 +23,12 @@ interface STUNClientOptions {
23
23
  transport?: string;
24
24
  /** Wrap the link to the server in DTLS (TURN-over-DTLS, the `turns:` scheme) */
25
25
  secure?: boolean;
26
+ /**
27
+ * Validate the TURN server's TLS certificate (TURN-over-TLS only). Defaults
28
+ * to `true`. Set `false` to accept self-signed / otherwise unverifiable
29
+ * server certificates — insecure, intended for local/test servers only.
30
+ */
31
+ rejectUnauthorized?: boolean;
26
32
  /** Additional query parameters from URL */
27
33
  params?: Record<string, unknown>;
28
34
  }