@oddin-gg/havik-player 2.16.0 → 2.16.2

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
@@ -290,32 +290,32 @@ function me(e, t) {
290
290
  function he(e) {
291
291
  return e.ownerDocument ?? document;
292
292
  }
293
- function S(e) {
293
+ function ge(e) {
294
294
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
295
295
  }
296
- function C(e, t) {
297
- let n = S(he(e));
296
+ function S(e, t) {
297
+ let n = ge(he(e));
298
298
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
299
299
  }
300
- async function w(e, t) {
300
+ async function C(e, t) {
301
301
  let n = t ?? e;
302
302
  if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
303
303
  if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
304
304
  let r = e;
305
305
  return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
306
306
  }
307
- async function T(e, t) {
307
+ async function w(e, t) {
308
308
  let n = e;
309
309
  if (n.webkitDisplayingFullscreen) {
310
310
  n.webkitExitFullscreen?.();
311
311
  return;
312
312
  }
313
- let r = he(e), i = S(r);
313
+ let r = he(e), i = ge(r);
314
314
  i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
315
315
  }
316
316
  //#endregion
317
317
  //#region src/core/catalog.ts
318
- async function ge(e) {
318
+ async function _e(e) {
319
319
  let t = new URLSearchParams();
320
320
  e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
321
321
  let i = t.toString(), a = d(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
@@ -333,12 +333,12 @@ async function ge(e) {
333
333
  };
334
334
  if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
335
335
  return {
336
- tournaments: _e(await s.json()),
336
+ tournaments: ve(await s.json()),
337
337
  etag: s.headers.get("etag") ?? void 0,
338
338
  notModified: !1
339
339
  };
340
340
  }
341
- function _e(e) {
341
+ function ve(e) {
342
342
  return (e.tournaments ?? []).map((e) => {
343
343
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
344
344
  return {
@@ -360,7 +360,7 @@ function _e(e) {
360
360
  };
361
361
  });
362
362
  }
363
- async function ve(e) {
363
+ async function ye(e) {
364
364
  let t = d(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
365
365
  e.etag && i.set("If-None-Match", e.etag);
366
366
  let a = await p(t, {
@@ -380,13 +380,13 @@ async function ve(e) {
380
380
  };
381
381
  if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
382
382
  return {
383
- tournament: ye(await a.json()),
383
+ tournament: be(await a.json()),
384
384
  etag: a.headers.get("etag") ?? void 0,
385
385
  notModified: !1,
386
386
  notFound: !1
387
387
  };
388
388
  }
389
- function ye(e) {
389
+ function be(e) {
390
390
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
391
391
  return {
392
392
  urn: t,
@@ -406,17 +406,17 @@ function ye(e) {
406
406
  }))
407
407
  };
408
408
  }
409
- function be(e) {
409
+ function xe(e) {
410
410
  return e.tournaments.flatMap((e) => e.matches);
411
411
  }
412
412
  //#endregion
413
413
  //#region src/core/poll.ts
414
- var xe = /* @__PURE__ */ new Set([
414
+ var Se = /* @__PURE__ */ new Set([
415
415
  "NOT_FOUND",
416
416
  "GONE",
417
417
  "INVALID_URN"
418
418
  ]);
419
- function Se(e) {
419
+ function Ce(e) {
420
420
  let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, u = !1, f = () => {
421
421
  u || (a = setTimeout(m, t));
422
422
  }, m = async () => {
@@ -449,7 +449,7 @@ function Se(e) {
449
449
  } catch (t) {
450
450
  if (!i.signal.aborted) {
451
451
  let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
452
- xe.has(r.code) && (u = !0), e.onError?.(r);
452
+ Se.has(r.code) && (u = !0), e.onError?.(r);
453
453
  }
454
454
  } finally {
455
455
  f();
@@ -461,9 +461,9 @@ function Se(e) {
461
461
  }
462
462
  //#endregion
463
463
  //#region src/core/events.ts
464
- var Ce = 45e3;
465
- function E(e) {
466
- let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? Ce, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
464
+ var we = 45e3;
465
+ function T(e) {
466
+ let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? we, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
467
467
  if (a.signal.aborted) return t();
468
468
  let n = setTimeout(t, e);
469
469
  a.signal.addEventListener("abort", () => {
@@ -544,7 +544,7 @@ function E(e) {
544
544
  o || (o = !0, a.abort());
545
545
  } };
546
546
  }
547
- function D(e) {
547
+ function E(e) {
548
548
  try {
549
549
  let t = new URL(e);
550
550
  return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
@@ -554,27 +554,27 @@ function D(e) {
554
554
  }
555
555
  //#endregion
556
556
  //#region src/core/drm/deviceId.ts
557
- var O = "havik.player.deviceId", k;
558
- function A() {
559
- if (k) return k;
557
+ var D = "havik.player.deviceId", O;
558
+ function k() {
559
+ if (O) return O;
560
560
  try {
561
- let e = globalThis.localStorage?.getItem(O);
562
- if (e) return k = e, e;
561
+ let e = globalThis.localStorage?.getItem(D);
562
+ if (e) return O = e, e;
563
563
  } catch {}
564
- let e = Te();
565
- k = e;
564
+ let e = Ee();
565
+ O = e;
566
566
  try {
567
- globalThis.localStorage?.setItem(O, e);
567
+ globalThis.localStorage?.setItem(D, e);
568
568
  } catch {}
569
569
  return e;
570
570
  }
571
- function we() {
572
- k = void 0;
571
+ function Te() {
572
+ O = void 0;
573
573
  try {
574
- globalThis.localStorage?.removeItem(O);
574
+ globalThis.localStorage?.removeItem(D);
575
575
  } catch {}
576
576
  }
577
- function Te() {
577
+ function Ee() {
578
578
  let e = globalThis.crypto;
579
579
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
580
580
  let t = /* @__PURE__ */ new Uint8Array(16);
@@ -586,21 +586,21 @@ function Te() {
586
586
  }
587
587
  //#endregion
588
588
  //#region src/core/drm/headers.ts
589
- function Ee(e, t, n = {}) {
589
+ function De(e, t, n = {}) {
590
590
  let r = {
591
591
  "x-api-key": t.apiKey,
592
592
  "X-Match-Urn": e.matchUrn,
593
- "X-Device-Id": n.deviceId ?? A(),
593
+ "X-Device-Id": n.deviceId ?? k(),
594
594
  "Content-Type": "application/octet-stream"
595
595
  };
596
596
  return n.userId && (r["X-User-Id"] = n.userId), r;
597
597
  }
598
598
  //#endregion
599
599
  //#region src/core/drm/cdm.ts
600
- var j = /* @__PURE__ */ new WeakMap();
601
- function De(e, t) {
602
- let n = j.get(e);
603
- n || (n = /* @__PURE__ */ new Map(), j.set(e, n));
600
+ var A = /* @__PURE__ */ new WeakMap();
601
+ function Oe(e, t) {
602
+ let n = A.get(e);
603
+ n || (n = /* @__PURE__ */ new Map(), A.set(e, n));
604
604
  let r = n.get(t.keySystem);
605
605
  if (r) return r;
606
606
  let i = t.createMediaKeys().catch((e) => {
@@ -608,22 +608,22 @@ function De(e, t) {
608
608
  });
609
609
  return n.set(t.keySystem, i), i;
610
610
  }
611
- function M() {
611
+ function j() {
612
612
  return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
613
613
  }
614
- var N = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
615
- function Oe(e) {
614
+ var M = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
615
+ function ke(e) {
616
616
  return e.startsWith("com.widevine");
617
617
  }
618
- function P(e, t) {
619
- if (!Oe(e)) return t;
618
+ function N(e, t) {
619
+ if (!ke(e)) return t;
620
620
  let n = (e, t) => {
621
621
  let n = e.videoCapabilities;
622
622
  return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
623
- let n = N.indexOf(e.robustness);
624
- return n === -1 || N.indexOf(t) > n;
623
+ let n = M.indexOf(e.robustness);
624
+ return n === -1 || M.indexOf(t) > n;
625
625
  });
626
- }, r = N.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
626
+ }, r = M.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
627
627
  ...t,
628
628
  videoCapabilities: t.videoCapabilities?.map((t) => ({
629
629
  ...t,
@@ -632,53 +632,53 @@ function P(e, t) {
632
632
  })));
633
633
  return [...t, ...r];
634
634
  }
635
- function F(e) {
636
- return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, P(t, n)).then((t) => ({
635
+ function P(e) {
636
+ return (t, n) => j() ? navigator.requestMediaKeySystemAccess(t, N(t, n)).then((t) => ({
637
637
  keySystem: t.keySystem,
638
638
  getConfiguration: () => t.getConfiguration(),
639
- createMediaKeys: () => De(e, t)
639
+ createMediaKeys: () => Oe(e, t)
640
640
  })) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
641
641
  }
642
- var I = {
642
+ var F = {
643
643
  video: "SW_SECURE_DECODE",
644
644
  audio: "SW_SECURE_CRYPTO",
645
645
  scheme: "cbcs"
646
646
  };
647
- function ke(e) {
648
- if (!M()) return;
647
+ function Ae(e) {
648
+ if (!j()) return;
649
649
  let t = (e, t) => ({
650
650
  contentType: e,
651
651
  robustness: t,
652
- encryptionScheme: I.scheme
652
+ encryptionScheme: F.scheme
653
653
  });
654
- F(e)("com.widevine.alpha", [{
654
+ P(e)("com.widevine.alpha", [{
655
655
  initDataTypes: ["cenc"],
656
656
  distinctiveIdentifier: "optional",
657
657
  persistentState: "optional",
658
658
  sessionTypes: ["temporary"],
659
- audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", I.audio)],
660
- videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", I.video)]
659
+ audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", F.audio)],
660
+ videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", F.video)]
661
661
  }]).then((e) => e.createMediaKeys()).catch(() => {});
662
662
  }
663
- function L(e) {
664
- let t = R(e);
663
+ function I(e) {
664
+ let t = L(e);
665
665
  if (/^avc[13]/.test(t)) return "avc";
666
666
  if (/^(hvc1|hev1)/.test(t)) return "hevc";
667
667
  if (/^(dvh1|dvhe)/.test(t)) return "dv";
668
668
  if (t.startsWith("av01")) return "av1";
669
669
  if (/^vp0?9/.test(t)) return "vp9";
670
670
  }
671
- function R(e) {
671
+ function L(e) {
672
672
  return (e ?? "").trim().toLowerCase();
673
673
  }
674
- var Ae = {
674
+ var R = {
675
675
  hevc: "hvc1.1.6.L93.90",
676
676
  dv: "dvh1.05.06",
677
677
  av1: "av01.0.05M.08",
678
678
  vp9: "vp09.00.10.08"
679
- }, je = /* @__PURE__ */ new Map(), z = /* @__PURE__ */ new Map();
680
- function Me(e) {
681
- let t = R(e), n = je.get(t);
679
+ }, z = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map();
680
+ function V(e) {
681
+ let t = L(e), n = z.get(t);
682
682
  if (n) return n;
683
683
  let r = {
684
684
  initDataTypes: ["cenc"],
@@ -687,32 +687,32 @@ function Me(e) {
687
687
  sessionTypes: ["temporary"],
688
688
  videoCapabilities: [{
689
689
  contentType: `video/mp4; codecs="${e.trim()}"`,
690
- robustness: I.video,
691
- encryptionScheme: I.scheme
690
+ robustness: F.video,
691
+ encryptionScheme: F.scheme
692
692
  }]
693
693
  }, i = (async () => {
694
694
  try {
695
- return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", P("com.widevine.alpha", [r])), !0;
695
+ return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", N("com.widevine.alpha", [r])), !0;
696
696
  } catch {
697
697
  return !1;
698
698
  }
699
- })().then((e) => (z.set(t, e), e));
700
- return je.set(t, i), i;
699
+ })().then((e) => (B.set(t, e), e));
700
+ return z.set(t, i), i;
701
701
  }
702
- function Ne() {
703
- if (M()) for (let e of Object.values(Ae)) Me(e);
702
+ function je() {
703
+ if (j()) for (let e of Object.values(R)) V(e);
704
704
  }
705
- function Pe(e) {
706
- let t = L(e);
707
- if (t) return t === "avc" ? !0 : z.get(R(e)) ?? z.get(R(Ae[t]));
705
+ function Me(e) {
706
+ let t = I(e);
707
+ if (t) return t === "avc" ? !0 : B.get(L(e)) ?? B.get(L(R[t]));
708
708
  }
709
709
  //#endregion
710
710
  //#region src/core/drm/support.ts
711
- var Fe = 5e3, Ie = "video/mp4; codecs=\"avc1.42E01E\"", Le = "audio/mp4; codecs=\"mp4a.40.2\"", Re = {
711
+ var Ne = 5e3, Pe = "video/mp4; codecs=\"avc1.42E01E\"", Fe = "audio/mp4; codecs=\"mp4a.40.2\"", Ie = {
712
712
  widevine: ["com.widevine.alpha"],
713
713
  fairplay: ["com.apple.fps"]
714
714
  };
715
- function ze(e) {
715
+ function Le(e) {
716
716
  return e === "fairplay" ? [{
717
717
  initDataTypes: [
718
718
  "sinf",
@@ -720,30 +720,30 @@ function ze(e) {
720
720
  "cenc"
721
721
  ],
722
722
  videoCapabilities: [{
723
- contentType: Ie,
723
+ contentType: Pe,
724
724
  robustness: "",
725
725
  encryptionScheme: "cbcs"
726
726
  }],
727
727
  audioCapabilities: [{
728
- contentType: Le,
728
+ contentType: Fe,
729
729
  robustness: "",
730
730
  encryptionScheme: "cbcs"
731
731
  }]
732
- }] : P("com.widevine.alpha", [{
732
+ }] : N("com.widevine.alpha", [{
733
733
  initDataTypes: ["cenc"],
734
734
  videoCapabilities: [{
735
- contentType: Ie,
736
- robustness: I.video,
737
- encryptionScheme: I.scheme
735
+ contentType: Pe,
736
+ robustness: F.video,
737
+ encryptionScheme: F.scheme
738
738
  }],
739
739
  audioCapabilities: [{
740
- contentType: Le,
741
- robustness: I.audio,
742
- encryptionScheme: I.scheme
740
+ contentType: Fe,
741
+ robustness: F.audio,
742
+ encryptionScheme: F.scheme
743
743
  }]
744
744
  }]);
745
745
  }
746
- function Be(e, t) {
746
+ function Re(e, t) {
747
747
  return new Promise((n, r) => {
748
748
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
749
749
  e.then((e) => {
@@ -753,8 +753,8 @@ function Be(e, t) {
753
753
  });
754
754
  });
755
755
  }
756
- async function Ve(e = {}) {
757
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Fe, r = {};
756
+ async function ze(e = {}) {
757
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ne, r = {};
758
758
  if (typeof window < "u" && window.isSecureContext === !1) return {
759
759
  verdict: "insecure-context",
760
760
  detail: r
@@ -766,7 +766,7 @@ async function Ve(e = {}) {
766
766
  };
767
767
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
768
768
  for (let e of t) {
769
- let t = Re[e];
769
+ let t = Ie[e];
770
770
  if (!t) {
771
771
  r[e] = "unknown system";
772
772
  continue;
@@ -777,7 +777,7 @@ async function Ve(e = {}) {
777
777
  break;
778
778
  }
779
779
  try {
780
- return await Be((await Be(i(n, ze(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
780
+ return await Re((await Re(i(n, Le(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
781
781
  verdict: "supported",
782
782
  system: e,
783
783
  detail: r
@@ -801,49 +801,49 @@ async function Ve(e = {}) {
801
801
  }
802
802
  //#endregion
803
803
  //#region src/core/manifest.ts
804
- var He = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
805
- function Ue(e) {
806
- return He.test(e);
804
+ var Be = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
805
+ function Ve(e) {
806
+ return Be.test(e);
807
807
  }
808
808
  //#endregion
809
809
  //#region src/core/env.ts
810
- var We = {
810
+ var He = {
811
811
  integration: "https://feed-dev.oddin-video.gg",
812
812
  production: "https://feed.oddin-video.gg"
813
813
  };
814
- function B(e) {
815
- let t = Object.prototype.hasOwnProperty.call(We, e) ? We[e] : void 0;
814
+ function Ue(e) {
815
+ let t = Object.prototype.hasOwnProperty.call(He, e) ? He[e] : void 0;
816
816
  if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
817
817
  return t;
818
818
  }
819
819
  //#endregion
820
820
  //#region src/core/stats.ts
821
- var V = { droppedFrames: 0 };
822
- function H(e) {
821
+ var We = { droppedFrames: 0 };
822
+ function Ge(e) {
823
823
  try {
824
824
  return new URL(e).host;
825
825
  } catch {
826
826
  return "";
827
827
  }
828
828
  }
829
- var Ge = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
830
- function Ke(e) {
829
+ var Ke = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
830
+ function qe(e) {
831
831
  if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
832
832
  let t = "", n = -1, r = performance.getEntriesByType("resource");
833
- for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Ge.test(i.name)) && i.startTime >= n) {
834
- let e = H(i.name);
833
+ for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Ke.test(i.name)) && i.startTime >= n) {
834
+ let e = Ge(i.name);
835
835
  e && (t = e, n = i.startTime);
836
836
  }
837
837
  return t;
838
838
  }
839
- function U(e) {
839
+ function H(e) {
840
840
  let t = e.getVideoPlaybackQuality?.();
841
841
  return {
842
842
  dropped: t?.droppedVideoFrames ?? 0,
843
843
  totalFrames: t?.totalVideoFrames ?? 0
844
844
  };
845
845
  }
846
- function qe(e, t) {
846
+ function Je(e, t) {
847
847
  let n = [
848
848
  ["playing", () => t("playing")],
849
849
  ["waiting", () => t("buffering")],
@@ -860,7 +860,8 @@ function qe(e, t) {
860
860
  }
861
861
  //#endregion
862
862
  //#region src/core/engine/native.ts
863
- function Je(e) {
863
+ var Ye = 2e3, Xe = 3, U = 500, Ze = 6e3, Qe = .25;
864
+ function $e(e) {
864
865
  try {
865
866
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
866
867
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -876,7 +877,7 @@ function G() {
876
877
  let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
877
878
  return e || t;
878
879
  }
879
- function Ye() {
880
+ function et() {
880
881
  if (typeof navigator > "u" || !G()) return !1;
881
882
  let e = navigator.userAgent ?? "";
882
883
  return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
@@ -890,6 +891,10 @@ var K = class {
890
891
  fairplayLicenseUrl;
891
892
  keySession = null;
892
893
  fairplayArmed = !1;
894
+ onVisibility = null;
895
+ onPageShow = null;
896
+ hiddenSince = null;
897
+ refocusTimer = null;
893
898
  fairplayKeyIV;
894
899
  loadStarted;
895
900
  preloadTouched = !1;
@@ -901,7 +906,7 @@ var K = class {
901
906
  }
902
907
  async load() {
903
908
  let { video: e, descriptor: t, emit: r } = this.deps;
904
- if (this.loadStarted || (this.preloadTouched = !0, this.savedPreload = e.getAttribute("preload"), e.preload = "none"), t.drmEnabled) {
909
+ if (this.watchRefocus(), this.loadStarted || (this.preloadTouched = !0, this.savedPreload = e.getAttribute("preload"), e.preload = "none"), t.drmEnabled) {
905
910
  if (!t.drm?.fairplay) {
906
911
  r({
907
912
  type: "error",
@@ -917,7 +922,7 @@ var K = class {
917
922
  type: "error",
918
923
  error: new n("INTERNAL", 0, "native HLS playback error"),
919
924
  fatal: !0
920
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Xe(t.manifestUrl, t.analytics?.sid), e.load();
925
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = tt(t.manifestUrl, t.analytics?.sid), e.load();
921
926
  }
922
927
  startLoad() {
923
928
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -939,7 +944,7 @@ var K = class {
939
944
  });
940
945
  this.onEncrypted = (n) => {
941
946
  let i = n;
942
- i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Je(i.initData), (async () => {
947
+ i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = $e(i.initData), (async () => {
943
948
  try {
944
949
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
945
950
  initDataTypes: [i.initDataType],
@@ -1034,11 +1039,11 @@ var K = class {
1034
1039
  e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
1035
1040
  }
1036
1041
  getStats() {
1037
- let e = this.deps.video, t = U(e), n = {
1042
+ let e = this.deps.video, t = H(e), n = {
1038
1043
  droppedFrames: t.dropped,
1039
1044
  decodedFrames: t.totalFrames
1040
1045
  };
1041
- if (this.cdnHost ||= Ke(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1046
+ if (this.cdnHost ||= qe(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
1042
1047
  if (n.isLive = !0, e.seekable.length > 0) {
1043
1048
  let t = e.seekable.end(e.seekable.length - 1);
1044
1049
  n.atLiveEdge = e.currentTime >= t - 2;
@@ -1053,7 +1058,52 @@ var K = class {
1053
1058
  this.deps.video.pause();
1054
1059
  } catch {}
1055
1060
  }
1061
+ watchRefocus() {
1062
+ this.deps.snapToLiveOnRefocus === !1 || typeof document > "u" || this.onVisibility || (this.onVisibility = () => {
1063
+ let e = typeof performance < "u" ? performance.now() : Date.now();
1064
+ if (document.visibilityState === "hidden") {
1065
+ this.hiddenSince = e, this.cancelRefocus();
1066
+ return;
1067
+ }
1068
+ let t = this.hiddenSince;
1069
+ this.hiddenSince = null, t != null && e - t >= Ye && this.armRefocus();
1070
+ }, this.onPageShow = (e) => {
1071
+ e.persisted && this.armRefocus();
1072
+ }, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
1073
+ }
1074
+ armRefocus() {
1075
+ if (this.cancelRefocus(), Number.isFinite(this.deps.video.duration)) return;
1076
+ let e = this.liveEnd(), t = () => typeof performance < "u" ? performance.now() : Date.now(), n = t(), r = 0, i = () => {
1077
+ if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
1078
+ r += U;
1079
+ let a = this.liveEnd(), o = a != null && (e == null || a >= e + Qe), s = Math.max(r, t() - n) >= Ze;
1080
+ if (o || s && a != null) {
1081
+ this.snapToLive();
1082
+ return;
1083
+ }
1084
+ this.refocusTimer = setTimeout(i, U);
1085
+ };
1086
+ this.refocusTimer = setTimeout(i, U);
1087
+ }
1088
+ cancelRefocus() {
1089
+ this.refocusTimer != null && clearTimeout(this.refocusTimer), this.refocusTimer = null;
1090
+ }
1091
+ liveEnd() {
1092
+ let e = this.deps.video;
1093
+ if (e.duration !== Infinity || e.seekable.length === 0) return null;
1094
+ let t = e.seekable.end(e.seekable.length - 1);
1095
+ return Number.isFinite(t) ? t : null;
1096
+ }
1097
+ snapToLive() {
1098
+ let e = this.deps.video, t = this.liveEnd();
1099
+ if (t == null) return;
1100
+ let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - Xe, r);
1101
+ try {
1102
+ e.currentTime = i;
1103
+ } catch {}
1104
+ }
1056
1105
  destroy() {
1106
+ this.cancelRefocus(), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onPageShow && typeof window < "u" && (window.removeEventListener("pageshow", this.onPageShow), this.onPageShow = null);
1057
1107
  let { video: e } = this.deps;
1058
1108
  this.onLoaded && e.removeEventListener("loadedmetadata", this.onLoaded), this.onError && e.removeEventListener("error", this.onError), this.onEncrypted && e.removeEventListener("encrypted", this.onEncrypted), this.keySession?.close().catch(() => {}), this.keySession = null, this.fairplayArmed = !1, this.fairplayKeyIV = void 0;
1059
1109
  try {
@@ -1065,13 +1115,13 @@ var K = class {
1065
1115
  } catch {}
1066
1116
  }
1067
1117
  };
1068
- function Xe(e, t) {
1118
+ function tt(e, t) {
1069
1119
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
1070
1120
  }
1071
1121
  //#endregion
1072
1122
  //#region src/core/engine/prefetch.ts
1073
- var Ze = 15e3, Qe = 5e3, $e = 6;
1074
- function et(e) {
1123
+ var nt = 15e3, rt = 5e3, it = 6;
1124
+ function at(e) {
1075
1125
  try {
1076
1126
  let t = new URL(e);
1077
1127
  return t.searchParams.delete("CMCD"), t.toString();
@@ -1079,7 +1129,7 @@ function et(e) {
1079
1129
  return e;
1080
1130
  }
1081
1131
  }
1082
- var tt = class {
1132
+ var ot = class {
1083
1133
  cmcd;
1084
1134
  entries = /* @__PURE__ */ new Map();
1085
1135
  keyed = /* @__PURE__ */ new Set();
@@ -1102,10 +1152,10 @@ var tt = class {
1102
1152
  }
1103
1153
  prefetch(e, t, n) {
1104
1154
  if (!this.isActive(t)) return;
1105
- let r = et(e);
1155
+ let r = at(e);
1106
1156
  if (this.entries.has(r)) return;
1107
1157
  let i = this.perTrack.get(t) ?? 0;
1108
- if (i >= $e) return;
1158
+ if (i >= it) return;
1109
1159
  this.perTrack.set(t, i + 1);
1110
1160
  let a = new AbortController(), o = {
1111
1161
  started: performance.now(),
@@ -1119,10 +1169,10 @@ var tt = class {
1119
1169
  signal: a.signal
1120
1170
  }).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
1121
1171
  this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
1122
- }, Ze);
1172
+ }, nt);
1123
1173
  }
1124
1174
  take(e) {
1125
- let t = et(e), n = this.entries.get(t);
1175
+ let t = at(e), n = this.entries.get(t);
1126
1176
  return n && this.entries.delete(t), n;
1127
1177
  }
1128
1178
  destroy() {
@@ -1142,13 +1192,13 @@ var tt = class {
1142
1192
  }
1143
1193
  }
1144
1194
  };
1145
- function nt(t) {
1195
+ function st(t) {
1146
1196
  let n = e.DefaultConfig?.loader;
1147
1197
  if (typeof n != "function") return;
1148
1198
  class r extends n {
1149
1199
  served = !1;
1150
1200
  cancelled = !1;
1151
- stats = rt();
1201
+ stats = ct();
1152
1202
  load(e, n, r) {
1153
1203
  let i = e.rangeEnd ? void 0 : t.take(e.url);
1154
1204
  if (!i) {
@@ -1156,7 +1206,7 @@ function nt(t) {
1156
1206
  return;
1157
1207
  }
1158
1208
  this.served = !0;
1159
- let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || Qe, s = setTimeout(() => {
1209
+ let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || rt, s = setTimeout(() => {
1160
1210
  !this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
1161
1211
  }, o);
1162
1212
  i.bytes.then((o) => {
@@ -1183,7 +1233,7 @@ function nt(t) {
1183
1233
  }
1184
1234
  return r;
1185
1235
  }
1186
- function rt() {
1236
+ function ct() {
1187
1237
  return {
1188
1238
  aborted: !1,
1189
1239
  loaded: 0,
@@ -1207,10 +1257,10 @@ function rt() {
1207
1257
  }
1208
1258
  };
1209
1259
  }
1210
- function it(e) {
1260
+ function lt(e) {
1211
1261
  return e === "audio" ? "audio" : "main";
1212
1262
  }
1213
- function at(e, t) {
1263
+ function ut(e, t) {
1214
1264
  let n = [];
1215
1265
  t.initSegment?.url && !t.initSegment.data && n.push({
1216
1266
  url: t.initSegment.url,
@@ -1229,24 +1279,24 @@ function at(e, t) {
1229
1279
  }
1230
1280
  //#endregion
1231
1281
  //#region src/core/engine/hls.ts
1232
- function ot() {
1282
+ function dt() {
1233
1283
  return e.isSupported();
1234
1284
  }
1235
- var st = 3, ct = 5, lt = 3, ut = 3e4, dt = 12e3, ft = 3e3, pt = 6e3, mt = .5, ht = 3, gt = .5, _t = 1.1, vt = .25, yt = 5e3, bt = 4e3, xt = 2, St = 5, Ct = 2, wt = 2, Tt = 4, Et = 4, Dt = 2e3, Ot = 3e4, kt = .2, At = 30, jt = 2, Mt = 2, Nt = 9, Pt = .5, Ft = 64;
1236
- function It(e) {
1285
+ var ft = 3, pt = 5, mt = 3, ht = 3e4, gt = 12e3, _t = 3e3, vt = 6e3, yt = .5, bt = 3, xt = .5, St = 1.1, Ct = .25, wt = 5e3, Tt = 4e3, Et = 2, Dt = 5, Ot = 2, kt = 2, At = 4, jt = 4, Mt = 2e3, Nt = 3e4, Pt = .2, Ft = 30, It = 2, Lt = 2, Rt = 9, zt = .5, Bt = 64;
1286
+ function Vt(e) {
1237
1287
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
1238
1288
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
1239
1289
  return;
1240
1290
  }
1241
- e.liveSyncDuration ??= Mt;
1242
- let t = Math.max(12, e.liveSyncDuration + Nt);
1243
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Lt(e, e.liveSyncDuration);
1291
+ e.liveSyncDuration ??= Lt;
1292
+ let t = Math.max(12, e.liveSyncDuration + Rt);
1293
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Ht(e, e.liveSyncDuration);
1244
1294
  }
1245
- function Lt(e, t) {
1295
+ function Ht(e, t) {
1246
1296
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
1247
1297
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
1248
1298
  }
1249
- var Rt = class {
1299
+ var Ut = class {
1250
1300
  name = "hls";
1251
1301
  hls = null;
1252
1302
  deps;
@@ -1336,7 +1386,7 @@ var Rt = class {
1336
1386
  });
1337
1387
  return;
1338
1388
  }
1339
- e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (ke(r), Ne()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1389
+ e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), je()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
1340
1390
  let e = this.hls;
1341
1391
  if (document.visibilityState !== "visible" || !e) return;
1342
1392
  let t = e.liveSyncPosition;
@@ -1359,7 +1409,7 @@ var Rt = class {
1359
1409
  }
1360
1410
  this.loadSuspended = !0;
1361
1411
  }
1362
- }, yt));
1412
+ }, wt));
1363
1413
  }
1364
1414
  resumeLoading() {
1365
1415
  if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
@@ -1391,7 +1441,7 @@ var Rt = class {
1391
1441
  let t = e.liveSyncPosition;
1392
1442
  if (typeof t != "number" || !Number.isFinite(t)) return;
1393
1443
  let { video: n } = this.deps;
1394
- n.currentTime <= t + Pt || (n.currentTime = t);
1444
+ n.currentTime <= t + zt || (n.currentTime = t);
1395
1445
  }
1396
1446
  startHls() {
1397
1447
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
@@ -1410,12 +1460,12 @@ var Rt = class {
1410
1460
  emeEnabled: !0,
1411
1461
  drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
1412
1462
  drmSystemOptions: {
1413
- videoRobustness: I.video,
1414
- audioRobustness: I.audio,
1415
- videoEncryptionScheme: I.scheme,
1416
- audioEncryptionScheme: I.scheme
1463
+ videoRobustness: F.video,
1464
+ audioRobustness: F.audio,
1465
+ videoEncryptionScheme: F.scheme,
1466
+ audioEncryptionScheme: F.scheme
1417
1467
  },
1418
- ...M() ? { requestMediaKeySystemAccessFunc: F(t) } : {},
1468
+ ...j() ? { requestMediaKeySystemAccessFunc: P(t) } : {},
1419
1469
  licenseXhrSetup: (e, t) => {
1420
1470
  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;
1421
1471
  let o = performance.now();
@@ -1432,20 +1482,20 @@ var Rt = class {
1432
1482
  ...c
1433
1483
  };
1434
1484
  if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !d.fLoader) {
1435
- let e = new tt({
1485
+ let e = new ot({
1436
1486
  sessionId: n.analytics?.sid,
1437
1487
  contentId: n.matchUrn
1438
- }), t = nt(e);
1488
+ }), t = st(e);
1439
1489
  t && (this.prefetch = e, d.fLoader = t);
1440
1490
  }
1441
- It(d), this.catchUpRate = typeof d.maxLiveSyncPlaybackRate == "number" ? d.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (d.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = d.autoStartLoad !== !1;
1491
+ Vt(d), this.catchUpRate = typeof d.maxLiveSyncPlaybackRate == "number" ? d.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (d.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = d.autoStartLoad !== !1;
1442
1492
  let f = new e(d);
1443
1493
  if (this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
1444
1494
  this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(f), this.measureLadder(f), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
1445
1495
  }), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
1446
1496
  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(() => {
1447
1497
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1448
- }, ut)));
1498
+ }, ht)));
1449
1499
  }), f.on(e.Events.FRAG_LOADING, (e, t) => {
1450
1500
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1451
1501
  }), f.on(e.Events.FRAG_LOADED, (e, t) => {
@@ -1453,10 +1503,10 @@ var Rt = class {
1453
1503
  let n = t?.frag?.stats, r = n?.loaded;
1454
1504
  typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
1455
1505
  let i = n?.loading;
1456
- i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Ft && this.requestTimesMs.shift());
1506
+ i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Bt && this.requestTimesMs.shift());
1457
1507
  let a = t?.frag?.url;
1458
1508
  if (a) {
1459
- let e = H(a);
1509
+ let e = Ge(a);
1460
1510
  e && (this.cdnHost = e);
1461
1511
  }
1462
1512
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1470,15 +1520,15 @@ var Rt = class {
1470
1520
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
1471
1521
  let t = this.prefetch;
1472
1522
  f.on(e.Events.KEY_LOADING, (e, n) => {
1473
- let r = n?.frag, i = it(r?.type);
1474
- if (r && t.isActive(i)) for (let e of at(f, r)) t.prefetch(e.url, i, e.kind);
1475
- }), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(it(n?.frag?.type)));
1523
+ let r = n?.frag, i = lt(r?.type);
1524
+ if (r && t.isActive(i)) for (let e of ut(f, r)) t.prefetch(e.url, i, e.kind);
1525
+ }), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(lt(n?.frag?.type)));
1476
1526
  }
1477
1527
  f.on(e.Events.KEY_LOADED, () => {
1478
1528
  u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
1479
1529
  }), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1480
1530
  this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
1481
- }, ft), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1531
+ }, _t), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1482
1532
  this.renditionSwitches += 1;
1483
1533
  let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
1484
1534
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
@@ -1542,7 +1592,7 @@ var Rt = class {
1542
1592
  return;
1543
1593
  }
1544
1594
  this.capTimer && clearTimeout(this.capTimer);
1545
- let t = e > this.sizeCapLevel ? Dt : Ot;
1595
+ let t = e > this.sizeCapLevel ? Mt : Nt;
1546
1596
  this.capTimer = setTimeout(() => {
1547
1597
  this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
1548
1598
  }, t);
@@ -1552,9 +1602,9 @@ var Rt = class {
1552
1602
  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;
1553
1603
  }
1554
1604
  dropLevelsWidevineCannotPlay(e) {
1555
- this.removeLevelsWhere(e, (e) => Pe(e) !== !0);
1556
- let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && L(e) !== "avc" && !!L(e)));
1557
- for (let n of t) Me(n).then((t) => {
1605
+ this.removeLevelsWhere(e, (e) => Me(e) !== !0);
1606
+ let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && I(e) !== "avc" && !!I(e)));
1607
+ for (let n of t) V(n).then((t) => {
1558
1608
  t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
1559
1609
  });
1560
1610
  }
@@ -1562,10 +1612,10 @@ var Rt = class {
1562
1612
  let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
1563
1613
  if (n.forEach((e, n) => {
1564
1614
  let a = e.videoCodec;
1565
- a && L(a) && t(a) && (r.push(n), i.add(a));
1615
+ a && I(a) && t(a) && (r.push(n), i.add(a));
1566
1616
  }), !r.length) return !1;
1567
1617
  let a = [...i].join(", ");
1568
- if (!n.some((e, t) => r.includes(t) ? !1 : !L(e.videoCodec) || Pe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
1618
+ if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) || Me(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
1569
1619
  for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
1570
1620
  return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
1571
1621
  }
@@ -1615,7 +1665,7 @@ var Rt = class {
1615
1665
  e.widevine && (this.licenseUrl = e.widevine);
1616
1666
  }
1617
1667
  getStats() {
1618
- let e = this.hls, t = U(this.deps.video), n = {
1668
+ let e = this.hls, t = H(this.deps.video), n = {
1619
1669
  droppedFrames: t.dropped,
1620
1670
  decodedFrames: t.totalFrames,
1621
1671
  lowLatency: this.detectedLowLatency,
@@ -1663,7 +1713,7 @@ var Rt = class {
1663
1713
  return;
1664
1714
  }
1665
1715
  let e = Date.now() - this.lastAdvanceMs;
1666
- !this.chaseSuspended && e > pt && this.suspendChasing(), e > dt && this.emitEnded("stalled");
1716
+ !this.chaseSuspended && e > vt && this.suspendChasing(), e > gt && this.emitEnded("stalled");
1667
1717
  }
1668
1718
  resetStarvationWindow() {
1669
1719
  this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
@@ -1678,7 +1728,7 @@ var Rt = class {
1678
1728
  this.resetStarvationWindow();
1679
1729
  return;
1680
1730
  }
1681
- let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < pt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > bt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = U(t), c = o - s, l = c !== this.starvedFrames;
1731
+ let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < vt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > Tt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = H(t), c = o - s, l = c !== this.starvedFrames;
1682
1732
  if (this.starvedFrames = c, !a || l) {
1683
1733
  (t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
1684
1734
  return;
@@ -1687,12 +1737,12 @@ var Rt = class {
1687
1737
  this.resetStarvationWindow();
1688
1738
  return;
1689
1739
  }
1690
- 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 > Tt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= Ct && (this.clearKick(), this.starvationRebuilds < wt)) {
1740
+ 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 > At && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= Ot && (this.clearKick(), this.starvationRebuilds < kt)) {
1691
1741
  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");
1692
1742
  return;
1693
1743
  }
1694
- let u = i && this.starvedTicks >= xt, d = !i && this.deadTicks >= Tt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= Et;
1695
- if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= St))) {
1744
+ let u = i && this.starvedTicks >= Et, d = !i && this.deadTicks >= At && this.recentMainFrags.reduce((e, t) => e + t, 0) >= jt;
1745
+ if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= Dt))) {
1696
1746
  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");
1697
1747
  try {
1698
1748
  e.stopLoad(), e.startLoad(-1);
@@ -1707,7 +1757,7 @@ var Rt = class {
1707
1757
  let t = e.latency, n = e.targetLatency;
1708
1758
  if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
1709
1759
  let r = t - n;
1710
- !this.catchUpEngaged && r > mt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= mt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
1760
+ !this.catchUpEngaged && r > yt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= yt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
1711
1761
  let i = this.catchUpEngaged ? this.catchUpRate : 1;
1712
1762
  e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
1713
1763
  }
@@ -1728,16 +1778,16 @@ var Rt = class {
1728
1778
  this.resetFrameDropWindow();
1729
1779
  return;
1730
1780
  }
1731
- let { totalFrames: n, dropped: r } = U(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
1732
- if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < At || o < 0) {
1781
+ let { totalFrames: n, dropped: r } = H(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
1782
+ if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Ft || o < 0) {
1733
1783
  this.fpsBadTicks = 0;
1734
1784
  return;
1735
1785
  }
1736
- if (o <= kt * a) {
1786
+ if (o <= Pt * a) {
1737
1787
  this.fpsBadTicks = 0;
1738
1788
  return;
1739
1789
  }
1740
- if (this.fpsBadTicks += 1, this.fpsBadTicks < jt) return;
1790
+ if (this.fpsBadTicks += 1, this.fpsBadTicks < It) return;
1741
1791
  this.fpsBadTicks = 0;
1742
1792
  let s = e.levels, c = s[e.currentLevel];
1743
1793
  if (!c) return;
@@ -1754,20 +1804,20 @@ var Rt = class {
1754
1804
  return;
1755
1805
  }
1756
1806
  let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
1757
- if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(_t, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
1807
+ if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(St, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
1758
1808
  this.resetChaseWindow();
1759
1809
  return;
1760
1810
  }
1761
- if (this.chaseLatency < 0 || this.chaseLatency - n >= gt) {
1811
+ if (this.chaseLatency < 0 || this.chaseLatency - n >= xt) {
1762
1812
  this.chaseLatency = n, this.chaseTicks = 0;
1763
1813
  return;
1764
1814
  }
1765
- if (this.chaseTicks += 1, this.chaseTicks < ht) return;
1815
+ if (this.chaseTicks += 1, this.chaseTicks < bt) return;
1766
1816
  this.resetChaseWindow();
1767
1817
  let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
1768
1818
  if (!(a > 1)) return;
1769
1819
  let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
1770
- s < o + vt || (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);
1820
+ s < o + Ct || (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);
1771
1821
  }
1772
1822
  suspendChasing() {
1773
1823
  let e = this.hls;
@@ -1812,7 +1862,7 @@ var Rt = class {
1812
1862
  scheduleLicenseRetry(t) {
1813
1863
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
1814
1864
  let n = t.response?.code ?? 0;
1815
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= lt) return !1;
1865
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= mt) return !1;
1816
1866
  this.licenseRecoveries += 1;
1817
1867
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
1818
1868
  return this.licenseRetryTimer = setTimeout(() => {
@@ -1844,7 +1894,7 @@ var Rt = class {
1844
1894
  return;
1845
1895
  }
1846
1896
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
1847
- if (this.networkRecoveries < ct) {
1897
+ if (this.networkRecoveries < pt) {
1848
1898
  this.networkRecoveries += 1;
1849
1899
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
1850
1900
  this.networkRetryTimer = setTimeout(() => {
@@ -1861,7 +1911,7 @@ var Rt = class {
1861
1911
  return;
1862
1912
  }
1863
1913
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
1864
- if (this.mediaRecoveries < st) {
1914
+ if (this.mediaRecoveries < ft) {
1865
1915
  this.mediaRecoveries += 1, n.recoverMediaError();
1866
1916
  return;
1867
1917
  }
@@ -1885,19 +1935,19 @@ var Rt = class {
1885
1935
  let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
1886
1936
  return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
1887
1937
  }
1888
- }, zt = 15e3, Bt = 6e5, Vt = 3e5, Ht = 100, q = 1, Ut = 1e3, Wt = 3e4, Gt = 1e3, Kt = {
1938
+ }, Wt = 15e3, Gt = 6e5, Kt = 3e5, qt = 100, q = 1, Jt = 1e3, Yt = 3e4, Xt = 1e3, Zt = {
1889
1939
  inline: "PRESENTATION_INLINE",
1890
1940
  fullscreen: "PRESENTATION_FULLSCREEN",
1891
1941
  pip: "PRESENTATION_PIP"
1892
- }, qt = {
1942
+ }, Qt = {
1893
1943
  widevine: "KEY_SYSTEM_WIDEVINE",
1894
1944
  fairplay: "KEY_SYSTEM_FAIRPLAY",
1895
1945
  none: "KEY_SYSTEM_NONE"
1896
1946
  };
1897
- function Jt(e, t) {
1947
+ function $t(e, t) {
1898
1948
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1899
1949
  }
1900
- var Yt = /* @__PURE__ */ new Set([
1950
+ var en = /* @__PURE__ */ new Set([
1901
1951
  "INVALID_URN",
1902
1952
  "NOT_FOUND",
1903
1953
  "GONE",
@@ -1917,7 +1967,7 @@ var Yt = /* @__PURE__ */ new Set([
1917
1967
  ended: "PLAYER_STATE_ENDED",
1918
1968
  error: "PLAYER_STATE_ERROR"
1919
1969
  };
1920
- function Xt(e) {
1970
+ function tn(e) {
1921
1971
  try {
1922
1972
  let t = new URL(e), [n, ...r] = t.hostname.split(".");
1923
1973
  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);
@@ -1925,8 +1975,8 @@ function Xt(e) {
1925
1975
  return;
1926
1976
  }
1927
1977
  }
1928
- var Zt = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), Qt = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), $t = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
1929
- function en(e) {
1978
+ var nn = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), rn = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), an = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
1979
+ function on(e) {
1930
1980
  if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
1931
1981
  let t;
1932
1982
  try {
@@ -1935,19 +1985,19 @@ function en(e) {
1935
1985
  } catch {
1936
1986
  return;
1937
1987
  }
1938
- if (Qt.has(t) && !Y.has(t)) {
1939
- Y.add(t), g($t(new URL(t).origin));
1988
+ if (rn.has(t) && !Y.has(t)) {
1989
+ Y.add(t), g(an(new URL(t).origin));
1940
1990
  for (let e of X) e.noteCspBlocked();
1941
1991
  }
1942
1992
  }
1943
- function tn(e, t) {
1993
+ function sn(e, t) {
1944
1994
  return g(t, e), { disabledReason: t };
1945
1995
  }
1946
- function nn(e, t, n) {
1947
- if (n) return t && !Zt(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
1996
+ function cn(e, t, n) {
1997
+ if (n) return t && !nn(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
1948
1998
  if (t) return { endpoint: t };
1949
- if (t !== void 0) return tn("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).");
1950
- let r = Xt(e);
1999
+ if (t !== void 0) return sn("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).");
2000
+ let r = tn(e);
1951
2001
  if (r) return { endpoint: r };
1952
2002
  let i;
1953
2003
  try {
@@ -1955,9 +2005,9 @@ function nn(e, t, n) {
1955
2005
  } catch {
1956
2006
  i = e;
1957
2007
  }
1958
- return tn(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).`);
2008
+ return sn(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).`);
1959
2009
  }
1960
- var rn = class {
2010
+ var ln = class {
1961
2011
  opts;
1962
2012
  url;
1963
2013
  cspKey;
@@ -2039,8 +2089,8 @@ var rn = class {
2039
2089
  constructor(e) {
2040
2090
  this.opts = {
2041
2091
  ...e,
2042
- heartbeatMs: e.heartbeatMs ?? zt,
2043
- idleMs: e.idleMs ?? Bt
2092
+ heartbeatMs: e.heartbeatMs ?? Wt,
2093
+ idleMs: e.idleMs ?? Gt
2044
2094
  }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
2045
2095
  try {
2046
2096
  let e = new URL(this.url);
@@ -2057,11 +2107,11 @@ var rn = class {
2057
2107
  sdkVersion: this.opts.sdkVersion,
2058
2108
  ...this.opts.environment
2059
2109
  };
2060
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Ut), 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 && Qt.add(this.cspKey), document.addEventListener("securitypolicyviolation", en), X.add(this), this.noteCspBlocked(), this.onVisibility());
2110
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Jt), 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 && rn.add(this.cspKey), document.addEventListener("securitypolicyviolation", on), X.add(this), this.noteCspBlocked(), this.onVisibility());
2061
2111
  }
2062
2112
  checkSuspension(e) {
2063
2113
  if (this.endedFlag || !this.opts.idleMs) return !1;
2064
- let t = Math.max(this.opts.idleMs, Vt);
2114
+ let t = Math.max(this.opts.idleMs, Kt);
2065
2115
  return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
2066
2116
  }
2067
2117
  syncIdle(e) {
@@ -2084,12 +2134,12 @@ var rn = class {
2084
2134
  let a = {
2085
2135
  fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
2086
2136
  toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
2087
- presentation: Kt[this.presentation]
2137
+ presentation: Zt[this.presentation]
2088
2138
  }, o = this.causeOf(e, t, i);
2089
2139
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
2090
2140
  }
2091
2141
  seekInduced(e) {
2092
- return this.lastSeekMs >= 0 && e - this.lastSeekMs < Gt;
2142
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < Xt;
2093
2143
  }
2094
2144
  causeOf(e, t, n) {
2095
2145
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
@@ -2163,7 +2213,7 @@ var rn = class {
2163
2213
  let r = n ?? "";
2164
2214
  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";
2165
2215
  if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
2166
- if (Yt.has(e)) return "ERROR_STAGE_RESOLVE";
2216
+ if (en.has(e)) return "ERROR_STAGE_RESOLVE";
2167
2217
  let i = t ?? "";
2168
2218
  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";
2169
2219
  }
@@ -2210,14 +2260,14 @@ var rn = class {
2210
2260
  if (this.lastRequestCount = g, _ > 0) {
2211
2261
  o.requestCountDelta = _;
2212
2262
  let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
2213
- n.length > 0 && (o.requestTimeP50Ms = Jt(n, 50), o.requestTimeP95Ms = Jt(n, 95));
2263
+ n.length > 0 && (o.requestTimeP50Ms = $t(n, 50), o.requestTimeP95Ms = $t(n, 95));
2214
2264
  }
2215
2265
  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();
2216
2266
  }
2217
2267
  maybeEmitMediaInfo(e) {
2218
2268
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
2219
2269
  let t = {};
2220
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = qt[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);
2270
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Qt[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);
2221
2271
  let n = JSON.stringify(t);
2222
2272
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
2223
2273
  }
@@ -2237,7 +2287,7 @@ var rn = class {
2237
2287
  let c = r?.positionMs ?? 0;
2238
2288
  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));
2239
2289
  let l = e !== "END_REASON_ENDED";
2240
- l && this.lastStallMs > 0 && n - this.lastStallMs <= Wt && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Wt && (i.abandonAfterErrorMs = Math.max(q, 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);
2290
+ l && this.lastStallMs > 0 && n - this.lastStallMs <= Yt && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Yt && (i.abandonAfterErrorMs = Math.max(q, 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);
2241
2291
  let u = r?.decodedFrames ?? this.lastDecoded;
2242
2292
  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");
2243
2293
  }
@@ -2257,13 +2307,13 @@ var rn = class {
2257
2307
  };
2258
2308
  }
2259
2309
  noteCspBlocked() {
2260
- this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.($t(new URL(this.url).origin)));
2310
+ this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(an(new URL(this.url).origin)));
2261
2311
  }
2262
2312
  cspBlocked() {
2263
2313
  return !!this.cspKey && Y.has(this.cspKey);
2264
2314
  }
2265
2315
  enqueue(e) {
2266
- if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > Ht;) {
2316
+ if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > qt;) {
2267
2317
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
2268
2318
  this.pending.splice(e >= 0 ? e : 0, 1);
2269
2319
  }
@@ -2290,7 +2340,7 @@ var rn = class {
2290
2340
  };
2291
2341
  //#endregion
2292
2342
  //#region src/core/environment.ts
2293
- function an() {
2343
+ function un() {
2294
2344
  if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
2295
2345
  let e;
2296
2346
  try {
@@ -2315,14 +2365,14 @@ function an() {
2315
2365
  integration: "INTEGRATION_KIND_IFRAME"
2316
2366
  };
2317
2367
  }
2318
- function on() {
2368
+ function dn() {
2319
2369
  if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
2320
2370
  let e = navigator.userAgentData, t = e?.platform ?? "";
2321
2371
  if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
2322
2372
  let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
2323
2373
  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";
2324
2374
  }
2325
- function sn() {
2375
+ function fn() {
2326
2376
  let e = typeof navigator < "u" ? navigator.connection : void 0;
2327
2377
  if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
2328
2378
  let t = {
@@ -2341,17 +2391,17 @@ function sn() {
2341
2391
  }
2342
2392
  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;
2343
2393
  }
2344
- function cn(e) {
2345
- let t = an(), n = {
2346
- deviceClass: on(),
2394
+ function pn(e) {
2395
+ let t = un(), n = {
2396
+ deviceClass: dn(),
2347
2397
  integration: t.integration,
2348
- ...sn()
2398
+ ...fn()
2349
2399
  };
2350
2400
  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);
2351
2401
  let r = e.getBoundingClientRect?.();
2352
2402
  return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
2353
2403
  }
2354
- async function ln() {
2404
+ async function mn() {
2355
2405
  let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
2356
2406
  if (!e?.getHighEntropyValues) return {};
2357
2407
  try {
@@ -2363,7 +2413,7 @@ async function ln() {
2363
2413
  }
2364
2414
  //#endregion
2365
2415
  //#region src/core/version.ts
2366
- var un = "2.16.0", dn = {
2416
+ var hn = "2.16.2", gn = {
2367
2417
  accent: "#E1B600",
2368
2418
  accentText: "#1B1C23",
2369
2419
  background: "#0e0f13",
@@ -2374,7 +2424,7 @@ var un = "2.16.0", dn = {
2374
2424
  border: "rgba(255, 255, 255, 0.1)",
2375
2425
  radius: "8px",
2376
2426
  fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
2377
- }, fn = {
2427
+ }, _n = {
2378
2428
  accent: "--havik-accent",
2379
2429
  accentText: "--havik-accent-text",
2380
2430
  background: "--havik-bg",
@@ -2386,26 +2436,26 @@ var un = "2.16.0", dn = {
2386
2436
  radius: "--havik-radius",
2387
2437
  fontFamily: "--havik-font"
2388
2438
  };
2389
- function pn(e, t) {
2439
+ function vn(e, t) {
2390
2440
  let n = {
2391
- ...dn,
2441
+ ...gn,
2392
2442
  ...t
2393
2443
  };
2394
- for (let t of Object.keys(fn)) e.style.setProperty(fn[t], n[t]);
2444
+ for (let t of Object.keys(_n)) e.style.setProperty(_n[t], n[t]);
2395
2445
  n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
2396
2446
  }
2397
2447
  //#endregion
2398
2448
  //#region src/ui/styles.ts
2399
- var mn = "havik-player-styles", hn = "\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", Z = /* @__PURE__ */ new WeakMap();
2400
- function gn(e = document, t) {
2401
- let n = e.querySelector(`style#${mn}`);
2402
- if (n && (!t || Z.get(n) === t)) return;
2449
+ var yn = "havik-player-styles", bn = "\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", xn = /* @__PURE__ */ new WeakMap();
2450
+ function Sn(e = document, t) {
2451
+ let n = e.querySelector(`style#${yn}`);
2452
+ if (n && (!t || xn.get(n) === t)) return;
2403
2453
  let r = e.createElement("style");
2404
- r.id = mn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = hn, Z.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2454
+ r.id = yn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = bn, xn.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
2405
2455
  }
2406
2456
  //#endregion
2407
2457
  //#region src/ui/icons.ts
2408
- var _n = {
2458
+ var Cn = {
2409
2459
  play: "<path d=\"M8 5v14l11-7z\"/>",
2410
2460
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
2411
2461
  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\"/>",
@@ -2418,21 +2468,21 @@ var _n = {
2418
2468
  liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
2419
2469
  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\"/>"
2420
2470
  };
2421
- function Q(e) {
2422
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${_n[e]}</svg>`;
2471
+ function Z(e) {
2472
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Cn[e]}</svg>`;
2423
2473
  }
2424
2474
  //#endregion
2425
2475
  //#region src/ui/controls.ts
2426
- var vn = 3e3, yn = 250, bn = /* @__PURE__ */ new Set([
2476
+ var wn = 3e3, Tn = 250, En = /* @__PURE__ */ new Set([
2427
2477
  "GONE",
2428
2478
  "NOT_FOUND",
2429
2479
  "INVALID_URN",
2430
2480
  "UNAUTHORIZED"
2431
2481
  ]);
2432
- function xn(e) {
2433
- return new Sn(e);
2482
+ function Dn(e) {
2483
+ return new On(e);
2434
2484
  }
2435
- var Sn = class {
2485
+ var On = class {
2436
2486
  root;
2437
2487
  video;
2438
2488
  player;
@@ -2478,7 +2528,7 @@ var Sn = class {
2478
2528
  scrubbing = !1;
2479
2529
  offFns = [];
2480
2530
  constructor(e) {
2481
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? vn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, gn(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");
2531
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? wn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Sn(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");
2482
2532
  let t = (e, t, n) => {
2483
2533
  let r = this.doc.createElement(e);
2484
2534
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -2489,12 +2539,12 @@ var Sn = class {
2489
2539
  "aria-label": r,
2490
2540
  title: r
2491
2541
  });
2492
- return i.innerHTML = Q(n), i;
2542
+ return i.innerHTML = Z(n), i;
2493
2543
  };
2494
2544
  this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
2495
2545
  type: "button",
2496
2546
  "aria-label": "Play"
2497
- }), 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", {
2547
+ }), this.center.innerHTML = Z("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", {
2498
2548
  role: "slider",
2499
2549
  "aria-label": "Seek",
2500
2550
  "aria-valuemin": "0",
@@ -2512,7 +2562,7 @@ var Sn = class {
2512
2562
  "aria-label": "Volume"
2513
2563
  });
2514
2564
  let a = t("div", "havik-vol");
2515
- a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
2565
+ a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Z("liveDot");
2516
2566
  let o = this.doc.createElement("span");
2517
2567
  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";
2518
2568
  let s = t("div", "havik-spacer");
@@ -2564,7 +2614,7 @@ var Sn = class {
2564
2614
  let t = this.surfaceWasHidden;
2565
2615
  this.tapTimer = setTimeout(() => {
2566
2616
  this.tapTimer = void 0, this.toggleBar(t);
2567
- }, yn);
2617
+ }, Tn);
2568
2618
  }
2569
2619
  toggleBar(e) {
2570
2620
  e ? this.poke() : this.hideIfIdle();
@@ -2596,12 +2646,12 @@ var Sn = class {
2596
2646
  }
2597
2647
  if (e === "preplay") {
2598
2648
  let e = this.doc.createElement("button");
2599
- 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);
2649
+ e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Z("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
2600
2650
  } else {
2601
2651
  let r = this.doc.createElement("div");
2602
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !bn.has(this.lastError.code)) {
2652
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !En.has(this.lastError.code)) {
2603
2653
  let e = this.doc.createElement("button");
2604
- 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);
2654
+ e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Z("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
2605
2655
  }
2606
2656
  }
2607
2657
  this.root.append(n), this.statusBox = n, this.show();
@@ -2640,7 +2690,7 @@ var Sn = class {
2640
2690
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
2641
2691
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
2642
2692
  }
2643
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Cn(this.video.currentTime)} / ${Cn(this.video.duration)}`);
2693
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${kn(this.video.currentTime)} / ${kn(this.video.duration)}`);
2644
2694
  }
2645
2695
  syncLive() {
2646
2696
  let e = this.player.getStats(), t = e.isLive !== !1;
@@ -2690,17 +2740,17 @@ var Sn = class {
2690
2740
  renderQualityMenu() {
2691
2741
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
2692
2742
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
2693
- for (let n of e) this.menu.append(this.menuItem(wn(n), t === n.index, () => this.player.setQuality(n.index)));
2743
+ for (let n of e) this.menu.append(this.menuItem(An(n), t === n.index, () => this.player.setQuality(n.index)));
2694
2744
  }
2695
2745
  renderAudioMenu() {
2696
2746
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
2697
2747
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
2698
- for (let t of e) this.menu.append(this.menuItem(Tn(t), t.default, () => this.player.setAudioTrack(t.id)));
2748
+ for (let t of e) this.menu.append(this.menuItem(jn(t), t.default, () => this.player.setAudioTrack(t.id)));
2699
2749
  }
2700
2750
  renderCcMenu() {
2701
2751
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
2702
2752
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
2703
- for (let t of e) this.menu.append(this.menuItem(En(t), !1, () => this.player.setTextTrack(t.id)));
2753
+ for (let t of e) this.menu.append(this.menuItem(Mn(t), !1, () => this.player.setTextTrack(t.id)));
2704
2754
  }
2705
2755
  onTracksChanged() {
2706
2756
  this.openMenu && this.renderMenu(this.openMenu);
@@ -2720,11 +2770,11 @@ var Sn = class {
2720
2770
  }
2721
2771
  async toggleFullscreen() {
2722
2772
  try {
2723
- C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
2773
+ S(this.video, this.root) ? await w(this.video, this.root) : await C(this.video, this.root);
2724
2774
  } catch {}
2725
2775
  }
2726
2776
  syncFullscreen() {
2727
- let e = C(this.video, this.root);
2777
+ let e = S(this.video, this.root);
2728
2778
  this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
2729
2779
  }
2730
2780
  poke() {
@@ -2784,7 +2834,7 @@ var Sn = class {
2784
2834
  }
2785
2835
  }
2786
2836
  setIcon(e, t) {
2787
- e.innerHTML = Q(t);
2837
+ e.innerHTML = Z(t);
2788
2838
  }
2789
2839
  destroy() {
2790
2840
  this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
@@ -2801,41 +2851,41 @@ var Sn = class {
2801
2851
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
2802
2852
  }
2803
2853
  };
2804
- function Cn(e) {
2854
+ function kn(e) {
2805
2855
  (!Number.isFinite(e) || e < 0) && (e = 0);
2806
2856
  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");
2807
2857
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
2808
2858
  }
2809
- function wn(e) {
2859
+ function An(e) {
2810
2860
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
2811
2861
  }
2812
- function Tn(e) {
2862
+ function jn(e) {
2813
2863
  return e.name || e.lang || `Track ${e.id}`;
2814
2864
  }
2815
- function En(e) {
2865
+ function Mn(e) {
2816
2866
  return e.name || e.lang || `Track ${e.id}`;
2817
2867
  }
2818
2868
  //#endregion
2819
2869
  //#region src/managed/index.ts
2820
- var Dn = 6e3, On = 45e3, kn = 2e3, An = 3, jn = 2e3, Mn = 48e4;
2821
- function Nn(e) {
2870
+ var Nn = 6e3, Pn = 45e3, Q = 2e3, Fn = 3, In = 2e3, Ln = 48e4;
2871
+ function Rn(e) {
2822
2872
  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)})`);
2823
- if (e.env !== void 0) return B(e.env);
2873
+ if (e.env !== void 0) return Ue(e.env);
2824
2874
  if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
2825
2875
  return e.baseUrl;
2826
2876
  }
2827
- async function Pn(e) {
2877
+ async function zn(e) {
2828
2878
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
2829
- let t = Nn(e);
2879
+ let t = Rn(e);
2830
2880
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
2831
2881
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
2832
- let r = new Fn({
2882
+ let r = new Bn({
2833
2883
  ...e,
2834
2884
  baseUrl: t
2835
2885
  });
2836
2886
  return await r.start(), r;
2837
2887
  }
2838
- var Fn = class {
2888
+ var Bn = class {
2839
2889
  opts;
2840
2890
  abort = new AbortController();
2841
2891
  listeners = {};
@@ -2902,7 +2952,7 @@ var Fn = class {
2902
2952
  };
2903
2953
  }
2904
2954
  beginArming(e, t, n = !1) {
2905
- let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
2955
+ let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
2906
2956
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
2907
2957
  }
2908
2958
  beginArmingByPolling(e) {
@@ -2923,7 +2973,7 @@ var Fn = class {
2923
2973
  setTimeout(() => {
2924
2974
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
2925
2975
  phase: i ? "unavailable" : "tooEarly",
2926
- retryInMs: On,
2976
+ retryInMs: Pn,
2927
2977
  attempt: 1,
2928
2978
  elapsedMs: 0,
2929
2979
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -2962,13 +3012,13 @@ var Fn = class {
2962
3012
  !a && !p() && h();
2963
3013
  }, e);
2964
3014
  };
2965
- _(Dn), this.armingSub = E({
3015
+ _(Nn), this.armingSub = T({
2966
3016
  eventsBaseUrl: t,
2967
3017
  matchUrn: this.opts.matchUrn,
2968
3018
  credential: this.opts.credential,
2969
- onAlive: () => _(On),
3019
+ onAlive: () => _(Pn),
2970
3020
  onState: (e) => {
2971
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * kn);
3021
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Q);
2972
3022
  },
2973
3023
  onError: () => h()
2974
3024
  });
@@ -2991,7 +3041,7 @@ var Fn = class {
2991
3041
  let n = await s(this.opts.credential);
2992
3042
  if (this.destroyed || t !== this.loadGen) return;
2993
3043
  this.setState("loading");
2994
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = qe(this.opts.video, (e) => {
3044
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Je(this.opts.video, (e) => {
2995
3045
  this._state !== "ended" && this._state !== "error" && this.setState(e);
2996
3046
  });
2997
3047
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -3013,26 +3063,26 @@ var Fn = class {
3013
3063
  if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
3014
3064
  let i = e.analytics?.sid;
3015
3065
  if (!i) return;
3016
- let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = nn(this.opts.baseUrl, a, e.analytics?.endpoint);
3066
+ let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = cn(this.opts.baseUrl, a, e.analytics?.endpoint);
3017
3067
  if (!o) {
3018
3068
  s && setTimeout(() => {
3019
3069
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
3020
3070
  }, 0);
3021
3071
  return;
3022
3072
  }
3023
- let c = this.opts.video, l = new rn({
3073
+ let c = this.opts.video, l = new ln({
3024
3074
  endpoint: o,
3025
3075
  sid: i,
3026
3076
  player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
3027
- sdkVersion: un,
3028
- environment: cn(c),
3077
+ sdkVersion: hn,
3078
+ environment: pn(c),
3029
3079
  idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
3030
3080
  onIdle: () => this.onAnalyticsIdle(t),
3031
3081
  onBlocked: (e) => setTimeout(() => {
3032
3082
  this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
3033
3083
  }, 0),
3034
3084
  sample: () => {
3035
- let e = this.engine?.getStats() ?? V, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3085
+ let e = this.engine?.getStats() ?? We, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
3036
3086
  return {
3037
3087
  ...e,
3038
3088
  bufferedMs: Math.round(t * 1e3),
@@ -3046,7 +3096,7 @@ var Fn = class {
3046
3096
  let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
3047
3097
  c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
3048
3098
  c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
3049
- }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), ln().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3099
+ }, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), mn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
3050
3100
  }
3051
3101
  currentPresentation() {
3052
3102
  let e = this.opts.video;
@@ -3061,7 +3111,7 @@ var Fn = class {
3061
3111
  video: this.opts.video,
3062
3112
  descriptor: e,
3063
3113
  credential: t,
3064
- deviceId: A(),
3114
+ deviceId: k(),
3065
3115
  userId: this.opts.userId,
3066
3116
  lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
3067
3117
  snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
@@ -3072,9 +3122,9 @@ var Fn = class {
3072
3122
  emit: (e) => this.onEngineEvent(e)
3073
3123
  }, o = this.opts.engine ?? "auto";
3074
3124
  if (o === "native") return new K(a);
3075
- if (o === "hls") return new Rt(a);
3076
- if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled && Ye() && W(this.opts.video)) return new K(a);
3077
- if (ot()) return new Rt(a);
3125
+ if (o === "hls") return new Ut(a);
3126
+ if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled && et() && W(this.opts.video)) return new K(a);
3127
+ if (dt()) return new Ut(a);
3078
3128
  if (W(this.opts.video)) return new K(a);
3079
3129
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
3080
3130
  }
@@ -3112,11 +3162,11 @@ var Fn = class {
3112
3162
  }
3113
3163
  startLiveState(e) {
3114
3164
  if (this.opts.liveStateEvents === !1) return;
3115
- let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
3165
+ let t = this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
3116
3166
  if (!t) return;
3117
3167
  this.closeLiveState();
3118
3168
  let r = 0, i = !1;
3119
- this.liveStateSub = E({
3169
+ this.liveStateSub = T({
3120
3170
  eventsBaseUrl: t,
3121
3171
  matchUrn: this.opts.matchUrn,
3122
3172
  credential: this.opts.credential,
@@ -3127,7 +3177,7 @@ var Fn = class {
3127
3177
  r = 0, i = !1;
3128
3178
  },
3129
3179
  onError: () => {
3130
- this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= An && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} 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.`))));
3180
+ this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Fn && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} 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.`))));
3131
3181
  }
3132
3182
  });
3133
3183
  }
@@ -3149,7 +3199,7 @@ var Fn = class {
3149
3199
  scheduleRejoin(e) {
3150
3200
  this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
3151
3201
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
3152
- }, Math.random() * kn));
3202
+ }, Math.random() * Q));
3153
3203
  }
3154
3204
  cancelRejoin() {
3155
3205
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -3173,7 +3223,7 @@ var Fn = class {
3173
3223
  }
3174
3224
  t.controls = !1;
3175
3225
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
3176
- r && r.insertBefore(n, t), n.appendChild(t), pn(n, this.opts.theme), this.container = n, this.controlBar = xn({
3226
+ r && r.insertBefore(n, t), n.appendChild(t), vn(n, this.opts.theme), this.container = n, this.controlBar = Dn({
3177
3227
  root: n,
3178
3228
  video: t,
3179
3229
  player: this,
@@ -3204,7 +3254,7 @@ var Fn = class {
3204
3254
  }
3205
3255
  startStats() {
3206
3256
  this.stopStats();
3207
- let e = Math.max(500, this.opts.statsIntervalMs ?? jn);
3257
+ let e = Math.max(500, this.opts.statsIntervalMs ?? In);
3208
3258
  this.statsTimer = setInterval(() => {
3209
3259
  if (!this.engine) return;
3210
3260
  let e = this.engine.getStats();
@@ -3216,7 +3266,7 @@ var Fn = class {
3216
3266
  }
3217
3267
  scheduleLicenseRefresh() {
3218
3268
  this.stopRefresh();
3219
- let e = this.opts.licenseRefreshMs ?? Mn;
3269
+ let e = this.opts.licenseRefreshMs ?? Ln;
3220
3270
  e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
3221
3271
  }
3222
3272
  stopRefresh() {
@@ -3261,7 +3311,7 @@ var Fn = class {
3261
3311
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
3262
3312
  }
3263
3313
  getStats() {
3264
- return this.engine?.getStats() ?? V;
3314
+ return this.engine?.getStats() ?? We;
3265
3315
  }
3266
3316
  getQualityLevels() {
3267
3317
  return this.engine?.getQualityLevels() ?? [];
@@ -3300,10 +3350,10 @@ var Fn = class {
3300
3350
  e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
3301
3351
  }
3302
3352
  async enterFullscreen() {
3303
- return !this.destroyed && w(this.opts.video, this.container ?? void 0);
3353
+ return !this.destroyed && C(this.opts.video, this.container ?? void 0);
3304
3354
  }
3305
3355
  async exitFullscreen() {
3306
- await T(this.opts.video, this.container ?? void 0);
3356
+ await w(this.opts.video, this.container ?? void 0);
3307
3357
  }
3308
3358
  retry() {
3309
3359
  return this.reload();
@@ -3371,7 +3421,7 @@ function $(e) {
3371
3421
  }
3372
3422
  //#endregion
3373
3423
  //#region src/embed/host.ts
3374
- function In(e) {
3424
+ function Vn(e) {
3375
3425
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
3376
3426
  if (!e.src) throw Error("mountEmbed: opts.src is required");
3377
3427
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -3430,15 +3480,15 @@ function In(e) {
3430
3480
  }
3431
3481
  //#endregion
3432
3482
  //#region src/embed/page.ts
3433
- var Ln = /^[A-Za-z0-9:_.-]{1,128}$/;
3434
- function Rn(e) {
3483
+ var Hn = /^[A-Za-z0-9:_.-]{1,128}$/;
3484
+ function Un(e) {
3435
3485
  if (typeof e == "boolean") return e;
3436
3486
  if (typeof e == "object" && e) {
3437
3487
  let t = e.endpoint;
3438
3488
  return typeof t == "string" ? { endpoint: t } : {};
3439
3489
  }
3440
3490
  }
3441
- function zn() {
3491
+ function Wn() {
3442
3492
  let e = window.HAVIK_EMBED_CONFIG;
3443
3493
  if (e) return {
3444
3494
  baseUrl: e.baseUrl ?? "",
@@ -3448,7 +3498,7 @@ function zn() {
3448
3498
  autoplay: e.autoplay ?? !0,
3449
3499
  muted: e.muted ?? !0,
3450
3500
  waitForLive: e.waitForLive ?? !0,
3451
- analytics: Rn(e.analytics)
3501
+ analytics: Un(e.analytics)
3452
3502
  };
3453
3503
  let t = new URLSearchParams(location.search);
3454
3504
  return {
@@ -3461,9 +3511,9 @@ function zn() {
3461
3511
  waitForLive: !0
3462
3512
  };
3463
3513
  }
3464
- async function Bn() {
3465
- let e = zn();
3466
- Hn();
3514
+ async function Gn() {
3515
+ let e = Wn();
3516
+ qn();
3467
3517
  let t = document.createElement("video");
3468
3518
  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);
3469
3519
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -3518,12 +3568,12 @@ async function Bn() {
3518
3568
  code: e.code,
3519
3569
  message: e.message
3520
3570
  })), e.on("autoplayblocked", () => {
3521
- i({ type: "oddin:autoplayblocked" }), Vn(t, e);
3571
+ i({ type: "oddin:autoplayblocked" }), Kn(t, e);
3522
3572
  });
3523
3573
  }, s = async (r) => {
3524
3574
  a?.destroy(), a = null;
3525
3575
  try {
3526
- let n = await Pn({
3576
+ let n = await zn({
3527
3577
  video: t,
3528
3578
  baseUrl: e.baseUrl,
3529
3579
  matchUrn: r,
@@ -3585,7 +3635,7 @@ async function Bn() {
3585
3635
  a?.retry();
3586
3636
  break;
3587
3637
  case "oddin:load":
3588
- typeof e.matchUrn == "string" && Ln.test(e.matchUrn) && s(e.matchUrn);
3638
+ typeof e.matchUrn == "string" && Hn.test(e.matchUrn) && s(e.matchUrn);
3589
3639
  break;
3590
3640
  case "oddin:destroy": c();
3591
3641
  }
@@ -3597,18 +3647,18 @@ async function Bn() {
3597
3647
  protocol: 1
3598
3648
  });
3599
3649
  }
3600
- function Vn(e, t) {
3650
+ function Kn(e, t) {
3601
3651
  if (document.getElementById("havik-tap")) return;
3602
3652
  let n = document.createElement("button");
3603
3653
  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", () => {
3604
3654
  n.remove(), t.play();
3605
3655
  }), document.body.appendChild(n);
3606
3656
  }
3607
- function Hn() {
3657
+ function qn() {
3608
3658
  let e = document.createElement("style");
3609
3659
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
3610
3660
  }
3611
3661
  //#endregion
3612
- export { dn as ODDIN_THEME, n as PlaybackError, pn as applyTheme, B as baseUrlForEnv, Bn as bootEmbed, we as clearDeviceId, Pn as createPlayer, D as deriveEventsBaseUrl, Ve as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ge as fetchCatalog, ve as fetchTournament, be as flattenMatches, A as getDeviceId, Ue as isLowLatencyManifest, $ as isOddinMessage, Ee as licenseRequestHeaders, In as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, Se as watchStatus };
3662
+ export { gn as ODDIN_THEME, n as PlaybackError, vn as applyTheme, Ue as baseUrlForEnv, Gn as bootEmbed, Te as clearDeviceId, zn as createPlayer, E as deriveEventsBaseUrl, ze as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, _e as fetchCatalog, ye as fetchTournament, xe as flattenMatches, k as getDeviceId, Ve as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, Vn as mountEmbed, v as pollToLive, b as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
3613
3663
 
3614
3664
  //# sourceMappingURL=index.js.map