UNPKG

@klever-one/web-sdk

Version:

Web SDK for integrating real-time room management and streaming functionality into web applications

1,115 lines 436 kB
"use client"; var Fn = Object.defineProperty; var Bt = (i) => { throw TypeError(i); }; var _n = (i, e, t) => e in i ? Fn(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t; var c = (i, e, t) => _n(i, typeof e != "symbol" ? e + "" : e, t), zt = (i, e, t) => e.has(i) || Bt("Cannot " + t); var x = (i, e, t) => (zt(i, e, "read from private field"), t ? t.call(i) : e.get(i)), st = (i, e, t) => e.has(i) ? Bt("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(i) : e.set(i, t), ve = (i, e, t, s) => (zt(i, e, "write to private field"), s ? s.call(i, t) : e.set(i, t), t); const Ht = "initialData", Wt = "azureSttOpenai", Fe = "openai", Un = "occupyingResource"; const Gt = "openai", Bn = "X-Nlp-Api-Key", zn = "Pending", Hn = "Failed"; const Wn = { 1: "av_2", // 차누 2: "av_5", // 유리 3: "av_3", // 크리스 4: "av_4", // 마이클 5: "av_1" // 제니 }, Gn = { "en-US": "Introduce yourself in exactly 2–3 sentences. Do not exceed 3 sentences. Be concise and clear about your main role and how you can help.", "ko-KR": "자신을 반드시 2~3문장으로만 간단히 소개해주세요. 3문장을 넘기지 말고, 주요 역할과 어떻게 도울 수 있는지만 간결하게 설명해주세요." }, Vn = new Proxy(Gn, { get(i, e) { return typeof e == "string" && e in i ? i[e] : i["ko-KR"]; } }), $n = 60 * 1e3; var nt = { exports: {} }, Vt; function Qn() { return Vt || (Vt = 1, (function(i) { const e = {}; e.generateIdentifier = function() { return Math.random().toString(36).substring(2, 12); }, e.localCName = e.generateIdentifier(), e.splitLines = function(t) { return t.trim().split(` `).map((s) => s.trim()); }, e.splitSections = function(t) { return t.split(` m=`).map((n, r) => (r > 0 ? "m=" + n : n).trim() + `\r `); }, e.getDescription = function(t) { const s = e.splitSections(t); return s && s[0]; }, e.getMediaSections = function(t) { const s = e.splitSections(t); return s.shift(), s; }, e.matchPrefix = function(t, s) { return e.splitLines(t).filter((n) => n.indexOf(s) === 0); }, e.parseCandidate = function(t) { let s; t.indexOf("a=candidate:") === 0 ? s = t.substring(12).split(" ") : s = t.substring(10).split(" "); const n = { foundation: s[0], component: { 1: "rtp", 2: "rtcp" }[s[1]] || s[1], protocol: s[2].toLowerCase(), priority: parseInt(s[3], 10), ip: s[4], address: s[4], // address is an alias for ip. port: parseInt(s[5], 10), // skip parts[6] == 'typ' type: s[7] }; for (let r = 8; r < s.length; r += 2) switch (s[r]) { case "raddr": n.relatedAddress = s[r + 1]; break; case "rport": n.relatedPort = parseInt(s[r + 1], 10); break; case "tcptype": n.tcpType = s[r + 1]; break; case "ufrag": n.ufrag = s[r + 1], n.usernameFragment = s[r + 1]; break; default: n[s[r]] === void 0 && (n[s[r]] = s[r + 1]); break; } return n; }, e.writeCandidate = function(t) { const s = []; s.push(t.foundation); const n = t.component; n === "rtp" ? s.push(1) : n === "rtcp" ? s.push(2) : s.push(n), s.push(t.protocol.toUpperCase()), s.push(t.priority), s.push(t.address || t.ip), s.push(t.port); const r = t.type; return s.push("typ"), s.push(r), r !== "host" && t.relatedAddress && t.relatedPort && (s.push("raddr"), s.push(t.relatedAddress), s.push("rport"), s.push(t.relatedPort)), t.tcpType && t.protocol.toLowerCase() === "tcp" && (s.push("tcptype"), s.push(t.tcpType)), (t.usernameFragment || t.ufrag) && (s.push("ufrag"), s.push(t.usernameFragment || t.ufrag)), "candidate:" + s.join(" "); }, e.parseIceOptions = function(t) { return t.substring(14).split(" "); }, e.parseRtpMap = function(t) { let s = t.substring(9).split(" "); const n = { payloadType: parseInt(s.shift(), 10) // was: id }; return s = s[0].split("/"), n.name = s[0], n.clockRate = parseInt(s[1], 10), n.channels = s.length === 3 ? parseInt(s[2], 10) : 1, n.numChannels = n.channels, n; }, e.writeRtpMap = function(t) { let s = t.payloadType; t.preferredPayloadType !== void 0 && (s = t.preferredPayloadType); const n = t.channels || t.numChannels || 1; return "a=rtpmap:" + s + " " + t.name + "/" + t.clockRate + (n !== 1 ? "/" + n : "") + `\r `; }, e.parseExtmap = function(t) { const s = t.substring(9).split(" "); return { id: parseInt(s[0], 10), direction: s[0].indexOf("/") > 0 ? s[0].split("/")[1] : "sendrecv", uri: s[1], attributes: s.slice(2).join(" ") }; }, e.writeExtmap = function(t) { return "a=extmap:" + (t.id || t.preferredId) + (t.direction && t.direction !== "sendrecv" ? "/" + t.direction : "") + " " + t.uri + (t.attributes ? " " + t.attributes : "") + `\r `; }, e.parseFmtp = function(t) { const s = {}; let n; const r = t.substring(t.indexOf(" ") + 1).split(";"); for (let a = 0; a < r.length; a++) n = r[a].trim().split("="), s[n[0].trim()] = n[1]; return s; }, e.writeFmtp = function(t) { let s = "", n = t.payloadType; if (t.preferredPayloadType !== void 0 && (n = t.preferredPayloadType), t.parameters && Object.keys(t.parameters).length) { const r = []; Object.keys(t.parameters).forEach((a) => { t.parameters[a] !== void 0 ? r.push(a + "=" + t.parameters[a]) : r.push(a); }), s += "a=fmtp:" + n + " " + r.join(";") + `\r `; } return s; }, e.parseRtcpFb = function(t) { const s = t.substring(t.indexOf(" ") + 1).split(" "); return { type: s.shift(), parameter: s.join(" ") }; }, e.writeRtcpFb = function(t) { let s = "", n = t.payloadType; return t.preferredPayloadType !== void 0 && (n = t.preferredPayloadType), t.rtcpFeedback && t.rtcpFeedback.length && t.rtcpFeedback.forEach((r) => { s += "a=rtcp-fb:" + n + " " + r.type + (r.parameter && r.parameter.length ? " " + r.parameter : "") + `\r `; }), s; }, e.parseSsrcMedia = function(t) { const s = t.indexOf(" "), n = { ssrc: parseInt(t.substring(7, s), 10) }, r = t.indexOf(":", s); return r > -1 ? (n.attribute = t.substring(s + 1, r), n.value = t.substring(r + 1)) : n.attribute = t.substring(s + 1), n; }, e.parseSsrcGroup = function(t) { const s = t.substring(13).split(" "); return { semantics: s.shift(), ssrcs: s.map((n) => parseInt(n, 10)) }; }, e.getMid = function(t) { const s = e.matchPrefix(t, "a=mid:")[0]; if (s) return s.substring(6); }, e.parseFingerprint = function(t) { const s = t.substring(14).split(" "); return { algorithm: s[0].toLowerCase(), // algorithm is case-sensitive in Edge. value: s[1].toUpperCase() // the definition is upper-case in RFC 4572. }; }, e.getDtlsParameters = function(t, s) { return { role: "auto", fingerprints: e.matchPrefix( t + s, "a=fingerprint:" ).map(e.parseFingerprint) }; }, e.writeDtlsParameters = function(t, s) { let n = "a=setup:" + s + `\r `; return t.fingerprints.forEach((r) => { n += "a=fingerprint:" + r.algorithm + " " + r.value + `\r `; }), n; }, e.parseCryptoLine = function(t) { const s = t.substring(9).split(" "); return { tag: parseInt(s[0], 10), cryptoSuite: s[1], keyParams: s[2], sessionParams: s.slice(3) }; }, e.writeCryptoLine = function(t) { return "a=crypto:" + t.tag + " " + t.cryptoSuite + " " + (typeof t.keyParams == "object" ? e.writeCryptoKeyParams(t.keyParams) : t.keyParams) + (t.sessionParams ? " " + t.sessionParams.join(" ") : "") + `\r `; }, e.parseCryptoKeyParams = function(t) { if (t.indexOf("inline:") !== 0) return null; const s = t.substring(7).split("|"); return { keyMethod: "inline", keySalt: s[0], lifeTime: s[1], mkiValue: s[2] ? s[2].split(":")[0] : void 0, mkiLength: s[2] ? s[2].split(":")[1] : void 0 }; }, e.writeCryptoKeyParams = function(t) { return t.keyMethod + ":" + t.keySalt + (t.lifeTime ? "|" + t.lifeTime : "") + (t.mkiValue && t.mkiLength ? "|" + t.mkiValue + ":" + t.mkiLength : ""); }, e.getCryptoParameters = function(t, s) { return e.matchPrefix( t + s, "a=crypto:" ).map(e.parseCryptoLine); }, e.getIceParameters = function(t, s) { const n = e.matchPrefix( t + s, "a=ice-ufrag:" )[0], r = e.matchPrefix( t + s, "a=ice-pwd:" )[0]; return n && r ? { usernameFragment: n.substring(12), password: r.substring(10) } : null; }, e.writeIceParameters = function(t) { let s = "a=ice-ufrag:" + t.usernameFragment + `\r a=ice-pwd:` + t.password + `\r `; return t.iceLite && (s += `a=ice-lite\r `), s; }, e.parseRtpParameters = function(t) { const s = { codecs: [], headerExtensions: [], fecMechanisms: [], rtcp: [] }, r = e.splitLines(t)[0].split(" "); s.profile = r[2]; for (let l = 3; l < r.length; l++) { const d = r[l], u = e.matchPrefix( t, "a=rtpmap:" + d + " " )[0]; if (u) { const m = e.parseRtpMap(u), p = e.matchPrefix( t, "a=fmtp:" + d + " " ); switch (m.parameters = p.length ? e.parseFmtp(p[0]) : {}, m.rtcpFeedback = e.matchPrefix( t, "a=rtcp-fb:" + d + " " ).map(e.parseRtcpFb), s.codecs.push(m), m.name.toUpperCase()) { case "RED": case "ULPFEC": s.fecMechanisms.push(m.name.toUpperCase()); break; } } } e.matchPrefix(t, "a=extmap:").forEach((l) => { s.headerExtensions.push(e.parseExtmap(l)); }); const a = e.matchPrefix(t, "a=rtcp-fb:* ").map(e.parseRtcpFb); return s.codecs.forEach((l) => { a.forEach((d) => { l.rtcpFeedback.find((m) => m.type === d.type && m.parameter === d.parameter) || l.rtcpFeedback.push(d); }); }), s; }, e.writeRtpDescription = function(t, s) { let n = ""; n += "m=" + t + " ", n += s.codecs.length > 0 ? "9" : "0", n += " " + (s.profile || "UDP/TLS/RTP/SAVPF") + " ", n += s.codecs.map((a) => a.preferredPayloadType !== void 0 ? a.preferredPayloadType : a.payloadType).join(" ") + `\r `, n += `c=IN IP4 0.0.0.0\r `, n += `a=rtcp:9 IN IP4 0.0.0.0\r `, s.codecs.forEach((a) => { n += e.writeRtpMap(a), n += e.writeFmtp(a), n += e.writeRtcpFb(a); }); let r = 0; return s.codecs.forEach((a) => { a.maxptime > r && (r = a.maxptime); }), r > 0 && (n += "a=maxptime:" + r + `\r `), s.headerExtensions && s.headerExtensions.forEach((a) => { n += e.writeExtmap(a); }), n; }, e.parseRtpEncodingParameters = function(t) { const s = [], n = e.parseRtpParameters(t), r = n.fecMechanisms.indexOf("RED") !== -1, a = n.fecMechanisms.indexOf("ULPFEC") !== -1, l = e.matchPrefix(t, "a=ssrc:").map((S) => e.parseSsrcMedia(S)).filter((S) => S.attribute === "cname"), d = l.length > 0 && l[0].ssrc; let u; const m = e.matchPrefix(t, "a=ssrc-group:FID").map((S) => S.substring(17).split(" ").map((b) => parseInt(b, 10))); m.length > 0 && m[0].length > 1 && m[0][0] === d && (u = m[0][1]), n.codecs.forEach((S) => { if (S.name.toUpperCase() === "RTX" && S.parameters.apt) { let C = { ssrc: d, codecPayloadType: parseInt(S.parameters.apt, 10) }; d && u && (C.rtx = { ssrc: u }), s.push(C), r && (C = JSON.parse(JSON.stringify(C)), C.fec = { ssrc: d, mechanism: a ? "red+ulpfec" : "red" }, s.push(C)); } }), s.length === 0 && d && s.push({ ssrc: d }); let p = e.matchPrefix(t, "b="); return p.length && (p[0].indexOf("b=TIAS:") === 0 ? p = parseInt(p[0].substring(7), 10) : p[0].indexOf("b=AS:") === 0 ? p = parseInt(p[0].substring(5), 10) * 1e3 * 0.95 - 2e3 * 8 : p = void 0, s.forEach((S) => { S.maxBitrate = p; })), s; }, e.parseRtcpParameters = function(t) { const s = {}, n = e.matchPrefix(t, "a=ssrc:").map((l) => e.parseSsrcMedia(l)).filter((l) => l.attribute === "cname")[0]; n && (s.cname = n.value, s.ssrc = n.ssrc); const r = e.matchPrefix(t, "a=rtcp-rsize"); s.reducedSize = r.length > 0, s.compound = r.length === 0; const a = e.matchPrefix(t, "a=rtcp-mux"); return s.mux = a.length > 0, s; }, e.writeRtcpParameters = function(t) { let s = ""; return t.reducedSize && (s += `a=rtcp-rsize\r `), t.mux && (s += `a=rtcp-mux\r `), t.ssrc !== void 0 && t.cname && (s += "a=ssrc:" + t.ssrc + " cname:" + t.cname + `\r `), s; }, e.parseMsid = function(t) { let s; const n = e.matchPrefix(t, "a=msid:"); if (n.length === 1) return s = n[0].substring(7).split(" "), { stream: s[0], track: s[1] }; const r = e.matchPrefix(t, "a=ssrc:").map((a) => e.parseSsrcMedia(a)).filter((a) => a.attribute === "msid"); if (r.length > 0) return s = r[0].value.split(" "), { stream: s[0], track: s[1] }; }, e.parseSctpDescription = function(t) { const s = e.parseMLine(t), n = e.matchPrefix(t, "a=max-message-size:"); let r; n.length > 0 && (r = parseInt(n[0].substring(19), 10)), isNaN(r) && (r = 65536); const a = e.matchPrefix(t, "a=sctp-port:"); if (a.length > 0) return { port: parseInt(a[0].substring(12), 10), protocol: s.fmt, maxMessageSize: r }; const l = e.matchPrefix(t, "a=sctpmap:"); if (l.length > 0) { const d = l[0].substring(10).split(" "); return { port: parseInt(d[0], 10), protocol: d[1], maxMessageSize: r }; } }, e.writeSctpDescription = function(t, s) { let n = []; return t.protocol !== "DTLS/SCTP" ? n = [ "m=" + t.kind + " 9 " + t.protocol + " " + s.protocol + `\r `, `c=IN IP4 0.0.0.0\r `, "a=sctp-port:" + s.port + `\r ` ] : n = [ "m=" + t.kind + " 9 " + t.protocol + " " + s.port + `\r `, `c=IN IP4 0.0.0.0\r `, "a=sctpmap:" + s.port + " " + s.protocol + ` 65535\r ` ], s.maxMessageSize !== void 0 && n.push("a=max-message-size:" + s.maxMessageSize + `\r `), n.join(""); }, e.generateSessionId = function() { return Math.random().toString().substr(2, 22); }, e.writeSessionBoilerplate = function(t, s, n) { let r; const a = s !== void 0 ? s : 2; return t ? r = t : r = e.generateSessionId(), `v=0\r o=` + (n || "thisisadapterortc") + " " + r + " " + a + ` IN IP4 127.0.0.1\r s=-\r t=0 0\r `; }, e.getDirection = function(t, s) { const n = e.splitLines(t); for (let r = 0; r < n.length; r++) switch (n[r]) { case "a=sendrecv": case "a=sendonly": case "a=recvonly": case "a=inactive": return n[r].substring(2); } return s ? e.getDirection(s) : "sendrecv"; }, e.getKind = function(t) { return e.splitLines(t)[0].split(" ")[0].substring(2); }, e.isRejected = function(t) { return t.split(" ", 2)[1] === "0"; }, e.parseMLine = function(t) { const n = e.splitLines(t)[0].substring(2).split(" "); return { kind: n[0], port: parseInt(n[1], 10), protocol: n[2], fmt: n.slice(3).join(" ") }; }, e.parseOLine = function(t) { const n = e.matchPrefix(t, "o=")[0].substring(2).split(" "); return { username: n[0], sessionId: n[1], sessionVersion: parseInt(n[2], 10), netType: n[3], addressType: n[4], address: n[5] }; }, e.isValidSDP = function(t) { if (typeof t != "string" || t.length === 0) return !1; const s = e.splitLines(t); for (let n = 0; n < s.length; n++) if (s[n].length < 2 || s[n].charAt(1) !== "=") return !1; return !0; }, i.exports = e; })(nt)), nt.exports; } var $t = /* @__PURE__ */ Qn(), H, I, Ve = { d: (i, e) => { for (var t in e) Ve.o(e, t) && !Ve.o(i, t) && Object.defineProperty(i, t, { enumerable: !0, get: e[t] }); }, o: (i, e) => Object.prototype.hasOwnProperty.call(i, e) }, W = {}; Ve.d(W, { Dz: () => sn, g$: () => Rs, Lt: () => Ts, Q9: () => ws, qf: () => ft, hV: () => ln, z$: () => Bi, J0: () => vt, De: () => ui, $C: () => de, al: () => Ds, _W: () => Ns, Gv: () => qs, m: () => Xs, tz: () => Os, Nu: () => an, zg: () => hn, vp: () => tn, vU: () => h, wF: () => Vs, rv: () => nn, Nh: () => rn, ss: () => dn, qW: () => Js, QL: () => js, cf: () => mn, eM: () => Gs, Yd: () => o, Tk: () => f, iM: () => Cs, qy: () => j, ce: () => si, sK: () => g, Ok: () => w, q5: () => on, g: () => Ui, xl: () => Hs, I: () => Ws, bx: () => St, dD: () => Zs, Ib: () => Oe, Az: () => k, Iw: () => G, qY: () => pt, db: () => bs, mR: () => Ee, Tn: () => gt, rV: () => $s, gh: () => _s, Mi: () => Us, j: () => Bs, YB: () => zs, Yt: () => Ks, i5: () => Qs, x_: () => Q, Am: () => yt, eR: () => Ms, r8: () => Fs, u3: () => un, vd: () => Is, iV: () => As, jZ: () => Ps, SW: () => xs, ZH: () => Ls, Ni: () => gn, lh: () => ks, ZP: () => en, bq: () => Es, $f: () => pn, eu: () => Ys, Ax: () => oi, Mc: () => ai }); class o { static GetStackTrace() { const e = new Error(); let t = "No Stack Available for this browser"; return e.stack && (t = e.stack.toString().replace(/Error/g, "")), t; } static SetLoggerVerbosity(e) { this.verboseLogLevel != null && (this.verboseLogLevel = e); } static Log(e, t, s) { if (s > this.verboseLogLevel) return; const n = `Level: Log Msg: ${t} Caller: ${e}`; } static Info(e, t, s) { if (s > this.verboseLogLevel) return; const n = `Level: Info Msg: ${t}`; console.info(n); } static Error(e, t) { const s = `Level: Error Msg: ${t} Caller: ${e}`; } static Warning(e, t) { const s = `Level: Warning Caller: ${e} Msg: ${t}`; } } o.verboseLogLevel = 5, (function(i) { i.LIST_STREAMERS = "listStreamers", i.SUBSCRIBE = "subscribe", i.UNSUBSCRIBE = "unsubscribe", i.ICE_CANDIDATE = "iceCandidate", i.OFFER = "offer", i.ANSWER = "answer", i.DATACHANNELREQUEST = "dataChannelRequest", i.SFURECVDATACHANNELREADY = "peerDataChannelsReady", i.PONG = "pong"; })(H || (H = {})); let j = class { sendFilter(e, t) { return t; } payload() { return o.Log(o.GetStackTrace(), `Sending => ` + JSON.stringify(this, this.sendFilter, 4), 6), JSON.stringify(this, this.sendFilter); } }, Kn = class extends j { constructor() { super(), this.type = H.LIST_STREAMERS; } }, jn = class extends j { constructor(e) { super(), this.type = H.SUBSCRIBE, this.streamerId = e; } }, qn = class extends j { constructor() { super(), this.type = H.UNSUBSCRIBE; } }, Xn = class extends j { constructor(e) { super(), this.type = H.PONG, this.time = e; } }, Jn = class extends j { constructor(e, t) { super(), this.type = H.OFFER, this.minBitrate = 0, this.maxBitrate = 0, e && (this.type = e.type, this.sdp = e.sdp, this.minBitrate = t.minBitrateBps, this.maxBitrate = t.maxBitrateBps); } sendFilter(e, t) { if (e != "minBitrate" && e != "maxBitrate" || !(t <= 0)) return t; } }, Yn = class extends j { constructor(e, t) { super(), this.type = H.ANSWER, this.minBitrate = 0, this.maxBitrate = 0, e && (this.type = e.type, this.sdp = e.sdp, this.minBitrate = t.minBitrateBps, this.maxBitrate = t.maxBitrateBps); } sendFilter(e, t) { if (e != "minBitrate" && e != "maxBitrate" || !(t <= 0)) return t; } }, Zn = class extends j { constructor() { super(), this.type = H.DATACHANNELREQUEST; } }, ei = class extends j { constructor() { super(), this.type = H.SFURECVDATACHANNELREADY; } }, ti = class { constructor(e) { this.type = H.ICE_CANDIDATE, this.candidate = e; } payload() { return o.Log(o.GetStackTrace(), `Sending => ` + JSON.stringify(this, void 0, 4), 6), JSON.stringify(this); } }; (function(i) { i.CONFIG = "config", i.STREAMER_LIST = "streamerList", i.STREAMER_ID_CHANGED = "streamerIDChanged", i.PLAYER_COUNT = "playerCount", i.OFFER = "offer", i.ANSWER = "answer", i.ICE_CANDIDATE = "iceCandidate", i.PEER_DATA_CHANNELS = "peerDataChannels", i.PING = "ping", i.WARNING = "warning"; })(I || (I = {})); let Cs = class { }, si = class extends Cs { }, gt = class { constructor() { this.FromUEMessageHandlers = /* @__PURE__ */ new Map(); } addMessageHandler(e, t) { this.FromUEMessageHandlers.set(e, t); } handleMessage(e, t) { this.FromUEMessageHandlers.has(e) ? this.FromUEMessageHandlers.get(e)(t) : o.Error(o.GetStackTrace(), `Message type of ${e} does not have a message handler registered on the frontend - ignoring message.`); } static setupDefaultHandlers(e) { e.signallingProtocol.addMessageHandler(I.PING, ((t) => { const s = new Xn((/* @__PURE__ */ new Date()).getTime()).payload(); o.Log(o.GetStackTrace(), I.PING + ": " + t, 6), e.webSocket.send(s); })), e.signallingProtocol.addMessageHandler(I.CONFIG, ((t) => { o.Log(o.GetStackTrace(), I.CONFIG, 6); const s = JSON.parse(t); e.onConfig(s); })), e.signallingProtocol.addMessageHandler(I.STREAMER_LIST, ((t) => { o.Log(o.GetStackTrace(), I.STREAMER_LIST, 6); const s = JSON.parse(t); e.onStreamerList(s); })), e.signallingProtocol.addMessageHandler(I.STREAMER_ID_CHANGED, ((t) => { o.Log(o.GetStackTrace(), I.STREAMER_ID_CHANGED, 6); const s = JSON.parse(t); e.onStreamerIDChanged(s); })), e.signallingProtocol.addMessageHandler(I.PLAYER_COUNT, ((t) => { o.Log(o.GetStackTrace(), I.PLAYER_COUNT, 6); const s = JSON.parse(t); o.Log(o.GetStackTrace(), "Player Count: " + s.count, 6), e.onPlayerCount(s); })), e.signallingProtocol.addMessageHandler(I.ANSWER, ((t) => { o.Log(o.GetStackTrace(), I.ANSWER, 6); const s = JSON.parse(t); e.onWebRtcAnswer(s); })), e.signallingProtocol.addMessageHandler(I.OFFER, ((t) => { o.Log(o.GetStackTrace(), I.OFFER, 6); const s = JSON.parse(t); e.onWebRtcOffer(s); })), e.signallingProtocol.addMessageHandler(I.ICE_CANDIDATE, ((t) => { o.Log(o.GetStackTrace(), I.ICE_CANDIDATE, 6); const s = JSON.parse(t); e.onIceCandidate(s.candidate); })), e.signallingProtocol.addMessageHandler(I.WARNING, ((t) => { o.Warning(o.GetStackTrace(), `Warning received: ${t}`); })), e.signallingProtocol.addMessageHandler(I.PEER_DATA_CHANNELS, ((t) => { o.Log(o.GetStackTrace(), I.PEER_DATA_CHANNELS, 6); const s = JSON.parse(t); e.onWebRtcPeerDataChannels(s); })); } }, Es = class { constructor() { this.WS_OPEN_STATE = 1, this.onOpen = new EventTarget(), this.onClose = new EventTarget(), this.signallingProtocol = new gt(), gt.setupDefaultHandlers(this); } connect(e) { o.Log(o.GetStackTrace(), e, 6); try { return this.webSocket = new WebSocket(e), this.webSocket.onopen = (t) => this.handleOnOpen(t), this.webSocket.onerror = () => this.handleOnError(), this.webSocket.onclose = (t) => this.handleOnClose(t), this.webSocket.onmessage = (t) => this.handleOnMessage(t), this.webSocket.onmessagebinary = (t) => this.handleOnMessageBinary(t), !0; } catch (t) { return o.Error(t, t), !1; } } handleOnMessageBinary(e) { e && e.data && e.data.text().then(((t) => { const s = new MessageEvent("messageFromBinary", { data: t }); this.handleOnMessage(s); })).catch(((t) => { o.Error(o.GetStackTrace(), `Failed to parse binary blob from websocket, reason: ${t}`); })); } handleOnMessage(e) { if (e.data && e.data instanceof Blob) return void this.handleOnMessageBinary(e); const t = JSON.parse(e.data); o.Log(o.GetStackTrace(), `received => ` + JSON.stringify(JSON.parse(e.data), void 0, 4), 6), this.signallingProtocol.handleMessage(t.type, e.data); } handleOnOpen(e) { o.Log(o.GetStackTrace(), "Connected to the signalling server via WebSocket", 6), this.onOpen.dispatchEvent(new Event("open")); } handleOnError() { o.Error(o.GetStackTrace(), "WebSocket error"); } handleOnClose(e) { o.Log(o.GetStackTrace(), "Disconnected to the signalling server via WebSocket: " + JSON.stringify(e.code) + " - " + e.reason), this.onClose.dispatchEvent(new CustomEvent("close", { detail: e })); } requestStreamerList() { const e = new Kn(); this.webSocket.send(e.payload()); } sendSubscribe(e) { const t = new jn(e); this.webSocket.send(t.payload()); } sendUnsubscribe() { const e = new qn(); this.webSocket.send(e.payload()); } sendWebRtcOffer(e, t) { const s = new Jn(e, t); this.webSocket.send(s.payload()); } sendWebRtcAnswer(e, t) { const s = new Yn(e, t); this.webSocket.send(s.payload()); } sendWebRtcDatachannelRequest() { const e = new Zn(); this.webSocket.send(e.payload()); } sendSFURecvDataChannelReady() { const e = new ei(); this.webSocket.send(e.payload()); } sendIceCandidate(e) { if (o.Log(o.GetStackTrace(), "Sending Ice Candidate"), this.webSocket && this.webSocket.readyState === this.WS_OPEN_STATE) { const t = new ti(e); this.webSocket.send(t.payload()); } } close() { var e; (e = this.webSocket) === null || e === void 0 || e.close(); } onConfig(e) { } onStreamerList(e) { } onStreamerIDChanged(e) { } onIceCandidate(e) { } onWebRtcAnswer(e) { } onWebRtcOffer(e) { } onWebRtcPeerDataChannels(e) { } onPlayerCount(e) { } }, ni = class { constructor(e) { this.videoElementProvider = e, this.audioElement = document.createElement("Audio"), this.videoElementProvider.setAudioElement(this.audioElement); } handleOnTrack(e) { if (o.Log(o.GetStackTrace(), "handleOnTrack " + JSON.stringify(e.streams), 6), e.track.id == "probator") return; const t = this.videoElementProvider.getVideoElement(); if (e.track && o.Log(o.GetStackTrace(), "Got track - " + e.track.kind + " id=" + e.track.id + " readyState=" + e.track.readyState, 6), e.track.kind != "audio") return e.track.kind == "video" && t.srcObject !== e.streams[0] ? (t.srcObject = e.streams[0], void o.Log(o.GetStackTrace(), "Set video source from video track ontrack.")) : void 0; this.CreateAudioTrack(e.streams[0]); } CreateAudioTrack(e) { const t = this.videoElementProvider.getVideoElement(); t.srcObject != e && t.srcObject && t.srcObject !== e && (this.audioElement.srcObject = e, o.Log(o.GetStackTrace(), "Created new audio element to play separate audio stream.")); } }, ii = class { constructor(e) { this.freezeFrameHeight = 0, this.freezeFrameWidth = 0, this.rootDiv = e, this.rootElement = document.createElement("div"), this.rootElement.id = "freezeFrame", this.rootElement.style.display = "none", this.rootElement.style.pointerEvents = "none", this.rootElement.style.position = "absolute", this.rootElement.style.zIndex = "20", this.imageElement = document.createElement("img"), this.imageElement.style.position = "absolute", this.rootElement.appendChild(this.imageElement), this.rootDiv.appendChild(this.rootElement); } setElementForShow() { this.rootElement.style.display = "block"; } setElementForHide() { this.rootElement.style.display = "none"; } updateImageElementSource(e) { const t = btoa(e.reduce(((s, n) => s + String.fromCharCode(n)), "")); this.imageElement.src = "data:image/jpeg;base64," + t; } setDimensionsFromElementAndResize() { this.freezeFrameHeight = this.imageElement.naturalHeight, this.freezeFrameWidth = this.imageElement.naturalWidth, this.resize(); } resize() { if (this.freezeFrameWidth !== 0 && this.freezeFrameHeight !== 0) { let e = 0, t = 0, s = 0, n = 0; const r = this.rootDiv.clientWidth / this.rootDiv.clientHeight, a = this.freezeFrameWidth / this.freezeFrameHeight; r < a ? (e = this.rootDiv.clientWidth, t = Math.floor(this.rootDiv.clientWidth / a), s = Math.floor(0.5 * (this.rootDiv.clientHeight - t)), n = 0) : (e = Math.floor(this.rootDiv.clientHeight * a), t = this.rootDiv.clientHeight, s = 0, n = Math.floor(0.5 * (this.rootDiv.clientWidth - e))), this.rootElement.style.width = this.rootDiv.offsetWidth + "px", this.rootElement.style.height = this.rootDiv.offsetHeight + "px", this.rootElement.style.left = "0px", this.rootElement.style.top = "0px", this.imageElement.style.width = e + "px", this.imageElement.style.height = t + "px", this.imageElement.style.left = n + "px", this.imageElement.style.top = s + "px"; } } }, ri = class { constructor(e) { this.receiving = !1, this.size = 0, this.jpeg = void 0, this.valid = !1, this.freezeFrameDelay = 50, this.freezeFrame = new ii(e); } showFreezeFrame() { this.valid && this.freezeFrame.setElementForShow(); } hideFreezeFrame() { this.valid = !1, this.freezeFrame.setElementForHide(); } updateFreezeFrameAndShow(e, t) { this.freezeFrame.updateImageElementSource(e), this.freezeFrame.imageElement.onload = () => { this.freezeFrame.setDimensionsFromElementAndResize(), t(); }; } processFreezeFrameMessage(e, t) { this.receiving || (this.receiving = !0, this.valid = !1, this.size = 0, this.jpeg = void 0), this.size = new DataView(e.slice(1, 5).buffer).getInt32(0, !0); const s = e.slice(5); if (this.jpeg) { const n = new Uint8Array(this.jpeg.length + s.length); n.set(this.jpeg, 0), n.set(s, this.jpeg.length), this.jpeg = n; } else this.jpeg = s, this.receiving = !0, o.Log(o.GetStackTrace(), `received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`, 6); this.jpeg.length === this.size ? (this.receiving = !1, this.valid = !0, o.Log(o.GetStackTrace(), `received complete freeze frame ${this.size}`, 6), this.updateFreezeFrameAndShow(this.jpeg, t)) : this.jpeg.length > this.size && (o.Error(o.GetStackTrace(), `received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`), this.jpeg = void 0, this.receiving = !1); } }, Oe = class { constructor(e, t, s, n, r = (() => { })) { this.onChange = r, this.onChangeEmit = () => { }, this.id = e, this.description = s, this.label = t, this.value = n; } set label(e) { this._label = e, this.onChangeEmit(this._value); } get label() { return this._label; } get value() { return this._value; } set value(e) { this._value = e, this.onChange(this._value, this), this.onChangeEmit(this._value); } }, k = class extends Oe { constructor(e, t, s, n, r, a = (() => { })) { super(e, t, s, n, a); const l = new URLSearchParams(window.location.search); if (r && l.has(this.id)) { const d = this.getUrlParamFlag(); this.flag = d; } else this.flag = n; this.useUrlParams = r; } getUrlParamFlag() { const e = new URLSearchParams(window.location.search); return !!e.has(this.id) && e.get(this.id) !== "false" && e.get(this.id) !== "False"; } updateURLParams() { if (this.useUrlParams) { const e = new URLSearchParams(window.location.search); this.flag === !0 ? e.set(this.id, "true") : e.set(this.id, "false"), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`); } } enable() { this.flag = !0; } get flag() { return !!this.value; } set flag(e) { this.value = e; } }, G = class extends Oe { constructor(e, t, s, n, r, a, l, d = (() => { })) { super(e, t, s, a, d), this._min = n, this._max = r; const u = new URLSearchParams(window.location.search); if (l && u.has(this.id)) { const m = Number.parseFloat(u.get(this.id)); this.number = Number.isNaN(m) ? a : m; } else this.number = a; this.useUrlParams = l; } updateURLParams() { if (this.useUrlParams) { const e = new URLSearchParams(window.location.search); e.set(this.id, this.number.toString()), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`); } } set number(e) { this.value = this.clamp(e); } get number() { return this.value; } clamp(e) { return this._min == null && this._max == null ? e : this._min == null ? Math.min(this._max, e) : this._max == null ? Math.max(this._min, e) : Math.max(Math.min(this._max, e), this._min); } get min() { return this._min; } get max() { return this._max; } addOnChangedListener(e) { this.onChange = e; } }, bs = class extends Oe { constructor(e, t, s, n, r, a = (() => { })) { super(e, t, s, n, a); const l = new URLSearchParams(window.location.search); if (r && l.has(this.id)) { const d = this.getUrlParamText(); this.text = d; } else this.text = n; this.useUrlParams = r; } getUrlParamText() { var e; const t = new URLSearchParams(window.location.search); return t.has(this.id) && (e = t.get(this.id)) !== null && e !== void 0 ? e : ""; } updateURLParams() { if (this.useUrlParams) { const e = new URLSearchParams(window.location.search); e.set(this.id, this.text), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`); } } get text() { return this.value; } set text(e) { this.value = e; } }, pt = class extends Oe { constructor(e, t, s, n, r, a, l = (() => { })) { super(e, t, s, n, l), this.options = r; const d = new URLSearchParams(window.location.search), u = a && d.has(this.id) ? this.getUrlParamText() : n; this.selected = u, this.useUrlParams = a; } getUrlParamText() { var e; const t = new URLSearchParams(window.location.search); return t.has(this.id) && (e = t.get(this.id)) !== null && e !== void 0 ? e : ""; } updateURLParams() { if (this.useUrlParams) { const e = new URLSearchParams(window.location.search); e.set(this.id, this.selected), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`); } } addOnChangedListener(e) { this.onChange = e; } get options() { return this._options; } set options(e) { this._options = e, this.onChangeEmit(this.selected); } get selected() { return this.value; } set selected(e) { let t = this.options.filter(((s) => s.indexOf(e) !== -1)); t.length ? this.value = t[0] : (t = this.options.filter(((s) => s.indexOf(e.split(" ")[0]) !== -1)), t.length && (this.value = t[0])); } }, Ts = class extends Event { constructor(e) { super("afkWarningActivate"), this.data = e; } }, ft = class extends Event { constructor(e) { super("afkWarningUpdate"), this.data = e; } }, ws = class extends Event { constructor() { super("afkWarningDeactivate"); } }, Rs = class extends Event { constructor() { super("afkTimedOut"); } }, Ms = class extends Event { constructor(e) { super("videoEncoderAvgQP"), this.data = e; } }, ks = class extends Event { constructor() { super("webRtcSdp"); } }, Is = class extends Event { constructor() { super("webRtcAutoConnect"); } }, Ps = class extends Event { constructor() { super("webRtcConnecting"); } }, As = class extends Event { constructor() { super("webRtcConnected"); } }; class Ls extends Event { constructor() { super("webRtcFailed"); } } let xs = class extends Event { constructor(e) { super("webRtcDisconnected"), this.data = e; } }, Os = class extends Event { constructor(e) { super("dataChannelOpen"), this.data = e; } }, Ds = class extends Event { constructor(e) { super("dataChannelClose"), this.data = e; } }; class Ns extends Event { constructor(e) { super("dataChannelError"), this.data = e; } } let Fs = class extends Event { constructor() { super("videoInitialized"); } }, _s = class extends Event { constructor() { super("streamLoading"); } }, Us = class extends Event { constructor() { super("streamConnect"); } }; class Bs extends Event { constructor() { super("streamDisconnect"); } } let zs = class extends Event { constructor() { super("streamReconnect"); } }, Hs = class extends Event { constructor(e) { super("playStreamError"), this.data = e; } }; class Ws extends Event { constructor() { super("playStream"); } } let St = class extends Event { constructor(e) { super("playStreamRejected"), this.data = e; } }, Gs = class extends Event { constructor(e) { super("loadFreezeFrame"), this.data = e; } }, Vs = class extends Event { constructor() { super("hideFreezeFrame"); } }; class $s extends Event { constructor(e) { super("statsReceived"), this.data = e; } } let Qs = class extends Event { constructor(e) { super("streamerListMessage"), this.data = e; } }; class Ks extends Event { constructor(e) { super("StreamerIDChangedMessage"), this.data = e; } } class js extends Event { constructor(e) { super("latencyTestResult"), this.data = e; } } class qs extends Event { constructor(e) { super("dataChannelLatencyTestResponse"), this.data = e; } } class Xs extends Event { constructor(e) { super("dataChannelLatencyTestResult"), this.data = e; } } class Js extends Event { constructor(e) { super("initialSettings"), this.data = e; } } class Ee extends Event { constructor(e) { super("settingsChanged"), this.data = e; } } class ai extends Event { constructor() { super("xrSessionStarted"); } } class oi extends Event { constructor() { super("xrSessionEnded"); } } class Ys extends Event { constructor(e) { super("xrFrame"), this.data = e; } } class Zs extends Event { constructor(e) { super("playerCount"), this.data = e; } } class en extends Event { constructor() { super("webRtcTCPRelayDetected"); } } class tn extends EventTarget { dispatchEvent(e) { return super.dispatchEvent(e); } addEventListener(e, t) { super.addEventListener(e, t); } removeEventListener(e, t) { super.removeEventListener(e, t); } } class h { } h.AutoConnect = "AutoConnect", h.AutoPlayVideo = "AutoPlayVideo", h.AFKDetection = "TimeoutIfIdle", h.BrowserSendOffer = "OfferToReceive", h.HoveringMouseMode = "HoveringMouse", h.ForceMonoAudio = "ForceMonoAudio", h.ForceTURN = "ForceTURN", h.FakeMouseWithTouches = "FakeMouseWithTouches", h.IsQualityController = "ControlsQuality", h.MatchViewportResolution = "MatchViewportRes", h.StartVideoMuted = "StartVideoMuted", h.SuppressBrowserKeys = "SuppressBrowserKeys", h.UseMic = "UseMic", h.KeyboardInput = "KeyboardInput", h.MouseInput = "MouseInput", h.TouchInput = "TouchInput", h.GamepadInput = "GamepadInput", h.XRControllerInput = "XRControllerInput", h.WaitForStreamer = "WaitForStreamer", h.HideUI = "HideUI"; const li = (i) => Object.getOwnPropertyNames(h).some(((e) => h[e] === i)); class g { } g.AFKTimeoutSecs = "AFKTimeout", g.AFKCountdownSecs = "AFKCountdown", g.MinQP = "MinQP", g.MaxQP = "MaxQP", g.WebRTCFPS = "WebRTCFPS", g.WebRTCMinBitrate = "WebRTCMinBitrate", g.WebRTCMaxBitrate = "WebRTCMaxBitrate", g.MaxReconnectAttempts = "MaxReconnectAttempts", g.StreamerAutoJoinInterval = "StreamerAutoJoinInterval"; const ci = (i) => Object.getOwnPropertyNames(g).some(((e) => g[e] === i)); class Q { } Q.SignallingServerUrl = "ss"; const di = (i) => Object.getOwnPropertyNames(Q).some(((e) => Q[e] === i)); class w { } w.PreferredCodec = "PreferredCodec", w.StreamerId = "StreamerId"; const hi = (i) => Object.getOwnPropertyNames(w).some(((e) => w[e] === i)); class ui { constructor(e = {}) { this.flags = /* @__PURE__ */ new Map(), this.numericParameters = /* @__PURE__ */ new Map(), this.textParameters = /* @__PURE__ */ new Map(), this.optionParameters = /* @__PURE__ */ new Map(); const { initialSettings: t, useUrlParams: s } = e; this._useUrlParams = !!s, this.populateDefaultSettings(this._useUrlParams, t); } get useUrlParams() { return this._useUrlParams; } populateDefaultSettings(e, t) { this.textParameters.set(Q.SignallingServerUrl, new bs(Q.SignallingServerUrl, "Signalling url", "Url of the signalling server", t && t.hasOwnProperty(Q.SignallingServerUrl) ? t[Q.SignallingServerUrl] : (location.protocol === "https:" ? "wss://" : "ws://") + window.location.hostname + (window.location.port === "80" || window.location.port === "" ? "" : `:${window.location.port}`), e)), this.optionParameters.set(w.StreamerId, new pt(w.StreamerId, "Streamer ID", "The ID of the streamer to stream.", t && t.hasOwnProperty(w.StreamerId) ? t[w.StreamerId] : "", [], e)), this.optionParameters.set(w.PreferredCodec, new pt(w.PreferredCodec, "Preferred Codec", "The preferred codec to be used during codec negotiation", "H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f", t && t.hasOwnProperty(w.PreferredCodec) ? [t[w.PreferredCodec]] : (function() { const s = []; if (!RTCRtpReceiver.getCapabilities) return s.push("Only available on Chrome"), s; const n = /(VP\d|H26\d|AV1).*/; return RTCRtpReceiver.getCapabilities("video").codecs.forEach(((r) => { const a = r.mimeType.split("/")[1] + " " + (r.sdpFmtpLine || ""); n.exec(a) !== null && s.push(a); })), s; })(), e)), this.flags.set(h.AutoConnect, new k(h.AutoConnect, "Auto connect to stream", "Whether we should attempt to auto connect to the signalling server or show a click to start prompt.", !(!t || !t.hasOwnProperty(h.AutoConnect)) && t[h.AutoConnect], e)), this.flags.set(h.AutoPlayVideo, new k(h.AutoPlayVideo, "Auto play video", "When video is ready automatically start playing it as opposed to showing a play button.", !t || !t.hasOwnProperty(h.AutoPlayVideo) || t[h.AutoPlayVideo], e)), this.flags.set(h.BrowserSendOffer, new k(h.BrowserSendOffer, "Browser send offer", "Browser will initiate the WebRTC handshake by sending the offer to the streamer", !(!t || !t.hasOwnProperty(h.BrowserSendOffer)) && t[h.BrowserSendOffer], e)), this.flags.set(h.UseMic, new k(h.UseMic, "Use microphone", "Make browser request microphone access and open an input audio track.", !(!t || !t.hasOwnProperty(h.UseMic)) && t[h.UseMic], e)), this.flags.set(h.StartVideoMuted, new k(h.StartVideoMuted, "Start video muted", "Video will start muted if true.", !(!t || !t.hasOwnProperty(h.StartVideoMuted)) && t[h.StartVideoMuted], e)), this.flags.set(h.SuppressBrowserKeys, new k(h.SuppressBrowserKeys, "Suppress browser keys", "Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.", !t || !t.hasOwnProperty(h.SuppressBrowserKeys) || t[h.SuppressBrowserKeys], e)), this.flags.set(h.IsQualityController, new k(h.IsQualityController, "Is quality controller?", "True if this peer controls stream quality", !t || !t.hasOwnProperty(h.IsQualityController) || t[h.IsQualityController], e)), this.flags.set(h.ForceMonoAudio, new k(h.ForceMonoAudio, "Force mono audio", "Force browser to request mono audio in the SDP", !(!t || !t.hasOwnProperty(h.ForceMonoAudio)) && t[h.ForceMonoAudio], e)), this.flags.set(h.ForceTURN, new k(h.ForceTURN, "Force TURN", "Only generate TURN/Relayed ICE candidates.", !(!t || !t.hasOwnProperty(h.ForceTURN)) && t[h.ForceTURN], e)), this.flags.set(h.AFKDetection, new k(h.AFKDetection, "AFK if idle", "Timeout the experience if user is AFK for a period.", !(!t || !t.hasOwnProperty(h.AFKDetection)) && t[h.AFKDetection], e)), this.flags.set(h.MatchViewportResolution, new k(h.MatchViewportResolution, "Match viewport resolution", "Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.", !(!t || !t.hasOwnProperty(h.MatchViewportResolution)) && t[h.MatchViewportResolution], e)), this.flags.set(h.HoveringMouseMode, new k(h.HoveringMouseMode, "Control Scheme: Locked Mouse", "Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.", !(!t || !t.hasOwnProperty(h.HoveringMouseMode)) && t[h.HoveringMouseMode], e, ((s, n) => { n.label = `Control Scheme: ${s ? "Hovering" : "Locked"} Mouse`; }))), this.flags.set(h.FakeMouseWithTouches, new k(h.FakeMouseWithTouches, "Fake mouse with touches", "A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.", !(!t || !t.hasOwnProperty(h.FakeMouseWithTouches)) && t[h.FakeMouseWithTouches], e)), this.flags.set(h.KeyboardInput, new k(h.KeyboardInput, "Keyboard input", "If enabled, send keyboard events to streamer", !t || !t.hasOwnProperty(h.KeyboardInput) || t[h.KeyboardInput], e)), this.flags.set(h.MouseInput, new k(h.MouseInput, "Mouse input", "If enabled, send mouse events to streamer", !t || !t.hasOwnProperty(h.MouseInput) || t[h.MouseInput], e)), this.flags.set(h.TouchInput, new k(h.TouchInput, "Touch input", "If enabled, send touch events to streamer", !t || !t.hasOwnProperty(h.TouchInput) || t[h.TouchInput], e)), this.flags.set(h.GamepadInput, new k(h.GamepadInput, "Gamepad input", "If enabled, send gamepad events to streamer", !t || !t.hasOwnProperty(h.GamepadInput) || t[h.GamepadInput], e)), this.flags.set(h.XRControllerInput, new k(h.XRControllerInput, "XR controller input", "If enabled, send XR controller events to streamer", !t || !t.hasOwnProperty(h.XRControllerInput) || t[h.XRControllerInput], e)), this.flags.set(h.WaitForStreamer, new k(h.WaitForStreamer, "Wait for streamer", "Will continue trying to connect to the first streamer available.", !t || !t.hasOwnProperty(h.WaitForStreamer) || t[h.WaitForStreamer], e)), this.flags.set(h.HideUI, new k(h.HideUI, "Hide the UI overlay", "Will hide all UI overlay details", !(!t || !t.hasOwnProperty(h.HideUI)) && t[h.HideUI], e)), this.numericParameters.set(g.AFKTimeoutSecs, new G(g.AFKTimeoutSecs, "AFK timeout", "The time (in seconds) it takes for the application to time out if AFK timeout is enabled.", 0, null, t && t.hasOwnProperty(g.AFKTimeoutSecs) ? t[g.AFKTimeoutSecs] : 120, e)), this.numericParameters.set(g.AFKCountdownSecs, new G(g.AFKCountdownSecs, "AFK countdown", "The time (in seconds) for a user to respond before the stream is ended after an AFK timeout.", 10, null, 10, e)), this.numericParameters.set(g.MaxReconnectAttempts, new G(g.MaxReconnectAttempts, "Max Reconnects", "Maximum number of reconnects the application will attempt when a streamer disconnects.", 0, 999, t && t.hasOwnProperty(g.MaxReconnectAttempts) ? t[g.MaxReconnectAttempts] : 3, e)), this.numericParameters.set(g.MinQP, new G(g.MinQP, "Min QP", "The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.", 0, 51, t && t.hasOwnProperty(g.MinQP) ? t[g.MinQP] : 0, e)), this.numericParameters.set(g.MaxQP, new G(g.MaxQP, "Max QP", "The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.", 0, 51, t && t.hasOwnProperty(g.MaxQP) ? t[g.MaxQP] : 51, e)), this.numericParameters.set(g.WebRTCFPS, new G(g.WebRTCFPS, "Max FPS", "The maximum FPS that WebRTC will try to transmit frames at.", 1, 999, t && t.hasOwnProperty(g.WebRTCFPS) ? t[g.WebRTCFPS] : 60, e)), this.numericParameters.set(g.WebRTCMinBitrate, new G(g.WebRTCMinBitrate, "Min Bitrate (kbps)", "The minimum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(g.WebRTCMinBitrate) ? t[g.WebRTCMinBitrate] : 0, e)), this.numericParameters.set(g.WebRTCMaxBitrate, new G(g.WebRTCMaxBitrate, "Max Bitrate (kbps)", "The maximum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(g.WebRTCMaxBitrate) ? t[g.WebRTCMaxBitrate] : 0, e)), this.numericParameters.set(g.StreamerAutoJoinInterval, new G(g.StreamerAutoJoinInterval, "Streamer Auto Join Interval (ms)", "Delay between retries when waiting for an available streamer.", 500, 9e5, t && t.hasOwnProperty(g.StreamerAutoJoinInterval) ? t[g.StreamerAutoJoinInterval] : 3e3, e)); } _addOnNumericSettingChangedListener(e, t) { this.numericParameters.has(e) && this.numericParameters.get(e).addOnChangedListener(t); } _addOnOptionSettingChangedListener(e, t) { this.optionParameters.has(e) && this.optionParameters.get(e).addOnChangedListener(t); } getNumericSettingValue(e) { if (this.numericParameters.has(e)) return this.numericParameters.get(e).number; throw new Error(`There is no numeric setting with the id of ${e}`); } getTextSettingValue(e) { if (this.textParameters.has(e)) return this.textParameters.get(e).value; throw new Error(`There is no numeric setting with the id of ${e}`); } setNumericSetting(e, t) { if (!this.numericParameters.has(e)) throw new Error(`There is no numeric setting with the id of ${e}`); this.numericParameters.get(e).number = t; } _addOnSettingChangedListener(e, t) { this.flags.has(e) && (this.flags.get(e).onChange = t); } _addOnTextSettingChangedListener(e, t) { this.textParameters.has(e) && (this.textParameters.get(e).onChange = t); } getSettingOption(e) { return this.optionParameters.get(e); } isFlagEnabled(e) { return this.flags.get(e).flag; } setFlagEnabled(e, t) { this.flags.has(e) ? this.flags.get(e).flag = t : o.Warning(o.GetStackTrace(), `Cannot toggle flag called ${e} -