@oddin-gg/havik-player 2.25.1 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -315,25 +315,25 @@ function x(e) {
315
315
  function _e(e) {
316
316
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
317
317
  }
318
- function ve(e, t) {
318
+ function S(e, t) {
319
319
  let n = _e(x(e));
320
320
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
321
321
  }
322
- function ye(e, t) {
322
+ function C(e, t) {
323
323
  let n = t ?? e, r = x(e);
324
324
  if (typeof n.requestFullscreen == "function") return r.fullscreenEnabled !== !1;
325
325
  if (typeof n.webkitRequestFullscreen == "function") return r.webkitFullscreenEnabled !== !1;
326
326
  let i = e;
327
327
  return i.webkitSupportsFullscreen === !0 && typeof i.webkitEnterFullscreen == "function" || e.readyState < 1;
328
328
  }
329
- async function S(e, t) {
329
+ async function w(e, t) {
330
330
  let n = t ?? e;
331
331
  if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
332
332
  if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
333
333
  let r = e;
334
334
  return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
335
335
  }
336
- async function C(e, t) {
336
+ async function T(e, t) {
337
337
  let n = e;
338
338
  if (n.webkitDisplayingFullscreen) {
339
339
  n.webkitExitFullscreen?.();
@@ -344,7 +344,7 @@ async function C(e, t) {
344
344
  }
345
345
  //#endregion
346
346
  //#region src/core/catalog.ts
347
- async function be(e) {
347
+ async function ve(e) {
348
348
  let t = new URLSearchParams();
349
349
  e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
350
350
  let i = t.toString(), a = f(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
@@ -362,12 +362,12 @@ async function be(e) {
362
362
  };
363
363
  if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
364
364
  return {
365
- tournaments: xe(await s.json()),
365
+ tournaments: ye(await s.json()),
366
366
  etag: s.headers.get("etag") ?? void 0,
367
367
  notModified: !1
368
368
  };
369
369
  }
370
- function xe(e) {
370
+ function ye(e) {
371
371
  return (e.tournaments ?? []).map((e) => {
372
372
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
373
373
  return {
@@ -389,7 +389,7 @@ function xe(e) {
389
389
  };
390
390
  });
391
391
  }
392
- async function Se(e) {
392
+ async function be(e) {
393
393
  let t = f(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
394
394
  e.etag && i.set("If-None-Match", e.etag);
395
395
  let a = await m(t, {
@@ -409,13 +409,13 @@ async function Se(e) {
409
409
  };
410
410
  if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
411
411
  return {
412
- tournament: Ce(await a.json()),
412
+ tournament: xe(await a.json()),
413
413
  etag: a.headers.get("etag") ?? void 0,
414
414
  notModified: !1,
415
415
  notFound: !1
416
416
  };
417
417
  }
418
- function Ce(e) {
418
+ function xe(e) {
419
419
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
420
420
  return {
421
421
  urn: t,
@@ -435,18 +435,18 @@ function Ce(e) {
435
435
  }))
436
436
  };
437
437
  }
438
- function we(e) {
438
+ function Se(e) {
439
439
  return e.tournaments.flatMap((e) => e.matches);
440
440
  }
441
441
  //#endregion
442
442
  //#region src/core/poll.ts
443
- var Te = /* @__PURE__ */ new Set([
443
+ var Ce = /* @__PURE__ */ new Set([
444
444
  "NOT_FOUND",
445
445
  "GEO_DENIED",
446
446
  "GONE",
447
447
  "INVALID_URN"
448
448
  ]);
449
- function Ee(e) {
449
+ function we(e) {
450
450
  let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, c = !1, d = () => {
451
451
  c || (a = setTimeout(p, t));
452
452
  }, p = async () => {
@@ -479,7 +479,7 @@ function Ee(e) {
479
479
  } catch (t) {
480
480
  if (!i.signal.aborted) {
481
481
  let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
482
- Te.has(r.code) && (c = !0), e.onError?.(r);
482
+ Ce.has(r.code) && (c = !0), e.onError?.(r);
483
483
  }
484
484
  } finally {
485
485
  d();
@@ -491,16 +491,16 @@ function Ee(e) {
491
491
  }
492
492
  //#endregion
493
493
  //#region src/core/events.ts
494
- var De = 45e3, w = class extends Error {
494
+ var Te = 45e3, E = class extends Error {
495
495
  status;
496
496
  terminal;
497
497
  constructor(e) {
498
498
  let t = e === 410;
499
499
  super(t ? `live-state subscribe failed: HTTP ${e} — match is gone, not retrying` : e === 404 ? `live-state subscribe failed: HTTP ${e} — match not in the catalog, retrying slowly` : `live-state subscribe failed: HTTP ${e}`), this.name = "LiveStateHttpError", this.status = e, this.terminal = t;
500
500
  }
501
- }, Oe = 3e5;
502
- function T(e) {
503
- let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Oe), i = e.idleTimeoutMs ?? De, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
501
+ }, Ee = 3e5;
502
+ function D(e) {
503
+ let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Ee), i = e.idleTimeoutMs ?? Te, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
504
504
  if (o.signal.aborted) return t();
505
505
  let n = setTimeout(t, e);
506
506
  o.signal.addEventListener("abort", () => {
@@ -567,7 +567,7 @@ function T(e) {
567
567
  });
568
568
  if (clearTimeout(_), s) return;
569
569
  if (!o.ok || !o.body) {
570
- let t = new w(o.status);
570
+ let t = new E(o.status);
571
571
  h = t.terminal, g = o.status === 404, e.onError?.(t);
572
572
  } else await p(o.body, () => {
573
573
  i = t;
@@ -585,7 +585,7 @@ function T(e) {
585
585
  s || (s = !0, o.abort());
586
586
  } };
587
587
  }
588
- function E(e) {
588
+ function O(e) {
589
589
  try {
590
590
  let t = new URL(e);
591
591
  return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
@@ -595,24 +595,24 @@ function E(e) {
595
595
  }
596
596
  //#endregion
597
597
  //#region src/core/drm/deviceId.ts
598
- var D = "havik.player.deviceId", O;
599
- function k() {
600
- if (O) return O;
598
+ var De = "havik.player.deviceId", k;
599
+ function Oe() {
600
+ if (k) return k;
601
601
  try {
602
- let e = globalThis.localStorage?.getItem(D);
603
- if (e) return O = e, e;
602
+ let e = globalThis.localStorage?.getItem(De);
603
+ if (e) return k = e, e;
604
604
  } catch {}
605
605
  let e = Ae();
606
- O = e;
606
+ k = e;
607
607
  try {
608
- globalThis.localStorage?.setItem(D, e);
608
+ globalThis.localStorage?.setItem(De, e);
609
609
  } catch {}
610
610
  return e;
611
611
  }
612
612
  function ke() {
613
- O = void 0;
613
+ k = void 0;
614
614
  try {
615
- globalThis.localStorage?.removeItem(D);
615
+ globalThis.localStorage?.removeItem(De);
616
616
  } catch {}
617
617
  }
618
618
  function Ae() {
@@ -631,28 +631,28 @@ function je(e, t, n = {}) {
631
631
  let r = {
632
632
  "x-api-key": t.apiKey,
633
633
  "X-Match-Urn": e.matchUrn,
634
- "X-Device-Id": n.deviceId ?? k(),
634
+ "X-Device-Id": n.deviceId ?? Oe(),
635
635
  "Content-Type": "application/octet-stream"
636
636
  };
637
637
  return n.userId && (r["X-User-Id"] = n.userId), r;
638
638
  }
639
639
  //#endregion
640
640
  //#region src/core/bandwidthMemory.ts
641
- var A = "havik.player.bandwidth", Me = .8, Ne = 2e7, Pe = 3e5;
642
- function Fe() {
641
+ var Me = "havik.player.bandwidth", Ne = .8, Pe = 2e7, Fe = 3e5;
642
+ function Ie() {
643
643
  return globalThis.navigator?.connection;
644
644
  }
645
- function Ie() {
646
- let e = Fe()?.type;
645
+ function Le() {
646
+ let e = Ie()?.type;
647
647
  return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
648
648
  }
649
- function Le() {
650
- let e = Fe()?.downlink;
649
+ function Re() {
650
+ let e = Ie()?.downlink;
651
651
  return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
652
652
  }
653
- function Re() {
653
+ function ze() {
654
654
  try {
655
- let e = globalThis.localStorage?.getItem(A);
655
+ let e = globalThis.localStorage?.getItem(Me);
656
656
  if (!e) return {};
657
657
  let t = JSON.parse(e);
658
658
  return t && typeof t == "object" && !Array.isArray(t) ? t : {};
@@ -660,36 +660,36 @@ function Re() {
660
660
  return {};
661
661
  }
662
662
  }
663
- function ze(e = Date.now()) {
664
- let t = Re()[Ie()];
663
+ function Be(e = Date.now()) {
664
+ let t = ze()[Le()];
665
665
  if (!t || typeof t.bps != "number" || typeof t.at != "number" || !Number.isFinite(t.bps) || t.bps <= 0) return;
666
666
  let n = e - t.at;
667
667
  if (n < 0 || n > 2592e5) return;
668
- let r = Le(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
669
- return Math.round(Math.min(Ne, Math.max(Pe, i * Me)));
668
+ let r = Re(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
669
+ return Math.round(Math.min(Pe, Math.max(Fe, i * Ne)));
670
670
  }
671
- function Be(e, t = Date.now()) {
671
+ function Ve(e, t = Date.now()) {
672
672
  if (!Number.isFinite(e) || e <= 0) return;
673
- let n = Re();
674
- n[Ie()] = {
673
+ let n = ze();
674
+ n[Le()] = {
675
675
  bps: Math.round(e),
676
676
  at: t
677
677
  };
678
678
  try {
679
- globalThis.localStorage?.setItem(A, JSON.stringify(n));
679
+ globalThis.localStorage?.setItem(Me, JSON.stringify(n));
680
680
  } catch {}
681
681
  }
682
- function Ve() {
682
+ function He() {
683
683
  try {
684
- globalThis.localStorage?.removeItem(A);
684
+ globalThis.localStorage?.removeItem(Me);
685
685
  } catch {}
686
686
  }
687
687
  //#endregion
688
688
  //#region src/core/drm/cdm.ts
689
- var He = /* @__PURE__ */ new WeakMap();
690
- function Ue(e, t) {
691
- let n = He.get(e);
692
- n || (n = /* @__PURE__ */ new Map(), He.set(e, n));
689
+ var Ue = /* @__PURE__ */ new WeakMap();
690
+ function We(e, t) {
691
+ let n = Ue.get(e);
692
+ n || (n = /* @__PURE__ */ new Map(), Ue.set(e, n));
693
693
  let r = n.get(t.keySystem);
694
694
  if (r) return r;
695
695
  let i = t.createMediaKeys().catch((e) => {
@@ -697,22 +697,22 @@ function Ue(e, t) {
697
697
  });
698
698
  return n.set(t.keySystem, i), i;
699
699
  }
700
- function j() {
700
+ function A() {
701
701
  return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
702
702
  }
703
- var M = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
704
- function We(e) {
703
+ var j = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
704
+ function Ge(e) {
705
705
  return e.startsWith("com.widevine");
706
706
  }
707
- function N(e, t) {
708
- if (!We(e)) return t;
707
+ function M(e, t) {
708
+ if (!Ge(e)) return t;
709
709
  let n = (e, t) => {
710
710
  let n = e.videoCapabilities;
711
711
  return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
712
- let n = M.indexOf(e.robustness);
713
- return n === -1 || M.indexOf(t) > n;
712
+ let n = j.indexOf(e.robustness);
713
+ return n === -1 || j.indexOf(t) > n;
714
714
  });
715
- }, r = M.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
715
+ }, r = j.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
716
716
  ...t,
717
717
  videoCapabilities: t.videoCapabilities?.map((t) => ({
718
718
  ...t,
@@ -721,53 +721,53 @@ function N(e, t) {
721
721
  })));
722
722
  return [...t, ...r];
723
723
  }
724
- function Ge(e) {
725
- return (t, n) => j() ? navigator.requestMediaKeySystemAccess(t, N(t, n)).then((t) => ({
724
+ function Ke(e) {
725
+ return (t, n) => A() ? navigator.requestMediaKeySystemAccess(t, M(t, n)).then((t) => ({
726
726
  keySystem: t.keySystem,
727
727
  getConfiguration: () => t.getConfiguration(),
728
- createMediaKeys: () => Ue(e, t)
728
+ createMediaKeys: () => We(e, t)
729
729
  })) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
730
730
  }
731
- var P = {
731
+ var N = {
732
732
  video: "SW_SECURE_DECODE",
733
733
  audio: "SW_SECURE_CRYPTO",
734
734
  scheme: "cbcs"
735
735
  };
736
- function Ke(e) {
737
- if (!j()) return;
736
+ function qe(e) {
737
+ if (!A()) return;
738
738
  let t = (e, t) => ({
739
739
  contentType: e,
740
740
  robustness: t,
741
- encryptionScheme: P.scheme
741
+ encryptionScheme: N.scheme
742
742
  });
743
- Ge(e)("com.widevine.alpha", [{
743
+ Ke(e)("com.widevine.alpha", [{
744
744
  initDataTypes: ["cenc"],
745
745
  distinctiveIdentifier: "optional",
746
746
  persistentState: "optional",
747
747
  sessionTypes: ["temporary"],
748
- audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", P.audio)],
749
- videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", P.video)]
748
+ audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", N.audio)],
749
+ videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", N.video)]
750
750
  }]).then((e) => e.createMediaKeys()).catch(() => {});
751
751
  }
752
- function F(e) {
753
- let t = I(e);
752
+ function P(e) {
753
+ let t = F(e);
754
754
  if (/^avc[13]/.test(t)) return "avc";
755
755
  if (/^(hvc1|hev1)/.test(t)) return "hevc";
756
756
  if (/^(dvh1|dvhe)/.test(t)) return "dv";
757
757
  if (t.startsWith("av01")) return "av1";
758
758
  if (/^vp0?9/.test(t)) return "vp9";
759
759
  }
760
- function I(e) {
760
+ function F(e) {
761
761
  return (e ?? "").trim().toLowerCase();
762
762
  }
763
- var qe = {
763
+ var Je = {
764
764
  hevc: "hvc1.1.6.L93.90",
765
765
  dv: "dvh1.05.06",
766
766
  av1: "av01.0.05M.08",
767
767
  vp9: "vp09.00.10.08"
768
- }, Je = /* @__PURE__ */ new Map(), L = /* @__PURE__ */ new Map();
769
- function Ye(e) {
770
- let t = I(e), n = Je.get(t);
768
+ }, Ye = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map();
769
+ function Xe(e) {
770
+ let t = F(e), n = Ye.get(t);
771
771
  if (n) return n;
772
772
  let r = {
773
773
  initDataTypes: ["cenc"],
@@ -776,32 +776,32 @@ function Ye(e) {
776
776
  sessionTypes: ["temporary"],
777
777
  videoCapabilities: [{
778
778
  contentType: `video/mp4; codecs="${e.trim()}"`,
779
- robustness: P.video,
780
- encryptionScheme: P.scheme
779
+ robustness: N.video,
780
+ encryptionScheme: N.scheme
781
781
  }]
782
782
  }, i = (async () => {
783
783
  try {
784
- return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", N("com.widevine.alpha", [r])), !0;
784
+ return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", M("com.widevine.alpha", [r])), !0;
785
785
  } catch {
786
786
  return !1;
787
787
  }
788
- })().then((e) => (L.set(t, e), e));
789
- return Je.set(t, i), i;
788
+ })().then((e) => (I.set(t, e), e));
789
+ return Ye.set(t, i), i;
790
790
  }
791
- function Xe() {
792
- if (j()) for (let e of Object.values(qe)) Ye(e);
791
+ function Ze() {
792
+ if (A()) for (let e of Object.values(Je)) Xe(e);
793
793
  }
794
- function Ze(e) {
795
- let t = F(e);
796
- if (t) return t === "avc" ? !0 : L.get(I(e)) ?? L.get(I(qe[t]));
794
+ function Qe(e) {
795
+ let t = P(e);
796
+ if (t) return t === "avc" ? !0 : I.get(F(e)) ?? I.get(F(Je[t]));
797
797
  }
798
798
  //#endregion
799
799
  //#region src/core/drm/support.ts
800
- var Qe = 5e3, $e = "video/mp4; codecs=\"avc1.42E01E\"", et = "audio/mp4; codecs=\"mp4a.40.2\"", tt = {
800
+ var $e = 5e3, et = "video/mp4; codecs=\"avc1.42E01E\"", tt = "audio/mp4; codecs=\"mp4a.40.2\"", nt = {
801
801
  widevine: ["com.widevine.alpha"],
802
802
  fairplay: ["com.apple.fps"]
803
803
  };
804
- function nt(e) {
804
+ function rt(e) {
805
805
  return e === "fairplay" ? [{
806
806
  initDataTypes: [
807
807
  "sinf",
@@ -809,30 +809,30 @@ function nt(e) {
809
809
  "cenc"
810
810
  ],
811
811
  videoCapabilities: [{
812
- contentType: $e,
812
+ contentType: et,
813
813
  robustness: "",
814
814
  encryptionScheme: "cbcs"
815
815
  }],
816
816
  audioCapabilities: [{
817
- contentType: et,
817
+ contentType: tt,
818
818
  robustness: "",
819
819
  encryptionScheme: "cbcs"
820
820
  }]
821
- }] : N("com.widevine.alpha", [{
821
+ }] : M("com.widevine.alpha", [{
822
822
  initDataTypes: ["cenc"],
823
823
  videoCapabilities: [{
824
- contentType: $e,
825
- robustness: P.video,
826
- encryptionScheme: P.scheme
824
+ contentType: et,
825
+ robustness: N.video,
826
+ encryptionScheme: N.scheme
827
827
  }],
828
828
  audioCapabilities: [{
829
- contentType: et,
830
- robustness: P.audio,
831
- encryptionScheme: P.scheme
829
+ contentType: tt,
830
+ robustness: N.audio,
831
+ encryptionScheme: N.scheme
832
832
  }]
833
833
  }]);
834
834
  }
835
- function rt(e, t) {
835
+ function it(e, t) {
836
836
  return new Promise((n, r) => {
837
837
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
838
838
  e.then((e) => {
@@ -842,8 +842,8 @@ function rt(e, t) {
842
842
  });
843
843
  });
844
844
  }
845
- async function it(e = {}) {
846
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Qe, r = {};
845
+ async function at(e = {}) {
846
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? $e, r = {};
847
847
  if (typeof window < "u" && window.isSecureContext === !1) return {
848
848
  verdict: "insecure-context",
849
849
  detail: r
@@ -855,7 +855,7 @@ async function it(e = {}) {
855
855
  };
856
856
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
857
857
  for (let e of t) {
858
- let t = tt[e];
858
+ let t = nt[e];
859
859
  if (!t) {
860
860
  r[e] = "unknown system";
861
861
  continue;
@@ -866,7 +866,7 @@ async function it(e = {}) {
866
866
  break;
867
867
  }
868
868
  try {
869
- return await rt((await rt(i(n, nt(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
869
+ return await it((await it(i(n, rt(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
870
870
  verdict: "supported",
871
871
  system: e,
872
872
  detail: r
@@ -890,32 +890,32 @@ async function it(e = {}) {
890
890
  }
891
891
  //#endregion
892
892
  //#region src/core/manifest.ts
893
- var at = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
894
- function ot(e) {
895
- return at.test(e);
893
+ var ot = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
894
+ function st(e) {
895
+ return ot.test(e);
896
896
  }
897
897
  //#endregion
898
898
  //#region src/core/env.ts
899
- var st = {
899
+ var ct = {
900
900
  integration: "https://feed-dev.oddin-video.gg",
901
901
  production: "https://feed.oddin-video.gg"
902
902
  };
903
- function ct(e) {
904
- let t = Object.prototype.hasOwnProperty.call(st, e) ? st[e] : void 0;
903
+ function lt(e) {
904
+ let t = Object.prototype.hasOwnProperty.call(ct, e) ? ct[e] : void 0;
905
905
  if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
906
906
  return t;
907
907
  }
908
908
  //#endregion
909
909
  //#region src/core/connectivity.ts
910
- function R() {
910
+ function L() {
911
911
  return typeof navigator > "u" || navigator.onLine !== !1;
912
912
  }
913
- function lt() {
913
+ function ut() {
914
914
  let e = /* @__PURE__ */ new Set(), t = (t) => {
915
915
  for (let n of Array.from(e)) n(t);
916
916
  }, n = () => t(!0), r = () => t(!1), i = typeof window < "u" && typeof window.addEventListener == "function";
917
917
  return i && (window.addEventListener("online", n), window.addEventListener("offline", r)), {
918
- isOnline: R,
918
+ isOnline: L,
919
919
  onChange(t) {
920
920
  return e.add(t), () => {
921
921
  e.delete(t);
@@ -928,32 +928,32 @@ function lt() {
928
928
  }
929
929
  //#endregion
930
930
  //#region src/core/stats.ts
931
- var ut = { droppedFrames: 0 };
932
- function dt(e) {
931
+ var dt = { droppedFrames: 0 };
932
+ function ft(e) {
933
933
  try {
934
934
  return new URL(e).host;
935
935
  } catch {
936
936
  return "";
937
937
  }
938
938
  }
939
- var ft = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
940
- function pt(e) {
939
+ var pt = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
940
+ function mt(e) {
941
941
  if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
942
942
  let t = "", n = -1, r = performance.getEntriesByType("resource");
943
- for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || ft.test(i.name)) && i.startTime >= n) {
944
- let e = dt(i.name);
943
+ for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || pt.test(i.name)) && i.startTime >= n) {
944
+ let e = ft(i.name);
945
945
  e && (t = e, n = i.startTime);
946
946
  }
947
947
  return t;
948
948
  }
949
- function z(e) {
949
+ function R(e) {
950
950
  let t = e.getVideoPlaybackQuality?.();
951
951
  return {
952
952
  dropped: t?.droppedVideoFrames ?? 0,
953
953
  totalFrames: t?.totalVideoFrames ?? 0
954
954
  };
955
955
  }
956
- var mt = class {
956
+ var ht = class {
957
957
  video;
958
958
  baseFrames = 0;
959
959
  baseDropped = 0;
@@ -963,7 +963,7 @@ var mt = class {
963
963
  this.video = e;
964
964
  }
965
965
  read() {
966
- let e = z(this.video);
966
+ let e = R(this.video);
967
967
  return e.totalFrames < this.lastFrames && (this.baseFrames += this.lastFrames), e.dropped < this.lastDropped && (this.baseDropped += this.lastDropped), this.lastFrames = e.totalFrames, this.lastDropped = e.dropped, {
968
968
  dropped: this.baseDropped + e.dropped,
969
969
  totalFrames: this.baseFrames + e.totalFrames
@@ -976,7 +976,7 @@ var mt = class {
976
976
  };
977
977
  }
978
978
  };
979
- function ht(e, t) {
979
+ function gt(e, t) {
980
980
  let n = [
981
981
  ["playing", () => t("playing")],
982
982
  ["waiting", () => t("buffering")],
@@ -993,8 +993,8 @@ function ht(e, t) {
993
993
  }
994
994
  //#endregion
995
995
  //#region src/core/engine/native.ts
996
- var gt = 2e3, _t = 3, B = 500, vt = 6e3, yt = .25, bt = 250, xt = .05, St = 4, Ct = 12e3, wt = .25, Tt = 1e3;
997
- function Et(e) {
996
+ var _t = 2e3, vt = 3, z = 500, yt = 6e3, bt = .25, xt = 250, St = .05, Ct = 4, wt = 12e3, Tt = .25, Et = 1e3;
997
+ function Dt(e) {
998
998
  try {
999
999
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
1000
1000
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -1002,20 +1002,20 @@ function Et(e) {
1002
1002
  return;
1003
1003
  }
1004
1004
  }
1005
- function V(e) {
1005
+ function B(e) {
1006
1006
  return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
1007
1007
  }
1008
- function H() {
1008
+ function V() {
1009
1009
  if (typeof window > "u") return !1;
1010
1010
  let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
1011
1011
  return e || t;
1012
1012
  }
1013
- function Dt() {
1014
- if (typeof navigator > "u" || !H()) return !1;
1013
+ function Ot() {
1014
+ if (typeof navigator > "u" || !V()) return !1;
1015
1015
  let e = navigator.userAgent ?? "";
1016
1016
  return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
1017
1017
  }
1018
- var U = class {
1018
+ var H = class {
1019
1019
  name = "native";
1020
1020
  deps;
1021
1021
  onLoaded;
@@ -1045,7 +1045,7 @@ var U = class {
1045
1045
  frameCounter;
1046
1046
  detachFrames = null;
1047
1047
  constructor(e) {
1048
- this.deps = e, this.frameCounter = new mt(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
1048
+ this.deps = e, this.frameCounter = new ht(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
1049
1049
  }
1050
1050
  async load() {
1051
1051
  this.detachFrames ??= this.frameCounter.attach();
@@ -1064,9 +1064,9 @@ var U = class {
1064
1064
  let i = !this.loadStarted;
1065
1065
  this.onLoaded = i ? void 0 : () => r({ type: "ready" }), this.onError = () => r({
1066
1066
  type: "error",
1067
- error: R() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
1067
+ error: L() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
1068
1068
  fatal: !0
1069
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = kt(t.manifestUrl, t.analytics?.sid), e.load();
1069
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = At(t.manifestUrl, t.analytics?.sid), e.load();
1070
1070
  }
1071
1071
  startLoad() {
1072
1072
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -1094,7 +1094,7 @@ var U = class {
1094
1094
  };
1095
1095
  this.onEncrypted = (n) => {
1096
1096
  let a = n;
1097
- a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Et(a.initData), (async () => {
1097
+ a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Dt(a.initData), (async () => {
1098
1098
  try {
1099
1099
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
1100
1100
  initDataTypes: [a.initDataType],
@@ -1194,10 +1194,10 @@ var U = class {
1194
1194
  droppedFrames: t.dropped,
1195
1195
  decodedFrames: t.totalFrames
1196
1196
  };
1197
- if (this.cdnHost ||= pt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1197
+ if (this.cdnHost ||= mt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1198
1198
  n.isLive = !0;
1199
1199
  let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
1200
- Number.isFinite(r) && (n.atLiveEdge = r <= St, !e.paused && r >= 0 && (n.latencySeconds = r));
1200
+ Number.isFinite(r) && (n.atLiveEdge = r <= Ct, !e.paused && r >= 0 && (n.latencySeconds = r));
1201
1201
  } else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
1202
1202
  return n;
1203
1203
  }
@@ -1209,30 +1209,30 @@ var U = class {
1209
1209
  }
1210
1210
  watchRefocus() {
1211
1211
  this.deps.snapToLiveOnRefocus === !1 || typeof document > "u" || this.onVisibility || (this.onVisibility = () => {
1212
- let e = W();
1212
+ let e = U();
1213
1213
  if (document.visibilityState === "hidden") {
1214
1214
  this.hiddenSince = e, this.cancelRefocus();
1215
1215
  return;
1216
1216
  }
1217
1217
  let t = this.hiddenSince;
1218
- this.hiddenSince = null, t != null && e - t >= gt && this.armRefocus();
1218
+ this.hiddenSince = null, t != null && e - t >= _t && this.armRefocus();
1219
1219
  }, this.onPageShow = (e) => {
1220
1220
  e.persisted && this.armRefocus();
1221
1221
  }, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
1222
1222
  }
1223
1223
  armRefocus() {
1224
1224
  if (this.cancelRefocus(), Number.isFinite(this.deps.video.duration)) return;
1225
- let e = this.liveEnd(), t = W, n = t(), r = 0, i = () => {
1225
+ let e = this.liveEnd(), t = U, n = t(), r = 0, i = () => {
1226
1226
  if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
1227
- r += B;
1228
- let a = this.liveEnd(), o = a != null && (e == null || a >= e + yt), s = Math.max(r, t() - n) >= vt;
1227
+ r += z;
1228
+ let a = this.liveEnd(), o = a != null && (e == null || a >= e + bt), s = Math.max(r, t() - n) >= yt;
1229
1229
  if (o || s && a != null) {
1230
1230
  this.snapToLive();
1231
1231
  return;
1232
1232
  }
1233
- this.refocusTimer = setTimeout(i, B);
1233
+ this.refocusTimer = setTimeout(i, z);
1234
1234
  };
1235
- this.refocusTimer = setTimeout(i, B);
1235
+ this.refocusTimer = setTimeout(i, z);
1236
1236
  }
1237
1237
  cancelRefocus() {
1238
1238
  this.refocusTimer != null && clearTimeout(this.refocusTimer), this.refocusTimer = null;
@@ -1245,24 +1245,24 @@ var U = class {
1245
1245
  }, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
1246
1246
  if (e.duration !== Infinity) return;
1247
1247
  this.checkEndStale();
1248
- let t = Ot(e, e.currentTime);
1249
- t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= xt) && (this.bufferedAdvancedAt = W()), this.lastBufferedEnd = t);
1250
- }, bt);
1248
+ let t = kt(e, e.currentTime);
1249
+ t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= St) && (this.bufferedAdvancedAt = U()), this.lastBufferedEnd = t);
1250
+ }, xt);
1251
1251
  }
1252
1252
  checkEndStale() {
1253
1253
  if (this.endedEmitted) return;
1254
- let e = W(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
1254
+ let e = U(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
1255
1255
  this.lastTickAt = e;
1256
1256
  let n = this.liveEnd();
1257
1257
  if (n == null) return;
1258
- let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= wt;
1258
+ let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= Tt;
1259
1259
  this.lastSeekableEnd = n;
1260
1260
  let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
1261
- if (r || t > Tt || a || i.paused) {
1261
+ if (r || t > Et || a || i.paused) {
1262
1262
  this.edgeStampedAt = e;
1263
1263
  return;
1264
1264
  }
1265
- e - (this.edgeStampedAt ?? e) > Ct && (this.endedEmitted = !0, this.deps.emit({
1265
+ e - (this.edgeStampedAt ?? e) > wt && (this.endedEmitted = !0, this.deps.emit({
1266
1266
  type: "ended",
1267
1267
  reason: "stalled"
1268
1268
  }));
@@ -1276,9 +1276,9 @@ var U = class {
1276
1276
  liveEdgeEstimate() {
1277
1277
  let e = this.deps.video;
1278
1278
  if (e.duration !== Infinity) return null;
1279
- let t = this.liveEnd(), n = Ot(e, e.currentTime) ?? this.lastBufferedEnd;
1279
+ let t = this.liveEnd(), n = kt(e, e.currentTime) ?? this.lastBufferedEnd;
1280
1280
  if (n != null) {
1281
- let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (W() - e) / 1e3));
1281
+ let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (U() - e) / 1e3));
1282
1282
  (t == null || r > t) && (t = r);
1283
1283
  }
1284
1284
  return t != null && Number.isFinite(t) ? t : null;
@@ -1292,7 +1292,7 @@ var U = class {
1292
1292
  snapToLive() {
1293
1293
  let e = this.deps.video, t = this.liveEnd();
1294
1294
  if (t == null) return;
1295
- let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - _t, r);
1295
+ let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - vt, r);
1296
1296
  try {
1297
1297
  e.currentTime = i;
1298
1298
  } catch {}
@@ -1310,10 +1310,10 @@ var U = class {
1310
1310
  } catch {}
1311
1311
  }
1312
1312
  };
1313
- function W() {
1313
+ function U() {
1314
1314
  return typeof performance < "u" ? performance.now() : Date.now();
1315
1315
  }
1316
- function Ot(e, t) {
1316
+ function kt(e, t) {
1317
1317
  let n = e.buffered;
1318
1318
  if (!n || !Number.isFinite(t)) return null;
1319
1319
  for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
@@ -1322,12 +1322,12 @@ function Ot(e, t) {
1322
1322
  }
1323
1323
  return null;
1324
1324
  }
1325
- function kt(e, t) {
1325
+ function At(e, t) {
1326
1326
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
1327
1327
  }
1328
1328
  //#endregion
1329
1329
  //#region src/core/drm/signedUrl.ts
1330
- function G(e, t = Date.now()) {
1330
+ function W(e, t = Date.now()) {
1331
1331
  if (!e) return !1;
1332
1332
  let n;
1333
1333
  try {
@@ -1339,13 +1339,13 @@ function G(e, t = Date.now()) {
1339
1339
  }
1340
1340
  //#endregion
1341
1341
  //#region src/core/drm/xhrBody.ts
1342
- var At = 4096;
1343
- function jt(e) {
1342
+ var jt = 4096;
1343
+ function Mt(e) {
1344
1344
  if (!e || typeof e != "object") return;
1345
1345
  let { response: t } = e;
1346
1346
  if (typeof t == "string") return t;
1347
1347
  let n;
1348
- if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength > At)) try {
1348
+ if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength > jt)) try {
1349
1349
  return new TextDecoder().decode(n);
1350
1350
  } catch {
1351
1351
  return;
@@ -1353,8 +1353,8 @@ function jt(e) {
1353
1353
  }
1354
1354
  //#endregion
1355
1355
  //#region src/core/engine/prefetch.ts
1356
- var Mt = 15e3, Nt = 5e3, Pt = 6, Ft = 4e3, It = 2;
1357
- function K(e) {
1356
+ var Nt = 15e3, Pt = 5e3, Ft = 6, It = 4e3, Lt = 2;
1357
+ function G(e) {
1358
1358
  try {
1359
1359
  let t = new URL(e);
1360
1360
  return t.searchParams.delete("CMCD"), t.toString();
@@ -1362,7 +1362,7 @@ function K(e) {
1362
1362
  return e;
1363
1363
  }
1364
1364
  }
1365
- var Lt = class {
1365
+ var Rt = class {
1366
1366
  cmcd;
1367
1367
  entries = /* @__PURE__ */ new Map();
1368
1368
  keyed = /* @__PURE__ */ new Set();
@@ -1391,20 +1391,20 @@ var Lt = class {
1391
1391
  }
1392
1392
  prefetch(e, t, n) {
1393
1393
  if (!this.isActive(t)) return;
1394
- let r = K(e);
1394
+ let r = G(e);
1395
1395
  if (this.entries.has(r)) return;
1396
1396
  let i = this.perTrack.get(t) ?? 0;
1397
- i >= Pt || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Mt), this.stats.started += 1);
1397
+ i >= Ft || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Nt), this.stats.started += 1);
1398
1398
  }
1399
1399
  prefetchHint(e, t) {
1400
- let n = K(e);
1400
+ let n = G(e);
1401
1401
  if (this.entries.has(n)) return;
1402
1402
  let r = this.hints.get(t) ?? [];
1403
- for (; r.length >= It;) {
1403
+ for (; r.length >= Lt;) {
1404
1404
  let e = r.shift();
1405
1405
  e !== void 0 && this.drop(e) && (this.stats.hintDropped += 1);
1406
1406
  }
1407
- r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, Ft), this.stats.hintStarted += 1;
1407
+ r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, It), this.stats.hintStarted += 1;
1408
1408
  }
1409
1409
  dropHints(e) {
1410
1410
  for (let t of this.hints.get(e) ?? []) this.drop(t) && (this.stats.hintDropped += 1);
@@ -1437,7 +1437,7 @@ var Lt = class {
1437
1437
  }, r);
1438
1438
  }
1439
1439
  take(e) {
1440
- let t = K(e), n = this.entries.get(t);
1440
+ let t = G(e), n = this.entries.get(t);
1441
1441
  return n && this.entries.delete(t), n;
1442
1442
  }
1443
1443
  destroy() {
@@ -1457,14 +1457,14 @@ var Lt = class {
1457
1457
  }
1458
1458
  }
1459
1459
  };
1460
- function Rt(t) {
1461
- let n = e.DefaultConfig?.loader;
1462
- if (typeof n != "function") return;
1463
- class r extends n {
1460
+ function zt(t, n) {
1461
+ let r = typeof n == "function" ? n : e.DefaultConfig?.loader;
1462
+ if (typeof r != "function") return;
1463
+ class i extends r {
1464
1464
  served = !1;
1465
1465
  cancelled = !1;
1466
1466
  entry;
1467
- stats = zt();
1467
+ stats = Bt();
1468
1468
  load(e, n, r) {
1469
1469
  let i = e.rangeEnd ? void 0 : t.take(e.url);
1470
1470
  if (!i) {
@@ -1476,7 +1476,7 @@ function Rt(t) {
1476
1476
  i.hint ? t.stats.hintFailed += 1 : t.stats.failed += 1;
1477
1477
  }, s = () => {
1478
1478
  !this.cancelled && this.served && (i.abort.abort(), o(), this.served = !1, this.entry = void 0, super.load(e, n, r));
1479
- }, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Nt, u = setTimeout(s, l);
1479
+ }, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Pt, u = setTimeout(s, l);
1480
1480
  i.headers.then(() => {
1481
1481
  clearTimeout(u);
1482
1482
  let e = c?.maxLoadTimeMs;
@@ -1507,9 +1507,9 @@ function Rt(t) {
1507
1507
  super.abort();
1508
1508
  }
1509
1509
  }
1510
- return r;
1510
+ return i;
1511
1511
  }
1512
- function zt() {
1512
+ function Bt() {
1513
1513
  return {
1514
1514
  aborted: !1,
1515
1515
  loaded: 0,
@@ -1533,10 +1533,10 @@ function zt() {
1533
1533
  }
1534
1534
  };
1535
1535
  }
1536
- function Bt(e) {
1536
+ function Vt(e) {
1537
1537
  return e === "audio" ? "audio" : "main";
1538
1538
  }
1539
- function Vt(e, t) {
1539
+ function Ht(e, t) {
1540
1540
  let n = [];
1541
1541
  t.initSegment?.url && !t.initSegment.data && n.push({
1542
1542
  url: t.initSegment.url,
@@ -1553,7 +1553,7 @@ function Vt(e, t) {
1553
1553
  });
1554
1554
  return n;
1555
1555
  }
1556
- function Ht(e) {
1556
+ function Ut(e) {
1557
1557
  let t = e, n = t?.preloadHint;
1558
1558
  if (!n || !t?.url || n.TYPE !== "PART" || n["BYTERANGE-START"] !== void 0 || n["BYTERANGE-LENGTH"] !== void 0) return null;
1559
1559
  let r = n.URI;
@@ -1566,16 +1566,16 @@ function Ht(e) {
1566
1566
  }
1567
1567
  //#endregion
1568
1568
  //#region src/core/percentile.ts
1569
- function q(e, t) {
1569
+ function K(e, t) {
1570
1570
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1571
1571
  }
1572
1572
  //#endregion
1573
1573
  //#region src/core/engine/hls.ts
1574
- function Ut() {
1574
+ function Wt() {
1575
1575
  return e.isSupported();
1576
1576
  }
1577
- var Wt = 3, Gt = 1e6, Kt = 20, qt = 1e4, Jt = 3, Yt = 5, Xt = 3, Zt = 1e4, Qt = 3e4, $t = 12e3, en = 3e3, tn = .02, nn = 6e3, rn = .5, an = 3, on = .5, sn = 1.1, cn = .25, ln = 5e3, un = 4e3, dn = 2, fn = 5, pn = 2, mn = 2, hn = 4, gn = 4, _n = 2e3, vn = 3e4, yn = 1, bn = 2;
1578
- function xn(e, t, n) {
1577
+ var Gt = 3, Kt = 1e6, qt = 20, Jt = 1e4, Yt = 3, Xt = 5, Zt = 3, Qt = 1e4, $t = 3e4, en = 12e3, tn = 3e3, nn = .02, rn = 6e3, an = .5, on = 3, sn = .5, cn = 1.1, ln = .25, un = 5e3, dn = 4e3, fn = 2, pn = 5, mn = 2, hn = 2, gn = 4, _n = 4, vn = 2e3, yn = 3e4, bn = 1, xn = 2, Sn = .5, Cn = .6, wn = 2, Tn = 1.5, En = 1e4, q = 8, Dn = 12e4, On = 6e4;
1578
+ function J(e, t, n) {
1579
1579
  if (n <= 0 || t < 0 || t >= e.length) return t;
1580
1580
  let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
1581
1581
  for (; t + 1 < e.length && r(t + 1, t);) t++;
@@ -1584,11 +1584,14 @@ function xn(e, t, n) {
1584
1584
  for (let t = 0; t < n && a + 1 < e.length; t++) a = i(a + 1);
1585
1585
  return a;
1586
1586
  }
1587
- var Sn = .2, Cn = 30, wn = 2, Tn = 2, En = 2, Dn = 9, On = .5, kn = 64, An = 1e4, jn = 8, Mn = .6, Nn = .4, Pn = .4, Fn = 2, In = 6e4, J = .5, Ln = 3.5, Rn = 300;
1588
- function zn(e) {
1587
+ function Y() {
1588
+ return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
1589
+ }
1590
+ var kn = .2, An = 30, jn = 2, Mn = 2, Nn = 2, Pn = 9, Fn = .5, In = 64, Ln = 1e4, Rn = 8, zn = .6, Bn = .4, Vn = .4, Hn = 2, Un = 6e4, X = .5, Wn = 3.5, Gn = 300;
1591
+ function Kn(e) {
1589
1592
  return (e?.part ?? e?.frag)?.stats;
1590
1593
  }
1591
- function Bn() {
1594
+ function qn() {
1592
1595
  if (typeof navigator > "u") return 0;
1593
1596
  try {
1594
1597
  let e = navigator.connection?.rtt;
@@ -1597,20 +1600,20 @@ function Bn() {
1597
1600
  return 0;
1598
1601
  }
1599
1602
  }
1600
- function Vn(e) {
1603
+ function Jn(e) {
1601
1604
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
1602
1605
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
1603
1606
  return;
1604
1607
  }
1605
- e.liveSyncDuration ??= En;
1606
- let t = Math.max(12, e.liveSyncDuration + Dn);
1607
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Hn(e, e.liveSyncDuration);
1608
+ e.liveSyncDuration ??= Nn;
1609
+ let t = Math.max(12, e.liveSyncDuration + Pn);
1610
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Yn(e, e.liveSyncDuration);
1608
1611
  }
1609
- function Hn(e, t) {
1612
+ function Yn(e, t) {
1610
1613
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
1611
1614
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
1612
1615
  }
1613
- var Un = class {
1616
+ var Xn = class {
1614
1617
  name = "hls";
1615
1618
  hls = null;
1616
1619
  deps;
@@ -1679,6 +1682,12 @@ var Un = class {
1679
1682
  liveRetargets = 0;
1680
1683
  holdBackEnabled;
1681
1684
  holdBackSamples = [];
1685
+ headroomSamples = [];
1686
+ headroomGranted = !1;
1687
+ lastStallAt = 0;
1688
+ headroomRegrantAt = 0;
1689
+ headroomUngated = !1;
1690
+ playingSince = 0;
1682
1691
  holdBackBase = -1;
1683
1692
  holdBackStepCount = 0;
1684
1693
  holdBackApplied = 0;
@@ -1707,11 +1716,11 @@ var Un = class {
1707
1716
  frameCounter;
1708
1717
  detachFrames = null;
1709
1718
  constructor(e) {
1710
- this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new mt(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
1719
+ this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
1711
1720
  }
1712
1721
  async load() {
1713
1722
  this.detachFrames ??= this.frameCounter.attach();
1714
- let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = V(r) && H(), o = !!e.drm?.widevine?.licenseUrl && !a;
1723
+ let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = B(r) && V(), o = !!e.drm?.widevine?.licenseUrl && !a;
1715
1724
  if (e.drmEnabled && !o) {
1716
1725
  i({
1717
1726
  type: "error",
@@ -1720,7 +1729,7 @@ var Un = class {
1720
1729
  });
1721
1730
  return;
1722
1731
  }
1723
- e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ke(r), Xe()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1732
+ e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (qe(r), Ze()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1724
1733
  let e = this.hls;
1725
1734
  if (document.visibilityState !== "visible" || !e) return;
1726
1735
  let t = e.liveSyncPosition;
@@ -1736,7 +1745,7 @@ var Un = class {
1736
1745
  this.hls.startLoad(-1);
1737
1746
  } catch {}
1738
1747
  }
1739
- }, window.addEventListener("offline", this.onOffline), window.addEventListener("online", this.onOnline), R() || this.onOffline()), this.onSeeking = () => {
1748
+ }, window.addEventListener("offline", this.onOffline), window.addEventListener("online", this.onOnline), L() || this.onOffline()), this.onSeeking = () => {
1740
1749
  this.clampOverSeek(), this.loadSuspended && (this.resumeLoading(), this.schedulePauseSuspend());
1741
1750
  }, r.addEventListener("seeking", this.onSeeking), this.onTimeUpdate = () => this.updateCatchUpBand(), r.addEventListener("timeupdate", this.onTimeUpdate), this.onPause = () => this.schedulePauseSuspend(), this.onPlay = () => this.resumeLoading(), r.addEventListener("pause", this.onPause), r.addEventListener("play", this.onPlay), this.sizeCapManaged && typeof ResizeObserver < "u" && (this.capObserver = new ResizeObserver(() => this.onMediaResize()), this.capObserver.observe(r), this.watchDprChanges());
1742
1751
  }
@@ -1752,7 +1761,7 @@ var Un = class {
1752
1761
  }
1753
1762
  this.loadSuspended = !0;
1754
1763
  }
1755
- }, ln));
1764
+ }, un));
1756
1765
  }
1757
1766
  resumeLoading() {
1758
1767
  if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
@@ -1768,7 +1777,7 @@ var Un = class {
1768
1777
  watchDprChanges() {
1769
1778
  if (typeof matchMedia != "function") return;
1770
1779
  this.unwatchDprChanges();
1771
- let e = typeof self < "u" && self.devicePixelRatio || 1, t = matchMedia(`(resolution: ${e}dppx)`);
1780
+ let e = Y(), t = matchMedia(`(resolution: ${e}dppx)`);
1772
1781
  if (typeof t.addEventListener != "function") return;
1773
1782
  let n = () => {
1774
1783
  this.onMediaResize(), this.watchDprChanges();
@@ -1784,7 +1793,7 @@ var Un = class {
1784
1793
  let t = e.liveSyncPosition;
1785
1794
  if (typeof t != "number" || !Number.isFinite(t)) return;
1786
1795
  let { video: n } = this.deps;
1787
- n.currentTime <= t + On || (n.currentTime = t);
1796
+ n.currentTime <= t + Fn || (n.currentTime = t);
1788
1797
  }
1789
1798
  reanchorPartTimeline(e, t) {
1790
1799
  let { frag: n, part: r } = t;
@@ -1796,7 +1805,7 @@ var Un = class {
1796
1805
  let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
1797
1806
  if (!s) return;
1798
1807
  let c = a.startPTS - s.start;
1799
- if (!(!Number.isFinite(c) || Math.abs(c) < tn)) {
1808
+ if (!(!Number.isFinite(c) || Math.abs(c) < nn)) {
1800
1809
  for (let e of i.fragments) e && e.setStart(e.start + c);
1801
1810
  i.fragmentHint?.setStart(i.fragmentHint.start + c), this.deps.debug === !0 && console.info(`havik-player: LL-HLS timeline re-anchored by ${c >= 0 ? "+" : ""}${c.toFixed(3)}s at sn ${n.sn} (level ${n.level})`);
1802
1811
  }
@@ -1804,7 +1813,7 @@ var Un = class {
1804
1813
  startHls() {
1805
1814
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
1806
1815
  this.clearKick(), this.resetStarvationWindow(), this.resetChaseWindow(), this.resetFrameDropWindow(), this.lastFragLoadingMs = 0, this.lastEndSN = -1, this.lastAdvanceMs = 0;
1807
- let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d = V(this.deps.video) && H(), f = {
1816
+ let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d = B(this.deps.video) && V(), f = {
1808
1817
  debug: s === !0,
1809
1818
  enableWorker: !o,
1810
1819
  lowLatencyMode: o,
@@ -1819,24 +1828,24 @@ var Un = class {
1819
1828
  emeEnabled: !0,
1820
1829
  drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
1821
1830
  drmSystemOptions: {
1822
- videoRobustness: P.video,
1823
- audioRobustness: P.audio,
1824
- videoEncryptionScheme: P.scheme,
1825
- audioEncryptionScheme: P.scheme
1831
+ videoRobustness: N.video,
1832
+ audioRobustness: N.audio,
1833
+ videoEncryptionScheme: N.scheme,
1834
+ audioEncryptionScheme: N.scheme
1826
1835
  },
1827
- ...j() ? { requestMediaKeySystemAccessFunc: Ge(t) } : {},
1836
+ ...A() ? { requestMediaKeySystemAccessFunc: Ke(t) } : {},
1828
1837
  licenseXhrSetup: (e, t) => {
1829
1838
  let o = performance.now(), s = () => {
1830
1839
  e.open("POST", this.licenseUrl ?? t, !0), e.setRequestHeader("x-api-key", r.apiKey), e.setRequestHeader("X-Match-Urn", n.matchUrn), e.setRequestHeader("X-Device-Id", i), a && e.setRequestHeader("X-User-Id", a), this.licenseRequested = !0, e.addEventListener("loadend", () => {
1831
1840
  this.licenseTimeMs === 0 && (this.licenseTimeMs = Math.max(1, Math.round(performance.now() - o)));
1832
1841
  });
1833
1842
  }, { freshLicenseUrl: c } = this.deps;
1834
- if (!c || !G(this.licenseUrl)) {
1843
+ if (!c || !W(this.licenseUrl)) {
1835
1844
  s();
1836
1845
  return;
1837
1846
  }
1838
1847
  let l = this.hls, u, d = new Promise((e) => {
1839
- u = setTimeout(() => e(void 0), Zt);
1848
+ u = setTimeout(() => e(void 0), Qt);
1840
1849
  });
1841
1850
  return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
1842
1851
  if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
@@ -1852,51 +1861,51 @@ var Un = class {
1852
1861
  ...c
1853
1862
  };
1854
1863
  this.prefetch?.destroy(), this.prefetch = null;
1855
- let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints === !0;
1864
+ let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints !== !1;
1856
1865
  if ((h || g) && !f.fLoader) {
1857
- let e = new Lt({
1866
+ let e = new Rt({
1858
1867
  sessionId: n.analytics?.sid,
1859
1868
  contentId: n.matchUrn
1860
- }), t = Rt(e);
1869
+ }), t = zt(e, f.loader);
1861
1870
  t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
1862
1871
  }
1863
- Vn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
1872
+ Jn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
1864
1873
  let _ = new e(f);
1865
1874
  if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
1866
1875
  this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(_), this.measureLadder(_), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
1867
1876
  }), _.on(e.Events.FRAG_BUFFERED, (e, t) => {
1868
1877
  t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
1869
1878
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1870
- }, Qt)));
1879
+ }, $t)));
1871
1880
  }), _.on(e.Events.FRAG_LOADING, (e, t) => {
1872
1881
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1873
1882
  }), _.on(e.Events.FRAG_LOADED, (e, t) => {
1874
1883
  t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
1875
- let n = t?.frag, r = zn(t), i = r?.loaded;
1884
+ let n = t?.frag, r = Kn(t), i = r?.loaded;
1876
1885
  typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
1877
1886
  let a = r?.loading;
1878
- a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > kn && this.requestTimesMs.shift()), this.sampleHoldBack(t);
1887
+ a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > In && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
1879
1888
  let o = n?.url;
1880
1889
  if (o) {
1881
- let e = dt(o);
1890
+ let e = ft(o);
1882
1891
  e && (this.cdnHost = e);
1883
1892
  }
1884
1893
  }), _.on(e.Events.LEVEL_LOADED, (e, t) => {
1885
1894
  let n = t?.stats?.loaded;
1886
1895
  if (typeof n == "number" && (this.playlistBytesLoaded += n), this.reportedFirstPlaylist || (this.reportedFirstPlaylist = !0, l({ type: "firstPlaylist" })), this.detectedLowLatency) return;
1887
1896
  let r = t.details;
1888
- (r?.partList?.length || (r?.partTarget ?? 0) > 0) && (this.detectedLowLatency = !0, l({
1897
+ r?.partList?.length || (r?.partTarget ?? 0) > 0 ? (this.detectedLowLatency = !0, l({
1889
1898
  type: "lowLatencyDetected",
1890
1899
  value: !0
1891
- }));
1900
+ }), this.headroomUngated && (this.headroomUngated = !1, this.applySizeCapUnlessPending())) : r && !this.headroomUngated && (this.headroomUngated = !0, this.applySizeCapUnlessPending());
1892
1901
  }), _.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch && m) {
1893
1902
  let t = this.prefetch, n = this.deps.video, r = (e, r) => {
1894
1903
  if (n.paused) return;
1895
1904
  let i = e;
1896
1905
  if (!i?.live || !i.partList?.length || typeof i.edge != "number") return;
1897
1906
  let a = n.buffered, o = a.length ? a.end(a.length - 1) : 0;
1898
- if (i.edge - o > Wt * (i.partTarget || .5)) return;
1899
- let s = Ht(e);
1907
+ if (i.edge - o > Gt * (i.partTarget || .5)) return;
1908
+ let s = Ut(e);
1900
1909
  s && t.prefetchHint(s, r);
1901
1910
  };
1902
1911
  _.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1908,15 +1917,15 @@ var Un = class {
1908
1917
  if (this.prefetch && p) {
1909
1918
  let t = this.prefetch;
1910
1919
  _.on(e.Events.KEY_LOADING, (e, n) => {
1911
- let r = n?.frag, i = Bt(r?.type);
1912
- if (r && t.isActive(i)) for (let e of Vt(_, r)) t.prefetch(e.url, i, e.kind);
1913
- }), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Bt(n?.frag?.type)));
1920
+ let r = n?.frag, i = Vt(r?.type);
1921
+ if (r && t.isActive(i)) for (let e of Ht(_, r)) t.prefetch(e.url, i, e.kind);
1922
+ }), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Vt(n?.frag?.type)));
1914
1923
  }
1915
1924
  _.on(e.Events.KEY_LOADED, () => {
1916
1925
  u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
1917
1926
  }), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1918
- this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.checkFrameDrops();
1919
- }, en), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1927
+ this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.checkFrameDrops();
1928
+ }, tn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1920
1929
  this.renditionSwitches += 1;
1921
1930
  let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
1922
1931
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
@@ -1959,17 +1968,28 @@ var Un = class {
1959
1968
  this.pushCap();
1960
1969
  }
1961
1970
  }
1962
- computeSizeCapTarget() {
1971
+ sizeCapCover() {
1963
1972
  let e = this.hls;
1964
1973
  if (!e || e.levels.length === 0) return null;
1965
1974
  let { video: n } = this.deps, r = n.getBoundingClientRect(), i = r.width, a = r.height;
1966
1975
  if (!i && !a && (i = n.width || 0, a = n.height || 0), !(i > 0) || !(a > 0)) return null;
1967
- let o = e.config ?? {}, s = typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1, c = o.ignoreDevicePixelRatio ? 1 : s;
1968
- c = Math.min(c, o.maxDevicePixelRatio ?? Infinity);
1969
- let l = t.getMaxLevelByMediaSize(e.levels, i * c, a * c), u = this.deps.sizeCapHeadroom;
1970
- if (u == null && s >= bn) return l;
1971
- let d = u ?? yn, f = Number.isNaN(d) ? yn : d === Infinity ? e.levels.length : Math.max(0, Math.floor(d));
1972
- return xn(e.levels, l, f);
1976
+ let o = e.config ?? {}, s = Y(), c = o.ignoreDevicePixelRatio ? 1 : s;
1977
+ return c = Math.min(c, o.maxDevicePixelRatio ?? Infinity), {
1978
+ cover: t.getMaxLevelByMediaSize(e.levels, i * c, a * c),
1979
+ deviceRatio: s
1980
+ };
1981
+ }
1982
+ sizeCapCoverLevel() {
1983
+ return this.sizeCapCover()?.cover ?? null;
1984
+ }
1985
+ computeSizeCapTarget() {
1986
+ let e = this.hls, t = this.sizeCapCover();
1987
+ if (!e || !t) return null;
1988
+ let { cover: n, deviceRatio: r } = t, i = this.deps.sizeCapHeadroom, a = i == null || Number.isNaN(i);
1989
+ if (a && r >= xn) return n;
1990
+ if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n, bn) : n;
1991
+ let o = i === Infinity ? e.levels.length : Math.max(0, Math.floor(i));
1992
+ return J(e.levels, n, o);
1973
1993
  }
1974
1994
  onMediaResize() {
1975
1995
  if (!this.sizeCapManaged) return;
@@ -1984,9 +2004,11 @@ var Un = class {
1984
2004
  return;
1985
2005
  }
1986
2006
  this.capTimer && clearTimeout(this.capTimer);
1987
- let t = e > this.sizeCapLevel ? _n : vn;
2007
+ let t = e > this.sizeCapLevel ? vn : yn;
1988
2008
  this.capTimer = setTimeout(() => {
1989
- this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
2009
+ this.capTimer = null;
2010
+ let n = this.computeSizeCapTarget();
2011
+ n === e || t === yn && n != null && n < e ? this.applySizeCap() : this.onMediaResize();
1990
2012
  }, t);
1991
2013
  }
1992
2014
  measureLadder(e) {
@@ -1994,9 +2016,9 @@ var Un = class {
1994
2016
  this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
1995
2017
  }
1996
2018
  dropLevelsWidevineCannotPlay(e) {
1997
- this.removeLevelsWhere(e, (e) => Ze(e) !== !0);
1998
- let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && F(e) !== "avc" && !!F(e)));
1999
- for (let n of t) Ye(n).then((t) => {
2019
+ this.removeLevelsWhere(e, (e) => Qe(e) !== !0);
2020
+ let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && P(e) !== "avc" && !!P(e)));
2021
+ for (let n of t) Xe(n).then((t) => {
2000
2022
  t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
2001
2023
  });
2002
2024
  }
@@ -2004,13 +2026,69 @@ var Un = class {
2004
2026
  let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
2005
2027
  if (n.forEach((e, n) => {
2006
2028
  let a = e.videoCodec;
2007
- a && F(a) && t(a) && (r.push(n), i.add(a));
2029
+ a && P(a) && t(a) && (r.push(n), i.add(a));
2008
2030
  }), !r.length) return !1;
2009
2031
  let a = [...i].join(", ");
2010
- if (!n.some((e, t) => r.includes(t) ? !1 : !F(e.videoCodec) || Ze(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
2032
+ if (!n.some((e, t) => r.includes(t) ? !1 : !P(e.videoCodec) || Qe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
2011
2033
  for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
2012
2034
  return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
2013
2035
  }
2036
+ defaultHeadroomApplies() {
2037
+ let e = this.deps.sizeCapHeadroom;
2038
+ return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() < xn;
2039
+ }
2040
+ applySizeCapUnlessPending() {
2041
+ this.capTimer || this.applySizeCap();
2042
+ }
2043
+ sampleHeadroom(e) {
2044
+ if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
2045
+ let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
2046
+ if (typeof t != "number" || !(t > 0)) return;
2047
+ let n = Kn(e)?.loading;
2048
+ if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
2049
+ let r = this.hls?.levels?.[e.frag.level]?.bitrate;
2050
+ if (!(typeof r == "number" && r > 0)) return;
2051
+ let i = (n.end - n.start) / (t * 1e3);
2052
+ this.headroomSamples.push({
2053
+ t: Date.now(),
2054
+ ratio: i,
2055
+ bitrate: r
2056
+ }), this.headroomSamples.length > 256 && this.headroomSamples.shift();
2057
+ }
2058
+ onPlaybackStall() {
2059
+ let e = Date.now();
2060
+ this.deps.video.seeking || !this.playingSince || e - this.playingSince < En || (this.lastStallAt = e, this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
2061
+ }
2062
+ reviewSizeCapHeadroom() {
2063
+ let e = Date.now(), { video: t } = this.deps;
2064
+ !t.paused && !t.seeking && t.readyState >= 3 ? this.playingSince ||= e : this.playingSince = 0;
2065
+ let n = this.hls;
2066
+ if (!n || !this.sizeCapManaged) return;
2067
+ if (!this.defaultHeadroomApplies()) {
2068
+ this.headroomGranted = !1, this.headroomSamples = [];
2069
+ return;
2070
+ }
2071
+ this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Ln);
2072
+ let r = this.headroomEarned(n, e);
2073
+ r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + On), this.headroomGranted = r, this.applySizeCapUnlessPending());
2074
+ }
2075
+ headroomEarned(e, t) {
2076
+ if (t - this.lastStallAt < Dn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
2077
+ let n = e.levels, r = this.sizeCapCoverLevel();
2078
+ if (r == null) return this.headroomGranted;
2079
+ let i = J(n, r, bn);
2080
+ if (i === r) return this.headroomGranted;
2081
+ let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ? Tn : wn;
2082
+ if (!(a > 0) || !(o >= s * a)) return !1;
2083
+ let c = (e) => K([...e].sort((e, t) => e - t), 90);
2084
+ if (this.headroomGranted) {
2085
+ let e = this.headroomSamples.filter((e) => e.bitrate >= a).map((e) => e.ratio);
2086
+ return e.length < q || c(e) <= Cn;
2087
+ }
2088
+ let l = [];
2089
+ for (let e of this.headroomSamples) e.bitrate < a && l.push(e.ratio * (a / e.bitrate));
2090
+ return l.length >= q && c(l) <= Sn;
2091
+ }
2014
2092
  applySizeCap() {
2015
2093
  if (!this.sizeCapManaged) return;
2016
2094
  this.capTimer &&= (clearTimeout(this.capTimer), null);
@@ -2110,12 +2188,12 @@ var Un = class {
2110
2188
  this.lastAdvanceMs = Date.now();
2111
2189
  return;
2112
2190
  }
2113
- if (this.loadSuspended || this.offlineHold || !R()) {
2191
+ if (this.loadSuspended || this.offlineHold || !L()) {
2114
2192
  this.lastAdvanceMs = Date.now();
2115
2193
  return;
2116
2194
  }
2117
2195
  let e = Date.now() - this.lastAdvanceMs;
2118
- !this.chaseSuspended && e > nn && this.suspendChasing(), e > $t && this.emitEnded("stalled");
2196
+ !this.chaseSuspended && e > rn && this.suspendChasing(), e > en && this.emitEnded("stalled");
2119
2197
  }
2120
2198
  resetStarvationWindow() {
2121
2199
  this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
@@ -2126,11 +2204,11 @@ var Un = class {
2126
2204
  checkStarvation() {
2127
2205
  let e = this.hls, { video: t } = this.deps;
2128
2206
  if (!e || this.endedEmitted || !this.sawLive || this.chaseSuspended) return;
2129
- if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold || !R()) {
2207
+ if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold || !L()) {
2130
2208
  this.resetStarvationWindow();
2131
2209
  return;
2132
2210
  }
2133
- let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < nn, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > un, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = z(t), c = o - s, l = c !== this.starvedFrames;
2211
+ let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < rn, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > dn, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = R(t), c = o - s, l = c !== this.starvedFrames;
2134
2212
  if (this.starvedFrames = c, !a || l) {
2135
2213
  (t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
2136
2214
  return;
@@ -2139,12 +2217,12 @@ var Un = class {
2139
2217
  this.resetStarvationWindow();
2140
2218
  return;
2141
2219
  }
2142
- if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > hn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= pn && (this.clearKick(), this.starvationRebuilds < mn)) {
2220
+ if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > gn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= mn && (this.clearKick(), this.starvationRebuilds < hn)) {
2143
2221
  this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
2144
2222
  return;
2145
2223
  }
2146
- let u = i && this.starvedTicks >= dn, d = !i && this.deadTicks >= hn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= gn;
2147
- if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= fn))) {
2224
+ let u = i && this.starvedTicks >= fn, d = !i && this.deadTicks >= gn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= _n;
2225
+ if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= pn))) {
2148
2226
  this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
2149
2227
  try {
2150
2228
  e.stopLoad(), e.startLoad(-1);
@@ -2159,7 +2237,7 @@ var Un = class {
2159
2237
  let t = e.latency, n = e.targetLatency;
2160
2238
  if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
2161
2239
  let r = t - n;
2162
- !this.catchUpEngaged && r > rn ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= rn && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
2240
+ !this.catchUpEngaged && r > an ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= an && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
2163
2241
  let i = this.catchUpEngaged ? this.catchUpRate : 1;
2164
2242
  e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
2165
2243
  }
@@ -2172,7 +2250,7 @@ var Un = class {
2172
2250
  }), n < 0 ? 0 : n;
2173
2251
  }
2174
2252
  armFrameDropGrace() {
2175
- this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Tn, this.fpsBadTicks = 0);
2253
+ this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Mn, this.fpsBadTicks = 0);
2176
2254
  }
2177
2255
  resetFrameDropWindow() {
2178
2256
  this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
@@ -2183,8 +2261,8 @@ var Un = class {
2183
2261
  this.resetFrameDropWindow();
2184
2262
  return;
2185
2263
  }
2186
- let { totalFrames: n, dropped: r } = z(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
2187
- if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Cn || o < 0) {
2264
+ let { totalFrames: n, dropped: r } = R(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
2265
+ if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < An || o < 0) {
2188
2266
  this.fpsBadTicks = 0;
2189
2267
  return;
2190
2268
  }
@@ -2192,11 +2270,11 @@ var Un = class {
2192
2270
  --this.fpsGraceTicks, this.fpsBadTicks = 0;
2193
2271
  return;
2194
2272
  }
2195
- if (o <= Sn * a) {
2273
+ if (o <= kn * a) {
2196
2274
  this.fpsBadTicks = 0;
2197
2275
  return;
2198
2276
  }
2199
- if (this.fpsBadTicks += 1, this.fpsBadTicks < wn) return;
2277
+ if (this.fpsBadTicks += 1, this.fpsBadTicks < jn) return;
2200
2278
  this.fpsBadTicks = 0;
2201
2279
  let s = e.levels, c = s[e.currentLevel];
2202
2280
  if (!c) return;
@@ -2213,22 +2291,22 @@ var Un = class {
2213
2291
  return;
2214
2292
  }
2215
2293
  let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
2216
- if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(sn, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
2294
+ if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(cn, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
2217
2295
  this.resetChaseWindow();
2218
2296
  return;
2219
2297
  }
2220
- if (this.chaseLatency < 0 || this.chaseLatency - n >= on) {
2298
+ if (this.chaseLatency < 0 || this.chaseLatency - n >= sn) {
2221
2299
  this.chaseLatency = n, this.chaseTicks = 0;
2222
2300
  return;
2223
2301
  }
2224
- if (this.chaseTicks += 1, this.chaseTicks < an) return;
2302
+ if (this.chaseTicks += 1, this.chaseTicks < on) return;
2225
2303
  this.resetChaseWindow();
2226
2304
  let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2227
2305
  if (!(a > 1)) return;
2228
2306
  let o = e.targetLatency;
2229
2307
  if (typeof o != "number" || !(o > 0)) return;
2230
2308
  let s = Math.min(n, a - 1);
2231
- s < o + cn || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s, this.deps.emit({
2309
+ s < o + ln || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s, this.deps.emit({
2232
2310
  type: "livetargetchange",
2233
2311
  change: {
2234
2312
  targetSeconds: s,
@@ -2238,20 +2316,20 @@ var Un = class {
2238
2316
  }));
2239
2317
  }
2240
2318
  armHoldBack(e, t) {
2241
- this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
2319
+ this.headroomSamples = [], this.headroomGranted = !1, this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
2242
2320
  }
2243
2321
  applyHoldBackPrior() {
2244
2322
  let e = this.hls;
2245
2323
  if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
2246
2324
  let t = e.targetLatency;
2247
2325
  if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
2248
- let n = Bn();
2249
- if (!(n >= Rn)) return;
2250
- let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + J);
2326
+ let n = qn();
2327
+ if (!(n >= Gn)) return;
2328
+ let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
2251
2329
  i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
2252
2330
  }
2253
2331
  holdBackCeiling(e) {
2254
- let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Ln, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2332
+ let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Wn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
2255
2333
  return r > 1 ? Math.min(n, r - 1) : n;
2256
2334
  }
2257
2335
  sampleHoldBack(e) {
@@ -2260,7 +2338,7 @@ var Un = class {
2260
2338
  if (t !== "main" && t !== "audio") return;
2261
2339
  let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
2262
2340
  if (typeof n != "number" || !(n > 0)) return;
2263
- let r = zn(e)?.loading;
2341
+ let r = Kn(e)?.loading;
2264
2342
  if (!r || !(r.start > 0) || !(r.end > 0)) return;
2265
2343
  let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
2266
2344
  this.holdBackSamples.push({
@@ -2275,30 +2353,30 @@ var Un = class {
2275
2353
  this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
2276
2354
  return;
2277
2355
  }
2278
- let t = Date.now(), n = t - An, r = this.holdBackSamples, i = 0;
2356
+ let t = Date.now(), n = t - Ln, r = this.holdBackSamples, i = 0;
2279
2357
  for (; i < r.length && r[i].t < n;) i += 1;
2280
2358
  i > 0 && r.splice(0, i);
2281
2359
  let a = e.targetLatency;
2282
2360
  if (typeof a != "number" || !(a > 0)) return;
2283
2361
  this.holdBackBase < 0 && (this.holdBackBase = a);
2284
2362
  let o = this.holdBackBase, s = this.holdBackCeiling(e);
2285
- if (r.length < jn) {
2363
+ if (r.length < Rn) {
2286
2364
  this.holdBackSlowTicks = 0;
2287
2365
  return;
2288
2366
  }
2289
- let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = q(c, 95), u = q(c, 50), d = Math.round(l * 1e3);
2290
- if (l >= Mn && u >= Nn) {
2291
- if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Fn) return;
2367
+ let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = K(c, 95), u = K(c, 50), d = Math.round(l * 1e3);
2368
+ if (l >= zn && u >= Bn) {
2369
+ if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Hn) return;
2292
2370
  this.holdBackSlowTicks = 0;
2293
- let t = Math.ceil((s - o) / J), n = Math.ceil((a - o) / J - 1e-9);
2371
+ let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
2294
2372
  if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
2295
2373
  this.holdBackStepCount += 1;
2296
- let r = Math.min(s, o + this.holdBackStepCount * J);
2374
+ let r = Math.min(s, o + this.holdBackStepCount * X);
2297
2375
  if (r <= a) return;
2298
2376
  this.moveHoldBack(e, a, r, "slow-fetches", `part fetches slow (first byte p50 ${Math.round(u * 1e3)} / p95 ${d} ms per 1 s of media)`);
2299
2377
  return;
2300
2378
  }
2301
- if (this.holdBackSlowTicks = 0, l >= Pn) {
2379
+ if (this.holdBackSlowTicks = 0, l >= Vn) {
2302
2380
  this.holdBackFastSince = 0;
2303
2381
  return;
2304
2382
  }
@@ -2306,9 +2384,9 @@ var Un = class {
2306
2384
  this.holdBackFastSince = t;
2307
2385
  return;
2308
2386
  }
2309
- if (t - this.holdBackFastSince < In || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
2387
+ if (t - this.holdBackFastSince < Un || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
2310
2388
  --this.holdBackStepCount;
2311
- let f = Math.max(o, o + this.holdBackStepCount * J);
2389
+ let f = Math.max(o, o + this.holdBackStepCount * X);
2312
2390
  f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
2313
2391
  }
2314
2392
  moveHoldBack(e, t, n, r, i) {
@@ -2349,14 +2427,14 @@ var Un = class {
2349
2427
  } catch {}
2350
2428
  }
2351
2429
  startEstimate() {
2352
- return this.deps.rememberBandwidth === !1 ? Gt : ze() ?? Gt;
2430
+ return this.deps.rememberBandwidth === !1 ? Kt : Be() ?? Kt;
2353
2431
  }
2354
2432
  maybeRememberBandwidth(e) {
2355
- if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < Kt) return;
2433
+ if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < qt) return;
2356
2434
  let t = Date.now();
2357
- if (!e && t - this.bwSavedAt < qt) return;
2435
+ if (!e && t - this.bwSavedAt < Jt) return;
2358
2436
  let n = this.hls?.bandwidthEstimate;
2359
- typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Be(n));
2437
+ typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Ve(n));
2360
2438
  }
2361
2439
  destroy() {
2362
2440
  if (this.maybeRememberBandwidth(!0), this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onOffline && typeof window < "u" && (window.removeEventListener("offline", this.onOffline), this.onOffline = null), this.onOnline && typeof window < "u" && (window.removeEventListener("online", this.onOnline), this.onOnline = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
@@ -2374,7 +2452,7 @@ var Un = class {
2374
2452
  scheduleLicenseRetry(t) {
2375
2453
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
2376
2454
  let n = t.response?.code ?? 0;
2377
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Xt) return !1;
2455
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Zt) return !1;
2378
2456
  this.licenseRecoveries += 1;
2379
2457
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
2380
2458
  return this.licenseRetryTimer = setTimeout(() => {
@@ -2392,7 +2470,7 @@ var Un = class {
2392
2470
  }
2393
2471
  }
2394
2472
  onError(t) {
2395
- if (t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
2473
+ if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
2396
2474
  let n = this.hls;
2397
2475
  if (n) {
2398
2476
  if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
@@ -2406,11 +2484,11 @@ var Un = class {
2406
2484
  return;
2407
2485
  }
2408
2486
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
2409
- if (!R() && (t.response?.code ?? 0) === 0) {
2487
+ if (!L() && (t.response?.code ?? 0) === 0) {
2410
2488
  this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null);
2411
2489
  return;
2412
2490
  }
2413
- if (this.networkRecoveries < Yt) {
2491
+ if (this.networkRecoveries < Xt) {
2414
2492
  this.networkRecoveries += 1;
2415
2493
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
2416
2494
  this.networkRetryTimer = setTimeout(() => {
@@ -2427,7 +2505,7 @@ var Un = class {
2427
2505
  return;
2428
2506
  }
2429
2507
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
2430
- if (this.mediaRecoveries < Jt) {
2508
+ if (this.mediaRecoveries < Yt) {
2431
2509
  this.mediaRecoveries += 1, n.recoverMediaError();
2432
2510
  return;
2433
2511
  }
@@ -2448,18 +2526,18 @@ var Un = class {
2448
2526
  }
2449
2527
  }
2450
2528
  toError(t, r = "PLAYBACK") {
2451
- let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(jt(t.networkDetails)) : void 0;
2529
+ let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(Mt(t.networkDetails)) : void 0;
2452
2530
  return new n(r === "DRM" ? a(o, l) : r === "NETWORK" && o === 0 ? "NETWORK" : o === 401 ? "UNAUTHORIZED" : o === 403 ? "FORBIDDEN" : "INTERNAL", o, `${r} error: ${s}${c ? ` (${c})` : ""}`, l ? { serverCode: l } : void 0);
2453
2531
  }
2454
- }, Wn = 15e3, Gn = 6e5, Kn = 3e5, qn = 100, Y = 1, Jn = 1e3, Yn = 3e4, Xn = 1e3, Zn = {
2532
+ }, Zn = 15e3, Qn = 6e5, $n = 3e5, er = 100, Z = 1, tr = 1e3, nr = 3e4, rr = 1e3, ir = {
2455
2533
  inline: "PRESENTATION_INLINE",
2456
2534
  fullscreen: "PRESENTATION_FULLSCREEN",
2457
2535
  pip: "PRESENTATION_PIP"
2458
- }, Qn = {
2536
+ }, ar = {
2459
2537
  widevine: "KEY_SYSTEM_WIDEVINE",
2460
2538
  fairplay: "KEY_SYSTEM_FAIRPLAY",
2461
2539
  none: "KEY_SYSTEM_NONE"
2462
- }, $n = /* @__PURE__ */ new Set([
2540
+ }, or = /* @__PURE__ */ new Set([
2463
2541
  "INVALID_URN",
2464
2542
  "NOT_FOUND",
2465
2543
  "GEO_DENIED",
@@ -2470,7 +2548,7 @@ var Un = class {
2470
2548
  "FORBIDDEN",
2471
2549
  "RATE_LIMITED",
2472
2550
  "TIMEOUT"
2473
- ]), X = {
2551
+ ]), sr = {
2474
2552
  idle: "PLAYER_STATE_IDLE",
2475
2553
  waiting: "PLAYER_STATE_WAITING",
2476
2554
  loading: "PLAYER_STATE_LOADING",
@@ -2480,7 +2558,7 @@ var Un = class {
2480
2558
  ended: "PLAYER_STATE_ENDED",
2481
2559
  error: "PLAYER_STATE_ERROR"
2482
2560
  };
2483
- function er(e) {
2561
+ function cr(e) {
2484
2562
  try {
2485
2563
  let t = new URL(e), [n, ...r] = t.hostname.split(".");
2486
2564
  return !n || r.length === 0 || n !== "feed" && !n.startsWith("feed-") ? void 0 : (t.hostname = [n.replace(/^feed/, "beacons"), ...r].join("."), t.pathname = "", t.search = "", t.origin);
@@ -2488,8 +2566,8 @@ function er(e) {
2488
2566
  return;
2489
2567
  }
2490
2568
  }
2491
- var tr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), nr = /* @__PURE__ */ new Set(), Z = /* @__PURE__ */ new Set(), Q = /* @__PURE__ */ new Set(), rr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
2492
- function ir(e) {
2569
+ var lr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), ur = /* @__PURE__ */ new Set(), dr = /* @__PURE__ */ new Set(), fr = /* @__PURE__ */ new Set(), pr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
2570
+ function mr(e) {
2493
2571
  if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
2494
2572
  let t;
2495
2573
  try {
@@ -2498,19 +2576,19 @@ function ir(e) {
2498
2576
  } catch {
2499
2577
  return;
2500
2578
  }
2501
- if (nr.has(t) && !Z.has(t)) {
2502
- Z.add(t), _(rr(new URL(t).origin));
2503
- for (let e of Q) e.noteCspBlocked();
2579
+ if (ur.has(t) && !dr.has(t)) {
2580
+ dr.add(t), _(pr(new URL(t).origin));
2581
+ for (let e of fr) e.noteCspBlocked();
2504
2582
  }
2505
2583
  }
2506
- function ar(e, t) {
2584
+ function hr(e, t) {
2507
2585
  return _(t, e), { disabledReason: t };
2508
2586
  }
2509
- function or(e, t, n) {
2510
- if (n) return t && !tr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
2587
+ function gr(e, t, n) {
2588
+ if (n) return t && !lr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
2511
2589
  if (t) return { endpoint: t };
2512
- if (t !== void 0) return ar("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
2513
- let r = er(e);
2590
+ if (t !== void 0) return hr("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
2591
+ let r = cr(e);
2514
2592
  if (r) return { endpoint: r };
2515
2593
  let i;
2516
2594
  try {
@@ -2518,9 +2596,9 @@ function or(e, t, n) {
2518
2596
  } catch {
2519
2597
  i = e;
2520
2598
  }
2521
- return ar(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
2599
+ return hr(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
2522
2600
  }
2523
- var sr = class {
2601
+ var _r = class {
2524
2602
  opts;
2525
2603
  url;
2526
2604
  cspKey;
@@ -2602,8 +2680,8 @@ var sr = class {
2602
2680
  constructor(e) {
2603
2681
  this.opts = {
2604
2682
  ...e,
2605
- heartbeatMs: e.heartbeatMs ?? Wn,
2606
- idleMs: e.idleMs ?? Gn
2683
+ heartbeatMs: e.heartbeatMs ?? Zn,
2684
+ idleMs: e.idleMs ?? Qn
2607
2685
  }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
2608
2686
  try {
2609
2687
  let e = new URL(this.url);
@@ -2620,11 +2698,11 @@ var sr = class {
2620
2698
  sdkVersion: this.opts.sdkVersion,
2621
2699
  ...this.opts.environment
2622
2700
  };
2623
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Jn), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && nr.add(this.cspKey), document.addEventListener("securitypolicyviolation", ir), Q.add(this), this.noteCspBlocked(), this.onVisibility());
2701
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), tr), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && ur.add(this.cspKey), document.addEventListener("securitypolicyviolation", mr), fr.add(this), this.noteCspBlocked(), this.onVisibility());
2624
2702
  }
2625
2703
  checkSuspension(e) {
2626
2704
  if (this.endedFlag || !this.opts.idleMs) return !1;
2627
- let t = Math.max(this.opts.idleMs, Kn);
2705
+ let t = Math.max(this.opts.idleMs, $n);
2628
2706
  return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
2629
2707
  }
2630
2708
  syncIdle(e) {
@@ -2638,21 +2716,21 @@ var sr = class {
2638
2716
  noteStateChange(e, t, n, r) {
2639
2717
  if (this.endedFlag || e === t) return;
2640
2718
  let i = this.now();
2641
- if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Y, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Y, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
2719
+ if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Z, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Z, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
2642
2720
  this.stallIsSeekInduced = this.seekInduced(i);
2643
2721
  let e = !this.isHidden && !this.stallIsSeekInduced;
2644
- e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Y, Math.round(this.playingTotalMs)));
2722
+ e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Z, Math.round(this.playingTotalMs)));
2645
2723
  } else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
2646
2724
  this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
2647
2725
  let a = {
2648
- fromState: X[e] ?? "PLAYER_STATE_UNSPECIFIED",
2649
- toState: X[t] ?? "PLAYER_STATE_UNSPECIFIED",
2650
- presentation: Zn[this.presentation]
2726
+ fromState: sr[e] ?? "PLAYER_STATE_UNSPECIFIED",
2727
+ toState: sr[t] ?? "PLAYER_STATE_UNSPECIFIED",
2728
+ presentation: ir[this.presentation]
2651
2729
  }, o = this.causeOf(e, t, i);
2652
2730
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
2653
2731
  }
2654
2732
  seekInduced(e) {
2655
- return this.lastSeekMs >= 0 && e - this.lastSeekMs < Xn;
2733
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < rr;
2656
2734
  }
2657
2735
  causeOf(e, t, n) {
2658
2736
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
@@ -2689,25 +2767,25 @@ var sr = class {
2689
2767
  }
2690
2768
  this.muteChanges += 1;
2691
2769
  let r = this.now();
2692
- n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(Y, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
2770
+ n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(Z, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
2693
2771
  }
2694
2772
  notePresentation(e) {
2695
2773
  this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
2696
2774
  }
2697
2775
  notePlayIntent() {
2698
- this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Y), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Y), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Y), this.drmSetupMs > 0 && (this.drmSetupMs = Y));
2776
+ this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Z), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Z), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Z), this.drmSetupMs > 0 && (this.drmSetupMs = Z));
2699
2777
  }
2700
2778
  noteReady() {
2701
- this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
2779
+ this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
2702
2780
  }
2703
2781
  noteFirstPlaylist() {
2704
- this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Y, this.now() - this.startupAnchorMs));
2782
+ this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Z, this.now() - this.startupAnchorMs));
2705
2783
  }
2706
2784
  noteDrmReady() {
2707
- this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Y, this.now() - this.startupAnchorMs));
2785
+ this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Z, this.now() - this.startupAnchorMs));
2708
2786
  }
2709
2787
  noteFirstBytes() {
2710
- this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
2788
+ this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
2711
2789
  }
2712
2790
  noteSeek() {
2713
2791
  this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
@@ -2726,7 +2804,7 @@ var sr = class {
2726
2804
  let r = n ?? "";
2727
2805
  if (r !== "") return /^fragLoad/i.test(r) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /^(manifest|level|audioTrack|subtitleTrack)/i.test(r) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(r) ? "ERROR_STAGE_DRM" : /parsing|append|buffer|remux|decrypt|media/i.test(r) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
2728
2806
  if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
2729
- if ($n.has(e)) return "ERROR_STAGE_RESOLVE";
2807
+ if (or.has(e)) return "ERROR_STAGE_RESOLVE";
2730
2808
  let i = t ?? "";
2731
2809
  return /frag|segment/i.test(i) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /manifest|level|playlist/i.test(i) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(i) ? "ERROR_STAGE_DRM" : /buffer|decode|media|append/i.test(i) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
2732
2810
  }
@@ -2758,7 +2836,7 @@ var sr = class {
2758
2836
  let l = t.droppedFrames ?? 0;
2759
2837
  l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
2760
2838
  let u = t.renditionSwitches ?? 0;
2761
- u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = X[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
2839
+ u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = sr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
2762
2840
  let d = this.mutedTotalMs;
2763
2841
  this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
2764
2842
  let f = t.upshifts ?? 0;
@@ -2773,20 +2851,20 @@ var sr = class {
2773
2851
  if (this.lastRequestCount = g, _ > 0) {
2774
2852
  o.requestCountDelta = _;
2775
2853
  let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
2776
- n.length > 0 && (o.requestTimeP50Ms = q(n, 50), o.requestTimeP95Ms = q(n, 95));
2854
+ n.length > 0 && (o.requestTimeP50Ms = K(n, 50), o.requestTimeP95Ms = K(n, 95));
2777
2855
  }
2778
2856
  typeof t.latencySeconds == "number" && typeof t.targetLatencySeconds == "number" && (o.driftMs = Math.round((t.latencySeconds - t.targetLatencySeconds) * 1e3)), typeof t.playbackRate == "number" && t.playbackRate > 0 && (o.playbackRate = t.playbackRate), t.qualityPinned === !0 && (o.qualityPinned = !0), t.cdnHost && (o.cdnHost = t.cdnHost), this.maybeEmitMediaInfo(t), this.enqueue({ heartbeat: o }), this.flush(), s > 0 && this.noteFirstBytes();
2779
2857
  }
2780
2858
  maybeEmitMediaInfo(e) {
2781
2859
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
2782
2860
  let t = {};
2783
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Qn[e.keySystem]), e.drmSecurityLevel && (t.drmSecurityLevel = e.drmSecurityLevel), e.ladderHeights?.length && (t.ladderHeights = e.ladderHeights), e.ladderTopBitrateKbps && (t.ladderTopBitrateKbps = e.ladderTopBitrateKbps), e.lowLatency && (t.lowLatency = !0);
2861
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = ar[e.keySystem]), e.drmSecurityLevel && (t.drmSecurityLevel = e.drmSecurityLevel), e.ladderHeights?.length && (t.ladderHeights = e.ladderHeights), e.ladderTopBitrateKbps && (t.ladderTopBitrateKbps = e.ladderTopBitrateKbps), e.lowLatency && (t.lowLatency = !0);
2784
2862
  let n = JSON.stringify(t);
2785
2863
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
2786
2864
  }
2787
2865
  end(e, t) {
2788
2866
  if (this.endedFlag) return;
2789
- this.endedFlag = !0, Q.delete(this);
2867
+ this.endedFlag = !0, fr.delete(this);
2790
2868
  let n = t ?? this.now();
2791
2869
  this.playingSinceMs !== null && (this.playingTotalMs += n - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += n - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += n - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += n - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += n - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(n), this.closePresentation(n), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), this.idleTimer &&= (clearTimeout(this.idleTimer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), document.removeEventListener("freeze", this.onFreeze), document.removeEventListener("resume", this.onResume));
2792
2870
  let r = this.safeSample();
@@ -2800,7 +2878,7 @@ var sr = class {
2800
2878
  let c = r?.positionMs ?? 0;
2801
2879
  c > 0 && (i.exitPositionMs = Math.round(c)), this.activeTotalMs > 0 && (i.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (i.mutedTimeMs = Math.round(this.mutedTotalMs));
2802
2880
  let l = e !== "END_REASON_ENDED";
2803
- l && this.lastStallMs > 0 && n - this.lastStallMs <= Yn && (i.abandonAfterStallMs = Math.max(Y, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Yn && (i.abandonAfterErrorMs = Math.max(Y, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
2881
+ l && this.lastStallMs > 0 && n - this.lastStallMs <= nr && (i.abandonAfterStallMs = Math.max(Z, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= nr && (i.abandonAfterErrorMs = Math.max(Z, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
2804
2882
  let u = r?.decodedFrames ?? this.lastDecoded;
2805
2883
  u > 0 && (i.decodedFramesTotal = u), e === "END_REASON_STOPPED" && this.startupTimeMs === 0 && this.lastErrorStage === null && (e = "END_REASON_ABORTED", i.reason = e), this.startupTimeMs === 0 && e !== "END_REASON_ABORTED" && (i.failedStage = this.lastErrorStage ?? (this.manifestLoadMs === 0 ? "ERROR_STAGE_MANIFEST" : this.firstFragLoadMs === 0 ? "ERROR_STAGE_FIRST_SEGMENT" : "ERROR_STAGE_OTHER")), this.pending.push(this.wrap({ sessionEnd: i })), this.flush(e === "END_REASON_PAGEHIDE");
2806
2884
  }
@@ -2820,13 +2898,13 @@ var sr = class {
2820
2898
  };
2821
2899
  }
2822
2900
  noteCspBlocked() {
2823
- this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(rr(new URL(this.url).origin)));
2901
+ this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(pr(new URL(this.url).origin)));
2824
2902
  }
2825
2903
  cspBlocked() {
2826
- return !!this.cspKey && Z.has(this.cspKey);
2904
+ return !!this.cspKey && dr.has(this.cspKey);
2827
2905
  }
2828
2906
  enqueue(e) {
2829
- if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > qn;) {
2907
+ if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > er;) {
2830
2908
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
2831
2909
  this.pending.splice(e >= 0 ? e : 0, 1);
2832
2910
  }
@@ -2853,7 +2931,7 @@ var sr = class {
2853
2931
  };
2854
2932
  //#endregion
2855
2933
  //#region src/core/environment.ts
2856
- function cr() {
2934
+ function vr() {
2857
2935
  if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
2858
2936
  let e;
2859
2937
  try {
@@ -2878,14 +2956,14 @@ function cr() {
2878
2956
  integration: "INTEGRATION_KIND_IFRAME"
2879
2957
  };
2880
2958
  }
2881
- function lr() {
2959
+ function yr() {
2882
2960
  if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
2883
2961
  let e = navigator.userAgentData, t = e?.platform ?? "";
2884
2962
  if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
2885
2963
  let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
2886
2964
  return e?.mobile ?? (typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1 && n > 0 && n < 900) ? n >= 600 ? "DEVICE_CLASS_TABLET" : "DEVICE_CLASS_PHONE" : e || n >= 900 || /mac|win|linux|chrome os/i.test(t) ? "DEVICE_CLASS_DESKTOP" : "DEVICE_CLASS_OTHER";
2887
2965
  }
2888
- function ur() {
2966
+ function br() {
2889
2967
  let e = typeof navigator < "u" ? navigator.connection : void 0;
2890
2968
  if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
2891
2969
  let t = {
@@ -2904,17 +2982,17 @@ function ur() {
2904
2982
  }
2905
2983
  return typeof e.downlink == "number" && e.downlink > 0 && (i.downlinkKbps = Math.round(e.downlink * 1e3)), typeof e.rtt == "number" && e.rtt > 0 && (i.rttMs = Math.round(e.rtt)), e.saveData && (i.saveData = !0), i;
2906
2984
  }
2907
- function dr(e) {
2908
- let t = cr(), n = {
2909
- deviceClass: lr(),
2985
+ function xr(e) {
2986
+ let t = vr(), n = {
2987
+ deviceClass: yr(),
2910
2988
  integration: t.integration,
2911
- ...ur()
2989
+ ...br()
2912
2990
  };
2913
2991
  t.host && (n.host = t.host), typeof screen < "u" && screen.width > 0 && (n.screenWidth = screen.width, n.screenHeight = screen.height), typeof window < "u" && window.devicePixelRatio > 0 && (n.devicePixelRatio = Math.round(window.devicePixelRatio * 100) / 100);
2914
2992
  let r = e.getBoundingClientRect?.();
2915
2993
  return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
2916
2994
  }
2917
- async function fr() {
2995
+ async function Sr() {
2918
2996
  let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
2919
2997
  if (!e?.getHighEntropyValues) return {};
2920
2998
  try {
@@ -2926,7 +3004,7 @@ async function fr() {
2926
3004
  }
2927
3005
  //#endregion
2928
3006
  //#region src/core/version.ts
2929
- var pr = "2.25.1", mr = {
3007
+ var Cr = "2.26.0", wr = {
2930
3008
  accent: "#E1B600",
2931
3009
  accentText: "#1B1C23",
2932
3010
  background: "#0e0f13",
@@ -2937,7 +3015,7 @@ var pr = "2.25.1", mr = {
2937
3015
  border: "rgba(255, 255, 255, 0.1)",
2938
3016
  radius: "8px",
2939
3017
  fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
2940
- }, hr = {
3018
+ }, Tr = {
2941
3019
  accent: "--havik-accent",
2942
3020
  accentText: "--havik-accent-text",
2943
3021
  background: "--havik-bg",
@@ -2949,26 +3027,26 @@ var pr = "2.25.1", mr = {
2949
3027
  radius: "--havik-radius",
2950
3028
  fontFamily: "--havik-font"
2951
3029
  };
2952
- function gr(e, t) {
3030
+ function Er(e, t) {
2953
3031
  let n = {
2954
- ...mr,
3032
+ ...wr,
2955
3033
  ...t
2956
3034
  };
2957
- for (let t of Object.keys(hr)) e.style.setProperty(hr[t], n[t]);
3035
+ for (let t of Object.keys(Tr)) e.style.setProperty(Tr[t], n[t]);
2958
3036
  n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
2959
3037
  }
2960
3038
  //#endregion
2961
3039
  //#region src/ui/styles.ts
2962
- var _r = "havik-player-styles", vr = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;\n touch-action:manipulation}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n", yr = /* @__PURE__ */ new WeakMap();
2963
- function br(e = document, t) {
2964
- let n = e.querySelector(`style#${_r}`);
2965
- if (n && (!t || yr.get(n) === t)) return;
3040
+ var Dr = "havik-player-styles", Or = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;\n touch-action:manipulation}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n", kr = /* @__PURE__ */ new WeakMap();
3041
+ function Ar(e = document, t) {
3042
+ let n = e.querySelector(`style#${Dr}`);
3043
+ if (n && (!t || kr.get(n) === t)) return;
2966
3044
  let r = e.createElement("style");
2967
- r.id = _r, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = vr, yr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
3045
+ r.id = Dr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Or, kr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2968
3046
  }
2969
3047
  //#endregion
2970
3048
  //#region src/ui/icons.ts
2971
- var xr = {
3049
+ var jr = {
2972
3050
  play: "<path d=\"M8 5v14l11-7z\"/>",
2973
3051
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
2974
3052
  volumeHigh: "<path d=\"M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z\"/>",
@@ -2981,12 +3059,12 @@ var xr = {
2981
3059
  liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
2982
3060
  retry: "<path d=\"M17.65 6.35A8 8 0 1 0 19.73 13h-2.08A6 6 0 1 1 12 6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"/>"
2983
3061
  };
2984
- function $(e) {
2985
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${xr[e]}</svg>`;
3062
+ function Q(e) {
3063
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${jr[e]}</svg>`;
2986
3064
  }
2987
3065
  //#endregion
2988
3066
  //#region src/ui/controls.ts
2989
- var Sr = 3e3, Cr = 250, wr = /* @__PURE__ */ new Set([
3067
+ var Mr = 3e3, Nr = 250, Pr = /* @__PURE__ */ new Set([
2990
3068
  "GONE",
2991
3069
  "NOT_FOUND",
2992
3070
  "GEO_DENIED",
@@ -2994,15 +3072,15 @@ var Sr = 3e3, Cr = 250, wr = /* @__PURE__ */ new Set([
2994
3072
  "UNAUTHORIZED",
2995
3073
  "DRM_DEVICE_REVOKED"
2996
3074
  ]);
2997
- function Tr(e) {
3075
+ function Fr(e) {
2998
3076
  let t = "This match isn't available in your country";
2999
3077
  return e ? `${t} (${e})` : t;
3000
3078
  }
3001
- var Er = "This device can't play protected video";
3002
- function Dr(e) {
3003
- return new Or(e);
3079
+ var Ir = "This device can't play protected video";
3080
+ function Lr(e) {
3081
+ return new Rr(e);
3004
3082
  }
3005
- var Or = class {
3083
+ var Rr = class {
3006
3084
  root;
3007
3085
  video;
3008
3086
  player;
@@ -3051,7 +3129,7 @@ var Or = class {
3051
3129
  scrubbing = !1;
3052
3130
  offFns = [];
3053
3131
  constructor(e) {
3054
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Sr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", br(this.doc, e.cspNonce), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
3132
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Mr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", Ar(this.doc, e.cspNonce), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
3055
3133
  let t = (e, t, n) => {
3056
3134
  let r = this.doc.createElement(e);
3057
3135
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -3062,12 +3140,12 @@ var Or = class {
3062
3140
  "aria-label": r,
3063
3141
  title: r
3064
3142
  });
3065
- return i.innerHTML = $(n), i;
3143
+ return i.innerHTML = Q(n), i;
3066
3144
  };
3067
3145
  this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
3068
3146
  type: "button",
3069
3147
  "aria-label": "Play"
3070
- }), this.center.innerHTML = $("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
3148
+ }), this.center.innerHTML = Q("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
3071
3149
  role: "slider",
3072
3150
  "aria-label": "Seek",
3073
3151
  "aria-valuemin": "0",
@@ -3085,7 +3163,7 @@ var Or = class {
3085
3163
  "aria-label": "Volume"
3086
3164
  });
3087
3165
  let a = t("div", "havik-vol");
3088
- a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = $("liveDot");
3166
+ a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
3089
3167
  let o = this.doc.createElement("span");
3090
3168
  o.textContent = "LIVE", this.liveGo = t("button", "havik-live__go", { type: "button" }), this.liveGo.textContent = "Go live", this.live.append(o, this.liveGo), this.time = t("div", "havik-time"), this.time.textContent = "0:00", this.time.style.display = "none";
3091
3169
  let s = t("div", "havik-spacer");
@@ -3137,7 +3215,7 @@ var Or = class {
3137
3215
  let t = this.surfaceWasHidden;
3138
3216
  this.tapTimer = setTimeout(() => {
3139
3217
  this.tapTimer = void 0, this.toggleBar(t);
3140
- }, Cr);
3218
+ }, Nr);
3141
3219
  }
3142
3220
  toggleBar(e) {
3143
3221
  e ? this.poke() : this.hideIfIdle();
@@ -3161,7 +3239,7 @@ var Or = class {
3161
3239
  this.renderStatus(t);
3162
3240
  }
3163
3241
  statusMessageFor(e) {
3164
- return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? Tr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Er : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
3242
+ return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? Fr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Ir : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
3165
3243
  }
3166
3244
  renderStatus(e) {
3167
3245
  let t = this.statusMessageFor(e);
@@ -3173,12 +3251,12 @@ var Or = class {
3173
3251
  }
3174
3252
  if (e === "preplay") {
3175
3253
  let e = this.doc.createElement("button");
3176
- e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = $("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
3254
+ e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
3177
3255
  } else {
3178
3256
  let r = this.doc.createElement("div");
3179
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !wr.has(this.lastError.code)) {
3257
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Pr.has(this.lastError.code)) {
3180
3258
  let e = this.doc.createElement("button");
3181
- e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${$("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
3259
+ e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
3182
3260
  }
3183
3261
  }
3184
3262
  this.root.append(n), this.statusBox = n, this.show();
@@ -3217,7 +3295,7 @@ var Or = class {
3217
3295
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
3218
3296
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
3219
3297
  }
3220
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${kr(this.video.currentTime)} / ${kr(this.video.duration)}`);
3298
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${zr(this.video.currentTime)} / ${zr(this.video.duration)}`);
3221
3299
  }
3222
3300
  syncLive() {
3223
3301
  let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
@@ -3267,17 +3345,17 @@ var Or = class {
3267
3345
  renderQualityMenu() {
3268
3346
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
3269
3347
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
3270
- for (let n of e) this.menu.append(this.menuItem(Ar(n), t === n.index, () => this.player.setQuality(n.index)));
3348
+ for (let n of e) this.menu.append(this.menuItem(Br(n), t === n.index, () => this.player.setQuality(n.index)));
3271
3349
  }
3272
3350
  renderAudioMenu() {
3273
3351
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
3274
3352
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
3275
- for (let t of e) this.menu.append(this.menuItem(jr(t), t.default, () => this.player.setAudioTrack(t.id)));
3353
+ for (let t of e) this.menu.append(this.menuItem(Vr(t), t.default, () => this.player.setAudioTrack(t.id)));
3276
3354
  }
3277
3355
  renderCcMenu() {
3278
3356
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
3279
3357
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
3280
- for (let t of e) this.menu.append(this.menuItem(Mr(t), !1, () => this.player.setTextTrack(t.id)));
3358
+ for (let t of e) this.menu.append(this.menuItem(Hr(t), !1, () => this.player.setTextTrack(t.id)));
3281
3359
  }
3282
3360
  onTracksChanged() {
3283
3361
  this.openMenu && this.renderMenu(this.openMenu);
@@ -3297,14 +3375,14 @@ var Or = class {
3297
3375
  }
3298
3376
  async toggleFullscreen() {
3299
3377
  try {
3300
- ve(this.video, this.root) ? await C(this.video, this.root) : await S(this.video, this.root);
3378
+ S(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
3301
3379
  } catch {}
3302
3380
  }
3303
3381
  syncFullscreenSupport() {
3304
- this.fsSupported = ye(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
3382
+ this.fsSupported = C(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
3305
3383
  }
3306
3384
  syncFullscreen() {
3307
- let e = ve(this.video, this.root);
3385
+ let e = S(this.video, this.root);
3308
3386
  this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
3309
3387
  }
3310
3388
  poke() {
@@ -3365,7 +3443,7 @@ var Or = class {
3365
3443
  }
3366
3444
  }
3367
3445
  setIcon(e, t) {
3368
- e.innerHTML = $(t);
3446
+ e.innerHTML = Q(t);
3369
3447
  }
3370
3448
  destroy() {
3371
3449
  this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
@@ -3382,23 +3460,23 @@ var Or = class {
3382
3460
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
3383
3461
  }
3384
3462
  };
3385
- function kr(e) {
3463
+ function zr(e) {
3386
3464
  (!Number.isFinite(e) || e < 0) && (e = 0);
3387
3465
  let t = Math.floor(e % 60), n = Math.floor(e / 60 % 60), r = Math.floor(e / 3600), i = r > 0 ? String(n).padStart(2, "0") : String(n), a = String(t).padStart(2, "0");
3388
3466
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
3389
3467
  }
3390
- function Ar(e) {
3468
+ function Br(e) {
3391
3469
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
3392
3470
  }
3393
- function jr(e) {
3471
+ function Vr(e) {
3394
3472
  return e.name || e.lang || `Track ${e.id}`;
3395
3473
  }
3396
- function Mr(e) {
3474
+ function Hr(e) {
3397
3475
  return e.name || e.lang || `Track ${e.id}`;
3398
3476
  }
3399
3477
  //#endregion
3400
3478
  //#region src/managed/index.ts
3401
- var Nr = 6e3, Pr = 45e3, Fr = 2e3, Ir = 3, Lr = 5e3, Rr = 2e3, zr = 48e4, Br = "keySystemLicenseRequestFailed", Vr = /* @__PURE__ */ new Set([
3479
+ var Ur = 6e3, Wr = 45e3, Gr = 2e3, Kr = 3, qr = 5e3, Jr = 2e3, Yr = 48e4, Xr = "keySystemLicenseRequestFailed", Zr = /* @__PURE__ */ new Set([
3402
3480
  "GONE",
3403
3481
  "NOT_FOUND",
3404
3482
  "INVALID_URN",
@@ -3406,27 +3484,27 @@ var Nr = 6e3, Pr = 45e3, Fr = 2e3, Ir = 3, Lr = 5e3, Rr = 2e3, zr = 48e4, Br = "
3406
3484
  "GEO_DENIED",
3407
3485
  "DRM_DEVICE_REVOKED"
3408
3486
  ]);
3409
- function Hr(e) {
3410
- return !Vr.has(e);
3487
+ function Qr(e) {
3488
+ return !Zr.has(e);
3411
3489
  }
3412
- function Ur(e) {
3490
+ function $r(e) {
3413
3491
  if (e.env !== void 0 && e.baseUrl !== void 0) throw new n("INTERNAL", 0, `createPlayer: pass env OR baseUrl, not both (got env=${JSON.stringify(e.env)} and baseUrl=${JSON.stringify(e.baseUrl)})`);
3414
- if (e.env !== void 0) return ct(e.env);
3492
+ if (e.env !== void 0) return lt(e.env);
3415
3493
  if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
3416
3494
  return e.baseUrl;
3417
3495
  }
3418
- async function Wr(e) {
3496
+ async function ei(e) {
3419
3497
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
3420
- let t = Ur(e);
3498
+ let t = $r(e);
3421
3499
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
3422
3500
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
3423
- let r = new Gr({
3501
+ let r = new ti({
3424
3502
  ...e,
3425
3503
  baseUrl: t
3426
3504
  });
3427
3505
  return await r.start(), r;
3428
3506
  }
3429
- var Gr = class {
3507
+ var ti = class {
3430
3508
  opts;
3431
3509
  abort = new AbortController();
3432
3510
  listeners = {};
@@ -3470,7 +3548,7 @@ var Gr = class {
3470
3548
  return this._state;
3471
3549
  }
3472
3550
  get offline() {
3473
- return !R();
3551
+ return !L();
3474
3552
  }
3475
3553
  get descriptor() {
3476
3554
  return this._descriptor;
@@ -3505,7 +3583,7 @@ var Gr = class {
3505
3583
  };
3506
3584
  }
3507
3585
  beginArming(e, t, n = !1) {
3508
- let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3586
+ let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
3509
3587
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
3510
3588
  }
3511
3589
  beginArmingByPolling(e) {
@@ -3526,7 +3604,7 @@ var Gr = class {
3526
3604
  setTimeout(() => {
3527
3605
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
3528
3606
  phase: i ? "unavailable" : "tooEarly",
3529
- retryInMs: Pr,
3607
+ retryInMs: Wr,
3530
3608
  attempt: 1,
3531
3609
  elapsedMs: 0,
3532
3610
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -3565,13 +3643,13 @@ var Gr = class {
3565
3643
  !a && !p() && h();
3566
3644
  }, e);
3567
3645
  };
3568
- _(Nr), this.armingSub = T({
3646
+ _(Ur), this.armingSub = D({
3569
3647
  eventsBaseUrl: t,
3570
3648
  matchUrn: this.opts.matchUrn,
3571
3649
  credential: this.opts.credential,
3572
- onAlive: () => _(Pr),
3650
+ onAlive: () => _(Wr),
3573
3651
  onState: (e) => {
3574
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Fr);
3652
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Gr);
3575
3653
  },
3576
3654
  onError: () => h()
3577
3655
  });
@@ -3594,7 +3672,7 @@ var Gr = class {
3594
3672
  let n = await c(this.opts.credential);
3595
3673
  if (this.destroyed || t !== this.loadGen) return;
3596
3674
  this.setState("loading");
3597
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = ht(this.opts.video, (e) => {
3675
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = gt(this.opts.video, (e) => {
3598
3676
  this._state !== "ended" && this._state !== "error" && this.setState(e);
3599
3677
  });
3600
3678
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -3616,26 +3694,26 @@ var Gr = class {
3616
3694
  if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
3617
3695
  let i = e.analytics?.sid;
3618
3696
  if (!i) return;
3619
- let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = or(this.opts.baseUrl, a, e.analytics?.endpoint);
3697
+ let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = gr(this.opts.baseUrl, a, e.analytics?.endpoint);
3620
3698
  if (!o) {
3621
3699
  s && setTimeout(() => {
3622
3700
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
3623
3701
  }, 0);
3624
3702
  return;
3625
3703
  }
3626
- let c = this.opts.video, l = new sr({
3704
+ let c = this.opts.video, l = new _r({
3627
3705
  endpoint: o,
3628
3706
  sid: i,
3629
3707
  player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
3630
- sdkVersion: pr,
3631
- environment: dr(c),
3708
+ sdkVersion: Cr,
3709
+ environment: xr(c),
3632
3710
  idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
3633
3711
  onIdle: () => this.onAnalyticsIdle(t),
3634
3712
  onBlocked: (e) => setTimeout(() => {
3635
3713
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
3636
3714
  }, 0),
3637
3715
  sample: () => {
3638
- let e = this.engine?.getStats() ?? ut, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3716
+ let e = this.engine?.getStats() ?? dt, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3639
3717
  return {
3640
3718
  ...e,
3641
3719
  bufferedMs: Math.round(t * 1e3),
@@ -3649,7 +3727,7 @@ var Gr = class {
3649
3727
  let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
3650
3728
  c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
3651
3729
  c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
3652
- }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), fr().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3730
+ }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Sr().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3653
3731
  }
3654
3732
  currentPresentation() {
3655
3733
  let e = this.opts.video;
@@ -3664,7 +3742,7 @@ var Gr = class {
3664
3742
  video: this.opts.video,
3665
3743
  descriptor: e,
3666
3744
  credential: t,
3667
- deviceId: k(),
3745
+ deviceId: Oe(),
3668
3746
  userId: this.opts.userId,
3669
3747
  lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
3670
3748
  snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
@@ -3680,11 +3758,11 @@ var Gr = class {
3680
3758
  emit: (e) => this.onEngineEvent(e),
3681
3759
  freshLicenseUrl: () => this.refreshLicense()
3682
3760
  }, o = this.opts.engine ?? "auto";
3683
- if (o === "native") return new U(a);
3684
- if (o === "hls") return new Un(a);
3685
- if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && V(this.opts.video) && H() || !e.drmEnabled && Dt() && V(this.opts.video)) return new U(a);
3686
- if (Ut()) return new Un(a);
3687
- if (V(this.opts.video)) return new U(a);
3761
+ if (o === "native") return new H(a);
3762
+ if (o === "hls") return new Xn(a);
3763
+ if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && Ot() && B(this.opts.video)) return new H(a);
3764
+ if (Wt()) return new Xn(a);
3765
+ if (B(this.opts.video)) return new H(a);
3688
3766
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
3689
3767
  }
3690
3768
  onEngineEvent(e) {
@@ -3734,11 +3812,11 @@ var Gr = class {
3734
3812
  }
3735
3813
  startLiveState(e) {
3736
3814
  if (this.opts.liveStateEvents === !1) return;
3737
- let t = this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3815
+ let t = this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
3738
3816
  if (!t) return;
3739
3817
  this.closeLiveState();
3740
3818
  let i = 0, a = !1;
3741
- this.liveStateSub = T({
3819
+ this.liveStateSub = D({
3742
3820
  eventsBaseUrl: t,
3743
3821
  matchUrn: this.opts.matchUrn,
3744
3822
  credential: this.opts.credential,
@@ -3750,11 +3828,11 @@ var Gr = class {
3750
3828
  },
3751
3829
  onError: (o) => {
3752
3830
  if (!(this.destroyed || e !== this.loadGen || a) && !this.endedHandled) {
3753
- if (o instanceof w && (o.terminal || o.status === 404)) {
3831
+ if (o instanceof E && (o.terminal || o.status === 404)) {
3754
3832
  a = !0, this.emit("warning", new n(r(o.status), o.status, `live-state events answered HTTP ${o.status} for ${this.opts.matchUrn}: the match is ` + (o.terminal ? "gone, so the subscription stopped" : "not in the catalog (ended and dropped, or not listed yet), so it retries every 5 min") + " — end-of-stream detection falls back to the HLS staleness watchdog."));
3755
3833
  return;
3756
3834
  }
3757
- i += 1, i >= Ir && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`)));
3835
+ i += 1, i >= Kr && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`)));
3758
3836
  }
3759
3837
  }
3760
3838
  });
@@ -3763,7 +3841,7 @@ var Gr = class {
3763
3841
  this.liveStateSub?.close(), this.liveStateSub = null;
3764
3842
  }
3765
3843
  watchConnectivity() {
3766
- this.connectivity || (this.connectivity = lt(), this.connectivity.onChange((e) => {
3844
+ this.connectivity || (this.connectivity = ut(), this.connectivity.onChange((e) => {
3767
3845
  if (this.destroyed) return;
3768
3846
  if (!e) {
3769
3847
  this.emit("offline");
@@ -3771,7 +3849,7 @@ var Gr = class {
3771
3849
  }
3772
3850
  if (this.emit("online"), this._state !== "error" || !this._lastError) return;
3773
3851
  let t = this._lastError.code;
3774
- Hr(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
3852
+ Qr(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
3775
3853
  }));
3776
3854
  }
3777
3855
  watchReturn() {
@@ -3781,7 +3859,7 @@ var Gr = class {
3781
3859
  return;
3782
3860
  }
3783
3861
  let e = this.hiddenAtMs;
3784
- this.hiddenAtMs = null, e != null && Date.now() - e >= Lr && this.resyncLiveState();
3862
+ this.hiddenAtMs = null, e != null && Date.now() - e >= qr && this.resyncLiveState();
3785
3863
  }, this.onReturnPageShow = (e) => {
3786
3864
  e.persisted && this.resyncLiveState();
3787
3865
  }, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
@@ -3813,7 +3891,7 @@ var Gr = class {
3813
3891
  scheduleRejoin(e) {
3814
3892
  this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
3815
3893
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
3816
- }, Math.random() * Fr));
3894
+ }, Math.random() * Gr));
3817
3895
  }
3818
3896
  cancelRejoin() {
3819
3897
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -3837,7 +3915,7 @@ var Gr = class {
3837
3915
  }
3838
3916
  t.controls = !1;
3839
3917
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
3840
- r && r.insertBefore(n, t), n.appendChild(t), gr(n, this.opts.theme), this.container = n, this.controlBar = Dr({
3918
+ r && r.insertBefore(n, t), n.appendChild(t), Er(n, this.opts.theme), this.container = n, this.controlBar = Lr({
3841
3919
  root: n,
3842
3920
  video: t,
3843
3921
  player: this,
@@ -3876,7 +3954,7 @@ var Gr = class {
3876
3954
  }
3877
3955
  startStats() {
3878
3956
  this.stopStats();
3879
- let e = Math.max(500, this.opts.statsIntervalMs ?? Rr);
3957
+ let e = Math.max(500, this.opts.statsIntervalMs ?? Jr);
3880
3958
  this.statsTimer = setInterval(() => {
3881
3959
  if (!this.engine) return;
3882
3960
  let e = this.engine.getStats();
@@ -3887,14 +3965,14 @@ var Gr = class {
3887
3965
  this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
3888
3966
  }
3889
3967
  isStaleLicenseDenial(e) {
3890
- return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Br || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : G(this._descriptor?.drm?.widevine?.licenseUrl);
3968
+ return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Xr || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
3891
3969
  }
3892
3970
  scheduleLicenseRefresh() {
3893
3971
  if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
3894
3972
  typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
3895
- document.visibilityState !== "visible" || this.destroyed || G(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
3973
+ document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
3896
3974
  }, document.addEventListener("visibilitychange", this.onRefocus));
3897
- let e = this.opts.licenseRefreshMs ?? zr;
3975
+ let e = this.opts.licenseRefreshMs ?? Yr;
3898
3976
  e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
3899
3977
  }
3900
3978
  stopRefresh() {
@@ -3951,7 +4029,7 @@ var Gr = class {
3951
4029
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
3952
4030
  }
3953
4031
  getStats() {
3954
- return this.engine?.getStats() ?? ut;
4032
+ return this.engine?.getStats() ?? dt;
3955
4033
  }
3956
4034
  getQualityLevels() {
3957
4035
  return this.engine?.getQualityLevels() ?? [];
@@ -3990,13 +4068,13 @@ var Gr = class {
3990
4068
  e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
3991
4069
  }
3992
4070
  async enterFullscreen() {
3993
- return !this.destroyed && S(this.opts.video, this.container ?? void 0);
4071
+ return !this.destroyed && w(this.opts.video, this.container ?? void 0);
3994
4072
  }
3995
4073
  async exitFullscreen() {
3996
- await C(this.opts.video, this.container ?? void 0);
4074
+ await T(this.opts.video, this.container ?? void 0);
3997
4075
  }
3998
4076
  fullscreenSupported() {
3999
- return !this.destroyed && ye(this.opts.video, this.container ?? void 0);
4077
+ return !this.destroyed && C(this.opts.video, this.container ?? void 0);
4000
4078
  }
4001
4079
  retry() {
4002
4080
  return this.reload();
@@ -4027,7 +4105,7 @@ var Gr = class {
4027
4105
  for (let e of Object.keys(this.listeners)) this.listeners[e]?.clear();
4028
4106
  }
4029
4107
  fail(e) {
4030
- this._lastError = e, this.failedWhileOffline = !R(), this.setState("error"), this.analyticsSession?.noteFatal(), this.emit("error", e);
4108
+ this._lastError = e, this.failedWhileOffline = !L(), this.setState("error"), this.analyticsSession?.noteFatal(), this.emit("error", e);
4031
4109
  }
4032
4110
  setState(e) {
4033
4111
  if (e === this._state) return;
@@ -4059,12 +4137,12 @@ var Gr = class {
4059
4137
  };
4060
4138
  //#endregion
4061
4139
  //#region src/embed/protocol.ts
4062
- function Kr(e) {
4140
+ function $(e) {
4063
4141
  return !!e && typeof e == "object" && typeof e.type == "string" && e.type.startsWith("oddin:");
4064
4142
  }
4065
4143
  //#endregion
4066
4144
  //#region src/embed/host.ts
4067
- function qr(e) {
4145
+ function ni(e) {
4068
4146
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
4069
4147
  if (!e.src) throw Error("mountEmbed: opts.src is required");
4070
4148
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -4073,7 +4151,7 @@ function qr(e) {
4073
4151
  let r = document.createElement("iframe");
4074
4152
  r.src = t.toString(), r.allow = "autoplay; encrypted-media; fullscreen", r.setAttribute("allowfullscreen", ""), r.referrerPolicy = "no-referrer", r.setAttribute("sandbox", e.sandbox ?? "allow-scripts allow-same-origin allow-presentation"), r.style.cssText = "border:0;width:100%;height:100%;display:block", e.container.appendChild(r);
4075
4153
  let i = /* @__PURE__ */ new Set(), a = (t) => {
4076
- if (t.source !== r.contentWindow || t.origin !== n || !Kr(t.data)) return;
4154
+ if (t.source !== r.contentWindow || t.origin !== n || !$(t.data)) return;
4077
4155
  let a = t.data;
4078
4156
  a.type === "oddin:ready" && a.protocol !== 1 && console.warn(`havik-player: embed protocol v${a.protocol} != host v1. Pin the embed page version to the SDK version to avoid skew.`), e.onEvent?.(a), i.forEach((e) => e(a));
4079
4157
  };
@@ -4123,15 +4201,15 @@ function qr(e) {
4123
4201
  }
4124
4202
  //#endregion
4125
4203
  //#region src/embed/page.ts
4126
- var Jr = /^[A-Za-z0-9:_.-]{1,128}$/;
4127
- function Yr(e) {
4204
+ var ri = /^[A-Za-z0-9:_.-]{1,128}$/;
4205
+ function ii(e) {
4128
4206
  if (typeof e == "boolean") return e;
4129
4207
  if (typeof e == "object" && e) {
4130
4208
  let t = e.endpoint;
4131
4209
  return typeof t == "string" ? { endpoint: t } : {};
4132
4210
  }
4133
4211
  }
4134
- function Xr() {
4212
+ function ai() {
4135
4213
  let e = window.HAVIK_EMBED_CONFIG;
4136
4214
  if (e) return {
4137
4215
  baseUrl: e.baseUrl ?? "",
@@ -4141,7 +4219,7 @@ function Xr() {
4141
4219
  autoplay: e.autoplay ?? !0,
4142
4220
  muted: e.muted ?? !0,
4143
4221
  waitForLive: e.waitForLive ?? !0,
4144
- analytics: Yr(e.analytics)
4222
+ analytics: ii(e.analytics)
4145
4223
  };
4146
4224
  let t = new URLSearchParams(location.search);
4147
4225
  return {
@@ -4154,9 +4232,9 @@ function Xr() {
4154
4232
  waitForLive: !0
4155
4233
  };
4156
4234
  }
4157
- async function Zr() {
4158
- let e = Xr();
4159
- $r();
4235
+ async function oi() {
4236
+ let e = ai();
4237
+ ci();
4160
4238
  let t = document.createElement("video");
4161
4239
  t.setAttribute("playsinline", ""), t.muted = e.muted ?? !0, t.style.cssText = "width:100%;height:100%;object-fit:contain;background:#000;aspect-ratio:auto", document.body.appendChild(t);
4162
4240
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -4212,12 +4290,12 @@ async function Zr() {
4212
4290
  message: e.message,
4213
4291
  ...e.country === void 0 ? {} : { country: e.country }
4214
4292
  })), e.on("autoplayblocked", () => {
4215
- i({ type: "oddin:autoplayblocked" }), Qr(t, e);
4293
+ i({ type: "oddin:autoplayblocked" }), si(t, e);
4216
4294
  });
4217
4295
  }, s = async (r) => {
4218
4296
  a?.destroy(), a = null;
4219
4297
  try {
4220
- let n = await Wr({
4298
+ let n = await ei({
4221
4299
  video: t,
4222
4300
  baseUrl: e.baseUrl,
4223
4301
  matchUrn: r,
@@ -4280,30 +4358,30 @@ async function Zr() {
4280
4358
  a?.retry();
4281
4359
  break;
4282
4360
  case "oddin:load":
4283
- typeof e.matchUrn == "string" && Jr.test(e.matchUrn) && s(e.matchUrn);
4361
+ typeof e.matchUrn == "string" && ri.test(e.matchUrn) && s(e.matchUrn);
4284
4362
  break;
4285
4363
  case "oddin:destroy": c();
4286
4364
  }
4287
4365
  }, u = (e) => {
4288
- r && e.origin === r && Kr(e.data) && l(e.data);
4366
+ r && e.origin === r && $(e.data) && l(e.data);
4289
4367
  };
4290
4368
  r && window.addEventListener("message", u), window.addEventListener("pagehide", c, { once: !0 }), await s(e.matchUrn), i({
4291
4369
  type: "oddin:ready",
4292
4370
  protocol: 1
4293
4371
  });
4294
4372
  }
4295
- function Qr(e, t) {
4373
+ function si(e, t) {
4296
4374
  if (document.getElementById("havik-tap")) return;
4297
4375
  let n = document.createElement("button");
4298
4376
  n.id = "havik-tap", n.textContent = "▶ Tap to play", n.style.cssText = "position:fixed;inset:0;width:100%;height:100%;border:0;background:rgba(0,0,0,.55);color:#fff;font:600 18px system-ui,sans-serif;cursor:pointer;z-index:9", n.addEventListener("click", () => {
4299
4377
  n.remove(), t.play();
4300
4378
  }), document.body.appendChild(n);
4301
4379
  }
4302
- function $r() {
4380
+ function ci() {
4303
4381
  let e = document.createElement("style");
4304
4382
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
4305
4383
  }
4306
4384
  //#endregion
4307
- export { w as LiveStateHttpError, mr as ODDIN_THEME, n as PlaybackError, gr as applyTheme, ct as baseUrlForEnv, Zr as bootEmbed, ke as clearDeviceId, Ve as clearRememberedBandwidth, Wr as createPlayer, E as deriveEventsBaseUrl, it as detectDrmSupport, S as enterVideoFullscreen, C as exitVideoFullscreen, be as fetchCatalog, Se as fetchTournament, we as flattenMatches, ye as fullscreenSupported, k as getDeviceId, ot as isLowLatencyManifest, Kr as isOddinMessage, je as licenseRequestHeaders, qr as mountEmbed, fe as pollToLive, y as resolveStream, T as subscribeLiveState, ve as videoFullscreenActive, Ee as watchStatus };
4385
+ export { E as LiveStateHttpError, wr as ODDIN_THEME, n as PlaybackError, Er as applyTheme, lt as baseUrlForEnv, oi as bootEmbed, ke as clearDeviceId, He as clearRememberedBandwidth, ei as createPlayer, O as deriveEventsBaseUrl, at as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, Oe as getDeviceId, st as isLowLatencyManifest, $ as isOddinMessage, je as licenseRequestHeaders, ni as mountEmbed, fe as pollToLive, y as resolveStream, D as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
4308
4386
 
4309
4387
  //# sourceMappingURL=index.js.map