diff --git a/THIRD_PARTY.txt b/THIRD_PARTY.txt index 4100da19..d47b9f89 100644 --- a/THIRD_PARTY.txt +++ b/THIRD_PARTY.txt @@ -1451,7 +1451,9 @@ https://cdn.jsdelivr.net/npm/ngx-bootstrap@18.0.0/datepicker/bs-datepicker.css https://cdn.jsdelivr.net/npm/ngx-bootstrap@6.2.0/datepicker/bs-datepicker.css https://cdn.jsdelivr.net/npm/object-assign@4.1.1/index.js https://cdn.jsdelivr.net/npm/p2p-media-loader-core@0.6.2/build/p2p-media-loader-core.min.js +https://cdn.jsdelivr.net/npm/p2p-media-loader-core@1.0.3/dist/p2p-media-loader-core.es.min.js https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@0.6.2/build/p2p-media-loader-hlsjs.min.js +https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@1.0.3/dist/p2p-media-loader-hlsjs.es.min.js https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.css https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.min.js https://cdn.jsdelivr.net/npm/raven-js@3.27.2/dist/raven.min.js diff --git a/audit/audit.sh b/audit/audit.sh index 12c48ee7..694099f1 100755 --- a/audit/audit.sh +++ b/audit/audit.sh @@ -439,9 +439,17 @@ function create_url() { elif [ "$folder" = "react-side-effect" ]; then url="$UNPKG/react-side-effect@$version/lib/index.umd.min.js" elif [ "$folder" = "p2p-media-loader-core" ]; then - url="$JSDELIVR/npm/p2p-media-loader-core@$version/build/p2p-media-loader-core.min.js" + if [ "$version" = "0.6.2" ]; then + url="$JSDELIVR/npm/p2p-media-loader-core@$version/build/p2p-media-loader-core.min.js" + else + url="$JSDELIVR/npm/p2p-media-loader-core@$version/dist/p2p-media-loader-core.es.min.js" + fi elif [ "$folder" = "p2p-media-loader-hlsjs" ]; then - url="$JSDELIVR/npm/p2p-media-loader-hlsjs@$version/build/p2p-media-loader-hlsjs.min.js" + if [ "$version" = "0.6.2" ]; then + url="$JSDELIVR/npm/p2p-media-loader-hlsjs@$version/build/p2p-media-loader-hlsjs.min.js" + else + url="$JSDELIVR/npm/p2p-media-loader-hlsjs@$version/dist/p2p-media-loader-hlsjs.es.min.js" + fi elif [ "$folder" = "urlize" ]; then url="$JSDELIVR/npm/urlize.js/urlize.js" elif [ "$folder" = "videojs-seek-buttons" ]; then diff --git a/modules/internal/targets.js b/modules/internal/targets.js index 04654a88..fc93601f 100644 --- a/modules/internal/targets.js +++ b/modules/internal/targets.js @@ -364,7 +364,10 @@ targets.setLastVersion = function (type, version) { if (type.startsWith('/OwlCarousel2/2.')) return '2.3.4'; if (type.startsWith('/owl-carousel/1.')) return '1.3.3'; if (type.startsWith('/owl-carousel/2.')) return '2.3.4'; - if (type.startsWith('/p2p-media-loader-core') || type.startsWith('/p2p-media-loader-hlsjs')) return '0.6.2'; + if (type.startsWith('/p2p-media-loader-core') || type.startsWith('/p2p-media-loader-hlsjs')) { + if (helpers.compareVersion('0.6.2', version)) return '0.6.2'; // <= v0.6.2 + return '1.0.3'; + }; if (type.startsWith('/p5.js/0.')) return '0.10.2'; if (type.startsWith('/p5.js/1.')) return '1.9.4'; if (type.startsWith('/page.js/1.')) return '1.11.6'; diff --git a/pages/updates/updates.html b/pages/updates/updates.html index 207d5c68..f3e26a8e 100644 --- a/pages/updates/updates.html +++ b/pages/updates/updates.html @@ -48,6 +48,11 @@
  • vue v3.4.29 -> v3.4.31
  • vue-router v4.3.3 -> v4.4.0
  • +

    Added

    +
    diff --git a/resources/p2p-media-loader-core/1.0.3/p2p-media-loader-core.min.jsm b/resources/p2p-media-loader-core/1.0.3/p2p-media-loader-core.min.jsm new file mode 100644 index 00000000..a1b65dd4 --- /dev/null +++ b/resources/p2p-media-loader-core/1.0.3/p2p-media-loader-core.min.jsm @@ -0,0 +1,3501 @@ +var zn = Object.defineProperty; +var Vn = (s, t, e) => t in s ? zn(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e; +var f = (s, t, e) => Vn(s, typeof t != "symbol" ? t + "" : t, e); +class I extends Error { + constructor(e, n) { + super(n); + f(this, "timestamp"); + this.type = e, this.timestamp = performance.now(); + } +} +class fe extends Error { + constructor(t) { + super(), this.type = t; + } +} +class Gn { + constructor(t, e, n) { + f(this, "requestControls"); + f(this, "abortController", new AbortController()); + f(this, "expectedBytesLength"); + f(this, "requestByteRange"); + f(this, "onChunkDownloaded"); + this.request = t, this.httpConfig = e, this.onChunkDownloaded = n.getEventDispatcher("onChunkDownloaded"); + const { byteRange: r } = this.request.segment; + r && (this.requestByteRange = { ...r }), t.loadedBytes !== 0 && (this.requestByteRange = this.requestByteRange ?? { start: 0 }, this.requestByteRange.start = this.requestByteRange.start + t.loadedBytes), this.request.totalBytes && (this.expectedBytesLength = this.request.totalBytes - this.request.loadedBytes), this.requestControls = this.request.start({ downloadSource: "http" }, { abort: () => this.abortController.abort("abort"), notReceivingBytesTimeoutMs: this.httpConfig.httpNotReceivingBytesTimeoutMs }), this.fetch(); + } + async fetch() { + var e, n; + const { segment: t } = this.request; + try { + let r = await ((n = (e = this.httpConfig).httpRequestSetup) == null ? void 0 : n.call(e, t.url, t.byteRange, this.abortController.signal, this.requestByteRange)); + if (!r) { + const h = new Headers(this.requestByteRange ? { Range: `bytes=${this.requestByteRange.start}-${this.requestByteRange.end ?? ""}` } : void 0); + r = new Request(t.url, { headers: h, signal: this.abortController.signal }); + } + if (this.abortController.signal.aborted) throw new DOMException("Request aborted before request fetch", "AbortError"); + const i = await window.fetch(r); + if (this.handleResponseHeaders(i), !i.body) return; + const { requestControls: o } = this; + o.firstBytesReceived(); + const a = i.body.getReader(); + for await (const h of async function* (u) { + for (; ; ) { + const { done: d, value: p } = await u.read(); + if (d) break; + yield p; + } + }(a)) this.requestControls.addLoadedChunk(h), this.onChunkDownloaded(h.byteLength, "http"); + o.completeOnSuccess(); + } catch (r) { + this.handleError(r); + } + } + handleResponseHeaders(t) { + if (!t.ok) throw t.status === 406 ? (this.request.clearLoadedBytes(), new I("http-bytes-mismatch", t.statusText)) : new I("http-error", t.statusText); + const { requestByteRange: e } = this; + if (e) if (t.status === 200) { + if (this.request.segment.byteRange) throw new I("http-unexpected-status-code"); + this.request.clearLoadedBytes(); + } else { + if (t.status !== 206) throw new I("http-unexpected-status-code", t.statusText); + const n = t.headers.get("Content-Length"); + if (n && this.expectedBytesLength !== void 0 && this.expectedBytesLength !== +n) throw this.request.clearLoadedBytes(), new I("http-bytes-mismatch", t.statusText); + const r = t.headers.get("Content-Range"), i = r ? function(o) { + const a = o.trim().match(/^bytes (?:(?:(\d+)|)-(?:(\d+)|)|\*)\/(?:(\d+)|\*)$/); + if (!a) return; + const [, h, u, d] = a; + return { from: h ? parseInt(h) : void 0, to: u ? parseInt(u) : void 0, total: d ? parseInt(d) : void 0 }; + }(r) : void 0; + if (i) { + const { from: o, to: a, total: h } = i; + if (h !== void 0 && this.request.totalBytes !== h || o !== void 0 && e.start !== o || a !== void 0 && e.end !== void 0 && e.end !== a) throw this.request.clearLoadedBytes(), new I("http-bytes-mismatch", t.statusText); + } + } + if (t.status === 200 && this.request.totalBytes === void 0) { + const n = t.headers.get("Content-Length"); + n && this.request.setTotalBytes(+n); + } + } + handleError(t) { + if (t instanceof Error) { + if (t.name !== "abort") return; + const e = t instanceof I ? t : new I("http-error", t.message); + this.requestControls.abortOnError(e); + } + } +} +function Jn(s) { + return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; +} +var D, N, nn = { exports: {} }, v = nn.exports = {}; +function jt() { + throw new Error("setTimeout has not been defined"); +} +function Qt() { + throw new Error("clearTimeout has not been defined"); +} +function sn(s) { + if (D === setTimeout) return setTimeout(s, 0); + if ((D === jt || !D) && setTimeout) return D = setTimeout, setTimeout(s, 0); + try { + return D(s, 0); + } catch { + try { + return D.call(null, s, 0); + } catch { + return D.call(this, s, 0); + } + } +} +(function() { + try { + D = typeof setTimeout == "function" ? setTimeout : jt; + } catch { + D = jt; + } + try { + N = typeof clearTimeout == "function" ? clearTimeout : Qt; + } catch { + N = Qt; + } +})(); +var Q, M = [], J = !1, bt = -1; +function Yn() { + J && Q && (J = !1, Q.length ? M = Q.concat(M) : bt = -1, M.length && rn()); +} +function rn() { + if (!J) { + var s = sn(Yn); + J = !0; + for (var t = M.length; t; ) { + for (Q = M, M = []; ++bt < t; ) Q && Q[bt].run(); + bt = -1, t = M.length; + } + Q = null, J = !1, function(e) { + if (N === clearTimeout) return clearTimeout(e); + if ((N === Qt || !N) && clearTimeout) return N = clearTimeout, clearTimeout(e); + try { + return N(e); + } catch { + try { + return N.call(null, e); + } catch { + return N.call(this, e); + } + } + }(s); + } +} +function pe(s, t) { + this.fun = s, this.array = t; +} +function O() { +} +v.nextTick = function(s) { + var t = new Array(arguments.length - 1); + if (arguments.length > 1) for (var e = 1; e < arguments.length; e++) t[e - 1] = arguments[e]; + M.push(new pe(s, t)), M.length !== 1 || J || sn(rn); +}, pe.prototype.run = function() { + this.fun.apply(null, this.array); +}, v.title = "browser", v.browser = !0, v.env = {}, v.argv = [], v.version = "", v.versions = {}, v.on = O, v.addListener = O, v.once = O, v.off = O, v.removeListener = O, v.removeAllListeners = O, v.emit = O, v.prependListener = O, v.prependOnceListener = O, v.listeners = function(s) { + return []; +}, v.binding = function(s) { + throw new Error("process.binding is not supported"); +}, v.cwd = function() { + return "/"; +}, v.chdir = function(s) { + throw new Error("process.chdir is not supported"); +}, v.umask = function() { + return 0; +}; +const wt = Jn(nn.exports); +var Kn = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; +function V(s) { + return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; +} +var me, ye, Wt = { exports: {} }; +function Xn() { + if (ye) return me; + ye = 1; + var s = 1e3, t = 60 * s, e = 60 * t, n = 24 * e, r = 7 * n, i = 365.25 * n; + function o(a, h, u, d) { + var p = h >= 1.5 * u; + return Math.round(a / u) + " " + d + (p ? "s" : ""); + } + return me = function(a, h) { + h = h || {}; + var u = typeof a; + if (u === "string" && a.length > 0) return function(d) { + if (!((d = String(d)).length > 100)) { + var p = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(d); + if (p) { + var _ = parseFloat(p[1]); + switch ((p[2] || "ms").toLowerCase()) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return _ * i; + case "weeks": + case "week": + case "w": + return _ * r; + case "days": + case "day": + case "d": + return _ * n; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return _ * e; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return _ * t; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return _ * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return _; + default: + return; + } + } + } + }(a); + if (u === "number" && isFinite(a)) return h.long ? function(d) { + var p = Math.abs(d); + return p >= n ? o(d, p, n, "day") : p >= e ? o(d, p, e, "hour") : p >= t ? o(d, p, t, "minute") : p >= s ? o(d, p, s, "second") : d + " ms"; + }(a) : function(d) { + var p = Math.abs(d); + return p >= n ? Math.round(d / n) + "d" : p >= e ? Math.round(d / e) + "h" : p >= t ? Math.round(d / t) + "m" : p >= s ? Math.round(d / s) + "s" : d + "ms"; + }(a); + throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(a)); + }; +} +var Zn = function(s) { + function t(r) { + let i, o, a, h = null; + function u(...d) { + if (!u.enabled) return; + const p = u, _ = Number(/* @__PURE__ */ new Date()), S = _ - (i || _); + p.diff = S, p.prev = i, p.curr = _, i = _, d[0] = t.coerce(d[0]), typeof d[0] != "string" && d.unshift("%O"); + let c = 0; + d[0] = d[0].replace(/%([a-zA-Z%])/g, (g, l) => { + if (g === "%%") return "%"; + c++; + const m = t.formatters[l]; + if (typeof m == "function") { + const y = d[c]; + g = m.call(p, y), d.splice(c, 1), c--; + } + return g; + }), t.formatArgs.call(p, d), (p.log || t.log).apply(p, d); + } + return u.namespace = r, u.useColors = t.useColors(), u.color = t.selectColor(r), u.extend = e, u.destroy = t.destroy, Object.defineProperty(u, "enabled", { enumerable: !0, configurable: !1, get: () => h !== null ? h : (o !== t.namespaces && (o = t.namespaces, a = t.enabled(r)), a), set: (d) => { + h = d; + } }), typeof t.init == "function" && t.init(u), u; + } + function e(r, i) { + const o = t(this.namespace + (i === void 0 ? ":" : i) + r); + return o.log = this.log, o; + } + function n(r) { + return r.toString().substring(2, r.toString().length - 2).replace(/\.\*\?$/, "*"); + } + return t.debug = t, t.default = t, t.coerce = function(r) { + return r instanceof Error ? r.stack || r.message : r; + }, t.disable = function() { + const r = [...t.names.map(n), ...t.skips.map(n).map((i) => "-" + i)].join(","); + return t.enable(""), r; + }, t.enable = function(r) { + let i; + t.save(r), t.namespaces = r, t.names = [], t.skips = []; + const o = (typeof r == "string" ? r : "").split(/[\s,]+/), a = o.length; + for (i = 0; i < a; i++) o[i] && ((r = o[i].replace(/\*/g, ".*?"))[0] === "-" ? t.skips.push(new RegExp("^" + r.slice(1) + "$")) : t.names.push(new RegExp("^" + r + "$"))); + }, t.enabled = function(r) { + if (r[r.length - 1] === "*") return !0; + let i, o; + for (i = 0, o = t.skips.length; i < o; i++) if (t.skips[i].test(r)) return !1; + for (i = 0, o = t.names.length; i < o; i++) if (t.names[i].test(r)) return !0; + return !1; + }, t.humanize = Xn(), t.destroy = function() { + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + }, Object.keys(s).forEach((r) => { + t[r] = s[r]; + }), t.names = [], t.skips = [], t.formatters = {}, t.selectColor = function(r) { + let i = 0; + for (let o = 0; o < r.length; o++) i = (i << 5) - i + r.charCodeAt(o), i |= 0; + return t.colors[Math.abs(i) % t.colors.length]; + }, t.enable(t.load()), t; +}; +(function(s, t) { + t.formatArgs = function(n) { + if (n[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + n[0] + (this.useColors ? "%c " : " ") + "+" + s.exports.humanize(this.diff), !this.useColors) return; + const r = "color: " + this.color; + n.splice(1, 0, r, "color: inherit"); + let i = 0, o = 0; + n[0].replace(/%[a-zA-Z%]/g, (a) => { + a !== "%%" && (i++, a === "%c" && (o = i)); + }), n.splice(o, 0, r); + }, t.save = function(n) { + try { + n ? t.storage.setItem("debug", n) : t.storage.removeItem("debug"); + } catch { + } + }, t.load = function() { + let n; + try { + n = t.storage.getItem("debug"); + } catch { + } + return !n && wt !== void 0 && "env" in wt && (n = wt.env.DEBUG), n; + }, t.useColors = function() { + return typeof window < "u" && window.process && (window.process.type === "renderer" || window.process.__nwjs) ? !0 : typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/) ? !1 : typeof document < "u" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window < "u" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + }, t.storage = function() { + try { + return localStorage; + } catch { + } + }(), t.destroy = /* @__PURE__ */ (() => { + let n = !1; + return () => { + n || (n = !0, console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")); + }; + })(), t.colors = ["#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33"], t.log = console.debug || console.log || (() => { + }), s.exports = Zn(t); + const { formatters: e } = s.exports; + e.j = function(n) { + try { + return JSON.stringify(n); + } catch (r) { + return "[UnexpectedJSONParseError]: " + r.message; + } + }; +})(Wt, Wt.exports); +var on = Wt.exports; +const P = V(on); +var an, zt = { exports: {} }, Y = typeof Reflect == "object" ? Reflect : null, _e = Y && typeof Y.apply == "function" ? Y.apply : function(s, t, e) { + return Function.prototype.apply.call(s, t, e); +}; +an = Y && typeof Y.ownKeys == "function" ? Y.ownKeys : Object.getOwnPropertySymbols ? function(s) { + return Object.getOwnPropertyNames(s).concat(Object.getOwnPropertySymbols(s)); +} : function(s) { + return Object.getOwnPropertyNames(s); +}; +var be = Number.isNaN || function(s) { + return s != s; +}; +function w() { + w.init.call(this); +} +zt.exports = w, zt.exports.once = function(s, t) { + return new Promise(function(e, n) { + function r(o) { + s.removeListener(t, i), n(o); + } + function i() { + typeof s.removeListener == "function" && s.removeListener("error", r), e([].slice.call(arguments)); + } + ke(s, t, i, { once: !0 }), t !== "error" && function(o, a, h) { + typeof o.on == "function" && ke(o, "error", a, h); + }(s, r, { once: !0 }); + }); +}, w.EventEmitter = w, w.prototype._events = void 0, w.prototype._eventsCount = 0, w.prototype._maxListeners = void 0; +var we = 10; +function St(s) { + if (typeof s != "function") throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof s); +} +function hn(s) { + return s._maxListeners === void 0 ? w.defaultMaxListeners : s._maxListeners; +} +function Se(s, t, e, n) { + var r, i, o, a; + if (St(e), (i = s._events) === void 0 ? (i = s._events = /* @__PURE__ */ Object.create(null), s._eventsCount = 0) : (i.newListener !== void 0 && (s.emit("newListener", t, e.listener ? e.listener : e), i = s._events), o = i[t]), o === void 0) o = i[t] = e, ++s._eventsCount; + else if (typeof o == "function" ? o = i[t] = n ? [e, o] : [o, e] : n ? o.unshift(e) : o.push(e), (r = hn(s)) > 0 && o.length > r && !o.warned) { + o.warned = !0; + var h = new Error("Possible EventEmitter memory leak detected. " + o.length + " " + String(t) + " listeners added. Use emitter.setMaxListeners() to increase limit"); + h.name = "MaxListenersExceededWarning", h.emitter = s, h.type = t, h.count = o.length, a = h, console && console.warn && console.warn(a); + } + return s; +} +function ts() { + if (!this.fired) return this.target.removeListener(this.type, this.wrapFn), this.fired = !0, arguments.length === 0 ? this.listener.call(this.target) : this.listener.apply(this.target, arguments); +} +function Ce(s, t, e) { + var n = { fired: !1, wrapFn: void 0, target: s, type: t, listener: e }, r = ts.bind(n); + return r.listener = e, n.wrapFn = r, r; +} +function ve(s, t, e) { + var n = s._events; + if (n === void 0) return []; + var r = n[t]; + return r === void 0 ? [] : typeof r == "function" ? e ? [r.listener || r] : [r] : e ? function(i) { + for (var o = new Array(i.length), a = 0; a < o.length; ++a) o[a] = i[a].listener || i[a]; + return o; + }(r) : cn(r, r.length); +} +function Le(s) { + var t = this._events; + if (t !== void 0) { + var e = t[s]; + if (typeof e == "function") return 1; + if (e !== void 0) return e.length; + } + return 0; +} +function cn(s, t) { + for (var e = new Array(t), n = 0; n < t; ++n) e[n] = s[n]; + return e; +} +function ke(s, t, e, n) { + if (typeof s.on == "function") n.once ? s.once(t, e) : s.on(t, e); + else { + if (typeof s.addEventListener != "function") throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof s); + s.addEventListener(t, function r(i) { + n.once && s.removeEventListener(t, r), e(i); + }); + } +} +Object.defineProperty(w, "defaultMaxListeners", { enumerable: !0, get: function() { + return we; +}, set: function(s) { + if (typeof s != "number" || s < 0 || be(s)) throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + s + "."); + we = s; +} }), w.init = function() { + this._events !== void 0 && this._events !== Object.getPrototypeOf(this)._events || (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0), this._maxListeners = this._maxListeners || void 0; +}, w.prototype.setMaxListeners = function(s) { + if (typeof s != "number" || s < 0 || be(s)) throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + s + "."); + return this._maxListeners = s, this; +}, w.prototype.getMaxListeners = function() { + return hn(this); +}, w.prototype.emit = function(s) { + for (var t = [], e = 1; e < arguments.length; e++) t.push(arguments[e]); + var n = s === "error", r = this._events; + if (r !== void 0) n = n && r.error === void 0; + else if (!n) return !1; + if (n) { + var i; + if (t.length > 0 && (i = t[0]), i instanceof Error) throw i; + var o = new Error("Unhandled error." + (i ? " (" + i.message + ")" : "")); + throw o.context = i, o; + } + var a = r[s]; + if (a === void 0) return !1; + if (typeof a == "function") _e(a, this, t); + else { + var h = a.length, u = cn(a, h); + for (e = 0; e < h; ++e) _e(u[e], this, t); + } + return !0; +}, w.prototype.addListener = function(s, t) { + return Se(this, s, t, !1); +}, w.prototype.on = w.prototype.addListener, w.prototype.prependListener = function(s, t) { + return Se(this, s, t, !0); +}, w.prototype.once = function(s, t) { + return St(t), this.on(s, Ce(this, s, t)), this; +}, w.prototype.prependOnceListener = function(s, t) { + return St(t), this.prependListener(s, Ce(this, s, t)), this; +}, w.prototype.removeListener = function(s, t) { + var e, n, r, i, o; + if (St(t), (n = this._events) === void 0) return this; + if ((e = n[s]) === void 0) return this; + if (e === t || e.listener === t) --this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : (delete n[s], n.removeListener && this.emit("removeListener", s, e.listener || t)); + else if (typeof e != "function") { + for (r = -1, i = e.length - 1; i >= 0; i--) if (e[i] === t || e[i].listener === t) { + o = e[i].listener, r = i; + break; + } + if (r < 0) return this; + r === 0 ? e.shift() : function(a, h) { + for (; h + 1 < a.length; h++) a[h] = a[h + 1]; + a.pop(); + }(e, r), e.length === 1 && (n[s] = e[0]), n.removeListener !== void 0 && this.emit("removeListener", s, o || t); + } + return this; +}, w.prototype.off = w.prototype.removeListener, w.prototype.removeAllListeners = function(s) { + var t, e, n; + if ((e = this._events) === void 0) return this; + if (e.removeListener === void 0) return arguments.length === 0 ? (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0) : e[s] !== void 0 && (--this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : delete e[s]), this; + if (arguments.length === 0) { + var r, i = Object.keys(e); + for (n = 0; n < i.length; ++n) (r = i[n]) !== "removeListener" && this.removeAllListeners(r); + return this.removeAllListeners("removeListener"), this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0, this; + } + if (typeof (t = e[s]) == "function") this.removeListener(s, t); + else if (t !== void 0) for (n = t.length - 1; n >= 0; n--) this.removeListener(s, t[n]); + return this; +}, w.prototype.listeners = function(s) { + return ve(this, s, !0); +}, w.prototype.rawListeners = function(s) { + return ve(this, s, !1); +}, w.listenerCount = function(s, t) { + return typeof s.listenerCount == "function" ? s.listenerCount(t) : Le.call(s, t); +}, w.prototype.listenerCount = Le, w.prototype.eventNames = function() { + return this._eventsCount > 0 ? an(this._events) : []; +}; +var dn = zt.exports; +const un = V(dn); +var Vt = { exports: {} }, es = function s(t, e) { + if (t && e) return s(t)(e); + if (typeof t != "function") throw new TypeError("need wrapper function"); + return Object.keys(t).forEach(function(r) { + n[r] = t[r]; + }), n; + function n() { + for (var r = new Array(arguments.length), i = 0; i < r.length; i++) r[i] = arguments[i]; + var o = t.apply(this, r), a = r[r.length - 1]; + return typeof o == "function" && o !== a && Object.keys(a).forEach(function(h) { + o[h] = a[h]; + }), o; + } +}, xe = es; +function ut(s) { + var t = function() { + return t.called ? t.value : (t.called = !0, t.value = s.apply(this, arguments)); + }; + return t.called = !1, t; +} +function Ae(s) { + var t = function() { + if (t.called) throw new Error(t.onceError); + return t.called = !0, t.value = s.apply(this, arguments); + }, e = s.name || "Function wrapped with `once`"; + return t.onceError = e + " shouldn't be called more than once", t.called = !1, t; +} +Vt.exports = xe(ut), Vt.exports.strict = xe(Ae), ut.proto = ut(function() { + Object.defineProperty(Function.prototype, "once", { value: function() { + return ut(this); + }, configurable: !0 }), Object.defineProperty(Function.prototype, "onceStrict", { value: function() { + return Ae(this); + }, configurable: !0 }); +}); +const ns = V(Vt.exports); +let Ee; +var ln = typeof queueMicrotask == "function" ? queueMicrotask.bind(typeof window < "u" ? window : Kn) : (s) => (Ee || (Ee = Promise.resolve())).then(s).catch((t) => setTimeout(() => { + throw t; +}, 0)); +const Gt = V(ln); +var ss = function(s, t) { + let e, n, r, i = !0; + Array.isArray(s) ? (e = [], n = s.length) : (r = Object.keys(s), e = {}, n = r.length); + function o(h) { + function u() { + t && t(h, e), t = null; + } + i ? rs(u) : u(); + } + function a(h, u, d) { + e[h] = d, (--n == 0 || u) && o(u); + } + n ? r ? r.forEach(function(h) { + s[h](function(u, d) { + a(h, u, d); + }); + }) : s.forEach(function(h, u) { + h(function(d, p) { + a(u, d, p); + }); + }) : o(null), i = !1; +}; +const rs = ln, is = V(ss), F = typeof window < "u" ? window : self, Jt = F.RTCPeerConnection || F.mozRTCPeerConnection || F.webkitRTCPeerConnection, os = F.RTCSessionDescription || F.mozRTCSessionDescription || F.webkitRTCSessionDescription, as = F.RTCIceCandidate || F.mozRTCIceCandidate || F.webkitRTCIceCandidate; +var hs = typeof queueMicrotask == "function" ? queueMicrotask : (s) => Promise.resolve().then(s); +const Te = class { + constructor(s) { + if (!(s > 0) || s - 1 & s) throw new Error("Max size for a FixedFIFO should be a power of two"); + this.buffer = new Array(s), this.mask = s - 1, this.top = 0, this.btm = 0, this.next = null; + } + clear() { + this.top = this.btm = 0, this.next = null, this.buffer.fill(void 0); + } + push(s) { + return this.buffer[this.top] === void 0 && (this.buffer[this.top] = s, this.top = this.top + 1 & this.mask, !0); + } + shift() { + const s = this.buffer[this.btm]; + if (s !== void 0) return this.buffer[this.btm] = void 0, this.btm = this.btm + 1 & this.mask, s; + } + peek() { + return this.buffer[this.btm]; + } + isEmpty() { + return this.buffer[this.btm] === void 0; + } +}; +var Yt = { exports: {} }; +function Re(s) { + return s.length; +} +var cs = { byteLength: Re, toString: function(s) { + const t = s.byteLength; + let e = ""; + for (let n = 0; n < t; n++) e += String.fromCharCode(s[n]); + return e; +}, write: function(s, t, e = 0, n = Re(t)) { + const r = Math.min(n, s.byteLength - e); + for (let i = 0; i < r; i++) s[e + i] = t.charCodeAt(i); + return r; +} }; +const nt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", W = new Uint8Array(256); +for (let s = 0; s < 64; s++) W[nt.charCodeAt(s)] = s; +function Ie(s) { + let t = s.length; + return s.charCodeAt(t - 1) === 61 && t--, t > 1 && s.charCodeAt(t - 1) === 61 && t--, 3 * t >>> 2; +} +W[45] = 62, W[95] = 63; +var ds = { byteLength: Ie, toString: function(s) { + const t = s.byteLength; + let e = ""; + for (let n = 0; n < t; n += 3) e += nt[s[n] >> 2] + nt[(3 & s[n]) << 4 | s[n + 1] >> 4] + nt[(15 & s[n + 1]) << 2 | s[n + 2] >> 6] + nt[63 & s[n + 2]]; + return t % 3 == 2 ? e = e.substring(0, e.length - 1) + "=" : t % 3 == 1 && (e = e.substring(0, e.length - 2) + "=="), e; +}, write: function(s, t, e = 0, n = Ie(t)) { + const r = Math.min(n, s.byteLength - e); + for (let i = 0, o = 0; o < r; i += 4) { + const a = W[t.charCodeAt(i)], h = W[t.charCodeAt(i + 1)], u = W[t.charCodeAt(i + 2)], d = W[t.charCodeAt(i + 3)]; + s[o++] = a << 2 | h >> 4, s[o++] = (15 & h) << 4 | u >> 2, s[o++] = (3 & u) << 6 | 63 & d; + } + return r; +} }; +function Be(s) { + return s.length >>> 1; +} +var us = { byteLength: Be, toString: function(s) { + const t = s.byteLength; + s = new DataView(s.buffer, s.byteOffset, t); + let e = "", n = 0; + for (let r = t - t % 4; n < r; n += 4) e += s.getUint32(n).toString(16).padStart(8, "0"); + for (; n < t; n++) e += s.getUint8(n).toString(16).padStart(2, "0"); + return e; +}, write: function(s, t, e = 0, n = Be(t)) { + const r = Math.min(n, s.byteLength - e); + for (let i = 0; i < r; i++) { + const o = Pe(t.charCodeAt(2 * i)), a = Pe(t.charCodeAt(2 * i + 1)); + if (o === void 0 || a === void 0) return s.subarray(0, i); + s[e + i] = o << 4 | a; + } + return r; +} }; +function Pe(s) { + return s >= 48 && s <= 57 ? s - 48 : s >= 65 && s <= 70 ? s - 65 + 10 : s >= 97 && s <= 102 ? s - 97 + 10 : void 0; +} +function Kt(s) { + let t = 0; + for (let e = 0, n = s.length; e < n; e++) { + const r = s.charCodeAt(e); + if (r >= 55296 && r <= 56319 && e + 1 < n) { + const i = s.charCodeAt(e + 1); + if (i >= 56320 && i <= 57343) { + t += 4, e++; + continue; + } + } + t += r <= 127 ? 1 : r <= 2047 ? 2 : 3; + } + return t; +} +let Xt, Zt; +if (typeof TextDecoder < "u") { + const s = new TextDecoder(); + Xt = function(t) { + return s.decode(t); + }; +} else Xt = function(s) { + const t = s.byteLength; + let e = "", n = 0; + for (; n < t; ) { + let r = s[n]; + if (r <= 127) { + e += String.fromCharCode(r), n++; + continue; + } + let i = 0, o = 0; + if (r <= 223 ? (i = 1, o = 31 & r) : r <= 239 ? (i = 2, o = 15 & r) : r <= 244 && (i = 3, o = 7 & r), t - n - i > 0) { + let a = 0; + for (; a < i; ) r = s[n + a + 1], o = o << 6 | 63 & r, a += 1; + } else o = 65533, i = t - n; + e += String.fromCodePoint(o), n += i + 1; + } + return e; +}; +if (typeof TextEncoder < "u") { + const s = new TextEncoder(); + Zt = function(t, e, n = 0, r = Kt(e)) { + const i = Math.min(r, t.byteLength - n); + return s.encodeInto(e, t.subarray(n, n + i)), i; + }; +} else Zt = function(s, t, e = 0, n = Kt(t)) { + const r = Math.min(n, s.byteLength - e); + s = s.subarray(e, e + r); + let i = 0, o = 0; + for (; i < t.length; ) { + const a = t.codePointAt(i); + if (a <= 127) { + s[o++] = a, i++; + continue; + } + let h = 0, u = 0; + for (a <= 2047 ? (h = 6, u = 192) : a <= 65535 ? (h = 12, u = 224) : a <= 2097151 && (h = 18, u = 240), s[o++] = u | a >> h, h -= 6; h >= 0; ) s[o++] = 128 | a >> h & 63, h -= 6; + i += a >= 65536 ? 2 : 1; + } + return r; +}; +var ls = { byteLength: Kt, toString: Xt, write: Zt }; +function Oe(s) { + return 2 * s.length; +} +var gs = { byteLength: Oe, toString: function(s) { + const t = s.byteLength; + let e = ""; + for (let n = 0; n < t - 1; n += 2) e += String.fromCharCode(s[n] + 256 * s[n + 1]); + return e; +}, write: function(s, t, e = 0, n = Oe(t)) { + const r = Math.min(n, s.byteLength - e); + let i = r; + for (let o = 0; o < t.length && !((i -= 2) < 0); ++o) { + const a = t.charCodeAt(o), h = a >> 8, u = a % 256; + s[e + 2 * o] = u, s[e + 2 * o + 1] = h; + } + return r; +} }; +(function(s, t) { + const e = cs, n = ds, r = us, i = ls, o = gs, a = new Uint8Array(Uint16Array.of(255).buffer)[0] === 255; + function h(c) { + switch (c) { + case "ascii": + return e; + case "base64": + return n; + case "hex": + return r; + case "utf8": + case "utf-8": + case void 0: + return i; + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return o; + default: + throw new Error(`Unknown encoding: ${c}`); + } + } + function u(c) { + return c instanceof Uint8Array; + } + function d(c, g, l) { + return typeof c == "string" ? function(m, y) { + const b = h(y), L = new Uint8Array(b.byteLength(m)); + return b.write(L, m, 0, L.byteLength), L; + }(c, g) : Array.isArray(c) ? function(m) { + const y = new Uint8Array(m.length); + return y.set(m), y; + }(c) : ArrayBuffer.isView(c) ? function(m) { + const y = new Uint8Array(m.byteLength); + return y.set(m), y; + }(c) : function(m, y, b) { + return new Uint8Array(m, y, b); + }(c, g, l); + } + function p(c, g, l, m, y) { + if (c.byteLength === 0) return -1; + if (typeof l == "string" ? (m = l, l = 0) : l === void 0 ? l = y ? 0 : c.length - 1 : l < 0 && (l += c.byteLength), l >= c.byteLength) { + if (y) return -1; + l = c.byteLength - 1; + } else if (l < 0) { + if (!y) return -1; + l = 0; + } + if (typeof g == "string") g = d(g, m); + else if (typeof g == "number") return g &= 255, y ? c.indexOf(g, l) : c.lastIndexOf(g, l); + if (g.byteLength === 0) return -1; + if (y) { + let b = -1; + for (let L = l; L < c.byteLength; L++) if (c[L] === g[b === -1 ? 0 : L - b]) { + if (b === -1 && (b = L), L - b + 1 === g.byteLength) return b; + } else b !== -1 && (L -= L - b), b = -1; + } else { + l + g.byteLength > c.byteLength && (l = c.byteLength - g.byteLength); + for (let b = l; b >= 0; b--) { + let L = !0; + for (let dt = 0; dt < g.byteLength; dt++) if (c[b + dt] !== g[dt]) { + L = !1; + break; + } + if (L) return b; + } + } + return -1; + } + function _(c, g, l, m) { + return p(c, g, l, m, !0); + } + function S(c, g, l) { + const m = c[g]; + c[g] = c[l], c[l] = m; + } + s.exports = t = { isBuffer: u, isEncoding: function(c) { + try { + return h(c), !0; + } catch { + return !1; + } + }, alloc: function(c, g, l) { + const m = new Uint8Array(c); + return g !== void 0 && t.fill(m, g, 0, m.byteLength, l), m; + }, allocUnsafe: function(c) { + return new Uint8Array(c); + }, allocUnsafeSlow: function(c) { + return new Uint8Array(c); + }, byteLength: function(c, g) { + return h(g).byteLength(c); + }, compare: function(c, g) { + if (c === g) return 0; + const l = Math.min(c.byteLength, g.byteLength); + c = new DataView(c.buffer, c.byteOffset, c.byteLength), g = new DataView(g.buffer, g.byteOffset, g.byteLength); + let m = 0; + for (let y = l - l % 4; m < y && c.getUint32(m, a) === g.getUint32(m, a); m += 4) + ; + for (; m < l; m++) { + const y = c.getUint8(m), b = g.getUint8(m); + if (y < b) return -1; + if (y > b) return 1; + } + return c.byteLength > g.byteLength ? 1 : c.byteLength < g.byteLength ? -1 : 0; + }, concat: function(c, g) { + g === void 0 && (g = c.reduce((y, b) => y + b.byteLength, 0)); + const l = new Uint8Array(g); + let m = 0; + for (const y of c) { + if (m + y.byteLength > l.byteLength) { + const b = y.subarray(0, l.byteLength - m); + return l.set(b, m), l; + } + l.set(y, m), m += y.byteLength; + } + return l; + }, copy: function(c, g, l = 0, m = 0, y = c.byteLength) { + if (y > 0 && y < m || y === m || c.byteLength === 0 || g.byteLength === 0) return 0; + if (l < 0) throw new RangeError("targetStart is out of range"); + if (m < 0 || m >= c.byteLength) throw new RangeError("sourceStart is out of range"); + if (y < 0) throw new RangeError("sourceEnd is out of range"); + l >= g.byteLength && (l = g.byteLength), y > c.byteLength && (y = c.byteLength), g.byteLength - l < y - m && (y = g.length - l + m); + const b = y - m; + return c === g ? g.copyWithin(l, m, y) : g.set(c.subarray(m, y), l), b; + }, equals: function(c, g) { + if (c === g) return !0; + if (c.byteLength !== g.byteLength) return !1; + const l = c.byteLength; + c = new DataView(c.buffer, c.byteOffset, c.byteLength), g = new DataView(g.buffer, g.byteOffset, g.byteLength); + let m = 0; + for (let y = l - l % 4; m < y; m += 4) if (c.getUint32(m, a) !== g.getUint32(m, a)) return !1; + for (; m < l; m++) if (c.getUint8(m) !== g.getUint8(m)) return !1; + return !0; + }, fill: function(c, g, l, m, y) { + if (typeof g == "string" ? typeof l == "string" ? (y = l, l = 0, m = c.byteLength) : typeof m == "string" && (y = m, m = c.byteLength) : typeof g == "number" ? g &= 255 : typeof g == "boolean" && (g = +g), l < 0 || c.byteLength < l || c.byteLength < m) throw new RangeError("Out of range index"); + if (l === void 0 && (l = 0), m === void 0 && (m = c.byteLength), m <= l) return c; + if (g || (g = 0), typeof g == "number") for (let b = l; b < m; ++b) c[b] = g; + else { + const b = (g = u(g) ? g : d(g, y)).byteLength; + for (let L = 0; L < m - l; ++L) c[L + l] = g[L % b]; + } + return c; + }, from: d, includes: function(c, g, l, m) { + return _(c, g, l, m) !== -1; + }, indexOf: _, lastIndexOf: function(c, g, l, m) { + return p(c, g, l, m, !1); + }, swap16: function(c) { + const g = c.byteLength; + if (g % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits"); + for (let l = 0; l < g; l += 2) S(c, l, l + 1); + return c; + }, swap32: function(c) { + const g = c.byteLength; + if (g % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits"); + for (let l = 0; l < g; l += 4) S(c, l, l + 3), S(c, l + 1, l + 2); + return c; + }, swap64: function(c) { + const g = c.byteLength; + if (g % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits"); + for (let l = 0; l < g; l += 8) S(c, l, l + 7), S(c, l + 1, l + 6), S(c, l + 2, l + 5), S(c, l + 3, l + 4); + return c; + }, toBuffer: function(c) { + return c; + }, toString: function(c, g, l = 0, m = c.byteLength) { + const y = c.byteLength; + return l >= y || m <= l ? "" : (l < 0 && (l = 0), m > y && (m = y), (l !== 0 || m < y) && (c = c.subarray(l, m)), h(g).toString(c)); + }, write: function(c, g, l, m, y) { + return l === void 0 ? y = "utf8" : m === void 0 && typeof l == "string" ? (y = l, l = void 0) : y === void 0 && typeof m == "string" && (y = m, m = void 0), h(y).write(c, g, l, m); + }, writeDoubleLE: function(c, g, l) { + return l === void 0 && (l = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).setFloat64(l, g, !0), l + 8; + }, writeFloatLE: function(c, g, l) { + return l === void 0 && (l = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).setFloat32(l, g, !0), l + 4; + }, writeUInt32LE: function(c, g, l) { + return l === void 0 && (l = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).setUint32(l, g, !0), l + 4; + }, writeInt32LE: function(c, g, l) { + return l === void 0 && (l = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).setInt32(l, g, !0), l + 4; + }, readDoubleLE: function(c, g) { + return g === void 0 && (g = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).getFloat64(g, !0); + }, readFloatLE: function(c, g) { + return g === void 0 && (g = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).getFloat32(g, !0); + }, readUInt32LE: function(c, g) { + return g === void 0 && (g = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).getUint32(g, !0); + }, readInt32LE: function(c, g) { + return g === void 0 && (g = 0), new DataView(c.buffer, c.byteOffset, c.byteLength).getInt32(g, !0); + } }; +})(Yt, Yt.exports); +var gn = Yt.exports; +const fs = gn, ps = gn, ms = class { + constructor(s) { + this.encoding = s; + } + decode(s) { + return fs.toString(s, this.encoding); + } + flush() { + return ""; + } +}, ys = class { + constructor() { + this.codePoint = 0, this.bytesSeen = 0, this.bytesNeeded = 0, this.lowerBoundary = 128, this.upperBoundary = 191; + } + decode(s) { + if (this.bytesNeeded === 0) { + let e = !0; + for (let n = Math.max(0, s.byteLength - 4), r = s.byteLength; n < r && e; n++) e = s[n] <= 127; + if (e) return ps.toString(s, "utf8"); + } + let t = ""; + for (let e = 0, n = s.byteLength; e < n; e++) { + const r = s[e]; + this.bytesNeeded !== 0 ? r < this.lowerBoundary || r > this.upperBoundary ? (this.codePoint = 0, this.bytesNeeded = 0, this.bytesSeen = 0, this.lowerBoundary = 128, this.upperBoundary = 191, t += "�") : (this.lowerBoundary = 128, this.upperBoundary = 191, this.codePoint = this.codePoint << 6 | 63 & r, this.bytesSeen++, this.bytesSeen === this.bytesNeeded && (t += String.fromCodePoint(this.codePoint), this.codePoint = 0, this.bytesNeeded = 0, this.bytesSeen = 0)) : r <= 127 ? t += String.fromCharCode(r) : r >= 194 && r <= 223 ? (this.bytesNeeded = 1, this.codePoint = 31 & r) : r >= 224 && r <= 239 ? (r === 224 ? this.lowerBoundary = 160 : r === 237 && (this.upperBoundary = 159), this.bytesNeeded = 2, this.codePoint = 15 & r) : r >= 240 && r <= 244 ? (r === 240 && (this.lowerBoundary = 144), r === 244 && (this.upperBoundary = 143), this.bytesNeeded = 3, this.codePoint = 7 & r) : t += "�"; + } + return t; + } + flush() { + const s = this.bytesNeeded > 0 ? "�" : ""; + return this.codePoint = 0, this.bytesNeeded = 0, this.bytesSeen = 0, this.lowerBoundary = 128, this.upperBoundary = 191, s; + } +}, { EventEmitter: _s } = dn, le = new Error("Stream was destroyed"), fn = (new Error("Premature close"), hs), pn = class { + constructor(s) { + this.hwm = s || 16, this.head = new Te(this.hwm), this.tail = this.head, this.length = 0; + } + clear() { + this.head = this.tail, this.head.clear(), this.length = 0; + } + push(s) { + if (this.length++, !this.head.push(s)) { + const t = this.head; + this.head = t.next = new Te(2 * this.head.buffer.length), this.head.push(s); + } + } + shift() { + this.length !== 0 && this.length--; + const s = this.tail.shift(); + if (s === void 0 && this.tail.next) { + const t = this.tail.next; + return this.tail.next = null, this.tail = t, this.tail.shift(); + } + return s; + } + peek() { + const s = this.tail.peek(); + return s === void 0 && this.tail.next ? this.tail.next.peek() : s; + } + isEmpty() { + return this.length === 0; + } +}, bs = class { + constructor(s = "utf8") { + switch (this.encoding = function(t) { + switch (t = t.toLowerCase()) { + case "utf8": + case "utf-8": + return "utf8"; + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return "utf16le"; + case "latin1": + case "binary": + return "latin1"; + case "base64": + case "ascii": + case "hex": + return t; + default: + throw new Error("Unknown encoding: " + t); + } + }(s), this.encoding) { + case "utf8": + this.decoder = new ys(); + break; + case "utf16le": + case "base64": + throw new Error("Unsupported encoding: " + this.encoding); + default: + this.decoder = new ms(this.encoding); + } + } + push(s) { + return typeof s == "string" ? s : this.decoder.decode(s); + } + write(s) { + return this.push(s); + } + end(s) { + let t = ""; + return s && (t = this.push(s)), t += this.decoder.flush(), t; + } +}, ct = 536870911, mn = 1 ^ ct, ws = 2 ^ ct, yn = 64, qe = 128, _n = 256, Ss = 1024, De = 2048, Cs = 4096, vs = 8192, Lt = 16384, Dt = 32768, te = 131072, Ls = 131328, ks = 16 ^ ct, Ne = 768 ^ ct, bn = 536838143, xs = 32 ^ ct, wn = 536739839, kt = 2 << 18, Sn = 4 << 18, Me = 8 << 18, As = 16 << 18, Cn = 32 << 18, ee = 64 << 18, Nt = 128 << 18, Fe = 512 << 18, Es = 1024 << 18, vn = 469499903, Ts = 535822335, Ln = 503316479, Rs = 268435455, xt = 262160, Is = 536608751, kn = 8404992, at = 14, Bs = 15, xn = 8405006, An = 33587200, En = 33587215, Ps = 2359296, Ue = 270794767, lt = Symbol.asyncIterator || Symbol("asyncIterator"); +class Os { + constructor(t, { highWaterMark: e = 16384, map: n = null, mapWritable: r, byteLength: i, byteLengthWritable: o } = {}) { + this.stream = t, this.queue = new pn(), this.highWaterMark = e, this.buffered = 0, this.error = null, this.pipeline = null, this.drains = null, this.byteLength = o || i || Bn, this.map = r || n, this.afterWrite = Fs.bind(this), this.afterUpdateNextTick = $s.bind(this); + } + get ended() { + return !!(this.stream._duplexState & Cn); + } + push(t) { + return this.map !== null && (t = this.map(t)), this.buffered += this.byteLength(t), this.queue.push(t), this.buffered < this.highWaterMark ? (this.stream._duplexState |= Me, !0) : (this.stream._duplexState |= 6291456, !1); + } + shift() { + const t = this.queue.shift(); + return this.buffered -= this.byteLength(t), this.buffered === 0 && (this.stream._duplexState &= 534773759), t; + } + end(t) { + typeof t == "function" ? this.stream.once("finish", t) : t != null && this.push(t), this.stream._duplexState = (this.stream._duplexState | Fe) & Ts; + } + autoBatch(t, e) { + const n = [], r = this.stream; + for (n.push(t); (r._duplexState & Ue) === Ps; ) n.push(r._writableState.shift()); + if (r._duplexState & Bs) return e(null); + r._writev(n, e); + } + update() { + const t = this.stream; + t._duplexState |= kt; + do { + for (; (t._duplexState & Ue) === Me; ) { + const e = this.shift(); + t._duplexState |= 67371008, t._write(e, this.afterWrite); + } + 1310720 & t._duplexState || this.updateNonPrimary(); + } while (this.continueUpdate() === !0); + t._duplexState &= 536346623; + } + updateNonPrimary() { + const t = this.stream; + if ((144965647 & t._duplexState) === Fe) return t._duplexState = 402653183 & t._duplexState | 262144, void t._final(Ms.bind(this)); + (t._duplexState & at) != 4 ? (t._duplexState & En) == 1 && (t._duplexState = (t._duplexState | xt) & mn, t._open(Rn.bind(this))) : t._duplexState & An || (t._duplexState |= xt, t._destroy(Tn.bind(this))); + } + continueUpdate() { + return !!(this.stream._duplexState & Nt) && (this.stream._duplexState &= Ln, !0); + } + updateCallback() { + (35127311 & this.stream._duplexState) === Sn ? this.update() : this.updateNextTick(); + } + updateNextTick() { + this.stream._duplexState & Nt || (this.stream._duplexState |= Nt, this.stream._duplexState & kt || fn(this.afterUpdateNextTick)); + } +} +class qs { + constructor(t, { highWaterMark: e = 16384, map: n = null, mapReadable: r, byteLength: i, byteLengthReadable: o } = {}) { + this.stream = t, this.queue = new pn(), this.highWaterMark = e === 0 ? 1 : e, this.buffered = 0, this.readAhead = e > 0, this.error = null, this.pipeline = null, this.byteLength = o || i || Bn, this.map = r || n, this.pipeTo = null, this.afterRead = Us.bind(this), this.afterUpdateNextTick = Hs.bind(this); + } + get ended() { + return !!(this.stream._duplexState & Lt); + } + pipe(t, e) { + if (this.pipeTo !== null) throw new Error("Can only pipe to one destination"); + if (typeof e != "function" && (e = null), this.stream._duplexState |= 512, this.pipeTo = t, this.pipeline = new Ds(this.stream, t, e), e && this.stream.on("error", He), In(t)) t._writableState.pipeline = this.pipeline, e && t.on("error", He), t.on("finish", this.pipeline.finished.bind(this.pipeline)); + else { + const n = this.pipeline.done.bind(this.pipeline, t), r = this.pipeline.done.bind(this.pipeline, t, null); + t.on("error", n), t.on("close", r), t.on("finish", this.pipeline.finished.bind(this.pipeline)); + } + t.on("drain", Ns.bind(this)), this.stream.emit("piping", t), t.emit("pipe", this.stream); + } + push(t) { + const e = this.stream; + return t === null ? (this.highWaterMark = 0, e._duplexState = 536805311 & e._duplexState | 1024, !1) : (this.map !== null && (t = this.map(t)) === null || (this.buffered += this.byteLength(t), this.queue.push(t), e._duplexState = 536805375 & e._duplexState | 128), this.buffered < this.highWaterMark); + } + shift() { + const t = this.queue.shift(); + return this.buffered -= this.byteLength(t), this.buffered === 0 && (this.stream._duplexState &= 536862591), t; + } + unshift(t) { + const e = [this.map !== null ? this.map(t) : t]; + for (; this.buffered > 0; ) e.push(this.shift()); + for (let n = 0; n < e.length - 1; n++) { + const r = e[n]; + this.buffered += this.byteLength(r), this.queue.push(r); + } + this.push(e[e.length - 1]); + } + read() { + const t = this.stream; + if ((16527 & t._duplexState) === qe) { + const e = this.shift(); + return this.pipeTo !== null && this.pipeTo.write(e) === !1 && (t._duplexState &= Ne), t._duplexState & De && t.emit("data", e), e; + } + return this.readAhead === !1 && (t._duplexState |= te, this.updateNextTick()), null; + } + drain() { + const t = this.stream; + for (; (16527 & t._duplexState) === qe && 768 & t._duplexState; ) { + const e = this.shift(); + this.pipeTo !== null && this.pipeTo.write(e) === !1 && (t._duplexState &= Ne), t._duplexState & De && t.emit("data", e); + } + } + update() { + const t = this.stream; + t._duplexState |= 32; + do { + for (this.drain(); this.buffered < this.highWaterMark && (214047 & t._duplexState) === te; ) t._duplexState |= 65552, t._read(this.afterRead), this.drain(); + (12431 & t._duplexState) == 4224 && (t._duplexState |= vs, t.emit("readable")), 80 & t._duplexState || this.updateNonPrimary(); + } while (this.continueUpdate() === !0); + t._duplexState &= xs; + } + updateNonPrimary() { + const t = this.stream; + (1167 & t._duplexState) === Ss && (t._duplexState = 536869887 & t._duplexState | 16384, t.emit("end"), (t._duplexState & xn) === kn && (t._duplexState |= 4), this.pipeTo !== null && this.pipeTo.end()), (t._duplexState & at) != 4 ? (t._duplexState & En) == 1 && (t._duplexState = (t._duplexState | xt) & mn, t._open(Rn.bind(this))) : t._duplexState & An || (t._duplexState |= xt, t._destroy(Tn.bind(this))); + } + continueUpdate() { + return !!(this.stream._duplexState & Dt) && (this.stream._duplexState &= bn, !0); + } + updateCallback() { + (32879 & this.stream._duplexState) === yn ? this.update() : this.updateNextTick(); + } + updateNextTick() { + this.stream._duplexState & Dt || (this.stream._duplexState |= Dt, 32 & this.stream._duplexState || fn(this.afterUpdateNextTick)); + } +} +class Ds { + constructor(t, e, n) { + this.from = t, this.to = e, this.afterPipe = n, this.error = null, this.pipeToFinished = !1; + } + finished() { + this.pipeToFinished = !0; + } + done(t, e) { + e && (this.error = e), t !== this.to || (this.to = null, this.from === null) ? t !== this.from || (this.from = null, this.to === null) ? (this.afterPipe !== null && this.afterPipe(this.error), this.to = this.from = this.afterPipe = null) : t._duplexState & Lt || this.to.destroy(this.error || new Error("Readable stream closed before ending")) : this.from._duplexState & Lt && this.pipeToFinished || this.from.destroy(this.error || new Error("Writable stream closed prematurely")); + } +} +function Ns() { + this.stream._duplexState |= 512, this.updateCallback(); +} +function Ms(s) { + const t = this.stream; + s && t.destroy(s), t._duplexState & at || (t._duplexState |= Cn, t.emit("finish")), (t._duplexState & xn) === kn && (t._duplexState |= 4), t._duplexState &= vn, t._duplexState & kt ? this.updateNextTick() : this.update(); +} +function Tn(s) { + const t = this.stream; + s || this.error === le || (s = this.error), s && t.emit("error", s), t._duplexState |= 8, t.emit("close"); + const e = t._readableState, n = t._writableState; + if (e !== null && e.pipeline !== null && e.pipeline.done(t, s), n !== null) { + for (; n.drains !== null && n.drains.length > 0; ) n.drains.shift().resolve(!1); + n.pipeline !== null && n.pipeline.done(t, s); + } +} +function Fs(s) { + const t = this.stream; + s && t.destroy(s), t._duplexState &= vn, this.drains !== null && function(e) { + for (let n = 0; n < e.length; n++) --e[n].writes == 0 && (e.shift().resolve(!0), n--); + }(this.drains), (6553615 & t._duplexState) === As && (t._duplexState &= 532676607, (t._duplexState & ee) === ee && t.emit("drain")), this.updateCallback(); +} +function Us(s) { + s && this.stream.destroy(s), this.stream._duplexState &= ks, this.readAhead !== !1 || this.stream._duplexState & _n || (this.stream._duplexState &= wn), this.updateCallback(); +} +function Hs() { + 32 & this.stream._duplexState || (this.stream._duplexState &= bn, this.update()); +} +function $s() { + this.stream._duplexState & kt || (this.stream._duplexState &= Ln, this.update()); +} +function Rn(s) { + const t = this.stream; + s && t.destroy(s), 4 & t._duplexState || (17423 & t._duplexState || (t._duplexState |= yn), 142606351 & t._duplexState || (t._duplexState |= Sn), t.emit("open")), t._duplexState &= Is, t._writableState !== null && t._writableState.updateCallback(), t._readableState !== null && t._readableState.updateCallback(); +} +function js(s) { + this._readableState !== null && (s === "data" && (this._duplexState |= 133376, this._readableState.updateNextTick()), s === "readable" && (this._duplexState |= Cs, this._readableState.updateNextTick())), this._writableState !== null && s === "drain" && (this._duplexState |= ee, this._writableState.updateNextTick()); +} +class Qs extends _s { + constructor(t) { + super(), this._duplexState = 0, this._readableState = null, this._writableState = null, t && (t.open && (this._open = t.open), t.destroy && (this._destroy = t.destroy), t.predestroy && (this._predestroy = t.predestroy), t.signal && t.signal.addEventListener("abort", Gs.bind(this))), this.on("newListener", js); + } + _open(t) { + t(null); + } + _destroy(t) { + t(null); + } + _predestroy() { + } + get readable() { + return this._readableState !== null || void 0; + } + get writable() { + return this._writableState !== null || void 0; + } + get destroyed() { + return !!(8 & this._duplexState); + } + get destroying() { + return !!(this._duplexState & at); + } + destroy(t) { + this._duplexState & at || (t || (t = le), this._duplexState = 535822271 & this._duplexState | 4, this._readableState !== null && (this._readableState.highWaterMark = 0, this._readableState.error = t), this._writableState !== null && (this._writableState.highWaterMark = 0, this._writableState.error = t), this._duplexState |= 2, this._predestroy(), this._duplexState &= ws, this._readableState !== null && this._readableState.updateNextTick(), this._writableState !== null && this._writableState.updateNextTick()); + } +} +class At extends Qs { + constructor(t) { + super(t), this._duplexState |= 8519681, this._readableState = new qs(this, t), t && (this._readableState.readAhead === !1 && (this._duplexState &= wn), t.read && (this._read = t.read), t.eagerOpen && this._readableState.updateNextTick(), t.encoding && this.setEncoding(t.encoding)); + } + setEncoding(t) { + const e = new bs(t), n = this._readableState.map || zs; + return this._readableState.map = function(r) { + const i = e.push(r); + return i === "" ? null : n(i); + }, this; + } + _read(t) { + t(null); + } + pipe(t, e) { + return this._readableState.updateNextTick(), this._readableState.pipe(t, e), t; + } + read() { + return this._readableState.updateNextTick(), this._readableState.read(); + } + push(t) { + return this._readableState.updateNextTick(), this._readableState.push(t); + } + unshift(t) { + return this._readableState.updateNextTick(), this._readableState.unshift(t); + } + resume() { + return this._duplexState |= Ls, this._readableState.updateNextTick(), this; + } + pause() { + return this._duplexState &= this._readableState.readAhead === !1 ? 536739583 : 536870655, this; + } + static _fromAsyncIterator(t, e) { + let n; + const r = new At({ ...e, read(o) { + t.next().then(i).then(o.bind(null, null)).catch(o); + }, predestroy() { + n = t.return(); + }, destroy(o) { + if (!n) return o(null); + n.then(o.bind(null, null)).catch(o); + } }); + return r; + function i(o) { + o.done ? r.push(null) : r.push(o.value); + } + } + static from(t, e) { + if (In(n = t) && n.readable) return t; + var n; + if (t[lt]) return this._fromAsyncIterator(t[lt](), e); + Array.isArray(t) || (t = t === void 0 ? [] : [t]); + let r = 0; + return new At({ ...e, read(i) { + this.push(r === t.length ? null : t[r++]), i(null); + } }); + } + static isBackpressured(t) { + return !!(17422 & t._duplexState) || t._readableState.buffered >= t._readableState.highWaterMark; + } + static isPaused(t) { + return !(t._duplexState & _n); + } + [lt]() { + const t = this; + let e = null, n = null, r = null; + return this.on("error", (a) => { + e = a; + }), this.on("readable", function() { + n !== null && i(t.read()); + }), this.on("close", function() { + n !== null && i(null); + }), { [lt]() { + return this; + }, next: () => new Promise(function(a, h) { + n = a, r = h; + const u = t.read(); + u !== null ? i(u) : 8 & t._duplexState && i(null); + }), return: () => o(null), throw: (a) => o(a) }; + function i(a) { + r !== null && (e ? r(e) : a !== null || t._duplexState & Lt ? n({ value: a, done: a === null }) : r(le), r = n = null); + } + function o(a) { + return t.destroy(a), new Promise((h, u) => { + if (8 & t._duplexState) return h({ value: void 0, done: !0 }); + t.once("close", function() { + a ? u(a) : h({ value: void 0, done: !0 }); + }); + }); + } + } +} +class Ws extends At { + constructor(t) { + super(t), this._duplexState = 1 | this._duplexState & te, this._writableState = new Os(this, t), t && (t.writev && (this._writev = t.writev), t.write && (this._write = t.write), t.final && (this._final = t.final)); + } + cork() { + this._duplexState |= Es; + } + uncork() { + this._duplexState &= Rs, this._writableState.updateNextTick(); + } + _writev(t, e) { + e(null); + } + _write(t, e) { + this._writableState.autoBatch(t, e); + } + _final(t) { + t(null); + } + write(t) { + return this._writableState.updateNextTick(), this._writableState.push(t); + } + end(t) { + return this._writableState.updateNextTick(), this._writableState.end(t), this; + } +} +function zs(s) { + return s; +} +function Vs(s) { + return !!s._readableState || !!s._writableState; +} +function In(s) { + return typeof s._duplexState == "number" && Vs(s); +} +function Bn(s) { + return function(t) { + return typeof t == "object" && t !== null && typeof t.byteLength == "number"; + }(s) ? s.byteLength : 1024; +} +function He() { +} +function Gs() { + this.destroy(new Error("Stream aborted.")); +} +var Pn = Ws; +function $e(s, t) { + for (const e in t) Object.defineProperty(s, e, { value: t[e], enumerable: !0, configurable: !0 }); + return s; +} +const C = V(function(s, t, e) { + if (!s || typeof s == "string") throw new TypeError("Please pass an Error to err-code"); + e || (e = {}), typeof t == "object" && (e = t, t = ""), t && (e.code = t); + try { + return $e(s, e); + } catch { + e.message = s.message, e.stack = s.stack; + const r = function() { + }; + return r.prototype = Object.create(Object.getPrototypeOf(s)), $e(new r(), e); + } +}), Et = "0123456789abcdef", On = [], Tt = []; +for (let s = 0; s < 256; s++) On[s] = Et[s >> 4 & 15] + Et[15 & s], s < 16 && (s < 10 ? Tt[48 + s] = s : Tt[87 + s] = s); +const Z = (s) => { + const t = s.length; + let e = "", n = 0; + for (; n < t; ) e += On[s[n++]]; + return e; +}, ne = (s) => { + const t = s.length >> 1, e = t << 1, n = new Uint8Array(t); + let r = 0, i = 0; + for (; i < e; ) n[r++] = Tt[s.charCodeAt(i++)] << 4 | Tt[s.charCodeAt(i++)]; + return n; +}; +for (var Js = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", Ys = typeof Uint8Array > "u" ? [] : new Uint8Array(256), gt = 0; gt < 64; gt++) Ys[Js.charCodeAt(gt)] = gt; +const Ks = new TextDecoder(), qn = (s, t) => Ks.decode(s), Xs = new TextEncoder(), ge = (s) => Xs.encode(s), G = (s) => { + let t, e = "", n = 0; + const r = s.length; + for (; n < r; ) t = s.charCodeAt(n++), e += Et[t >> 4] + Et[15 & t]; + return e; +}, it = (s) => { + const t = ne(s); + if (t.length <= 65536) return String.fromCharCode(...t); + let e = "", n = 0; + for (; n < t.length; ) e += String.fromCharCode(...t.subarray(n, n += 65536)); + return e; +}, je = typeof window < "u" ? window : self, se = je.crypto || je.msCrypto || {}; +se.subtle || se.webkitSubtle; +const Rt = (s) => { + const t = new Uint8Array(s); + return se.getRandomValues(t); +}, Zs = P("simple-peer"), Mt = 65536; +function Qe(s) { + return s.replace(/a=ice-options:trickle\s\n/g, ""); +} +let ot = class re extends Pn { + constructor(e) { + super(e = Object.assign({ allowHalfOpen: !1 }, e)); + f(this, "_pc"); + if (this.__objectMode = !!e.objectMode, this._id = Z(Rt(4)).slice(0, 7), this._debug("new peer %o", e), this.channelName = e.initiator ? e.channelName || Z(Rt(20)) : null, this.initiator = e.initiator || !1, this.channelConfig = e.channelConfig || re.channelConfig, this.channelNegotiated = this.channelConfig.negotiated, this.config = Object.assign({}, re.config, e.config), this.offerOptions = e.offerOptions || {}, this.answerOptions = e.answerOptions || {}, this.sdpTransform = e.sdpTransform || ((n) => n), this.trickle = e.trickle === void 0 || e.trickle, this.allowHalfTrickle = e.allowHalfTrickle !== void 0 && e.allowHalfTrickle, this.iceCompleteTimeout = e.iceCompleteTimeout || 5e3, this._destroying = !1, this._connected = !1, this.remoteAddress = void 0, this.remoteFamily = void 0, this.remotePort = void 0, this.localAddress = void 0, this.localFamily = void 0, this.localPort = void 0, !Jt) throw C(typeof window > "u" ? new Error("No WebRTC support: Specify `opts.wrtc` option in this environment") : new Error("No WebRTC support: Not a supported browser"), "ERR_WEBRTC_SUPPORT"); + this._pcReady = !1, this._channelReady = !1, this._iceComplete = !1, this._iceCompleteTimer = null, this._channel = null, this._pendingCandidates = [], this._isNegotiating = !1, this._firstNegotiation = !0, this._batchedNegotiation = !1, this._queuedNegotiation = !1, this._sendersAwaitingStable = [], this._closingInterval = null, this._remoteTracks = [], this._remoteStreams = [], this._chunk = null, this._cb = null, this._interval = null; + try { + this._pc = new Jt(this.config); + } catch (n) { + return void this.__destroy(C(n, "ERR_PC_CONSTRUCTOR")); + } + this._isReactNativeWebrtc = typeof this._pc._peerConnectionId == "number", this._pc.oniceconnectionstatechange = () => { + this._onIceStateChange(); + }, this._pc.onicegatheringstatechange = () => { + this._onIceStateChange(); + }, this._pc.onconnectionstatechange = () => { + this._onConnectionStateChange(); + }, this._pc.onsignalingstatechange = () => { + this._onSignalingStateChange(); + }, this._pc.onicecandidate = (n) => { + this._onIceCandidate(n); + }, typeof this._pc.peerIdentity == "object" && this._pc.peerIdentity.catch((n) => { + this.__destroy(C(n, "ERR_PC_PEER_IDENTITY")); + }), this.initiator || this.channelNegotiated ? this._setupData({ channel: this._pc.createDataChannel(this.channelName, this.channelConfig) }) : this._pc.ondatachannel = (n) => { + this._setupData(n); + }, this._debug("initial negotiation"), this._needsNegotiation(), this._onFinishBound = () => { + this._onFinish(); + }, this.once("finish", this._onFinishBound); + } + get bufferSize() { + return this._channel && this._channel.bufferedAmount || 0; + } + get connected() { + return this._connected && this._channel.readyState === "open"; + } + address() { + return { port: this.localPort, family: this.localFamily, address: this.localAddress }; + } + signal(e) { + if (!this._destroying) { + if (this.destroyed) throw C(new Error("cannot signal after peer is destroyed"), "ERR_DESTROYED"); + if (typeof e == "string") try { + e = JSON.parse(e); + } catch { + e = {}; + } + this._debug("signal()"), e.renegotiate && this.initiator && (this._debug("got request to renegotiate"), this._needsNegotiation()), e.transceiverRequest && this.initiator && (this._debug("got request for transceiver"), this.addTransceiver(e.transceiverRequest.kind, e.transceiverRequest.init)), e.candidate && (this._pc.remoteDescription && this._pc.remoteDescription.type ? this._addIceCandidate(e.candidate) : this._pendingCandidates.push(e.candidate)), e.sdp && this._pc.setRemoteDescription(new os(e)).then(() => { + this.destroyed || (this._pendingCandidates.forEach((n) => { + this._addIceCandidate(n); + }), this._pendingCandidates = [], this._pc.remoteDescription.type === "offer" && this._createAnswer()); + }).catch((n) => { + this.__destroy(C(n, "ERR_SET_REMOTE_DESCRIPTION")); + }), e.sdp || e.candidate || e.renegotiate || e.transceiverRequest || this.__destroy(C(new Error("signal() called with invalid signal data"), "ERR_SIGNALING")); + } + } + _addIceCandidate(e) { + const n = new as(e); + this._pc.addIceCandidate(n).catch((r) => { + var i; + !n.address || n.address.endsWith(".local") ? (i = "Ignoring unsupported ICE candidate.", console.warn(i)) : this.__destroy(C(r, "ERR_ADD_ICE_CANDIDATE")); + }); + } + send(e) { + if (!this._destroying) { + if (this.destroyed) throw C(new Error("cannot send after peer is destroyed"), "ERR_DESTROYED"); + this._channel.send(e); + } + } + _needsNegotiation() { + this._debug("_needsNegotiation"), this._batchedNegotiation || (this._batchedNegotiation = !0, queueMicrotask(() => { + this._batchedNegotiation = !1, this.initiator || !this._firstNegotiation ? (this._debug("starting batched negotiation"), this.negotiate()) : this._debug("non-initiator initial negotiation request discarded"), this._firstNegotiation = !1; + })); + } + negotiate() { + if (!this._destroying) { + if (this.destroyed) throw C(new Error("cannot negotiate after peer is destroyed"), "ERR_DESTROYED"); + this.initiator ? this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("start negotiation"), setTimeout(() => { + this._createOffer(); + }, 0)) : this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("requesting negotiation from initiator"), this.emit("signal", { type: "renegotiate", renegotiate: !0 })), this._isNegotiating = !0; + } + } + _final(e) { + this._readableState.ended || this.push(null), e(null); + } + __destroy(e) { + this.end(), this._destroy(() => { + }, e); + } + _destroy(e, n) { + this.destroyed || this._destroying || (this._destroying = !0, this._debug("destroying (error: %s)", n && (n.message || n)), setTimeout(() => { + if (this._connected = !1, this._pcReady = !1, this._channelReady = !1, this._remoteTracks = null, this._remoteStreams = null, this._senderMap = null, clearInterval(this._closingInterval), this._closingInterval = null, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._onFinishBound && this.removeListener("finish", this._onFinishBound), this._onFinishBound = null, this._channel) { + try { + this._channel.close(); + } catch { + } + this._channel.onmessage = null, this._channel.onopen = null, this._channel.onclose = null, this._channel.onerror = null; + } + if (this._pc) { + try { + this._pc.close(); + } catch { + } + this._pc.oniceconnectionstatechange = null, this._pc.onicegatheringstatechange = null, this._pc.onsignalingstatechange = null, this._pc.onicecandidate = null, this._pc.ontrack = null, this._pc.ondatachannel = null; + } + this._pc = null, this._channel = null, n && this.emit("error", n), e(); + }, 0)); + } + _setupData(e) { + if (!e.channel) return this.__destroy(C(new Error("Data channel event is missing `channel` property"), "ERR_DATA_CHANNEL")); + this._channel = e.channel, this._channel.binaryType = "arraybuffer", typeof this._channel.bufferedAmountLowThreshold == "number" && (this._channel.bufferedAmountLowThreshold = Mt), this.channelName = this._channel.label, this._channel.onmessage = (r) => { + this._onChannelMessage(r); + }, this._channel.onbufferedamountlow = () => { + this._onChannelBufferedAmountLow(); + }, this._channel.onopen = () => { + this._onChannelOpen(); + }, this._channel.onclose = () => { + this._onChannelClose(); + }, this._channel.onerror = (r) => { + const i = r.error instanceof Error ? r.error : new Error(`Datachannel error: ${r.message} ${r.filename}:${r.lineno}:${r.colno}`); + this.__destroy(C(i, "ERR_DATA_CHANNEL")); + }; + let n = !1; + this._closingInterval = setInterval(() => { + this._channel && this._channel.readyState === "closing" ? (n && this._onChannelClose(), n = !0) : n = !1; + }, 5e3); + } + _write(e, n) { + if (this.destroyed) return n(C(new Error("cannot write after peer is destroyed"), "ERR_DATA_CHANNEL")); + if (this._connected) { + try { + this.send(e); + } catch (r) { + return this.__destroy(C(r, "ERR_DATA_CHANNEL")); + } + this._channel.bufferedAmount > Mt ? (this._debug("start backpressure: bufferedAmount %d", this._channel.bufferedAmount), this._cb = n) : n(null); + } else this._debug("write before connect"), this._chunk = e, this._cb = n; + } + _onFinish() { + if (this.destroyed) return; + const e = () => { + setTimeout(() => this.__destroy(), 1e3); + }; + this._connected ? e() : this.once("connect", e); + } + _startIceCompleteTimeout() { + this.destroyed || this._iceCompleteTimer || (this._debug("started iceComplete timeout"), this._iceCompleteTimer = setTimeout(() => { + this._iceComplete || (this._iceComplete = !0, this._debug("iceComplete timeout completed"), this.emit("iceTimeout"), this.emit("_iceComplete")); + }, this.iceCompleteTimeout)); + } + _createOffer() { + this.destroyed || this._pc.createOffer(this.offerOptions).then((e) => { + if (this.destroyed) return; + this.trickle || this.allowHalfTrickle || (e.sdp = Qe(e.sdp)), e.sdp = this.sdpTransform(e.sdp); + const n = () => { + if (this.destroyed) return; + const r = this._pc.localDescription || e; + this._debug("signal"), this.emit("signal", { type: r.type, sdp: r.sdp }); + }; + this._pc.setLocalDescription(e).then(() => { + this._debug("createOffer success"), this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n)); + }).catch((r) => { + this.__destroy(C(r, "ERR_SET_LOCAL_DESCRIPTION")); + }); + }).catch((e) => { + this.__destroy(C(e, "ERR_CREATE_OFFER")); + }); + } + _createAnswer() { + this.destroyed || this._pc.createAnswer(this.answerOptions).then((e) => { + if (this.destroyed) return; + this.trickle || this.allowHalfTrickle || (e.sdp = Qe(e.sdp)), e.sdp = this.sdpTransform(e.sdp); + const n = () => { + var i; + if (this.destroyed) return; + const r = this._pc.localDescription || e; + this._debug("signal"), this.emit("signal", { type: r.type, sdp: r.sdp }), this.initiator || ((i = this._requestMissingTransceivers) == null || i.call(this)); + }; + this._pc.setLocalDescription(e).then(() => { + this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n)); + }).catch((r) => { + this.__destroy(C(r, "ERR_SET_LOCAL_DESCRIPTION")); + }); + }).catch((e) => { + this.__destroy(C(e, "ERR_CREATE_ANSWER")); + }); + } + _onConnectionStateChange() { + this.destroyed || this._destroying || this._pc.connectionState === "failed" && this.__destroy(C(new Error("Connection failed."), "ERR_CONNECTION_FAILURE")); + } + _onIceStateChange() { + if (this.destroyed) return; + const e = this._pc.iceConnectionState, n = this._pc.iceGatheringState; + this._debug("iceStateChange (connection: %s) (gathering: %s)", e, n), this.emit("iceStateChange", e, n), e !== "connected" && e !== "completed" || (this._pcReady = !0, this._maybeReady()), e === "failed" && this.__destroy(C(new Error("Ice connection failed."), "ERR_ICE_CONNECTION_FAILURE")), e === "closed" && this.__destroy(C(new Error("Ice connection closed."), "ERR_ICE_CONNECTION_CLOSED")); + } + getStats(e) { + const n = (r) => (Object.prototype.toString.call(r.values) === "[object Array]" && r.values.forEach((i) => { + Object.assign(r, i); + }), r); + this._pc.getStats.length === 0 || this._isReactNativeWebrtc ? this._pc.getStats().then((r) => { + const i = []; + r.forEach((o) => { + i.push(n(o)); + }), e(null, i); + }, (r) => e(r)) : this._pc.getStats.length > 0 ? this._pc.getStats((r) => { + if (this.destroyed) return; + const i = []; + r.result().forEach((o) => { + const a = {}; + o.names().forEach((h) => { + a[h] = o.stat(h); + }), a.id = o.id, a.type = o.type, a.timestamp = o.timestamp, i.push(n(a)); + }), e(null, i); + }, (r) => e(r)) : e(null, []); + } + _maybeReady() { + if (this._debug("maybeReady pc %s channel %s", this._pcReady, this._channelReady), this._connected || this._connecting || !this._pcReady || !this._channelReady) return; + this._connecting = !0; + const e = () => { + this.destroyed || this._destroying || this.getStats((n, r) => { + if (this.destroyed || this._destroying) return; + n && (r = []); + const i = {}, o = {}, a = {}; + let h = !1; + r.forEach((d) => { + d.type !== "remotecandidate" && d.type !== "remote-candidate" || (i[d.id] = d), d.type !== "localcandidate" && d.type !== "local-candidate" || (o[d.id] = d), d.type !== "candidatepair" && d.type !== "candidate-pair" || (a[d.id] = d); + }); + const u = (d) => { + h = !0; + let p = o[d.localCandidateId]; + p && (p.ip || p.address) ? (this.localAddress = p.ip || p.address, this.localPort = Number(p.port)) : p && p.ipAddress ? (this.localAddress = p.ipAddress, this.localPort = Number(p.portNumber)) : typeof d.googLocalAddress == "string" && (p = d.googLocalAddress.split(":"), this.localAddress = p[0], this.localPort = Number(p[1])), this.localAddress && (this.localFamily = this.localAddress.includes(":") ? "IPv6" : "IPv4"); + let _ = i[d.remoteCandidateId]; + _ && (_.ip || _.address) ? (this.remoteAddress = _.ip || _.address, this.remotePort = Number(_.port)) : _ && _.ipAddress ? (this.remoteAddress = _.ipAddress, this.remotePort = Number(_.portNumber)) : typeof d.googRemoteAddress == "string" && (_ = d.googRemoteAddress.split(":"), this.remoteAddress = _[0], this.remotePort = Number(_[1])), this.remoteAddress && (this.remoteFamily = this.remoteAddress.includes(":") ? "IPv6" : "IPv4"), this._debug("connect local: %s:%s remote: %s:%s", this.localAddress, this.localPort, this.remoteAddress, this.remotePort); + }; + if (r.forEach((d) => { + d.type === "transport" && d.selectedCandidatePairId && u(a[d.selectedCandidatePairId]), (d.type === "googCandidatePair" && d.googActiveConnection === "true" || (d.type === "candidatepair" || d.type === "candidate-pair") && d.selected) && u(d); + }), h || Object.keys(a).length && !Object.keys(o).length) { + if (this._connecting = !1, this._connected = !0, this._chunk) { + try { + this.send(this._chunk); + } catch (p) { + return this.__destroy(C(p, "ERR_DATA_CHANNEL")); + } + this._chunk = null, this._debug('sent chunk from "write before connect"'); + const d = this._cb; + this._cb = null, d(null); + } + typeof this._channel.bufferedAmountLowThreshold != "number" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect"); + } else setTimeout(e, 100); + }); + }; + e(); + } + _onInterval() { + !this._cb || !this._channel || this._channel.bufferedAmount > Mt || this._onChannelBufferedAmountLow(); + } + _onSignalingStateChange() { + this.destroyed || (this._pc.signalingState === "stable" && (this._isNegotiating = !1, this._debug("flushing sender queue", this._sendersAwaitingStable), this._sendersAwaitingStable.forEach((e) => { + this._pc.removeTrack(e), this._queuedNegotiation = !0; + }), this._sendersAwaitingStable = [], this._queuedNegotiation ? (this._debug("flushing negotiation queue"), this._queuedNegotiation = !1, this._needsNegotiation()) : (this._debug("negotiated"), this.emit("negotiated"))), this._debug("signalingStateChange %s", this._pc.signalingState), this.emit("signalingStateChange", this._pc.signalingState)); + } + _onIceCandidate(e) { + this.destroyed || (e.candidate && this.trickle ? this.emit("signal", { type: "candidate", candidate: { candidate: e.candidate.candidate, sdpMLineIndex: e.candidate.sdpMLineIndex, sdpMid: e.candidate.sdpMid } }) : e.candidate || this._iceComplete || (this._iceComplete = !0, this.emit("_iceComplete")), e.candidate && this._startIceCompleteTimeout()); + } + _onChannelMessage(e) { + if (this.destroyed) return; + let n = e.data; + n instanceof ArrayBuffer ? n = new Uint8Array(n) : this.__objectMode === !1 && (n = ge(n)), this.push(n); + } + _onChannelBufferedAmountLow() { + if (this.destroyed || !this._cb) return; + this._debug("ending backpressure: bufferedAmount %d", this._channel.bufferedAmount); + const e = this._cb; + this._cb = null, e(null); + } + _onChannelOpen() { + this._connected || this.destroyed || (this._debug("on channel open"), this._channelReady = !0, this._maybeReady()); + } + _onChannelClose() { + this.destroyed || (this._debug("on channel close"), this.__destroy()); + } + _debug() { + const e = [].slice.call(arguments); + e[0] = "[" + this._id + "] " + e[0], Zs.apply(null, e); + } +}; +ot.WEBRTC_SUPPORT = !!Jt, ot.config = { iceServers: [{ urls: ["stun:stun.l.google.com:19302", "stun:global.stun.twilio.com:3478"] }], sdpSemantics: "unified-plan" }, ot.channelConfig = {}; +const B = {}, ie = { DEFAULT_ANNOUNCE_PEERS: 50, MAX_ANNOUNCE_PEERS: 82, parseUrl: (s) => { + const t = new URL(s.replace(/^udp:/, "http:")); + return s.match(/^udp:/) && Object.defineProperties(t, { href: { value: t.href.replace(/^http/, "udp") }, protocol: { value: t.protocol.replace(/^http/, "udp") }, origin: { value: t.origin.replace(/^http/, "udp") } }), t; +}, ...Object.freeze(Object.defineProperty({ __proto__: null, default: B }, Symbol.toStringTag, { value: "Module" })) }, tr = P("simple-websocket"), st = typeof B != "function" ? WebSocket : B; +class Dn extends Pn { + constructor(t = {}) { + if (typeof t == "string" && (t = { url: t }), super(t = Object.assign({ allowHalfOpen: !1 }, t)), this.__objectMode = !!t.objectMode, t.objectMode != null && delete t.objectMode, t.url == null && t.socket == null) throw new Error("Missing required `url` or `socket` option"); + if (t.url != null && t.socket != null) throw new Error("Must specify either `url` or `socket` option, not both"); + if (this._id = Z(Rt(4)).slice(0, 7), this._debug("new websocket: %o", t), this.connected = !1, this._chunk = null, this._cb = null, this._interval = null, t.socket) this.url = t.socket.url, this._ws = t.socket, this.connected = t.socket.readyState === st.OPEN; + else { + this.url = t.url; + try { + this._ws = typeof B == "function" ? new st(t.url, { ...t, encoding: void 0 }) : new st(t.url); + } catch (e) { + return void Gt(() => this.destroy(e)); + } + } + this._ws.binaryType = "arraybuffer", t.socket && this.connected ? Gt(() => this._handleOpen()) : this._ws.onopen = () => this._handleOpen(), this._ws.onmessage = (e) => this._handleMessage(e), this._ws.onclose = () => this._handleClose(), this._ws.onerror = (e) => this._handleError(e), this._handleFinishBound = () => this._handleFinish(), this.once("finish", this._handleFinishBound); + } + send(t) { + this._ws.send(t); + } + _final(t) { + this._readableState.ended || this.push(null), t(null); + } + _destroy(t) { + if (!this.destroyed) { + if (this._writableState.ended || this.end(), this.connected = !1, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._handleFinishBound && this.removeListener("finish", this._handleFinishBound), this._handleFinishBound = null, this._ws) { + const e = this._ws, n = () => { + e.onclose = null; + }; + if (e.readyState === st.CLOSED) n(); + else try { + e.onclose = n, e.close(); + } catch { + n(); + } + e.onopen = null, e.onmessage = null, e.onerror = () => { + }; + } + this._ws = null, t(); + } + } + _write(t, e) { + if (this.destroyed) return e(new Error("cannot write after socket is destroyed")); + if (this.connected) { + try { + this.send(t); + } catch (n) { + return this.destroy(n); + } + typeof B != "function" && this._ws.bufferedAmount > 65536 ? (this._debug("start backpressure: bufferedAmount %d", this._ws.bufferedAmount), this._cb = e) : e(null); + } else this._debug("write before connect"), this._chunk = t, this._cb = e; + } + _handleOpen() { + if (!this.connected && !this.destroyed) { + if (this.connected = !0, this._chunk) { + try { + this.send(this._chunk); + } catch (e) { + return this.destroy(e); + } + this._chunk = null, this._debug('sent chunk from "write before connect"'); + const t = this._cb; + this._cb = null, t(null); + } + typeof B != "function" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect"); + } + } + _handleMessage(t) { + if (this.destroyed) return; + let e = t.data; + e instanceof ArrayBuffer && (e = new Uint8Array(e)), this.__objectMode === !1 && (e = ge(e)), this.push(e); + } + _handleClose() { + this.destroyed || (this._debug("on close"), this.destroy()); + } + _handleError(t) { + this.destroy(new Error(`Error connecting to ${this.url}`)); + } + _handleFinish() { + if (this.destroyed) return; + const t = () => { + setTimeout(() => this.destroy(), 1e3); + }; + this.connected ? t() : this.once("connect", t); + } + _onInterval() { + if (!this._cb || !this._ws || this._ws.bufferedAmount > 65536) return; + this._debug("ending backpressure: bufferedAmount %d", this._ws.bufferedAmount); + const t = this._cb; + this._cb = null, t(null); + } + _debug() { + const t = [].slice.call(arguments); + t[0] = "[" + this._id + "] " + t[0], tr.apply(null, t); + } +} +Dn.WEBSOCKET_SUPPORT = !!st; +class er extends un { + constructor(t, e) { + super(), this.client = t, this.announceUrl = e, this.interval = null, this.destroyed = !1; + } + setInterval(t) { + t == null && (t = this.DEFAULT_ANNOUNCE_INTERVAL), clearInterval(this.interval), t && (this.interval = setInterval(() => { + this.announce(this.client._defaultAnnounceOpts()); + }, t), this.interval.unref && this.interval.unref()); + } +} +const R = P("bittorrent-tracker:websocket-tracker"), q = {}; +class oe extends er { + constructor(t, e) { + super(t, e), R("new websocket tracker %s", e), this.peers = {}, this.socket = null, this.reconnecting = !1, this.retries = 0, this.reconnectTimer = null, this.expectingResponse = !1, this._openSocket(); + } + announce(t) { + if (this.destroyed || this.reconnecting) return; + if (!this.socket.connected) return void this.socket.once("connect", () => { + this.announce(t); + }); + const e = Object.assign({}, t, { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary }); + if (this._trackerId && (e.trackerid = this._trackerId), t.event === "stopped" || t.event === "completed") this._send(e); + else { + const n = Math.min(t.numwant, 5); + this._generateOffers(n, (r) => { + e.numwant = n, e.offers = r, this._send(e); + }); + } + } + scrape(t) { + if (this.destroyed || this.reconnecting) return; + if (!this.socket.connected) return void this.socket.once("connect", () => { + this.scrape(t); + }); + const e = { action: "scrape", info_hash: Array.isArray(t.infoHash) && t.infoHash.length > 0 ? t.infoHash.map((n) => it(n)) : t.infoHash && it(t.infoHash) || this.client._infoHashBinary }; + this._send(e); + } + destroy(t = We) { + if (this.destroyed) return t(null); + this.destroyed = !0, clearInterval(this.interval), clearTimeout(this.reconnectTimer); + for (const i in this.peers) { + const o = this.peers[i]; + clearTimeout(o.trackerTimeout), o.destroy(); + } + if (this.peers = null, this.socket && (this.socket.removeListener("connect", this._onSocketConnectBound), this.socket.removeListener("data", this._onSocketDataBound), this.socket.removeListener("close", this._onSocketCloseBound), this.socket.removeListener("error", this._onSocketErrorBound), this.socket = null), this._onSocketConnectBound = null, this._onSocketErrorBound = null, this._onSocketDataBound = null, this._onSocketCloseBound = null, q[this.announceUrl] && (q[this.announceUrl].consumers -= 1), q[this.announceUrl].consumers > 0) return t(); + let e, n = q[this.announceUrl]; + if (delete q[this.announceUrl], n.on("error", We), n.once("close", t), !this.expectingResponse) return r(); + function r() { + e && (clearTimeout(e), e = null), n.removeListener("data", r), n.destroy(), n = null; + } + e = setTimeout(r, ie.DESTROY_TIMEOUT), n.once("data", r); + } + _openSocket() { + if (this.destroyed = !1, this.peers || (this.peers = {}), this._onSocketConnectBound = () => { + this._onSocketConnect(); + }, this._onSocketErrorBound = (t) => { + this._onSocketError(t); + }, this._onSocketDataBound = (t) => { + this._onSocketData(t); + }, this._onSocketCloseBound = () => { + this._onSocketClose(); + }, this.socket = q[this.announceUrl], this.socket) q[this.announceUrl].consumers += 1, this.socket.connected && this._onSocketConnectBound(); + else { + const t = new URL(this.announceUrl); + let e; + this.client._proxyOpts && (e = t.protocol === "wss:" ? this.client._proxyOpts.httpsAgent : this.client._proxyOpts.httpAgent, !e && this.client._proxyOpts.socksProxy && (e = this.client._proxyOpts.socksProxy)), this.socket = q[this.announceUrl] = new Dn({ url: this.announceUrl, agent: e }), this.socket.consumers = 1, this.socket.once("connect", this._onSocketConnectBound); + } + this.socket.on("data", this._onSocketDataBound), this.socket.once("close", this._onSocketCloseBound), this.socket.once("error", this._onSocketErrorBound); + } + _onSocketConnect() { + this.destroyed || this.reconnecting && (this.reconnecting = !1, this.retries = 0, this.announce(this.client._defaultAnnounceOpts())); + } + _onSocketData(t) { + if (!this.destroyed) { + this.expectingResponse = !1; + try { + t = JSON.parse(qn(t)); + } catch { + return void this.client.emit("warning", new Error("Invalid tracker response")); + } + t.action === "announce" ? this._onAnnounceResponse(t) : t.action === "scrape" ? this._onScrapeResponse(t) : this._onSocketError(new Error(`invalid action in WS response: ${t.action}`)); + } + } + _onAnnounceResponse(t) { + if (t.info_hash !== this.client._infoHashBinary) return void R("ignoring websocket data from %s for %s (looking for %s: reused socket)", this.announceUrl, G(t.info_hash), this.client.infoHash); + if (t.peer_id && t.peer_id === this.client._peerIdBinary) return; + R("received %s from %s for %s", JSON.stringify(t), this.announceUrl, this.client.infoHash); + const e = t["failure reason"]; + if (e) return this.client.emit("warning", new Error(e)); + const n = t["warning message"]; + n && this.client.emit("warning", new Error(n)); + const r = t.interval || t["min interval"]; + r && this.setInterval(1e3 * r); + const i = t["tracker id"]; + if (i && (this._trackerId = i), t.complete != null) { + const a = Object.assign({}, t, { announce: this.announceUrl, infoHash: G(t.info_hash) }); + this.client.emit("update", a); + } + let o; + if (t.offer && t.peer_id && (R("creating peer (from remote offer)"), o = this._createPeer(), o.id = G(t.peer_id), o.once("signal", (a) => { + const h = { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary, to_peer_id: t.peer_id, answer: a, offer_id: t.offer_id }; + this._trackerId && (h.trackerid = this._trackerId), this._send(h); + }), this.client.emit("peer", o), o.signal(t.offer)), t.answer && t.peer_id) { + const a = G(t.offer_id); + o = this.peers[a], o ? (o.id = G(t.peer_id), this.client.emit("peer", o), o.signal(t.answer), clearTimeout(o.trackerTimeout), o.trackerTimeout = null, delete this.peers[a]) : R(`got unexpected answer: ${JSON.stringify(t.answer)}`); + } + } + _onScrapeResponse(t) { + t = t.files || {}; + const e = Object.keys(t); + e.length !== 0 ? e.forEach((n) => { + const r = Object.assign(t[n], { announce: this.announceUrl, infoHash: G(n) }); + this.client.emit("scrape", r); + }) : this.client.emit("warning", new Error("invalid scrape response")); + } + _onSocketClose() { + this.destroyed || (this.destroy(), this._startReconnectTimer()); + } + _onSocketError(t) { + this.destroyed || (this.destroy(), this.client.emit("warning", t), this._startReconnectTimer()); + } + _startReconnectTimer() { + const t = Math.floor(3e5 * Math.random()) + Math.min(1e4 * Math.pow(2, this.retries), 36e5); + this.reconnecting = !0, clearTimeout(this.reconnectTimer), this.reconnectTimer = setTimeout(() => { + this.retries++, this._openSocket(); + }, t), this.reconnectTimer.unref && this.reconnectTimer.unref(), R("reconnecting socket in %s ms", t); + } + _send(t) { + if (this.destroyed) return; + this.expectingResponse = !0; + const e = JSON.stringify(t); + R("send %s", e), this.socket.send(e); + } + _generateOffers(t, e) { + const n = this, r = []; + R("generating %s offers", t); + for (let a = 0; a < t; ++a) i(); + function i() { + const a = Z(Rt(20)); + R("creating peer (from _generateOffers)"); + const h = n.peers[a] = n._createPeer({ initiator: !0 }); + h.once("signal", (u) => { + r.push({ offer: u, offer_id: it(a) }), o(); + }), h.trackerTimeout = setTimeout(() => { + R("tracker timeout: destroying peer"), h.trackerTimeout = null, delete n.peers[a], h.destroy(); + }, 5e4), h.trackerTimeout.unref && h.trackerTimeout.unref(); + } + function o() { + r.length === t && (R("generated %s offers", t), e(r)); + } + o(); + } + _createPeer(t) { + const e = this; + t = Object.assign({ trickle: !1, config: e.client._rtcConfig, wrtc: e.client._wrtc }, t); + const n = new ot(t); + return n.once("error", r), n.once("connect", function i() { + n.removeListener("error", r), n.removeListener("connect", i); + }), n; + function r(i) { + e.client.emit("warning", new Error(`Connection error: ${i.message}`)), n.destroy(); + } + } +} +function We() { +} +oe.prototype.DEFAULT_ANNOUNCE_INTERVAL = 3e4, oe._socketPool = q; +const U = P("bittorrent-tracker:client"); +class ae extends un { + constructor(t = {}) { + if (super(), !t.peerId) throw new Error("Option `peerId` is required"); + if (!t.infoHash) throw new Error("Option `infoHash` is required"); + if (!t.announce) throw new Error("Option `announce` is required"); + if (!wt.browser && !t.port) throw new Error("Option `port` is required"); + this.peerId = typeof t.peerId == "string" ? t.peerId : Z(t.peerId), this._peerIdBuffer = ne(this.peerId), this._peerIdBinary = it(this.peerId), this.infoHash = typeof t.infoHash == "string" ? t.infoHash.toLowerCase() : Z(t.infoHash), this._infoHashBuffer = ne(this.infoHash), this._infoHashBinary = it(this.infoHash), U("new client %s", this.infoHash), this.destroyed = !1, this._port = t.port, this._getAnnounceOpts = t.getAnnounceOpts, this._rtcConfig = t.rtcConfig, this._userAgent = t.userAgent, this._proxyOpts = t.proxyOpts, this._wrtc = typeof t.wrtc == "function" ? t.wrtc() : t.wrtc; + let e = typeof t.announce == "string" ? [t.announce] : t.announce == null ? [] : t.announce; + e = e.map((i) => (ArrayBuffer.isView(i) && (i = qn(i)), i[i.length - 1] === "/" && (i = i.substring(0, i.length - 1)), i)), e = Array.from(new Set(e)); + const n = this._wrtc !== !1 && (!!this._wrtc || ot.WEBRTC_SUPPORT), r = (i) => { + Gt(() => { + this.emit("warning", i); + }); + }; + this._trackers = e.map((i) => { + let o; + try { + o = ie.parseUrl(i); + } catch { + return r(new Error(`Invalid tracker URL: ${i}`)), null; + } + const a = o.port; + if (a < 0 || a > 65535) return r(new Error(`Invalid tracker port: ${i}`)), null; + const h = o.protocol; + return h !== "http:" && h !== "https:" || typeof B != "function" ? h === "udp:" && typeof B == "function" ? new B(this, i) : h !== "ws:" && h !== "wss:" || !n || h === "ws:" && typeof window < "u" && window.location.protocol === "https:" ? (r(new Error(`Unsupported tracker protocol: ${i}`)), null) : new oe(this, i) : new B(this, i); + }).filter(Boolean); + } + start(t) { + (t = this._defaultAnnounceOpts(t)).event = "started", U("send `start` %o", t), this._announce(t), this._trackers.forEach((e) => { + e.setInterval(); + }); + } + stop(t) { + (t = this._defaultAnnounceOpts(t)).event = "stopped", U("send `stop` %o", t), this._announce(t); + } + complete(t) { + t || (t = {}), (t = this._defaultAnnounceOpts(t)).event = "completed", U("send `complete` %o", t), this._announce(t); + } + update(t) { + (t = this._defaultAnnounceOpts(t)).event && delete t.event, U("send `update` %o", t), this._announce(t); + } + _announce(t) { + this._trackers.forEach((e) => { + e.announce(t); + }); + } + scrape(t) { + U("send `scrape`"), t || (t = {}), this._trackers.forEach((e) => { + e.scrape(t); + }); + } + setInterval(t) { + U("setInterval %d", t), this._trackers.forEach((e) => { + e.setInterval(t); + }); + } + destroy(t) { + if (this.destroyed) return; + this.destroyed = !0, U("destroy"); + const e = this._trackers.map((n) => (r) => { + n.destroy(r); + }); + is(e, t), this._trackers = [], this._getAnnounceOpts = null; + } + _defaultAnnounceOpts(t = {}) { + return t.numwant == null && (t.numwant = ie.DEFAULT_ANNOUNCE_PEERS), t.uploaded == null && (t.uploaded = 0), t.downloaded == null && (t.downloaded = 0), this._getAnnounceOpts && (t = Object.assign({}, t, this._getAnnounceOpts())), t; + } +} +ae.scrape = (s, t) => { + if (t = ns(t), !s.infoHash) throw new Error("Option `infoHash` is required"); + if (!s.announce) throw new Error("Option `announce` is required"); + const e = Object.assign({}, s, { infoHash: Array.isArray(s.infoHash) ? s.infoHash[0] : s.infoHash, peerId: ge("01234567890123456789"), port: 6881 }), n = new ae(e); + n.once("error", t), n.once("warning", t); + let r = Array.isArray(s.infoHash) ? s.infoHash.length : 1; + const i = {}; + return n.on("scrape", (o) => { + if (r -= 1, i[o.infoHash] = o, r === 0) { + n.destroy(); + const a = Object.keys(i); + a.length === 1 ? t(null, i[a[0]]) : t(null, i); + } + }), n.scrape({ infoHash: s.infoHash }), n; +}; +var Nn = { exports: {} }; +function k(s, t, e, n, r, i, o) { + var a = s + (t & e | ~t & n) + (r >>> 0) + o; + return (a << i | a >>> 32 - i) + t; +} +function x(s, t, e, n, r, i, o) { + var a = s + (t & n | e & ~n) + (r >>> 0) + o; + return (a << i | a >>> 32 - i) + t; +} +function A(s, t, e, n, r, i, o) { + var a = s + (t ^ e ^ n) + (r >>> 0) + o; + return (a << i | a >>> 32 - i) + t; +} +function E(s, t, e, n, r, i, o) { + var a = s + (e ^ (t | ~n)) + (r >>> 0) + o; + return (a << i | a >>> 32 - i) + t; +} +function ft(s) { + return String.fromCharCode(255 & s); +} +function pt(s) { + return ft(s) + ft(s >>> 8) + ft(s >>> 16) + ft(s >>> 24); +} +var he = function(s) { + return unescape(encodeURIComponent(s)); +}, Ot = Nn.exports = function(s) { + return nr(s).toHex(); +}, Ct = Ot.fromBytes = function(s) { + for (var t = function(S) { + for (var c = S.length, g = c << 3, l = new Uint32Array(c + 72 >>> 6 << 4), m = 0, y = S.length; m < y; ++m) l[m >>> 2] |= S.charCodeAt(m) << ((3 & m) << 3); + return l[c >> 2] |= 128 << (31 & g), l[l.length - 2] = g, l; + }(s), e = 1732584193, n = 4023233417, r = 2562383102, i = 271733878, o = 0, a = t.length; o < a; o += 16) { + var h = e, u = n, d = r, p = i; + e = k(e, n, r, i, t[o + 0], 7, 3614090360), i = k(i, e, n, r, t[o + 1], 12, 3905402710), r = k(r, i, e, n, t[o + 2], 17, 606105819), n = k(n, r, i, e, t[o + 3], 22, 3250441966), e = k(e, n, r, i, t[o + 4], 7, 4118548399), i = k(i, e, n, r, t[o + 5], 12, 1200080426), r = k(r, i, e, n, t[o + 6], 17, 2821735955), n = k(n, r, i, e, t[o + 7], 22, 4249261313), e = k(e, n, r, i, t[o + 8], 7, 1770035416), i = k(i, e, n, r, t[o + 9], 12, 2336552879), r = k(r, i, e, n, t[o + 10], 17, 4294925233), n = k(n, r, i, e, t[o + 11], 22, 2304563134), e = k(e, n, r, i, t[o + 12], 7, 1804603682), i = k(i, e, n, r, t[o + 13], 12, 4254626195), r = k(r, i, e, n, t[o + 14], 17, 2792965006), e = x(e, n = k(n, r, i, e, t[o + 15], 22, 1236535329), r, i, t[o + 1], 5, 4129170786), i = x(i, e, n, r, t[o + 6], 9, 3225465664), r = x(r, i, e, n, t[o + 11], 14, 643717713), n = x(n, r, i, e, t[o + 0], 20, 3921069994), e = x(e, n, r, i, t[o + 5], 5, 3593408605), i = x(i, e, n, r, t[o + 10], 9, 38016083), r = x(r, i, e, n, t[o + 15], 14, 3634488961), n = x(n, r, i, e, t[o + 4], 20, 3889429448), e = x(e, n, r, i, t[o + 9], 5, 568446438), i = x(i, e, n, r, t[o + 14], 9, 3275163606), r = x(r, i, e, n, t[o + 3], 14, 4107603335), n = x(n, r, i, e, t[o + 8], 20, 1163531501), e = x(e, n, r, i, t[o + 13], 5, 2850285829), i = x(i, e, n, r, t[o + 2], 9, 4243563512), r = x(r, i, e, n, t[o + 7], 14, 1735328473), e = A(e, n = x(n, r, i, e, t[o + 12], 20, 2368359562), r, i, t[o + 5], 4, 4294588738), i = A(i, e, n, r, t[o + 8], 11, 2272392833), r = A(r, i, e, n, t[o + 11], 16, 1839030562), n = A(n, r, i, e, t[o + 14], 23, 4259657740), e = A(e, n, r, i, t[o + 1], 4, 2763975236), i = A(i, e, n, r, t[o + 4], 11, 1272893353), r = A(r, i, e, n, t[o + 7], 16, 4139469664), n = A(n, r, i, e, t[o + 10], 23, 3200236656), e = A(e, n, r, i, t[o + 13], 4, 681279174), i = A(i, e, n, r, t[o + 0], 11, 3936430074), r = A(r, i, e, n, t[o + 3], 16, 3572445317), n = A(n, r, i, e, t[o + 6], 23, 76029189), e = A(e, n, r, i, t[o + 9], 4, 3654602809), i = A(i, e, n, r, t[o + 12], 11, 3873151461), r = A(r, i, e, n, t[o + 15], 16, 530742520), e = E(e, n = A(n, r, i, e, t[o + 2], 23, 3299628645), r, i, t[o + 0], 6, 4096336452), i = E(i, e, n, r, t[o + 7], 10, 1126891415), r = E(r, i, e, n, t[o + 14], 15, 2878612391), n = E(n, r, i, e, t[o + 5], 21, 4237533241), e = E(e, n, r, i, t[o + 12], 6, 1700485571), i = E(i, e, n, r, t[o + 3], 10, 2399980690), r = E(r, i, e, n, t[o + 10], 15, 4293915773), n = E(n, r, i, e, t[o + 1], 21, 2240044497), e = E(e, n, r, i, t[o + 8], 6, 1873313359), i = E(i, e, n, r, t[o + 15], 10, 4264355552), r = E(r, i, e, n, t[o + 6], 15, 2734768916), n = E(n, r, i, e, t[o + 13], 21, 1309151649), e = E(e, n, r, i, t[o + 4], 6, 4149444226), i = E(i, e, n, r, t[o + 11], 10, 3174756917), r = E(r, i, e, n, t[o + 2], 15, 718787259), n = E(n, r, i, e, t[o + 9], 21, 3951481745), e = e + h >>> 0, n = n + u >>> 0, r = r + d >>> 0, i = i + p >>> 0; + } + var _ = new String(pt(e) + pt(n) + pt(r) + pt(i)); + return _.toHex = function() { + for (var S = "", c = 0, g = _.length; c < g; ++c) S += (256 + (255 & _.charCodeAt(c))).toString(16).substr(-2); + return S; + }, _; +}, nr = Ot.fromUtf8 = function(s) { + return Ct(he(s)); +}, Mn = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +function ze(s, t) { + for (var e = ""; --t >= 0; s >>>= 6) e += Mn.charAt(63 & s); + return e; +} +var mt = [0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5, 11], sr = Ot.salt = function(s) { + var t = ""; + s || (s = 8); + do + t += Mn.charAt(64 * Math.random() >>> 0); + while (--s); + return t; +}; +Ot.crypt = function(s, t) { + if (s.length > 64) throw Error("too long key"); + t || (t = "$1$" + sr()), s = he(s); + for (var e = he(t.replace(/^\$1\$([^$]+)(?:\$.*)?$/, "$1")), n = Ct(s + e + s), r = s + "$1$" + e, i = s.length; i > 16; i -= 16) r += n; + for (r += n.slice(0, i), i = s.length; i; i >>= 1) r += 1 & i ? "\0" : s.charAt(0); + n = Ct(r); + for (var o = 0; o < 1e3; ++o) n = Ct((1 & o ? s : n) + (o % 3 ? e : "") + (o % 7 ? s : "") + (1 & o ? n : s)); + var a = "$1$" + e + "$"; + for (o = 0; o < 15; o += 3) a += ze(n.charCodeAt(mt[o + 0]) << 16 | n.charCodeAt(mt[o + 1]) << 8 | n.charCodeAt(mt[o + 2]), 4); + return a + ze(n.charCodeAt(mt[15]), 2); +}; +const rr = V(Nn.exports), ir = `-PM${function(s) { + const t = s.split("."); + return `${t[0].padStart(2, "0")}${t[1].padStart(2, "0")}`; +}("1.0.3")}-`, or = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +function z(s) { + return `${s.type}-${s.index}`; +} +function Ve(s) { + const { externalId: t } = s; + return `(${z(s.stream)} | ${t})`; +} +function ce(s, t) { + t === void 0 && (t = s.reduce((r, i) => r + i.byteLength, 0)); + const e = new Uint8Array(t); + let n = 0; + for (const r of s) e.set(r, n), n += r.byteLength; + return e; +} +function Ge(s) { + const t = new TextEncoder(), e = new Uint8Array(s.length); + return t.encodeInto(s, e), e; +} +function* Je(s) { + for (let t = s.length - 1; t >= 0; t--) yield s[t]; +} +function Fn(s) { + return !!s && typeof s == "object" && !Array.isArray(s); +} +function K(s) { + if (function(t) { + return Array.isArray(t); + }(s)) return s.map((t) => K(t)); + if (Fn(s)) { + const t = {}; + for (const e of Object.keys(s)) t[e] = K(s[e]); + return t; + } + return s; +} +function et(s, t, e = {}) { + return typeof s != "object" || s === null || typeof t != "object" || t === null || Object.keys(t).forEach((n) => { + if (n === "__proto__" || n === "constructor" || n === "prototype") throw new Error(`Attempt to modify restricted property '${String(n)}'`); + const r = t[n], i = e[n]; + n in s && (s[n] = r === void 0 ? i === void 0 ? void 0 : i : r); + }), s; +} +function Ft(s) { + const { defaultConfig: t, baseConfig: e = {}, specificStreamConfig: n = {} } = s, r = K({ ...t, ...e, ...n }), i = Object.keys(t), o = {}; + return i.forEach((a) => { + a in r && (o[a] = r[a]); + }), o; +} +var H = ((s) => (s[s.SegmentsAnnouncement = 0] = "SegmentsAnnouncement", s[s.SegmentRequest = 1] = "SegmentRequest", s[s.SegmentData = 2] = "SegmentData", s[s.SegmentDataSendingCompleted = 3] = "SegmentDataSendingCompleted", s[s.SegmentAbsent = 4] = "SegmentAbsent", s[s.CancelSegmentRequest = 5] = "CancelSegmentRequest", s))(H || {}), X = ((s) => (s[s.Min = -1] = "Min", s[s.Int = 0] = "Int", s[s.SimilarIntArray = 1] = "SimilarIntArray", s[s.String = 2] = "String", s[s.Max = 3] = "Max", s))(X || {}); +function ar(s) { + const t = s < 0, e = function(i) { + const o = i.toString(2), a = i < 0 ? o.length : o.length + 1; + return Math.ceil(a / 8); + }(s), n = new Uint8Array(e), r = BigInt(e); + s = function(i) { + return i < 0 ? -i : i; + }(s); + for (let i = 0; i < e; i++) { + const o = s >> 8n * (r - 1n - BigInt(i)) & 0xffn; + n[i] = Number(o); + } + return t && (n[0] = 128 | n[0]), n; +} +function hr(s) { + const t = BigInt(s.length), e = (r, i) => { + const o = 8n * (t - 1n - BigInt(i)); + return BigInt(r) << o; + }; + let n = e(127 & s[0], 0); + for (let r = 1; r < t; r++) n = e(s[r], r) | n; + return (128 & s[0]) >> 7 && (n = -n), n; +} +function Ye(s) { + const t = ar(s), e = 0 | t.length; + return new Uint8Array([e, ...t]); +} +function Un(s) { + const t = s[0]; + if (t >> 4) throw new Error("Trying to deserialize integer with invalid serialized item code"); + const e = 15 & t, n = 1 + e; + return { number: hr(s.slice(1, n)), byteLength: e + 1 }; +} +function cr(s) { + const [t, e] = s; + if (t >> 4 !== 1) throw new Error("Trying to deserialize similar int array with invalid serialized item code"); + let n = 2; + const r = []; + for (let i = 0; i < e; i++) { + const { number: o, byteLength: a } = Un(s.slice(n)); + n += a; + const h = 0xffn & o, u = -256n & o; + for (let d = 0; d < h; d++) { + const p = BigInt(s[n]); + r.push(u | p), n++; + } + } + return { numbers: r, byteLength: n }; +} +function dr(s) { + const [t, e] = s; + if (t >> 4 !== 2) throw new Error("Trying to deserialize bytes (sting) with invalid serialized item code."); + const n = (15 & t) << 8 | e, r = s.slice(2, n + 2); + return { string: new TextDecoder("utf8").decode(r), byteLength: n + 2 }; +} +class rt { + constructor() { + f(this, "bytes", []); + f(this, "_length", 0); + } + push(t) { + this.addBytes(t, "end"); + } + unshift(t) { + this.addBytes(t, "start"); + } + addBytes(t, e) { + let n; + n = t instanceof Uint8Array ? t : Array.isArray(t) ? new Uint8Array(t) : new Uint8Array([t]), this._length += n.length, this.bytes[e === "start" ? "unshift" : "push"](n); + } + getBytesChunks() { + return this.bytes; + } + getBuffer() { + return ce(this.bytes, this._length); + } + get length() { + return this._length; + } +} +const tt = qt("cstr", 4), ht = qt("cend", 4), de = qt("dstr", 4), ue = qt("dend", 4), ur = [tt, de], lr = [ht, ue], Ke = tt.length + ht.length; +function Hn(s) { + const t = tt.length, e = s.slice(-t); + return ur.some((n) => Bt(s, n, 4)) && lr.some((n) => Bt(e, n, 4)); +} +class It extends Error { + constructor(t) { + super(), this.type = t; + } +} +class $n { + constructor(t) { + f(this, "chunks", new rt()); + f(this, "status", "joining"); + this.onComplete = t; + } + addCommandChunk(t) { + if (this.status === "completed") return; + const e = Bt(t, tt, 4); + if (!this.chunks.length && !e) throw new It("no-first-chunk"); + if (this.chunks.length && e) throw new It("incomplete-joining"); + this.chunks.push(this.unframeCommandChunk(t)), function(n) { + return Bt(n.slice(-4), ht, 4); + }(t) && (this.status = "completed", this.onComplete(this.chunks.getBuffer())); + } + unframeCommandChunk(t) { + return t.slice(4, t.length - 4); + } +} +class yt { + constructor(t, e) { + f(this, "bytes", new rt()); + f(this, "resultBuffers", []); + f(this, "status", "creating"); + this.maxChunkLength = e, this.bytes.push(t); + } + addInteger(t, e) { + this.bytes.push(t.charCodeAt(0)); + const n = Ye(BigInt(e)); + this.bytes.push(n); + } + addSimilarIntArr(t, e) { + this.bytes.push(t.charCodeAt(0)); + const n = function(r) { + const i = /* @__PURE__ */ new Map(); + for (const a of r) { + const h = -256n & a, u = 0xffn & a, d = i.get(h) ?? new rt(); + d.length || i.set(h, d), d.push(Number(u)); + } + const o = new rt(); + o.push([16, i.size]); + for (const [a, h] of i) { + const { length: u } = h.getBytesChunks(), d = a | 0xffn & BigInt(u); + h.unshift(Ye(d)), o.push(h.getBuffer()); + } + return o.getBuffer(); + }(e.map((r) => BigInt(r))); + this.bytes.push(n); + } + addString(t, e) { + this.bytes.push(t.charCodeAt(0)); + const n = function(r) { + const { length: i } = r, o = new rt(); + return o.push([32 | i >> 8 & 15, 255 & i]), o.push(new TextEncoder().encode(r)), o.getBuffer(); + }(e); + this.bytes.push(n); + } + complete() { + if (!this.bytes.length) throw new Error("Buffer is empty"); + if (this.status === "completed") return; + this.status = "completed"; + const t = this.bytes.getBuffer(); + if (t.length + Ke <= this.maxChunkLength) return void this.resultBuffers.push(_t(t, tt, ht)); + let e = Math.ceil(t.length / this.maxChunkLength); + Math.ceil(t.length / e) + Ke > this.maxChunkLength && e++; + for (const [n, r] of function* (i, o) { + const a = Math.ceil(i.length / o); + for (let h = 0; h < o; h++) yield [h, i.slice(h * a, (h + 1) * a)]; + }(t, e)) n === 0 ? this.resultBuffers.push(_t(r, tt, ue)) : n === e - 1 ? this.resultBuffers.push(_t(r, de, ht)) : this.resultBuffers.push(_t(r, de, ue)); + } + getResultBuffers() { + if (this.status === "creating" || !this.resultBuffers.length) throw new Error("Command is not complete."); + return this.resultBuffers; + } +} +function jn(s) { + const [t] = s, e = { c: t }; + let n = 1; + for (; n < s.length; ) { + const r = String.fromCharCode(s[n]); + switch (n++, gr(s[n])) { + case X.Int: + { + const { number: i, byteLength: o } = Un(s.slice(n)); + e[r] = Number(i), n += o; + } + break; + case X.SimilarIntArray: + { + const { numbers: i, byteLength: o } = cr(s.slice(n)); + e[r] = i.map((a) => Number(a)), n += o; + } + break; + case X.String: { + const { string: i, byteLength: o } = dr(s.slice(n)); + e[r] = i, n += o; + } + } + } + return e; +} +function gr(s) { + const t = s >> 4; + if (t <= X.Min || t >= X.Max) throw new Error("Not existing type"); + return t; +} +function qt(s, t) { + if (s.length !== t) throw new Error("Wrong string length"); + const e = new Uint8Array(t); + for (let n = 0; n < s.length; n++) e[n] = s.charCodeAt(n); + return e; +} +function _t(s, t, e) { + const n = new Uint8Array(s.length + t.length + e.length); + return n.set(t), n.set(s, t.length), n.set(e, t.length + s.length), n; +} +function Bt(s, t, e) { + for (let n = 0; n < e; n++) if (s[n] !== t[n]) return !1; + return !0; +} +function Qn(s, t) { + switch (s.c) { + case H.CancelSegmentRequest: + case H.SegmentAbsent: + case H.SegmentDataSendingCompleted: + return function(e, n) { + const r = new yt(e.c, n); + return r.addInteger("i", e.i), r.complete(), r.getResultBuffers(); + }(s, t); + case H.SegmentRequest: + return function(e, n) { + const r = new yt(e.c, n); + return r.addInteger("i", e.i), e.b && r.addInteger("b", e.b), r.complete(), r.getResultBuffers(); + }(s, t); + case H.SegmentsAnnouncement: + return function(e, n) { + const { c: r, p: i, l: o } = e, a = new yt(r, n); + return o != null && o.length && a.addSimilarIntArr("l", o), i != null && i.length && a.addSimilarIntArr("p", i), a.complete(), a.getResultBuffers(); + }(s, t); + case H.SegmentData: + return function(e, n) { + const r = new yt(e.c, n); + return r.addInteger("i", e.i), r.addInteger("s", e.s), r.complete(), r.getResultBuffers(); + }(s, t); + } +} +const fr = Object.freeze(Object.defineProperty({ __proto__: null, BinaryCommandChunksJoiner: $n, BinaryCommandJoiningError: It, PeerCommandType: H, deserializeCommand: jn, isCommandChunk: Hn, serializePeerCommand: Qn }, Symbol.toStringTag, { value: "Module" })); +class pr { + constructor(t, e, n, r) { + f(this, "commandChunks"); + f(this, "uploadingContext"); + f(this, "onChunkDownloaded"); + f(this, "onChunkUploaded"); + f(this, "onDataReceived", (t) => { + Hn(t) ? this.receivingCommandBytes(t) : (this.eventHandlers.onSegmentChunkReceived(t), this.onChunkDownloaded(t.length, "p2p", this.connection.idUtf8)); + }); + this.connection = t, this.peerConfig = e, this.eventHandlers = n, this.onChunkDownloaded = r.getEventDispatcher("onChunkDownloaded"), this.onChunkUploaded = r.getEventDispatcher("onChunkUploaded"), t.on("data", this.onDataReceived); + } + sendCommand(t) { + const e = Qn(t, this.peerConfig.webRtcMaxMessageSize); + for (const n of e) this.connection.send(n); + } + stopUploadingSegmentData() { + var t; + (t = this.uploadingContext) == null || t.stopUploading(), this.uploadingContext = void 0; + } + async splitSegmentDataToChunksAndUploadAsync(t) { + if (this.uploadingContext) throw new Error("Some segment data is already uploading."); + const e = function* (u, d) { + let p = u.byteLength; + for (; p > 0; ) { + const _ = p >= d ? d : p, S = u.byteLength - p, c = u.slice(S, S + _); + p -= _, yield c; + } + }(t, this.peerConfig.webRtcMaxMessageSize), { promise: n, resolve: r, reject: i } = function() { + let u, d; + return { promise: new Promise((p, _) => { + u = p, d = _; + }), resolve: u, reject: d }; + }(); + let o = !1; + const a = { stopUploading: () => { + o = !1; + } }; + this.uploadingContext = a; + const h = () => { + if (o) for (; ; ) { + const u = e.next().value; + if (!u) { + r(); + break; + } + const d = this.connection.write(u); + if (this.onChunkUploaded(u.byteLength, this.connection.idUtf8), !d) break; + } + else i(); + }; + try { + this.connection.on("drain", h), o = !0, h(), await n; + } finally { + this.connection.off("drain", h), this.uploadingContext === a && (this.uploadingContext = void 0); + } + } + receivingCommandBytes(t) { + this.commandChunks || (this.commandChunks = new $n((e) => { + this.commandChunks = void 0; + const n = jn(e); + this.eventHandlers.onCommandReceived(n); + })); + try { + this.commandChunks.addCommandChunk(t); + } catch (e) { + if (!(e instanceof It)) return; + this.commandChunks = void 0; + } + } +} +const { PeerCommandType: T } = fr; +class Pt { + constructor(t, e, n, r) { + f(this, "id"); + f(this, "peerProtocol"); + f(this, "downloadingContext"); + f(this, "loadedSegments", /* @__PURE__ */ new Set()); + f(this, "httpLoadingSegments", /* @__PURE__ */ new Set()); + f(this, "downloadingErrors", []); + f(this, "logger", P("p2pml-core:peer")); + f(this, "onPeerClosed"); + f(this, "onCommandReceived", async (t) => { + var e, n, r; + switch (t.c) { + case T.SegmentsAnnouncement: + this.loadedSegments = new Set(t.l), this.httpLoadingSegments = new Set(t.p), this.eventHandlers.onSegmentsAnnouncement(); + break; + case T.SegmentRequest: + this.peerProtocol.stopUploadingSegmentData(), this.eventHandlers.onSegmentRequested(this, t.i, t.b); + break; + case T.SegmentData: + { + if (!this.downloadingContext || this.downloadingContext.isSegmentDataCommandReceived) break; + const { request: i, controls: o } = this.downloadingContext; + if (i.segment.externalId !== t.i) break; + this.downloadingContext.isSegmentDataCommandReceived = !0, o.firstBytesReceived(), i.totalBytes === void 0 ? i.setTotalBytes(t.s) : i.totalBytes - i.loadedBytes !== t.s && (i.clearLoadedBytes(), this.sendCancelSegmentRequestCommand(i.segment), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), this.destroy()); + } + break; + case T.SegmentDataSendingCompleted: { + const i = this.downloadingContext; + if (!(i != null && i.isSegmentDataCommandReceived)) return; + const { request: o, controls: a } = i; + if (i.request.segment.externalId !== t.i) return o.clearLoadedBytes(), this.cancelSegmentDownloading("peer-protocol-violation"), void this.destroy(); + if (o.loadedBytes !== o.totalBytes) return o.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy(); + const h = await ((n = (e = this.peerConfig).validateP2PSegment) == null ? void 0 : n.call(e, o.segment.url, o.segment.byteRange)) ?? !0; + if (this.downloadingContext !== i) return; + if (!h) return o.clearLoadedBytes(), this.cancelSegmentDownloading("p2p-segment-validation-failed"), void this.destroy(); + this.downloadingErrors = [], a.completeOnSuccess(), this.downloadingContext = void 0; + break; + } + case T.SegmentAbsent: + ((r = this.downloadingContext) == null ? void 0 : r.request.segment.externalId) === t.i && (this.cancelSegmentDownloading("peer-segment-absent"), this.loadedSegments.delete(t.i)); + break; + case T.CancelSegmentRequest: + this.peerProtocol.stopUploadingSegmentData(); + } + }); + f(this, "onSegmentChunkReceived", (t) => { + var r; + if (!((r = this.downloadingContext) != null && r.isSegmentDataCommandReceived)) return; + const { request: e, controls: n } = this.downloadingContext; + if (e.totalBytes !== void 0 && e.loadedBytes + t.byteLength > e.totalBytes) return e.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy(); + n.addLoadedChunk(t); + }); + f(this, "onPeerConnectionClosed", () => { + this.destroy(); + }); + f(this, "onConnectionError", (t) => { + this.logger(`peer connection error ${this.id} %O`, t); + const e = t.code; + (e === "ERR_DATA_CHANNEL" || e === "ERR_CONNECTION_FAILURE" || e === "ERR_CONNECTION_FAILURE") && this.destroy(); + }); + f(this, "destroy", () => { + this.cancelSegmentDownloading("peer-closed"), this.connection.destroy(), this.eventHandlers.onPeerClosed(this), this.onPeerClosed({ peerId: this.id }), this.logger(`peer closed ${this.id}`); + }); + this.connection = t, this.eventHandlers = e, this.peerConfig = n, this.onPeerClosed = r.getEventDispatcher("onPeerClose"), this.id = Pt.getPeerIdFromConnection(t), this.peerProtocol = new pr(t, n, { onSegmentChunkReceived: this.onSegmentChunkReceived, onCommandReceived: this.onCommandReceived }, r), r.getEventDispatcher("onPeerConnect")({ peerId: this.id }), t.on("error", this.onConnectionError), t.on("close", this.onPeerConnectionClosed), t.on("end", this.onPeerConnectionClosed), t.on("finish", this.onPeerConnectionClosed); + } + get downloadingSegment() { + var t; + return (t = this.downloadingContext) == null ? void 0 : t.request.segment; + } + getSegmentStatus(t) { + const { externalId: e } = t; + return this.loadedSegments.has(e) ? "loaded" : this.httpLoadingSegments.has(e) ? "http-loading" : void 0; + } + downloadSegment(t) { + if (this.downloadingContext) throw new Error("Some segment already is downloading"); + this.downloadingContext = { request: t, isSegmentDataCommandReceived: !1, controls: t.start({ downloadSource: "p2p", peerId: this.id }, { notReceivingBytesTimeoutMs: this.peerConfig.p2pNotReceivingBytesTimeoutMs, abort: (n) => { + if (!this.downloadingContext) return; + const { request: r } = this.downloadingContext; + this.sendCancelSegmentRequestCommand(r.segment), this.downloadingErrors.push(n), this.downloadingContext = void 0, this.downloadingErrors.filter((i) => i.type === "bytes-receiving-timeout").length >= this.peerConfig.p2pErrorRetries && this.destroy(); + } }) }; + const e = { c: T.SegmentRequest, i: t.segment.externalId }; + t.loadedBytes && (e.b = t.loadedBytes), this.peerProtocol.sendCommand(e); + } + async uploadSegmentData(t, e) { + const { externalId: n } = t; + this.logger(`send segment ${t.externalId} to ${this.id}`); + const r = { c: T.SegmentData, i: n, s: e.byteLength }; + this.peerProtocol.sendCommand(r); + try { + await this.peerProtocol.splitSegmentDataToChunksAndUploadAsync(e), this.sendSegmentDataSendingCompletedCommand(t), this.logger(`segment ${n} has been sent to ${this.id}`); + } catch { + this.logger(`cancel segment uploading ${n}`); + } + } + cancelSegmentDownloading(t) { + if (!this.downloadingContext) return; + const { request: e, controls: n } = this.downloadingContext, { segment: r } = e; + this.logger(`cancel segment request ${r.externalId} (${t})`); + const i = new I(t); + n.abortOnError(i), this.downloadingContext = void 0, this.downloadingErrors.push(i); + } + sendSegmentsAnnouncementCommand(t, e) { + const n = { c: T.SegmentsAnnouncement, p: e, l: t }; + this.peerProtocol.sendCommand(n); + } + sendSegmentAbsentCommand(t) { + this.peerProtocol.sendCommand({ c: T.SegmentAbsent, i: t }); + } + sendCancelSegmentRequestCommand(t) { + this.peerProtocol.sendCommand({ c: T.CancelSegmentRequest, i: t.externalId }); + } + sendSegmentDataSendingCompletedCommand(t) { + this.peerProtocol.sendCommand({ c: T.SegmentDataSendingCompleted, i: t.externalId }); + } + static getPeerIdFromConnection(t) { + return function(e) { + const n = new Uint8Array(e.length / 2); + for (let r = 0; r < e.length; r += 2) n[r / 2] = parseInt(e.slice(r, r + 2), 16); + return new TextDecoder().decode(n); + }(t.id); + } +} +class mr { + constructor(t, e, n, r, i) { + f(this, "streamShortId"); + f(this, "client"); + f(this, "_peers", /* @__PURE__ */ new Map()); + f(this, "logger", P("p2pml-core:p2p-tracker-client")); + f(this, "onReceivePeerConnection", (t) => { + const e = Pt.getPeerIdFromConnection(t); + let n = this._peers.get(e); + n != null && n.peer ? t.destroy() : (n || (n = { potentialConnections: /* @__PURE__ */ new Set() }, t.idUtf8 = e, n.potentialConnections.add(t), this._peers.set(e, n)), t.on("connect", () => { + if (n && !n.peer) { + for (const r of n.potentialConnections) r !== t && r.destroy(); + n.potentialConnections.clear(), n.peer = new Pt(t, { onPeerClosed: this.onPeerClosed, onSegmentRequested: this.eventHandlers.onSegmentRequested, onSegmentsAnnouncement: this.eventHandlers.onSegmentsAnnouncement }, this.config, this.eventTarget), this.logger(`connected with peer: ${n.peer.id} ${this.streamShortId}`), this.eventHandlers.onPeerConnected(n.peer); + } + })); + }); + f(this, "onTrackerClientWarning", (t) => { + this.logger(`tracker warning (${this.streamShortId}: ${t})`); + }); + f(this, "onTrackerClientError", (t) => { + this.logger(`tracker error (${this.streamShortId}: ${t})`); + }); + f(this, "onPeerClosed", (t) => { + this.logger(`peer closed: ${t.id}`), this._peers.delete(t.id); + }); + this.eventHandlers = n, this.config = r, this.eventTarget = i; + const o = function(h) { + const u = rr.fromUtf8(h).slice(1); + return btoa(u); + }(t); + this.streamShortId = z(e); + const a = function(h) { + const u = [h], d = 20 - h.length; + for (let p = 0; p < d; p++) u.push(or[Math.floor(62 * Math.random())]); + return u.join(""); + }(r.trackerClientVersionPrefix); + this.client = new ae({ infoHash: Ge(o), peerId: Ge(a), announce: this.config.announceTrackers, rtcConfig: this.config.rtcConfig }), this.client.on("peer", this.onReceivePeerConnection), this.client.on("warning", this.onTrackerClientWarning), this.client.on("error", this.onTrackerClientError), this.logger(`create new client; +stream: ${this.streamShortId}; hash: ${o} +peerId: ${a}`); + } + start() { + this.client.start(); + } + destroy() { + this.client.destroy(); + for (const { peer: t, potentialConnections: e } of this._peers.values()) { + t == null || t.destroy(); + for (const n of e) n.destroy(); + } + this._peers.clear(), this.logger(`destroy client; stream: ${this.streamShortId}`); + } + *peers() { + for (const t of this._peers.values()) t != null && t.peer && (yield t.peer); + } +} +function Xe(s, t) { + for (const e of s.values()) { + const n = e.segments.get(t); + if (n) return n; + } +} +function $(s) { + return `${s.type}-${s.index}`; +} +function vt(s, t, e, n) { + const { highDemandTimeWindow: r, httpDownloadTimeWindow: i, p2pDownloadTimeWindow: o } = e; + return { isHighDemand: Ut(s, t, r), isHttpDownloadable: Ut(s, t, i), isP2PDownloadable: Ut(s, t, o) && (!n || n.isSegmentLoadingOrLoadedBySomeone(s)) }; +} +function Ut(s, t, e) { + const { startTime: n, endTime: r } = s, { position: i, rate: o } = t; + return !(i + e * o < n || i > r); +} +class yr { + constructor(t, e, n, r, i, o, a) { + f(this, "trackerClient"); + f(this, "isAnnounceMicrotaskCreated", !1); + f(this, "onPeerConnected", (t) => { + const { httpLoading: e, loaded: n } = this.getSegmentsAnnouncement(); + t.sendSegmentsAnnouncementCommand(n, e); + }); + f(this, "broadcastAnnouncement", () => { + this.isAnnounceMicrotaskCreated || (this.isAnnounceMicrotaskCreated = !0, queueMicrotask(() => { + const { httpLoading: t, loaded: e } = this.getSegmentsAnnouncement(); + for (const n of this.trackerClient.peers()) n.sendSegmentsAnnouncementCommand(e, t); + this.isAnnounceMicrotaskCreated = !1; + })); + }); + f(this, "onSegmentRequested", async (t, e, n) => { + const r = function(o, a) { + for (const h of o.segments.values()) if (h.externalId === a) return h; + }(this.stream, e); + if (!r) return; + const i = await this.segmentStorage.getSegmentData(r); + i ? await t.uploadSegmentData(r, n !== void 0 ? i.slice(n) : i) : t.sendSegmentAbsentCommand(e); + }); + this.streamManifestUrl = t, this.stream = e, this.requests = n, this.segmentStorage = r, this.config = i, this.eventTarget = o, this.onSegmentAnnouncement = a; + const h = function(u, d) { + return `v1-${u}-${$(d)}`; + }(this.config.swarmId ?? this.streamManifestUrl, this.stream); + this.trackerClient = new mr(h, this.stream, { onPeerConnected: this.onPeerConnected, onSegmentRequested: this.onSegmentRequested, onSegmentsAnnouncement: this.onSegmentAnnouncement }, this.config, this.eventTarget), this.segmentStorage.subscribeOnUpdate(this.stream, this.broadcastAnnouncement), this.trackerClient.start(); + } + downloadSegment(t) { + const e = []; + for (const o of this.trackerClient.peers()) o.downloadingSegment || o.getSegmentStatus(t) !== "loaded" || e.push(o); + const n = (r = e)[Math.floor(Math.random() * r.length)]; + var r; + if (!n) return; + const i = this.requests.getOrCreateRequest(t); + n.downloadSegment(i); + } + isSegmentLoadingOrLoadedBySomeone(t) { + for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t)) return !0; + return !1; + } + isSegmentLoadedBySomeone(t) { + for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t) === "loaded") return !0; + return !1; + } + get connectedPeerCount() { + let t = 0; + for (const e of this.trackerClient.peers()) t++; + return t; + } + getSegmentsAnnouncement() { + const t = this.segmentStorage.getStoredSegmentExternalIdsOfStream(this.stream), e = []; + for (const n of this.requests.httpRequests()) { + const r = this.stream.segments.get(n.segment.runtimeId); + r && e.push(r.externalId); + } + return { loaded: t, httpLoading: e }; + } + destroy() { + this.segmentStorage.unsubscribeFromUpdate(this.stream, this.broadcastAnnouncement), this.trackerClient.destroy(); + } +} +class _r { + constructor(t, e, n, r, i, o, a) { + f(this, "loaders", /* @__PURE__ */ new Map()); + f(this, "_currentLoaderItem"); + f(this, "logger", P("p2pml-core:p2p-loaders-container")); + this.streamManifestUrl = t, this.requests = n, this.segmentStorage = r, this.config = i, this.eventTarget = o, this.onSegmentAnnouncement = a, this.changeCurrentLoader(e); + } + createLoader(t) { + if (this.loaders.has(t.runtimeId)) throw new Error("Loader for this stream already exists"); + const e = new yr(this.streamManifestUrl, t, this.requests, this.segmentStorage, this.config, this.eventTarget, () => { + this._currentLoaderItem.loader === e && this.onSegmentAnnouncement(); + }), n = z(t); + return this.logger(`created new loader: ${n}`), { loader: e, stream: t, loggerInfo: z(t) }; + } + changeCurrentLoader(t) { + const e = this.loaders.get(t.runtimeId); + if (this._currentLoaderItem && (this.segmentStorage.getStoredSegmentExternalIdsOfStream(this._currentLoaderItem.stream).length ? this.setLoaderDestroyTimeout(this._currentLoaderItem) : this.destroyAndRemoveLoader(this._currentLoaderItem)), e) this._currentLoaderItem = e, clearTimeout(e.destroyTimeoutId), e.destroyTimeoutId = void 0; + else { + const n = this.createLoader(t); + this.loaders.set(t.runtimeId, n), this._currentLoaderItem = n; + } + this.logger(`change current p2p loader: ${z(t)}`); + } + setLoaderDestroyTimeout(t) { + t.destroyTimeoutId = window.setTimeout(() => this.destroyAndRemoveLoader(t), this.config.p2pInactiveLoaderDestroyTimeoutMs); + } + destroyAndRemoveLoader(t) { + t.loader.destroy(), this.loaders.delete(t.stream.runtimeId), this.logger("destroy p2p loader: ", t.loggerInfo); + } + get currentLoader() { + return this._currentLoaderItem.loader; + } + destroy() { + for (const { loader: t, destroyTimeoutId: e } of this.loaders.values()) t.destroy(), clearTimeout(e); + this.loaders.clear(); + } +} +let br = class { + constructor(s, t, e, n, r, i) { + f(this, "id"); + f(this, "currentAttempt"); + f(this, "_failedAttempts", new wr()); + f(this, "finalData"); + f(this, "bytes", []); + f(this, "_loadedBytes", 0); + f(this, "_totalBytes"); + f(this, "_status", "not-started"); + f(this, "progress"); + f(this, "notReceivingBytesTimeout"); + f(this, "_abortRequestCallback"); + f(this, "_logger"); + f(this, "_isHandledByProcessQueue", !1); + f(this, "onSegmentError"); + f(this, "onSegmentAbort"); + f(this, "onSegmentStart"); + f(this, "onSegmentLoaded"); + f(this, "abortOnTimeout", () => { + var t; + if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt) return; + this.setStatus("failed"); + const s = new I("bytes-receiving-timeout"); + (t = this._abortRequestCallback) == null || t.call(this, s), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${s.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: s }), this.onSegmentError({ segment: this.segment, error: s, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0 }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback(); + }); + f(this, "abortOnError", (s) => { + this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.setStatus("failed"), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${s.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: s }), this.onSegmentError({ segment: this.segment, error: s, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0 }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback()); + }); + f(this, "completeOnSuccess", () => { + this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear(), this.finalData = ce(this.bytes), this.setStatus("succeed"), this._totalBytes = this._loadedBytes, this.onSegmentLoaded({ bytesLength: this.finalData.byteLength, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0 }), this.logger(`${this.currentAttempt.downloadSource} ${this.segment.externalId} succeed`), this.requestProcessQueueCallback()); + }); + f(this, "addLoadedChunk", (s) => { + if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt || !this.progress) return; + this.notReceivingBytesTimeout.restart(); + const t = s.byteLength, { all: e, http: n } = this.bandwidthCalculators; + e.addBytes(t), this.currentAttempt.downloadSource === "http" && n.addBytes(t), this.bytes.push(s), this.progress.lastLoadedChunkTimestamp = performance.now(), this.progress.loadedBytes += t, this._loadedBytes += t; + }); + f(this, "firstBytesReceived", () => { + this.throwErrorIfNotLoadingStatus(), this.notReceivingBytesTimeout.restart(); + }); + this.segment = s, this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.playbackConfig = r, this.onSegmentError = i.getEventDispatcher("onSegmentError"), this.onSegmentAbort = i.getEventDispatcher("onSegmentAbort"), this.onSegmentStart = i.getEventDispatcher("onSegmentStart"), this.onSegmentLoaded = i.getEventDispatcher("onSegmentLoaded"), this.id = this.segment.runtimeId; + const { byteRange: o } = this.segment; + if (o) { + const { end: h, start: u } = o; + this._totalBytes = h - u + 1; + } + this.notReceivingBytesTimeout = new Sr(this.abortOnTimeout); + const { type: a } = this.segment.stream; + this._logger = P(`p2pml-core:request-${a}`); + } + clearLoadedBytes() { + this._loadedBytes = 0, this.bytes = [], this._totalBytes = void 0; + } + get status() { + return this._status; + } + setStatus(s) { + this._status = s, this._isHandledByProcessQueue = !1; + } + get downloadSource() { + var s; + return (s = this.currentAttempt) == null ? void 0 : s.downloadSource; + } + get loadedBytes() { + return this._loadedBytes; + } + get totalBytes() { + return this._totalBytes; + } + get data() { + if (this.status === "succeed") return this.finalData || (this.finalData = ce(this.bytes)), this.finalData; + } + get failedAttempts() { + return this._failedAttempts; + } + get isHandledByProcessQueue() { + return this._isHandledByProcessQueue; + } + markHandledByProcessQueue() { + this._isHandledByProcessQueue = !0; + } + setTotalBytes(s) { + if (this._totalBytes !== void 0) throw new Error("Request total bytes value is already set"); + this._totalBytes = s; + } + start(s, t) { + if (this._status === "succeed") throw new Error(`Request ${this.segment.externalId} has been already succeed.`); + if (this._status === "loading") throw new Error(`Request ${this.segment.externalId} has been already started.`); + this.setStatus("loading"), this.currentAttempt = { ...s }, this.progress = { startFromByte: this._loadedBytes, loadedBytes: 0, startTimestamp: performance.now() }, this.manageBandwidthCalculatorsState("start"); + const { notReceivingBytesTimeoutMs: e, abort: n } = t; + return this._abortRequestCallback = n, e !== void 0 && this.notReceivingBytesTimeout.start(e), this.logger(`${s.downloadSource} ${this.segment.externalId} started`), this.onSegmentStart({ segment: this.segment, downloadSource: s.downloadSource, peerId: s.downloadSource === "p2p" ? s.peerId : void 0 }), { firstBytesReceived: this.firstBytesReceived, addLoadedChunk: this.addLoadedChunk, completeOnSuccess: this.completeOnSuccess, abortOnError: this.abortOnError }; + } + abortFromProcessQueue() { + var s, t, e, n; + this.throwErrorIfNotLoadingStatus(), this.setStatus("aborted"), this.logger(`${(s = this.currentAttempt) == null ? void 0 : s.downloadSource} ${this.segment.externalId} aborted`), (t = this._abortRequestCallback) == null || t.call(this, new I("abort")), this.onSegmentAbort({ segment: this.segment, downloadSource: (e = this.currentAttempt) == null ? void 0 : e.downloadSource, peerId: ((n = this.currentAttempt) == null ? void 0 : n.downloadSource) === "p2p" ? this.currentAttempt.peerId : void 0 }), this._abortRequestCallback = void 0, this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear(); + } + throwErrorIfNotLoadingStatus() { + if (this._status !== "loading") throw new Error(`Request has been already ${this.status}.`); + } + logger(s) { + var t; + this._logger.color = ((t = this.currentAttempt) == null ? void 0 : t.downloadSource) === "http" ? "green" : "red", this._logger(s), this._logger.color = ""; + } + manageBandwidthCalculatorsState(s) { + var r; + const { all: t, http: e } = this.bandwidthCalculators, n = s === "start" ? "startLoading" : "stopLoading"; + ((r = this.currentAttempt) == null ? void 0 : r.downloadSource) === "http" && e[n](), t[n](); + } +}; +class wr { + constructor() { + f(this, "attempts", []); + } + add(t) { + this.attempts.push(t); + } + get httpAttemptsCount() { + return this.attempts.reduce((t, e) => e.downloadSource === "http" ? t + 1 : t, 0); + } + get lastAttempt() { + return this.attempts[this.attempts.length - 1]; + } + clear() { + this.attempts = []; + } +} +class Sr { + constructor(t) { + f(this, "timeoutId"); + f(this, "ms"); + this.action = t; + } + start(t) { + if (this.timeoutId) throw new Error("Timeout is already started."); + this.ms = t, this.timeoutId = window.setTimeout(this.action, this.ms); + } + restart(t) { + this.timeoutId && clearTimeout(this.timeoutId), t && (this.ms = t), this.ms && (this.timeoutId = window.setTimeout(this.action, this.ms)); + } + clear() { + clearTimeout(this.timeoutId), this.timeoutId = void 0; + } +} +class Cr { + constructor(t, e, n, r, i) { + f(this, "requests", /* @__PURE__ */ new Map()); + this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.config = r, this.eventTarget = i; + } + get executingHttpCount() { + let t = 0; + for (const e of this.httpRequests()) e.status === "loading" && t++; + return t; + } + get executingP2PCount() { + let t = 0; + for (const e of this.p2pRequests()) e.status === "loading" && t++; + return t; + } + get(t) { + return this.requests.get(t); + } + getOrCreateRequest(t) { + let e = this.requests.get(t); + return e || (e = new br(t, this.requestProcessQueueCallback, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), this.requests.set(t, e)), e; + } + remove(t) { + this.requests.delete(t.segment); + } + items() { + return this.requests.values(); + } + *httpRequests() { + for (const t of this.requests.values()) t.downloadSource === "http" && (yield t); + } + *p2pRequests() { + for (const t of this.requests.values()) t.downloadSource === "p2p" && (yield t); + } + destroy() { + for (const t of this.requests.values()) t.status === "loading" && t.abortFromProcessQueue(); + this.requests.clear(); + } +} +class vr { + constructor(t, e) { + f(this, "_status", "pending"); + f(this, "_shouldBeStartedImmediately", !1); + this.segment = t, this.engineCallbacks = e; + } + get status() { + return this._status; + } + get shouldBeStartedImmediately() { + return this._shouldBeStartedImmediately; + } + resolve(t, e) { + this._status === "pending" && (this._status = "succeed", this.engineCallbacks.onSuccess({ data: t, bandwidth: e })); + } + reject() { + this._status === "pending" && (this._status = "failed", this.engineCallbacks.onError(new fe("failed"))); + } + abort() { + this._status === "pending" && (this._status = "aborted", this.engineCallbacks.onError(new fe("aborted"))); + } + markAsShouldBeStartedImmediately() { + this._shouldBeStartedImmediately = !0; + } +} +function* Ze(s, t, e, n) { + const { runtimeId: r, stream: i } = s, o = i.segments.get(r); + if (!o) return; + const a = i.segments.values(); + let h; + do { + const d = a.next(); + if (d.done) return; + h = d.value; + } while (h !== o); + const u = vt(h, t, e, n); + if (Ht(u)) { + const d = a.next(); + if (d.done) return; + const p = d.value, _ = vt(p, t, e, n); + if (Ht(_)) return; + u.isHighDemand = !0, yield { segment: h, statuses: u }, yield { segment: p, statuses: _ }; + } else yield { segment: h, statuses: u }; + for (const d of a) { + const p = vt(d, t, e, n); + if (Ht(p)) break; + yield { segment: d, statuses: p }; + } +} +function Ht(s) { + const { isHighDemand: t = !1, isHttpDownloadable: e = !1, isP2PDownloadable: n = !1 } = s; + return !t && !e && !n; +} +class Lr { + constructor(t, e, n, r, i, o, a) { + f(this, "requests"); + f(this, "engineRequest"); + f(this, "p2pLoaders"); + f(this, "playback"); + f(this, "segmentAvgDuration"); + f(this, "logger"); + f(this, "storageCleanUpIntervalId"); + f(this, "levelChangedTimestamp"); + f(this, "lastQueueProcessingTimeStamp"); + f(this, "randomHttpDownloadInterval"); + f(this, "isProcessQueueMicrotaskCreated", !1); + f(this, "requestProcessQueueMicrotask", (t = !0) => { + const e = performance.now(); + !t && this.lastQueueProcessingTimeStamp !== void 0 && e - this.lastQueueProcessingTimeStamp <= 1e3 || this.isProcessQueueMicrotaskCreated || (this.isProcessQueueMicrotaskCreated = !0, queueMicrotask(() => { + try { + this.processQueue(), this.lastQueueProcessingTimeStamp = e; + } finally { + this.isProcessQueueMicrotaskCreated = !1; + } + })); + }); + this.streamManifestUrl = t, this.lastRequestedSegment = e, this.streamDetails = n, this.config = r, this.bandwidthCalculators = i, this.segmentStorage = o, this.eventTarget = a; + const h = this.lastRequestedSegment.stream; + if (this.playback = { position: this.lastRequestedSegment.startTime, rate: 1 }, this.segmentAvgDuration = function(u) { + const { segments: d } = u; + let p = 0; + const _ = d.size; + for (const S of d.values()) p += S.endTime - S.startTime; + return p / _; + }(h), this.requests = new Cr(this.requestProcessQueueMicrotask, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), !this.segmentStorage.isInitialized) throw new Error("Segment storage is not initialized."); + this.segmentStorage.addIsSegmentLockedPredicate((u) => u.stream === h && function(d, p, _) { + const { isHighDemand: S = !1, isHttpDownloadable: c = !1, isP2PDownloadable: g = !1 } = vt(d, p, _); + return S || c || g; + }(u, this.playback, this.config)), this.p2pLoaders = new _r(this.streamManifestUrl, this.lastRequestedSegment.stream, this.requests, this.segmentStorage, this.config, this.eventTarget, this.requestProcessQueueMicrotask), this.logger = P(`p2pml-core:hybrid-loader-${h.type}`), this.logger.color = "coral", this.setIntervalLoading(); + } + setIntervalLoading() { + const t = this.p2pLoaders.currentLoader.connectedPeerCount, e = 1e3 * Math.random() * t + 1e3; + this.randomHttpDownloadInterval = window.setTimeout(() => { + this.loadRandomThroughHttp(), this.setIntervalLoading(); + }, e); + } + async loadSegment(t, e) { + this.logger(`requests: ${Ve(t)}`); + const { stream: n } = t; + n !== this.lastRequestedSegment.stream && (this.logger(`stream changed to ${z(n)}`), this.p2pLoaders.changeCurrentLoader(n)), this.lastRequestedSegment = t; + const r = new vr(t, e); + if (this.segmentStorage.hasSegment(t)) { + const i = await this.segmentStorage.getSegmentData(t); + if (i) { + const { queueDownloadRatio: o } = this.generateQueue(); + r.resolve(i, this.getBandwidth(o)); + } + } else this.engineRequest = r; + this.requestProcessQueueMicrotask(); + } + processRequests(t, e) { + var o; + const { stream: n } = this.lastRequestedSegment, { httpErrorRetries: r } = this.config, i = performance.now(); + for (const a of this.requests.items()) { + const { downloadSource: h, status: u, segment: d, isHandledByProcessQueue: p } = a, _ = ((o = this.engineRequest) == null ? void 0 : o.segment) === d ? this.engineRequest : void 0; + switch (u) { + case "loading": + t.has(d.runtimeId) || _ || (a.abortFromProcessQueue(), this.requests.remove(a)); + break; + case "succeed": + if (!a.data || !h) break; + h === "http" && this.p2pLoaders.currentLoader.broadcastAnnouncement(), _ && (_.resolve(a.data, this.getBandwidth(e)), this.engineRequest = void 0), this.requests.remove(a), this.segmentStorage.storeSegment(a.segment, a.data, this.streamDetails.isLive); + break; + case "failed": + h !== "http" || p || this.p2pLoaders.currentLoader.broadcastAnnouncement(), _ || n.segments.has(a.segment.runtimeId) || this.requests.remove(a), a.failedAttempts.httpAttemptsCount >= r && _ && (this.engineRequest = void 0, _.reject()); + break; + case "not-started": + case "aborted": + this.requests.remove(a); + } + a.markHandledByProcessQueue(); + const { lastAttempt: S } = a.failedAttempts; + S && i - S.error.timestamp > 6e4 && a.failedAttempts.clear(); + } + } + processQueue() { + var a; + const { queue: t, queueSegmentIds: e, queueDownloadRatio: n } = this.generateQueue(); + this.processRequests(e, n); + const { simultaneousHttpDownloads: r, simultaneousP2PDownloads: i, httpErrorRetries: o } = this.config; + if ((a = this.engineRequest) != null && a.shouldBeStartedImmediately && this.engineRequest.status === "pending" && this.requests.executingHttpCount < r) { + const { segment: h } = this.engineRequest, u = this.requests.get(h); + (!u || u.status === "not-started" || u.status === "failed" && u.failedAttempts.httpAttemptsCount < this.config.httpErrorRetries) && this.loadThroughHttp(h); + } + for (const h of t) { + const { statuses: u, segment: d } = h, p = this.requests.get(d); + if (u.isHighDemand) { + if ((p == null ? void 0 : p.downloadSource) === "http" && p.status === "loading" || (p == null ? void 0 : p.downloadSource) === "http" && p.status === "failed" && p.failedAttempts.httpAttemptsCount >= o) continue; + const _ = (p == null ? void 0 : p.status) === "loading" && p.downloadSource === "p2p"; + if (this.requests.executingHttpCount < r) { + _ && p.abortFromProcessQueue(), this.loadThroughHttp(d); + continue; + } + if (this.abortLastHttpLoadingInQueueAfterItem(t, d) && this.requests.executingHttpCount < r) { + _ && p.abortFromProcessQueue(), this.loadThroughHttp(d); + continue; + } + if (_) continue; + if (this.requests.executingP2PCount < i) { + this.loadThroughP2P(d); + continue; + } + if (this.abortLastP2PLoadingInQueueAfterItem(t, d) && this.requests.executingP2PCount < i) { + this.loadThroughP2P(d); + continue; + } + } else if (u.isP2PDownloadable) { + if ((p == null ? void 0 : p.status) === "loading") continue; + (this.requests.executingP2PCount < i || this.p2pLoaders.currentLoader.isSegmentLoadedBySomeone(d) && this.abortLastP2PLoadingInQueueAfterItem(t, d) && this.requests.executingP2PCount < i) && this.loadThroughP2P(d); + } + } + } + abortSegmentRequest(t) { + var e; + ((e = this.engineRequest) == null ? void 0 : e.segment.runtimeId) === t && (this.engineRequest.abort(), this.logger("abort: ", Ve(this.engineRequest.segment)), this.engineRequest = void 0, this.requestProcessQueueMicrotask()); + } + loadThroughHttp(t) { + const e = this.requests.getOrCreateRequest(t); + new Gn(e, this.config, this.eventTarget), this.p2pLoaders.currentLoader.broadcastAnnouncement(); + } + loadThroughP2P(t) { + this.p2pLoaders.currentLoader.downloadSegment(t); + } + loadRandomThroughHttp() { + const { simultaneousHttpDownloads: t, httpErrorRetries: e } = this.config, n = this.p2pLoaders.currentLoader; + if (this.requests.executingHttpCount >= t || !n.connectedPeerCount) return; + const r = []; + for (const { segment: u, statuses: d } of Ze(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader)) { + if (!d.isHttpDownloadable || d.isP2PDownloadable || this.segmentStorage.hasSegment(u)) continue; + const p = this.requests.get(u); + p && (p.status === "loading" || p.status === "succeed" || (p.failedAttempts.httpAttemptsCount ?? 0) >= e) || r.push(u); + } + if (!r.length || t - this.requests.executingHttpCount === 0) return; + const i = n.connectedPeerCount + 1, o = Math.min(r.length, t * i), a = function(u) { + for (let d = u.length - 1; d > 0; d--) { + const p = Math.floor(Math.random() * (d + 1)); + [u[d], u[p]] = [u[p], u[d]]; + } + return u; + }(Array.from({ length: o }, (u, d) => d)); + let h = o / i; + for (const u of a) { + if (this.requests.executingHttpCount >= t) break; + if (h >= 1 || Math.random() <= h) { + const d = r[u]; + this.loadThroughHttp(d); + } + if (h--, h <= 0) break; + } + } + abortLastHttpLoadingInQueueAfterItem(t, e) { + for (const { segment: n } of Je(t)) { + if (n === e) break; + const r = this.requests.get(n); + if ((r == null ? void 0 : r.downloadSource) === "http" && r.status === "loading") return r.abortFromProcessQueue(), !0; + } + return !1; + } + abortLastP2PLoadingInQueueAfterItem(t, e) { + for (const { segment: n } of Je(t)) { + if (n === e) break; + const r = this.requests.get(n); + if ((r == null ? void 0 : r.downloadSource) === "p2p" && r.status === "loading") return r.abortFromProcessQueue(), !0; + } + return !1; + } + generateQueue() { + var i; + const t = [], e = /* @__PURE__ */ new Set(); + let n = 0, r = 0; + for (const o of Ze(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader)) { + n++; + const { segment: a } = o; + this.segmentStorage.hasSegment(a) || ((i = this.requests.get(a)) == null ? void 0 : i.status) === "succeed" ? r++ : (t.push(o), e.add(a.runtimeId)); + } + return { queue: t, queueSegmentIds: e, maxPossibleLength: n, alreadyLoadedCount: r, queueDownloadRatio: n !== 0 ? r / n : 0 }; + } + getBandwidth(t) { + const { http: e, all: n } = this.bandwidthCalculators, { activeLevelBitrate: r } = this.streamDetails; + if (this.streamDetails.activeLevelBitrate === 0) return n.getBandwidthLoadingOnly(3); + const i = Math.max(n.getBandwidth(30, this.levelChangedTimestamp), n.getBandwidth(60, this.levelChangedTimestamp), n.getBandwidth(90, this.levelChangedTimestamp)); + if (t >= 0.8 || i >= 0.9 * r) return Math.max(n.getBandwidthLoadingOnly(1), n.getBandwidthLoadingOnly(3), n.getBandwidthLoadingOnly(5)); + const o = Math.max(e.getBandwidthLoadingOnly(1), e.getBandwidthLoadingOnly(3), e.getBandwidthLoadingOnly(5)); + return Math.max(i, o); + } + notifyLevelChanged() { + this.levelChangedTimestamp = performance.now(); + } + updatePlayback(t, e) { + var o; + const n = this.playback.rate !== e, r = this.playback.position !== t; + if (!n && !r) return; + const i = Math.abs(t - this.playback.position) / this.segmentAvgDuration > 0.5; + r && (this.playback.position = t), n && e !== 0 && (this.playback.rate = e), i && (this.logger("position significantly changed"), (o = this.engineRequest) == null || o.markAsShouldBeStartedImmediately()), this.requestProcessQueueMicrotask(i); + } + updateStream(t) { + t === this.lastRequestedSegment.stream && (this.logger(`update stream: ${z(t)}`), this.requestProcessQueueMicrotask()); + } + destroy() { + var t; + clearInterval(this.storageCleanUpIntervalId), clearInterval(this.randomHttpDownloadInterval), this.storageCleanUpIntervalId = void 0, (t = this.engineRequest) == null || t.abort(), this.requests.destroy(), this.p2pLoaders.destroy(); + } +} +class tn { + constructor(t = 2e4) { + f(this, "loadingsCount", 0); + f(this, "bytes", []); + f(this, "loadingOnlyTimestamps", []); + f(this, "timestamps", []); + f(this, "noLoadingsTime", 0); + f(this, "loadingsStoppedAt", 0); + this.clearThresholdMs = t; + } + addBytes(t, e = performance.now()) { + this.bytes.push(t), this.loadingOnlyTimestamps.push(e - this.noLoadingsTime), this.timestamps.push(e); + } + startLoading(t = performance.now()) { + this.clearStale(), this.loadingsCount === 0 && this.loadingsStoppedAt !== 0 && (this.noLoadingsTime += t - this.loadingsStoppedAt), this.loadingsCount++; + } + stopLoading(t = performance.now()) { + this.loadingsCount > 0 && (this.loadingsCount--, this.loadingsCount === 0 && (this.loadingsStoppedAt = t)); + } + getBandwidthLoadingOnly(t, e = Number.NEGATIVE_INFINITY) { + if (!this.loadingOnlyTimestamps.length) return 0; + const n = 1e3 * t, r = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1]; + let i = r; + const o = r - n; + let a = 0; + for (let h = this.bytes.length - 1; h >= 0; h--) { + const u = this.loadingOnlyTimestamps[h]; + if (u < o || this.timestamps[h] < e) break; + i = u, a += this.bytes[h]; + } + return 8e3 * a / (r - i); + } + getBandwidth(t, e = Number.NEGATIVE_INFINITY, n = performance.now()) { + if (!this.timestamps.length) return 0; + const r = n - 1e3 * t; + let i = n, o = 0; + for (let a = this.bytes.length - 1; a >= 0; a--) { + const h = this.timestamps[a]; + if (h < r || h < e) break; + i = h, o += this.bytes[a]; + } + return 8e3 * o / (n - i); + } + clearStale() { + if (!this.loadingOnlyTimestamps.length) return; + const t = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1] - this.clearThresholdMs; + let e = 0; + for (const n of this.loadingOnlyTimestamps) { + if (n > t) break; + e++; + } + this.bytes.splice(0, e), this.loadingOnlyTimestamps.splice(0, e), this.timestamps.splice(0, e); + } +} +class Wn { + constructor() { + f(this, "events", /* @__PURE__ */ new Map()); + } + dispatchEvent(t, ...e) { + const n = this.events.get(t); + if (n) for (const r of n) r(...e); + } + getEventDispatcher(t) { + let e = this.events.get(t); + e || (e = [], this.events.set(t, e)); + const n = e; + return (...r) => { + for (const i of n) i(...r); + }; + } + addEventListener(t, e) { + const n = this.events.get(t); + n ? n.push(e) : this.events.set(t, [e]); + } + removeEventListener(t, e) { + const n = this.events.get(t); + if (n) { + const r = n.indexOf(e); + r !== -1 && n.splice(r, 1); + } + } +} +function $t(s) { + return `${$(s.stream)}|${s.externalId}`; +} +class kr { + constructor(t) { + f(this, "cache", /* @__PURE__ */ new Map()); + f(this, "_isInitialized", !1); + f(this, "isSegmentLockedPredicates", []); + f(this, "logger"); + f(this, "eventTarget", new Wn()); + this.storageConfig = t, this.logger = P("p2pml-core:segment-memory-storage"), this.logger.color = "RebeccaPurple"; + } + async initialize() { + this._isInitialized = !0, this.logger("initialized"); + } + get isInitialized() { + return this._isInitialized; + } + addIsSegmentLockedPredicate(t) { + this.isSegmentLockedPredicates.push(t); + } + isSegmentLocked(t) { + return this.isSegmentLockedPredicates.some((e) => e(t)); + } + async storeSegment(t, e, n) { + const r = $t(t); + this.cache.set(r, { segment: t, data: e, lastAccessed: performance.now() }), this.logger(`add segment: ${r}`), this.dispatchStorageUpdatedEvent(t.stream), this.clear(n); + } + async getSegmentData(t) { + const e = $t(t), n = this.cache.get(e); + if (n !== void 0) return n.lastAccessed = performance.now(), n.data; + } + hasSegment(t) { + const e = $t(t); + return this.cache.has(e); + } + getStoredSegmentExternalIdsOfStream(t) { + const e = $(t), n = []; + for (const { segment: r } of this.cache.values()) + $(r.stream) === e && n.push(r.externalId); + return n; + } + async clear(t) { + const e = 1e3 * (this.storageConfig.cachedSegmentExpiration ?? (t ? 1200 : 0)); + if (e === 0) return !1; + const n = [], r = [], i = /* @__PURE__ */ new Set(), o = performance.now(); + for (const a of this.cache.entries()) { + const [h, u] = a, { lastAccessed: d, segment: p } = u; + o - d > e ? this.isSegmentLocked(p) || (n.push(h), i.add(p.stream)) : r.push(a); + } + if (this.storageConfig.cachedSegmentsCount > 0) { + let a = r.length - this.storageConfig.cachedSegmentsCount; + if (a > 0) { + r.sort(([, h], [, u]) => h.lastAccessed - u.lastAccessed); + for (const [h, { segment: u }] of r) if (!this.isSegmentLocked(u) && (n.push(h), i.add(u.stream), a--, a === 0)) break; + } + } + if (n.length) { + this.logger(`cleared ${n.length} segments`), n.forEach((a) => this.cache.delete(a)); + for (const a of i) this.dispatchStorageUpdatedEvent(a); + } + return n.length > 0; + } + subscribeOnUpdate(t, e) { + const n = $(t); + this.eventTarget.addEventListener(`onStorageUpdated-${n}`, e); + } + unsubscribeFromUpdate(t, e) { + const n = $(t); + this.eventTarget.removeEventListener(`onStorageUpdated-${n}`, e); + } + dispatchStorageUpdatedEvent(t) { + this.eventTarget.dispatchEvent(`onStorageUpdated-${$(t)}`, t); + } + async destroy() { + this.cache.clear(), this._isInitialized = !1; + } +} +const j = class j { + constructor(t) { + f(this, "eventTarget", new Wn()); + f(this, "manifestResponseUrl"); + f(this, "streams", /* @__PURE__ */ new Map()); + f(this, "mainStreamConfig"); + f(this, "secondaryStreamConfig"); + f(this, "commonCoreConfig"); + f(this, "bandwidthCalculators", { all: new tn(), http: new tn() }); + f(this, "segmentStorage"); + f(this, "mainStreamLoader"); + f(this, "secondaryStreamLoader"); + f(this, "streamDetails", { isLive: !1, activeLevelBitrate: 0 }); + const e = function n(r) { + if (Fn(r)) { + const i = {}; + return Object.keys(r).forEach((o) => { + if (r[o] !== void 0) { + const a = n(r[o]); + a !== void 0 && (i[o] = a); + } + }), i; + } + return r; + }(t ?? {}); + this.commonCoreConfig = Ft({ defaultConfig: j.DEFAULT_COMMON_CORE_CONFIG, baseConfig: e }), this.mainStreamConfig = Ft({ defaultConfig: j.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e == null ? void 0 : e.mainStream }), this.secondaryStreamConfig = Ft({ defaultConfig: j.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e == null ? void 0 : e.secondaryStream }); + } + getConfig() { + return { ...K(this.commonCoreConfig), mainStream: K(this.mainStreamConfig), secondaryStream: K(this.secondaryStreamConfig) }; + } + applyDynamicConfig(t) { + const { mainStream: e, secondaryStream: n } = t; + this.overrideAllConfigs(t, e, n), this.mainStreamConfig.isP2PDisabled && this.destroyStreamLoader("main"), this.secondaryStreamConfig.isP2PDisabled && this.destroyStreamLoader("secondary"); + } + addEventListener(t, e) { + this.eventTarget.addEventListener(t, e); + } + removeEventListener(t, e) { + this.eventTarget.removeEventListener(t, e); + } + setManifestResponseUrl(t) { + this.manifestResponseUrl = t.split("?")[0]; + } + hasSegment(t) { + return !!Xe(this.streams, t); + } + getStream(t) { + return this.streams.get(t); + } + addStreamIfNoneExists(t) { + this.streams.has(t.runtimeId) || this.streams.set(t.runtimeId, { ...t, segments: /* @__PURE__ */ new Map() }); + } + updateStream(t, e, n) { + var i, o; + const r = this.streams.get(t); + if (r) { + if (e) for (const a of e) r.segments.has(a.runtimeId) || r.segments.set(a.runtimeId, { ...a, stream: r }); + if (n) for (const a of n) r.segments.delete(a); + (i = this.mainStreamLoader) == null || i.updateStream(r), (o = this.secondaryStreamLoader) == null || o.updateStream(r); + } + } + async loadSegment(t, e) { + if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined"); + this.segmentStorage || (this.segmentStorage = new kr(this.commonCoreConfig), await this.segmentStorage.initialize()); + const n = this.identifySegment(t); + this.getStreamHybridLoader(n).loadSegment(n, e); + } + abortSegmentLoading(t) { + var e, n; + (e = this.mainStreamLoader) == null || e.abortSegmentRequest(t), (n = this.secondaryStreamLoader) == null || n.abortSegmentRequest(t); + } + updatePlayback(t, e) { + var n, r; + (n = this.mainStreamLoader) == null || n.updatePlayback(t, e), (r = this.secondaryStreamLoader) == null || r.updatePlayback(t, e); + } + setActiveLevelBitrate(t) { + var e, n; + t !== this.streamDetails.activeLevelBitrate && (this.streamDetails.activeLevelBitrate = t, (e = this.mainStreamLoader) == null || e.notifyLevelChanged(), (n = this.secondaryStreamLoader) == null || n.notifyLevelChanged()); + } + setIsLive(t) { + this.streamDetails.isLive = t; + } + isSegmentLoadable(t) { + try { + const e = this.identifySegment(t); + return (e.stream.type !== "main" || !this.mainStreamConfig.isP2PDisabled) && (e.stream.type !== "secondary" || !this.secondaryStreamConfig.isP2PDisabled); + } catch { + return !1; + } + } + destroy() { + var t, e, n; + this.streams.clear(), (t = this.mainStreamLoader) == null || t.destroy(), (e = this.secondaryStreamLoader) == null || e.destroy(), (n = this.segmentStorage) == null || n.destroy(), this.mainStreamLoader = void 0, this.secondaryStreamLoader = void 0, this.segmentStorage = void 0, this.manifestResponseUrl = void 0, this.streamDetails = { isLive: !1, activeLevelBitrate: 0 }; + } + identifySegment(t) { + if (!this.manifestResponseUrl) throw new Error("Manifest response url is undefined"); + const e = Xe(this.streams, t); + if (!e) throw new Error(`Not found segment with id: ${t}`); + return e; + } + overrideAllConfigs(t, e, n) { + et(this.commonCoreConfig, t), et(this.mainStreamConfig, t), et(this.secondaryStreamConfig, t), e && et(this.mainStreamConfig, e), n && et(this.secondaryStreamConfig, n); + } + destroyStreamLoader(t) { + var e, n; + t === "main" ? ((e = this.mainStreamLoader) == null || e.destroy(), this.mainStreamLoader = void 0) : ((n = this.secondaryStreamLoader) == null || n.destroy(), this.secondaryStreamLoader = void 0); + } + getStreamHybridLoader(t) { + return t.stream.type === "main" ? (this.mainStreamLoader ?? (this.mainStreamLoader = this.createNewHybridLoader(t)), this.mainStreamLoader) : (this.secondaryStreamLoader ?? (this.secondaryStreamLoader = this.createNewHybridLoader(t)), this.secondaryStreamLoader); + } + createNewHybridLoader(t) { + var n; + if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined"); + if (!((n = this.segmentStorage) != null && n.isInitialized)) throw new Error("Segment storage is not initialized"); + const e = t.stream.type === "main" ? this.mainStreamConfig : this.secondaryStreamConfig; + return new Lr(this.manifestResponseUrl, t, this.streamDetails, e, this.bandwidthCalculators, this.segmentStorage, this.eventTarget); + } +}; +f(j, "DEFAULT_COMMON_CORE_CONFIG", { cachedSegmentExpiration: void 0, cachedSegmentsCount: 0 }), f(j, "DEFAULT_STREAM_CONFIG", { isP2PDisabled: !1, simultaneousHttpDownloads: 3, simultaneousP2PDownloads: 3, highDemandTimeWindow: 15, httpDownloadTimeWindow: 3e3, p2pDownloadTimeWindow: 6e3, webRtcMaxMessageSize: 65535, p2pNotReceivingBytesTimeoutMs: 1e3, p2pInactiveLoaderDestroyTimeoutMs: 3e4, httpNotReceivingBytesTimeoutMs: 1e3, httpErrorRetries: 3, p2pErrorRetries: 3, trackerClientVersionPrefix: ir, announceTrackers: ["wss://tracker.novage.com.ua", "wss://tracker.webtorrent.dev", "wss://tracker.openwebtorrent.com"], rtcConfig: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }, { urls: "stun:global.stun.twilio.com:3478" }] }, validateP2PSegment: void 0, httpRequestSetup: void 0, swarmId: void 0 }); +let en = j; +const Ar = on.debug; +export { + en as Core, + fe as CoreRequestError, + I as RequestError, + Ar as debug +}; +//# sourceMappingURL=p2p-media-loader-core.es.min.js.map diff --git a/resources/p2p-media-loader-hlsjs/1.0.3/p2p-media-loader-hlsjs.min.jsm b/resources/p2p-media-loader-hlsjs/1.0.3/p2p-media-loader-hlsjs.min.jsm new file mode 100644 index 00000000..23bbb096 --- /dev/null +++ b/resources/p2p-media-loader-hlsjs/1.0.3/p2p-media-loader-hlsjs.min.jsm @@ -0,0 +1,219 @@ +var j = Object.defineProperty; +var R = (n) => { + throw TypeError(n); +}; +var q = (n, t, e) => t in n ? j(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e; +var r = (n, t, e) => q(n, typeof t != "symbol" ? t + "" : t, e), A = (n, t, e) => t.has(n) || R("Cannot " + e); +var i = (n, t, e) => (A(n, t, "read from private field"), e ? e.call(n) : t.get(n)), l = (n, t, e) => t.has(n) ? R("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(n) : t.set(n, e), u = (n, t, e, s) => (A(n, t, "write to private field"), s ? s.call(n, e) : t.set(n, e), e), x = (n, t, e) => (A(n, t, "access private method"), e); +import { CoreRequestError as T, debug as N, Core as z } from "p2p-media-loader-core"; +function F(n, t) { + return t ? `${n}|${t.start}-${t.end}` : n; +} +function J(n, t) { + if (n !== void 0 && t !== void 0 && n <= t) return { start: n, end: t }; +} +var H, C, g, v, f, p, b, G, U; +class B { + constructor(t, e) { + l(this, b); + r(this, "context"); + r(this, "config"); + r(this, "stats"); + l(this, H); + l(this, C); + l(this, g); + l(this, v); + l(this, f); + l(this, p); + u(this, v, e), u(this, C, () => new t.loader(t)), this.stats = { aborted: !1, chunkCount: 0, loading: { start: 0, first: 0, end: 0 }, buffering: { start: 0, first: 0, end: 0 }, parsing: { start: 0, end: 0 }, total: 1, loaded: 1, bwEstimate: 0, retry: 0 }; + } + load(t, e, s) { + var L; + this.context = t, this.config = e, u(this, H, s); + const o = this.stats, { rangeStart: h, rangeEnd: a } = t, y = J(h, a !== void 0 ? a - 1 : void 0); + u(this, p, F(t.url, y)); + const c = i(this, v).isSegmentLoadable(i(this, p)); + if (!i(this, v).hasSegment(i(this, p)) || c === !1) return u(this, g, i(this, C).call(this)), i(this, g).stats = this.stats, void ((L = i(this, g)) == null ? void 0 : L.load(t, e, s)); + i(this, v).loadSegment(i(this, p), { onSuccess: (d) => { + u(this, f, d); + const E = i(this, f).data.byteLength; + o.loading = function(I, w, S) { + const P = 8e3 * w / I, M = S - P; + return { start: M - 10, first: M, end: S }; + }(i(this, f).bandwidth, E, performance.now()), o.total = o.loaded = E, s.onProgress && s.onProgress(this.stats, t, i(this, f).data, void 0), s.onSuccess({ data: i(this, f).data, url: t.url }, this.stats, t, void 0); + }, onError: (d) => { + d instanceof T && d.type === "aborted" && this.stats.aborted || x(this, b, G).call(this, d); + } }); + } + abort() { + var t, e; + i(this, g) ? i(this, g).abort() : (x(this, b, U).call(this), (e = (t = i(this, H)) == null ? void 0 : t.onAbort) == null || e.call(t, this.stats, this.context, {})); + } + destroy() { + i(this, g) ? i(this, g).destroy() : (this.stats.aborted || x(this, b, U).call(this), u(this, H, null), this.config = null); + } +} +H = new WeakMap(), C = new WeakMap(), g = new WeakMap(), v = new WeakMap(), f = new WeakMap(), p = new WeakMap(), b = new WeakSet(), G = function(t) { + var s; + const e = { code: 0, text: "" }; + (t instanceof T && t.type === "failed" || t instanceof Error) && (e.text = t.message), (s = i(this, H)) == null || s.onError(e, this.context, null, this.stats); +}, U = function() { + !i(this, f) && i(this, p) && (this.stats.aborted = !0, i(this, v).abortSegmentLoading(i(this, p))); +}; +var m; +class X { + constructor(t) { + l(this, m); + r(this, "context"); + r(this, "stats"); + u(this, m, new t.loader(t)), this.stats = i(this, m).stats, this.context = i(this, m).context; + } + load(t, e, s) { + i(this, m).load(t, e, s); + } + abort() { + i(this, m).abort(); + } + destroy() { + i(this, m).destroy(); + } +} +m = new WeakMap(); +class K { + constructor(t) { + r(this, "core"); + this.core = t; + } + processMainManifest(t) { + const { levels: e, audioTracks: s } = t; + for (const [o, h] of e.entries()) { + const { url: a } = h; + this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(a) ? a[0] : a, type: "main", index: o }); + } + for (const [o, h] of s.entries()) { + const { url: a } = h; + this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(a) ? a[0] : a, type: "secondary", index: o }); + } + } + updatePlaylist(t) { + if (!t.details) return; + const { details: { url: e, fragments: s, live: o } } = t, h = this.core.getStream(e); + if (!h) return; + const a = new Set(h.segments.keys()), y = []; + s.forEach((c, L) => { + const { url: d, byteRange: E, sn: I, start: w, end: S } = c; + if (I === "initSegment") return; + const [P, M] = E, k = J(P, M !== void 0 ? M - 1 : void 0), D = F(d, k); + a.delete(D), h.segments.has(D) || y.push({ runtimeId: D, url: d, externalId: o ? I : L, byteRange: k, startTime: w, endTime: S }); + }), (y.length || a.size) && this.core.updateStream(e, y, a.values()); + } +} +class $ { + constructor(t) { + r(this, "core"); + r(this, "segmentManager"); + r(this, "hlsInstanceGetter"); + r(this, "currentHlsInstance"); + r(this, "debug", N("p2pml-hlsjs:engine")); + r(this, "updateMediaElementEventHandlers", (t) => { + var o; + const e = (o = this.currentHlsInstance) == null ? void 0 : o.media; + if (!e) return; + const s = t === "register" ? "addEventListener" : "removeEventListener"; + e[s]("timeupdate", this.handlePlaybackUpdate), e[s]("seeking", this.handlePlaybackUpdate), e[s]("ratechange", this.handlePlaybackUpdate); + }); + r(this, "handleManifestLoaded", (t, e) => { + const s = e.networkDetails; + s instanceof XMLHttpRequest ? this.core.setManifestResponseUrl(s.responseURL) : s instanceof Response && this.core.setManifestResponseUrl(s.url), this.segmentManager.processMainManifest(e); + }); + r(this, "handleLevelSwitching", (t, e) => { + e.bitrate && this.core.setActiveLevelBitrate(e.bitrate); + }); + r(this, "handleLevelUpdated", (t, e) => { + this.currentHlsInstance && this.currentHlsInstance.config.liveSyncDurationCount !== e.details.fragments.length - 1 && e.details.live && e.details.fragments[0].type === "main" && !this.currentHlsInstance.userConfig.liveSyncDuration && !this.currentHlsInstance.userConfig.liveSyncDurationCount && e.details.fragments.length > 4 && (this.debug("set liveSyncDurationCount " + (e.details.fragments.length - 1)), this.currentHlsInstance.config.liveSyncDurationCount = e.details.fragments.length - 1), this.core.setIsLive(e.details.live), this.segmentManager.updatePlaylist(e); + }); + r(this, "handleMediaAttached", () => { + this.updateMediaElementEventHandlers("register"); + }); + r(this, "handleMediaDetached", () => { + this.updateMediaElementEventHandlers("unregister"); + }); + r(this, "handlePlaybackUpdate", (t) => { + const e = t.target; + this.core.updatePlayback(e.currentTime, e.playbackRate); + }); + r(this, "destroyCore", () => this.core.destroy()); + r(this, "destroy", () => { + this.destroyCore(), this.updateHlsEventsHandlers("unregister"), this.updateMediaElementEventHandlers("unregister"), this.currentHlsInstance = void 0; + }); + this.core = new z(t == null ? void 0 : t.core), this.segmentManager = new K(this.core); + } + static injectMixin(t) { + var s, o; + return e = t, o = class extends e { + constructor(...a) { + var E; + const y = a[0], { p2p: c, ...L } = y ?? {}, d = new $(c); + super({ ...L, ...d.getConfigForHlsJs() }); + l(this, s); + d.bindHls(this), u(this, s, d), (E = c == null ? void 0 : c.onHlsJsCreated) == null || E.call(c, this); + } + get p2pEngine() { + return i(this, s); + } + }, s = new WeakMap(), o; + var e; + } + addEventListener(t, e) { + this.core.addEventListener(t, e); + } + removeEventListener(t, e) { + this.core.removeEventListener(t, e); + } + getConfigForHlsJs() { + return { fLoader: this.createFragmentLoaderClass(), pLoader: this.createPlaylistLoaderClass() }; + } + getConfig() { + return { core: this.core.getConfig() }; + } + applyDynamicConfig(t) { + t.core && this.core.applyDynamicConfig(t.core); + } + bindHls(t) { + this.hlsInstanceGetter = typeof t == "function" ? t : () => t; + } + initHlsEvents() { + var e; + const t = (e = this.hlsInstanceGetter) == null ? void 0 : e.call(this); + this.currentHlsInstance !== t && (this.currentHlsInstance && this.destroy(), this.currentHlsInstance = t, this.updateHlsEventsHandlers("register"), this.updateMediaElementEventHandlers("register")); + } + updateHlsEventsHandlers(t) { + const e = this.currentHlsInstance; + if (!e) return; + const s = t === "register" ? "on" : "off"; + e[s]("hlsManifestLoaded", this.handleManifestLoaded), e[s]("hlsLevelSwitching", this.handleLevelSwitching), e[s]("hlsLevelUpdated", this.handleLevelUpdated), e[s]("hlsAudioTrackLoaded", this.handleLevelUpdated), e[s]("hlsDestroying", this.destroy), e[s]("hlsMediaAttaching", this.destroyCore), e[s]("hlsManifestLoading", this.destroyCore), e[s]("hlsMediaDetached", this.handleMediaDetached), e[s]("hlsMediaAttached", this.handleMediaAttached); + } + createFragmentLoaderClass() { + const t = this.core, e = this; + return class extends B { + constructor(s) { + super(s, t); + } + static getEngine() { + return e; + } + }; + } + createPlaylistLoaderClass() { + const t = this; + return class extends X { + constructor(e) { + super(e), t.initHlsEvents(); + } + }; + } +} +export { + $ as HlsJsP2PEngine +}; +//# sourceMappingURL=p2p-media-loader-hlsjs.es.min.js.map