@oddin-gg/havik-player 2.2.2 → 2.3.1

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
@@ -241,35 +241,35 @@ function ce(e, t) {
241
241
  }
242
242
  //#endregion
243
243
  //#region src/core/fullscreen.ts
244
- function S(e) {
244
+ function le(e) {
245
245
  return e.ownerDocument ?? document;
246
246
  }
247
- function le(e) {
247
+ function ue(e) {
248
248
  return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
249
249
  }
250
- function C(e, t) {
251
- let n = le(S(e));
250
+ function S(e, t) {
251
+ let n = ue(le(e));
252
252
  return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
253
253
  }
254
- async function w(e, t) {
254
+ async function C(e, t) {
255
255
  let n = t ?? e;
256
256
  if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
257
257
  if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
258
258
  let r = e;
259
259
  return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
260
260
  }
261
- async function T(e, t) {
261
+ async function w(e, t) {
262
262
  let n = e;
263
263
  if (n.webkitDisplayingFullscreen) {
264
264
  n.webkitExitFullscreen?.();
265
265
  return;
266
266
  }
267
- let r = S(e), i = le(r);
267
+ let r = le(e), i = ue(r);
268
268
  i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
269
269
  }
270
270
  //#endregion
271
271
  //#region src/core/catalog.ts
272
- async function ue(e) {
272
+ async function de(e) {
273
273
  let t = new URLSearchParams();
274
274
  e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
275
275
  let i = t.toString(), a = c(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
@@ -287,12 +287,12 @@ async function ue(e) {
287
287
  };
288
288
  if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
289
289
  return {
290
- tournaments: de(await s.json()),
290
+ tournaments: fe(await s.json()),
291
291
  etag: s.headers.get("etag") ?? void 0,
292
292
  notModified: !1
293
293
  };
294
294
  }
295
- function de(e) {
295
+ function fe(e) {
296
296
  return (e.tournaments ?? []).map((e) => {
297
297
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
298
298
  return {
@@ -312,7 +312,7 @@ function de(e) {
312
312
  };
313
313
  });
314
314
  }
315
- async function fe(e) {
315
+ async function pe(e) {
316
316
  let t = c(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
317
317
  e.etag && i.set("If-None-Match", e.etag);
318
318
  let a = await u(t, {
@@ -332,13 +332,13 @@ async function fe(e) {
332
332
  };
333
333
  if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
334
334
  return {
335
- tournament: pe(await a.json()),
335
+ tournament: me(await a.json()),
336
336
  etag: a.headers.get("etag") ?? void 0,
337
337
  notModified: !1,
338
338
  notFound: !1
339
339
  };
340
340
  }
341
- function pe(e) {
341
+ function me(e) {
342
342
  let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
343
343
  return {
344
344
  urn: t,
@@ -356,12 +356,12 @@ function pe(e) {
356
356
  }))
357
357
  };
358
358
  }
359
- function me(e) {
359
+ function he(e) {
360
360
  return e.tournaments.flatMap((e) => e.matches);
361
361
  }
362
362
  //#endregion
363
363
  //#region src/core/poll.ts
364
- function he(e) {
364
+ function ge(e) {
365
365
  let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, l = !1, d = () => {
366
366
  l || (a = setTimeout(f, t));
367
367
  }, f = async () => {
@@ -397,7 +397,7 @@ function he(e) {
397
397
  }
398
398
  //#endregion
399
399
  //#region src/core/events.ts
400
- function E(e) {
400
+ function T(e) {
401
401
  let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = new AbortController(), i = !1, a = (e) => new Promise((t) => {
402
402
  if (r.signal.aborted) return t();
403
403
  let n = setTimeout(t, e);
@@ -464,7 +464,7 @@ function E(e) {
464
464
  i || (i = !0, r.abort());
465
465
  } };
466
466
  }
467
- function D(e) {
467
+ function E(e) {
468
468
  try {
469
469
  let t = new URL(e);
470
470
  return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
@@ -474,27 +474,27 @@ function D(e) {
474
474
  }
475
475
  //#endregion
476
476
  //#region src/core/drm/deviceId.ts
477
- var O = "havik.player.deviceId", k;
478
- function A() {
479
- if (k) return k;
477
+ var D = "havik.player.deviceId", O;
478
+ function k() {
479
+ if (O) return O;
480
480
  try {
481
- let e = globalThis.localStorage?.getItem(O);
482
- if (e) return k = e, e;
481
+ let e = globalThis.localStorage?.getItem(D);
482
+ if (e) return O = e, e;
483
483
  } catch {}
484
- let e = _e();
485
- k = e;
484
+ let e = ve();
485
+ O = e;
486
486
  try {
487
- globalThis.localStorage?.setItem(O, e);
487
+ globalThis.localStorage?.setItem(D, e);
488
488
  } catch {}
489
489
  return e;
490
490
  }
491
- function ge() {
492
- k = void 0;
491
+ function _e() {
492
+ O = void 0;
493
493
  try {
494
- globalThis.localStorage?.removeItem(O);
494
+ globalThis.localStorage?.removeItem(D);
495
495
  } catch {}
496
496
  }
497
- function _e() {
497
+ function ve() {
498
498
  let e = globalThis.crypto;
499
499
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
500
500
  let t = /* @__PURE__ */ new Uint8Array(16);
@@ -506,21 +506,21 @@ function _e() {
506
506
  }
507
507
  //#endregion
508
508
  //#region src/core/drm/headers.ts
509
- function ve(e, t, n = {}) {
509
+ function ye(e, t, n = {}) {
510
510
  let r = {
511
511
  "x-api-key": t.apiKey,
512
512
  "X-Match-Urn": e.matchUrn,
513
- "X-Device-Id": n.deviceId ?? A(),
513
+ "X-Device-Id": n.deviceId ?? k(),
514
514
  "Content-Type": "application/octet-stream"
515
515
  };
516
516
  return n.userId && (r["X-User-Id"] = n.userId), r;
517
517
  }
518
518
  //#endregion
519
519
  //#region src/core/drm/cdm.ts
520
- var j = /* @__PURE__ */ new WeakMap();
521
- function ye(e, t) {
522
- let n = j.get(e);
523
- n || (n = /* @__PURE__ */ new Map(), j.set(e, n));
520
+ var A = /* @__PURE__ */ new WeakMap();
521
+ function be(e, t) {
522
+ let n = A.get(e);
523
+ n || (n = /* @__PURE__ */ new Map(), A.set(e, n));
524
524
  let r = n.get(t.keySystem);
525
525
  if (r) return r;
526
526
  let i = t.createMediaKeys().catch((e) => {
@@ -528,22 +528,22 @@ function ye(e, t) {
528
528
  });
529
529
  return n.set(t.keySystem, i), i;
530
530
  }
531
- function M() {
531
+ function j() {
532
532
  return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
533
533
  }
534
- var N = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
535
- function be(e) {
534
+ var M = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
535
+ function xe(e) {
536
536
  return e.startsWith("com.widevine");
537
537
  }
538
- function P(e, t) {
539
- if (!be(e)) return t;
538
+ function N(e, t) {
539
+ if (!xe(e)) return t;
540
540
  let n = (e, t) => {
541
541
  let n = e.videoCapabilities;
542
542
  return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
543
- let n = N.indexOf(e.robustness);
544
- return n === -1 || N.indexOf(t) > n;
543
+ let n = M.indexOf(e.robustness);
544
+ return n === -1 || M.indexOf(t) > n;
545
545
  });
546
- }, r = N.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
546
+ }, r = M.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
547
547
  ...t,
548
548
  videoCapabilities: t.videoCapabilities?.map((t) => ({
549
549
  ...t,
@@ -552,20 +552,20 @@ function P(e, t) {
552
552
  })));
553
553
  return [...t, ...r];
554
554
  }
555
- function xe(e) {
556
- return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, P(t, n)).then((t) => ({
555
+ function Se(e) {
556
+ return (t, n) => j() ? navigator.requestMediaKeySystemAccess(t, N(t, n)).then((t) => ({
557
557
  keySystem: t.keySystem,
558
558
  getConfiguration: () => t.getConfiguration(),
559
- createMediaKeys: () => ye(e, t)
559
+ createMediaKeys: () => be(e, t)
560
560
  })) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
561
561
  }
562
562
  //#endregion
563
563
  //#region src/core/drm/support.ts
564
- var Se = 5e3, Ce = "video/mp4; codecs=\"avc1.42E01E\"", F = "audio/mp4; codecs=\"mp4a.40.2\"", we = {
564
+ var Ce = 5e3, we = "video/mp4; codecs=\"avc1.42E01E\"", P = "audio/mp4; codecs=\"mp4a.40.2\"", Te = {
565
565
  widevine: ["com.widevine.alpha"],
566
566
  fairplay: ["com.apple.fps"]
567
567
  };
568
- function Te(e) {
568
+ function Ee(e) {
569
569
  return e === "fairplay" ? [{
570
570
  initDataTypes: [
571
571
  "sinf",
@@ -573,30 +573,30 @@ function Te(e) {
573
573
  "cenc"
574
574
  ],
575
575
  videoCapabilities: [{
576
- contentType: Ce,
576
+ contentType: we,
577
577
  robustness: "",
578
578
  encryptionScheme: "cbcs"
579
579
  }],
580
580
  audioCapabilities: [{
581
- contentType: F,
581
+ contentType: P,
582
582
  robustness: "",
583
583
  encryptionScheme: "cbcs"
584
584
  }]
585
- }] : P("com.widevine.alpha", [{
585
+ }] : N("com.widevine.alpha", [{
586
586
  initDataTypes: ["cenc"],
587
587
  videoCapabilities: [{
588
- contentType: Ce,
588
+ contentType: we,
589
589
  robustness: "SW_SECURE_DECODE",
590
590
  encryptionScheme: "cbcs"
591
591
  }],
592
592
  audioCapabilities: [{
593
- contentType: F,
593
+ contentType: P,
594
594
  robustness: "SW_SECURE_CRYPTO",
595
595
  encryptionScheme: "cbcs"
596
596
  }]
597
597
  }]);
598
598
  }
599
- function I(e, t) {
599
+ function F(e, t) {
600
600
  return new Promise((n, r) => {
601
601
  let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
602
602
  e.then((e) => {
@@ -606,8 +606,8 @@ function I(e, t) {
606
606
  });
607
607
  });
608
608
  }
609
- async function Ee(e = {}) {
610
- let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Se, r = {};
609
+ async function De(e = {}) {
610
+ let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ce, r = {};
611
611
  if (typeof window < "u" && window.isSecureContext === !1) return {
612
612
  verdict: "insecure-context",
613
613
  detail: r
@@ -619,7 +619,7 @@ async function Ee(e = {}) {
619
619
  };
620
620
  let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
621
621
  for (let e of t) {
622
- let t = we[e];
622
+ let t = Te[e];
623
623
  if (!t) {
624
624
  r[e] = "unknown system";
625
625
  continue;
@@ -630,7 +630,7 @@ async function Ee(e = {}) {
630
630
  break;
631
631
  }
632
632
  try {
633
- return await I((await I(i(n, Te(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
633
+ return await F((await F(i(n, Ee(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
634
634
  verdict: "supported",
635
635
  system: e,
636
636
  detail: r
@@ -654,13 +654,30 @@ async function Ee(e = {}) {
654
654
  }
655
655
  //#endregion
656
656
  //#region src/core/manifest.ts
657
- var De = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
658
- function Oe(e) {
659
- return De.test(e);
657
+ var Oe = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
658
+ function ke(e) {
659
+ return Oe.test(e);
660
660
  }
661
661
  //#endregion
662
662
  //#region src/core/stats.ts
663
- var L = { droppedFrames: 0 };
663
+ var I = { droppedFrames: 0 };
664
+ function L(e) {
665
+ try {
666
+ return new URL(e).host;
667
+ } catch {
668
+ return "";
669
+ }
670
+ }
671
+ var Ae = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
672
+ function je(e) {
673
+ if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
674
+ let t = "", n = -1, r = performance.getEntriesByType("resource");
675
+ for (let i of r) if (!(i.startTime < e) && !(i.initiatorType !== "video" && i.initiatorType !== "audio" && !Ae.test(i.name)) && i.startTime >= n) {
676
+ let e = L(i.name);
677
+ e && (t = e, n = i.startTime);
678
+ }
679
+ return t;
680
+ }
664
681
  function R(e) {
665
682
  let t = e.getVideoPlaybackQuality?.();
666
683
  return {
@@ -668,7 +685,7 @@ function R(e) {
668
685
  decoded: t?.totalVideoFrames ?? 0
669
686
  };
670
687
  }
671
- function ke(e, t) {
688
+ function Me(e, t) {
672
689
  let n = [
673
690
  ["playing", () => t("playing")],
674
691
  ["waiting", () => t("buffering")],
@@ -685,7 +702,7 @@ function ke(e, t) {
685
702
  }
686
703
  //#endregion
687
704
  //#region src/core/engine/native.ts
688
- function Ae(e) {
705
+ function Ne(e) {
689
706
  try {
690
707
  let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
691
708
  return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
@@ -714,8 +731,10 @@ var V = class {
714
731
  loadStarted;
715
732
  preloadTouched = !1;
716
733
  savedPreload = null;
734
+ cdnHost = "";
735
+ builtAt;
717
736
  constructor(e) {
718
- this.deps = e, this.loadStarted = e.deferLoad !== !0;
737
+ this.deps = e, this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
719
738
  }
720
739
  async load() {
721
740
  let { video: e, descriptor: t, emit: r } = this.deps;
@@ -735,7 +754,7 @@ var V = class {
735
754
  type: "error",
736
755
  error: new n("INTERNAL", 0, "native HLS playback error"),
737
756
  fatal: !0
738
- }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = je(t.manifestUrl, t.analytics?.sid), e.load();
757
+ }), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Pe(t.manifestUrl, t.analytics?.sid), e.load();
739
758
  }
740
759
  startLoad() {
741
760
  this.loadStarted || (this.loadStarted = !0, this.restorePreload());
@@ -757,7 +776,7 @@ var V = class {
757
776
  });
758
777
  this.onEncrypted = (n) => {
759
778
  let i = n;
760
- !i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV = Ae(i.initData), (async () => {
779
+ !i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV = Ne(i.initData), (async () => {
761
780
  try {
762
781
  let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
763
782
  initDataTypes: [i.initDataType],
@@ -856,7 +875,7 @@ var V = class {
856
875
  droppedFrames: t.dropped,
857
876
  decodedFrames: t.decoded
858
877
  };
859
- return this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
878
+ return this.cdnHost ||= je(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
860
879
  }
861
880
  stop() {
862
881
  try {
@@ -875,32 +894,25 @@ var V = class {
875
894
  } catch {}
876
895
  }
877
896
  };
878
- function je(e, t) {
897
+ function Pe(e, t) {
879
898
  return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
880
899
  }
881
900
  //#endregion
882
901
  //#region src/core/engine/hls.ts
883
- function Me() {
902
+ function Fe() {
884
903
  return e.isSupported();
885
904
  }
886
- var Ne = 3, Pe = 5, Fe = 3, Ie = 3e4, Le = 12e3, Re = 3e3, H = 6e3, ze = 4e3, Be = 2, Ve = 5, He = 2, Ue = 2, We = 2e3, Ge = 3e4, Ke = 2, qe = 9, Je = .5, Ye = 64;
887
- function Xe(e) {
888
- try {
889
- return new URL(e).host;
890
- } catch {
891
- return "";
892
- }
893
- }
894
- function Ze(e) {
905
+ var Ie = 3, Le = 5, Re = 3, ze = 3e4, Be = 12e3, Ve = 3e3, H = 6e3, He = 4e3, Ue = 2, We = 5, Ge = 2, Ke = 2, qe = 2e3, Je = 3e4, Ye = 2, Xe = 9, Ze = .5, Qe = 64;
906
+ function $e(e) {
895
907
  if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
896
908
  delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
897
909
  return;
898
910
  }
899
- e.liveSyncDuration ??= Ke;
900
- let t = Math.max(12, e.liveSyncDuration + qe);
901
- (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Qe(e, e.liveSyncDuration);
911
+ e.liveSyncDuration ??= Ye;
912
+ let t = Math.max(12, e.liveSyncDuration + Xe);
913
+ (e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), et(e, e.liveSyncDuration);
902
914
  }
903
- function Qe(e, t) {
915
+ function et(e, t) {
904
916
  let n = (e, t, n) => Math.min(n, Math.max(t, e));
905
917
  e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
906
918
  }
@@ -998,7 +1010,7 @@ var U = class {
998
1010
  let t = e.liveSyncPosition;
999
1011
  if (typeof t != "number" || !Number.isFinite(t)) return;
1000
1012
  let { video: n } = this.deps;
1001
- n.currentTime <= t + Je || (n.currentTime = t);
1013
+ n.currentTime <= t + Ze || (n.currentTime = t);
1002
1014
  }
1003
1015
  startHls() {
1004
1016
  let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
@@ -1022,7 +1034,7 @@ var U = class {
1022
1034
  videoEncryptionScheme: "cbcs",
1023
1035
  audioEncryptionScheme: "cbcs"
1024
1036
  },
1025
- ...M() ? { requestMediaKeySystemAccessFunc: xe(t) } : {},
1037
+ ...j() ? { requestMediaKeySystemAccessFunc: Se(t) } : {},
1026
1038
  licenseXhrSetup: (e, t) => {
1027
1039
  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;
1028
1040
  let o = performance.now();
@@ -1038,7 +1050,7 @@ var U = class {
1038
1050
  } } : {},
1039
1051
  ...c
1040
1052
  };
1041
- Ze(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
1053
+ $e(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
1042
1054
  let f = new e(d);
1043
1055
  this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
1044
1056
  this.mediaRecoveries = 0, this.networkRecoveries = 0;
@@ -1047,17 +1059,17 @@ var U = class {
1047
1059
  }), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
1048
1060
  t?.frag?.type === "main" && (this.kickPending = !1, this.kickTicks = 0, (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
1049
1061
  this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
1050
- }, Ie)));
1062
+ }, ze)));
1051
1063
  }), f.on(e.Events.FRAG_LOADING, (e, t) => {
1052
1064
  t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
1053
1065
  }), f.on(e.Events.FRAG_LOADED, (e, t) => {
1054
1066
  let n = t?.frag?.stats, r = n?.loaded;
1055
1067
  typeof r == "number" && (this.bytesLoaded += r);
1056
1068
  let i = n?.loading;
1057
- 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 > Ye && this.requestTimesMs.shift());
1069
+ 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 > Qe && this.requestTimesMs.shift());
1058
1070
  let a = t?.frag?.url;
1059
1071
  if (a) {
1060
- let e = Xe(a);
1072
+ let e = L(a);
1061
1073
  e && (this.cdnHost = e);
1062
1074
  }
1063
1075
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => {
@@ -1070,7 +1082,7 @@ var U = class {
1070
1082
  }));
1071
1083
  }), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
1072
1084
  this.checkEndStale(), this.checkStarvation();
1073
- }, Re), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1085
+ }, Ve), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
1074
1086
  this.renditionSwitches += 1;
1075
1087
  let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
1076
1088
  n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
@@ -1134,7 +1146,7 @@ var U = class {
1134
1146
  return;
1135
1147
  }
1136
1148
  this.capTimer && clearTimeout(this.capTimer);
1137
- let t = e > this.sizeCapLevel ? We : Ge;
1149
+ let t = e > this.sizeCapLevel ? qe : Je;
1138
1150
  this.capTimer = setTimeout(() => {
1139
1151
  this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
1140
1152
  }, t);
@@ -1223,7 +1235,7 @@ var U = class {
1223
1235
  return;
1224
1236
  }
1225
1237
  let e = Date.now() - this.lastAdvanceMs;
1226
- !this.chaseSuspended && e > H && this.suspendChasing(), e > Le && this.emitEnded("stalled");
1238
+ !this.chaseSuspended && e > H && this.suspendChasing(), e > Be && this.emitEnded("stalled");
1227
1239
  }
1228
1240
  checkStarvation() {
1229
1241
  let e = this.hls, { video: t } = this.deps;
@@ -1232,17 +1244,17 @@ var U = class {
1232
1244
  this.starvedTicks = 0;
1233
1245
  return;
1234
1246
  }
1235
- let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < H, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > ze;
1247
+ let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < H, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > He;
1236
1248
  if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
1237
1249
  this.starvedTicks = 0;
1238
1250
  return;
1239
1251
  }
1240
- if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Be)) {
1241
- if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= He && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Ue)) {
1252
+ if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Ue)) {
1253
+ if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Ge && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Ke)) {
1242
1254
  this.starvationRebuilds += 1, 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");
1243
1255
  return;
1244
1256
  }
1245
- if (!(this.starvationKicks >= Ve)) {
1257
+ if (!(this.starvationKicks >= We)) {
1246
1258
  this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, console.warn("havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
1247
1259
  try {
1248
1260
  e.stopLoad(), e.startLoad(-1);
@@ -1292,7 +1304,7 @@ var U = class {
1292
1304
  scheduleLicenseRetry(t) {
1293
1305
  if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
1294
1306
  let n = t.response?.code ?? 0;
1295
- if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Fe) return !1;
1307
+ if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Re) return !1;
1296
1308
  this.licenseRecoveries += 1;
1297
1309
  let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
1298
1310
  return this.licenseRetryTimer = setTimeout(() => {
@@ -1324,7 +1336,7 @@ var U = class {
1324
1336
  return;
1325
1337
  }
1326
1338
  if (t.type === e.ErrorTypes.NETWORK_ERROR) {
1327
- if (this.networkRecoveries < Pe) {
1339
+ if (this.networkRecoveries < Le) {
1328
1340
  this.networkRecoveries += 1;
1329
1341
  let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
1330
1342
  this.networkRetryTimer = setTimeout(() => {
@@ -1341,7 +1353,7 @@ var U = class {
1341
1353
  return;
1342
1354
  }
1343
1355
  if (t.type === e.ErrorTypes.MEDIA_ERROR) {
1344
- if (this.mediaRecoveries < Ne) {
1356
+ if (this.mediaRecoveries < Ie) {
1345
1357
  this.mediaRecoveries += 1, n.recoverMediaError();
1346
1358
  return;
1347
1359
  }
@@ -1365,11 +1377,11 @@ var U = class {
1365
1377
  let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
1366
1378
  return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
1367
1379
  }
1368
- }, $e = 15e3, et = 100, W = 1, tt = 1e3, G = 3e4, nt = {
1380
+ }, tt = 15e3, nt = 100, W = 1, rt = 1e3, G = 3e4, it = 1e3, at = {
1369
1381
  inline: "PRESENTATION_INLINE",
1370
1382
  fullscreen: "PRESENTATION_FULLSCREEN",
1371
1383
  pip: "PRESENTATION_PIP"
1372
- }, rt = {
1384
+ }, ot = {
1373
1385
  widevine: "KEY_SYSTEM_WIDEVINE",
1374
1386
  fairplay: "KEY_SYSTEM_FAIRPLAY",
1375
1387
  none: "KEY_SYSTEM_NONE"
@@ -1377,7 +1389,7 @@ var U = class {
1377
1389
  function K(e, t) {
1378
1390
  return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
1379
1391
  }
1380
- var it = /* @__PURE__ */ new Set([
1392
+ var st = /* @__PURE__ */ new Set([
1381
1393
  "INVALID_URN",
1382
1394
  "NOT_FOUND",
1383
1395
  "GONE",
@@ -1397,7 +1409,7 @@ var it = /* @__PURE__ */ new Set([
1397
1409
  ended: "PLAYER_STATE_ENDED",
1398
1410
  error: "PLAYER_STATE_ERROR"
1399
1411
  };
1400
- function at(e) {
1412
+ function ct(e) {
1401
1413
  try {
1402
1414
  let t = new URL(e), [n, ...r] = t.hostname.split(".");
1403
1415
  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);
@@ -1405,7 +1417,7 @@ function at(e) {
1405
1417
  return;
1406
1418
  }
1407
1419
  }
1408
- var ot = class {
1420
+ var lt = class {
1409
1421
  opts;
1410
1422
  url;
1411
1423
  now;
@@ -1450,7 +1462,8 @@ var ot = class {
1450
1462
  timeToFirstStallMs = 0;
1451
1463
  lastStallMs = 0;
1452
1464
  lastErrorMs = 0;
1453
- lastSeekMs = 0;
1465
+ lastSeekMs = -1;
1466
+ stallIsSeekInduced = !1;
1454
1467
  lastErrorStage = null;
1455
1468
  sawFirstBytes = !1;
1456
1469
  mediaInfoSignature = "";
@@ -1462,6 +1475,7 @@ var ot = class {
1462
1475
  pendingStart = null;
1463
1476
  firstFlushTimer = null;
1464
1477
  bornMs;
1478
+ startupAnchorMs;
1465
1479
  startupTimeMs = 0;
1466
1480
  manifestLoadMs = 0;
1467
1481
  firstFragLoadMs = 0;
@@ -1472,8 +1486,8 @@ var ot = class {
1472
1486
  constructor(e) {
1473
1487
  this.opts = {
1474
1488
  ...e,
1475
- heartbeatMs: e.heartbeatMs ?? $e
1476
- }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs;
1489
+ heartbeatMs: e.heartbeatMs ?? tt
1490
+ }, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs, this.startupAnchorMs = this.bornMs;
1477
1491
  }
1478
1492
  start() {
1479
1493
  if (this.endedFlag) return;
@@ -1482,22 +1496,30 @@ var ot = class {
1482
1496
  sdkVersion: this.opts.sdkVersion,
1483
1497
  ...this.opts.environment
1484
1498
  };
1485
- this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), tt), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), this.onVisibility());
1499
+ this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), rt), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), this.onVisibility());
1486
1500
  }
1487
1501
  noteStateChange(e, t, n, r) {
1488
1502
  if (this.endedFlag || e === t) return;
1489
1503
  let i = this.now();
1490
- t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(W, i - this.bornMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(W, i - this.bornMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing" ? (this.isHidden || (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(W, Math.round(this.playingTotalMs)))) : e === "buffering" && (this.isBuffering = !1), this.syncBuffering(), t === "paused" && (this.pauseCount += 1);
1504
+ if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(W, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(W, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
1505
+ this.stallIsSeekInduced = this.seekInduced(i);
1506
+ let e = !this.isHidden && !this.stallIsSeekInduced;
1507
+ e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(W, Math.round(this.playingTotalMs)));
1508
+ } else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
1509
+ this.syncBuffering(), t === "paused" && (this.pauseCount += 1);
1491
1510
  let a = {
1492
1511
  fromState: q[e] ?? "PLAYER_STATE_UNSPECIFIED",
1493
1512
  toState: q[t] ?? "PLAYER_STATE_UNSPECIFIED",
1494
- presentation: nt[this.presentation]
1513
+ presentation: at[this.presentation]
1495
1514
  }, o = this.causeOf(e, t, i);
1496
1515
  o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
1497
1516
  }
1517
+ seekInduced(e) {
1518
+ return this.lastSeekMs >= 0 && e - this.lastSeekMs < it;
1519
+ }
1498
1520
  causeOf(e, t, n) {
1499
1521
  if (t === "error") return "TRANSITION_CAUSE_ERROR";
1500
- if (t === "buffering") return n - this.lastSeekMs < 1e3 ? "TRANSITION_CAUSE_SEEK" : "TRANSITION_CAUSE_NETWORK_STALL";
1522
+ if (t === "buffering") return this.seekInduced(n) ? "TRANSITION_CAUSE_SEEK" : "TRANSITION_CAUSE_NETWORK_STALL";
1501
1523
  if (t === "paused" || t === "playing" && e === "paused") return "TRANSITION_CAUSE_USER";
1502
1524
  }
1503
1525
  syncActive() {
@@ -1505,7 +1527,7 @@ var ot = class {
1505
1527
  e && this.activeSinceMs === null ? this.activeSinceMs = this.now() : !e && this.activeSinceMs !== null && (this.activeTotalMs += this.now() - this.activeSinceMs, this.activeSinceMs = null);
1506
1528
  }
1507
1529
  syncBuffering() {
1508
- let e = this.isBuffering && !this.isHidden;
1530
+ let e = this.isBuffering && !this.isHidden && !this.stallIsSeekInduced;
1509
1531
  e && this.bufferingSinceMs === null ? this.bufferingSinceMs = this.now() : !e && this.bufferingSinceMs !== null && (this.rebufferTotalMs += this.now() - this.bufferingSinceMs, this.bufferingSinceMs = null);
1510
1532
  }
1511
1533
  closePresentation() {
@@ -1530,16 +1552,19 @@ var ot = class {
1530
1552
  }
1531
1553
  this.muteChanges += 1;
1532
1554
  let r = this.now();
1533
- n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(W, r - this.bornMs))), this.isMuted = n, this.syncActive();
1555
+ n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(W, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
1534
1556
  }
1535
1557
  notePresentation(e) {
1536
1558
  this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
1537
1559
  }
1560
+ notePlayIntent() {
1561
+ this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = W), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = W));
1562
+ }
1538
1563
  noteReady() {
1539
- this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(W, this.now() - this.bornMs));
1564
+ this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(W, this.now() - this.startupAnchorMs));
1540
1565
  }
1541
1566
  noteFirstBytes() {
1542
- this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(W, this.now() - this.bornMs));
1567
+ this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(W, this.now() - this.startupAnchorMs));
1543
1568
  }
1544
1569
  noteSeek() {
1545
1570
  this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
@@ -1558,7 +1583,7 @@ var ot = class {
1558
1583
  let r = n ?? "";
1559
1584
  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";
1560
1585
  if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
1561
- if (it.has(e)) return "ERROR_STAGE_RESOLVE";
1586
+ if (st.has(e)) return "ERROR_STAGE_RESOLVE";
1562
1587
  let i = t ?? "";
1563
1588
  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";
1564
1589
  }
@@ -1606,7 +1631,7 @@ var ot = class {
1606
1631
  maybeEmitMediaInfo(e) {
1607
1632
  if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
1608
1633
  let t = {};
1609
- e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = rt[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);
1634
+ e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = ot[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);
1610
1635
  let n = JSON.stringify(t);
1611
1636
  n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
1612
1637
  }
@@ -1646,7 +1671,7 @@ var ot = class {
1646
1671
  };
1647
1672
  }
1648
1673
  enqueue(e) {
1649
- for (this.pending.push(this.wrap(e)); this.pending.length > et;) {
1674
+ for (this.pending.push(this.wrap(e)); this.pending.length > nt;) {
1650
1675
  let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
1651
1676
  this.pending.splice(e >= 0 ? e : 0, 1);
1652
1677
  }
@@ -1671,7 +1696,7 @@ var ot = class {
1671
1696
  };
1672
1697
  //#endregion
1673
1698
  //#region src/core/environment.ts
1674
- function st() {
1699
+ function ut() {
1675
1700
  if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
1676
1701
  let e;
1677
1702
  try {
@@ -1696,14 +1721,14 @@ function st() {
1696
1721
  integration: "INTEGRATION_KIND_IFRAME"
1697
1722
  };
1698
1723
  }
1699
- function ct() {
1724
+ function dt() {
1700
1725
  if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
1701
1726
  let e = navigator.userAgentData, t = e?.platform ?? "";
1702
1727
  if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
1703
1728
  let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
1704
1729
  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";
1705
1730
  }
1706
- function lt() {
1731
+ function ft() {
1707
1732
  let e = typeof navigator < "u" ? navigator.connection : void 0;
1708
1733
  if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
1709
1734
  let t = { connectionType: e.type ? {
@@ -1713,17 +1738,17 @@ function lt() {
1713
1738
  }[e.type] ?? "CONNECTION_TYPE_OTHER" : "CONNECTION_TYPE_UNKNOWN" };
1714
1739
  return typeof e.downlink == "number" && e.downlink > 0 && (t.downlinkKbps = Math.round(e.downlink * 1e3)), e.saveData && (t.saveData = !0), t;
1715
1740
  }
1716
- function ut(e) {
1717
- let t = st(), n = {
1718
- deviceClass: ct(),
1741
+ function pt(e) {
1742
+ let t = ut(), n = {
1743
+ deviceClass: dt(),
1719
1744
  integration: t.integration,
1720
- ...lt()
1745
+ ...ft()
1721
1746
  };
1722
1747
  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);
1723
1748
  let r = e.getBoundingClientRect?.();
1724
1749
  return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
1725
1750
  }
1726
- async function dt() {
1751
+ async function mt() {
1727
1752
  let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
1728
1753
  if (!e?.getHighEntropyValues) return {};
1729
1754
  try {
@@ -1735,7 +1760,7 @@ async function dt() {
1735
1760
  }
1736
1761
  //#endregion
1737
1762
  //#region src/core/version.ts
1738
- var ft = "2.2.2", J = {
1763
+ var ht = "2.3.1", J = {
1739
1764
  accent: "#E1B600",
1740
1765
  accentText: "#1B1C23",
1741
1766
  background: "#0e0f13",
@@ -1768,15 +1793,15 @@ function X(e, t) {
1768
1793
  }
1769
1794
  //#endregion
1770
1795
  //#region src/ui/styles.ts
1771
- var Z = "havik-player-styles", pt = "\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.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.havik-spinner{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";
1772
- function mt(e = document) {
1796
+ var Z = "havik-player-styles", gt = "\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.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.havik-spinner{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";
1797
+ function _t(e = document) {
1773
1798
  if (e.getElementById(Z)) return;
1774
1799
  let t = e.createElement("style");
1775
- t.id = Z, t.textContent = pt, e.head.appendChild(t);
1800
+ t.id = Z, t.textContent = gt, e.head.appendChild(t);
1776
1801
  }
1777
1802
  //#endregion
1778
1803
  //#region src/ui/icons.ts
1779
- var ht = {
1804
+ var vt = {
1780
1805
  play: "<path d=\"M8 5v14l11-7z\"/>",
1781
1806
  pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
1782
1807
  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\"/>",
@@ -1790,20 +1815,20 @@ var ht = {
1790
1815
  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\"/>"
1791
1816
  };
1792
1817
  function Q(e) {
1793
- return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${ht[e]}</svg>`;
1818
+ return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${vt[e]}</svg>`;
1794
1819
  }
1795
1820
  //#endregion
1796
1821
  //#region src/ui/controls.ts
1797
- var gt = 3e3, _t = /* @__PURE__ */ new Set([
1822
+ var yt = 3e3, bt = /* @__PURE__ */ new Set([
1798
1823
  "GONE",
1799
1824
  "NOT_FOUND",
1800
1825
  "INVALID_URN",
1801
1826
  "UNAUTHORIZED"
1802
1827
  ]);
1803
- function vt(e) {
1804
- return new yt(e);
1828
+ function xt(e) {
1829
+ return new St(e);
1805
1830
  }
1806
- var yt = class {
1831
+ var St = class {
1807
1832
  root;
1808
1833
  video;
1809
1834
  player;
@@ -1845,7 +1870,7 @@ var yt = class {
1845
1870
  scrubbing = !1;
1846
1871
  offFns = [];
1847
1872
  constructor(e) {
1848
- this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? gt, 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, mt(this.doc), 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");
1873
+ this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? yt, 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, _t(this.doc), 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");
1849
1874
  let t = (e, t, n) => {
1850
1875
  let r = this.doc.createElement(e);
1851
1876
  if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
@@ -1936,7 +1961,7 @@ var yt = class {
1936
1961
  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);
1937
1962
  } else {
1938
1963
  let r = this.doc.createElement("div");
1939
- if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !_t.has(this.lastError.code)) {
1964
+ if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !bt.has(this.lastError.code)) {
1940
1965
  let e = this.doc.createElement("button");
1941
1966
  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);
1942
1967
  }
@@ -1977,7 +2002,7 @@ var yt = class {
1977
2002
  let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
1978
2003
  this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
1979
2004
  }
1980
- !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${bt(this.video.currentTime)} / ${bt(this.video.duration)}`);
2005
+ !this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Ct(this.video.currentTime)} / ${Ct(this.video.duration)}`);
1981
2006
  }
1982
2007
  syncLive() {
1983
2008
  let e = this.player.getStats(), t = e.isLive !== !1;
@@ -2027,17 +2052,17 @@ var yt = class {
2027
2052
  renderQualityMenu() {
2028
2053
  let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
2029
2054
  n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
2030
- for (let n of e) this.menu.append(this.menuItem(xt(n), t === n.index, () => this.player.setQuality(n.index)));
2055
+ for (let n of e) this.menu.append(this.menuItem(wt(n), t === n.index, () => this.player.setQuality(n.index)));
2031
2056
  }
2032
2057
  renderAudioMenu() {
2033
2058
  let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
2034
2059
  t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
2035
- for (let t of e) this.menu.append(this.menuItem(St(t), t.default, () => this.player.setAudioTrack(t.id)));
2060
+ for (let t of e) this.menu.append(this.menuItem(Tt(t), t.default, () => this.player.setAudioTrack(t.id)));
2036
2061
  }
2037
2062
  renderCcMenu() {
2038
2063
  let e = this.player.getTextTracks(), t = this.doc.createElement("div");
2039
2064
  t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
2040
- for (let t of e) this.menu.append(this.menuItem(Ct(t), !1, () => this.player.setTextTrack(t.id)));
2065
+ for (let t of e) this.menu.append(this.menuItem(Et(t), !1, () => this.player.setTextTrack(t.id)));
2041
2066
  }
2042
2067
  onTracksChanged() {
2043
2068
  this.openMenu && this.renderMenu(this.openMenu);
@@ -2057,11 +2082,11 @@ var yt = class {
2057
2082
  }
2058
2083
  async toggleFullscreen() {
2059
2084
  try {
2060
- C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
2085
+ S(this.video, this.root) ? await w(this.video, this.root) : await C(this.video, this.root);
2061
2086
  } catch {}
2062
2087
  }
2063
2088
  syncFullscreen() {
2064
- let e = C(this.video, this.root);
2089
+ let e = S(this.video, this.root);
2065
2090
  this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
2066
2091
  }
2067
2092
  poke() {
@@ -2137,32 +2162,32 @@ var yt = class {
2137
2162
  this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
2138
2163
  }
2139
2164
  };
2140
- function bt(e) {
2165
+ function Ct(e) {
2141
2166
  (!Number.isFinite(e) || e < 0) && (e = 0);
2142
2167
  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");
2143
2168
  return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
2144
2169
  }
2145
- function xt(e) {
2170
+ function wt(e) {
2146
2171
  return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
2147
2172
  }
2148
- function St(e) {
2173
+ function Tt(e) {
2149
2174
  return e.name || e.lang || `Track ${e.id}`;
2150
2175
  }
2151
- function Ct(e) {
2176
+ function Et(e) {
2152
2177
  return e.name || e.lang || `Track ${e.id}`;
2153
2178
  }
2154
2179
  //#endregion
2155
2180
  //#region src/managed/index.ts
2156
- var wt = 6e3, Tt = 45e3, Et = 2e3, Dt = 3, Ot = 2e3, kt = 48e4;
2157
- async function At(e) {
2181
+ var Dt = 6e3, Ot = 45e3, kt = 2e3, At = 3, jt = 2e3, Mt = 48e4;
2182
+ async function Nt(e) {
2158
2183
  if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
2159
2184
  if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: baseUrl is required");
2160
2185
  if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
2161
2186
  if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
2162
- let t = new jt(e);
2187
+ let t = new Pt(e);
2163
2188
  return await t.start(), t;
2164
2189
  }
2165
- var jt = class {
2190
+ var Pt = class {
2166
2191
  opts;
2167
2192
  abort = new AbortController();
2168
2193
  listeners = {};
@@ -2228,7 +2253,7 @@ var jt = class {
2228
2253
  };
2229
2254
  }
2230
2255
  beginArming(e, t, n = !1) {
2231
- let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
2256
+ let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
2232
2257
  r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
2233
2258
  }
2234
2259
  beginArmingByPolling(e) {
@@ -2249,7 +2274,7 @@ var jt = class {
2249
2274
  setTimeout(() => {
2250
2275
  a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
2251
2276
  phase: i ? "unavailable" : "tooEarly",
2252
- retryInMs: Tt,
2277
+ retryInMs: Ot,
2253
2278
  attempt: 1,
2254
2279
  elapsedMs: 0,
2255
2280
  ...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
@@ -2288,13 +2313,13 @@ var jt = class {
2288
2313
  !a && !p() && h();
2289
2314
  }, e);
2290
2315
  };
2291
- _(wt), this.armingSub = E({
2316
+ _(Dt), this.armingSub = T({
2292
2317
  eventsBaseUrl: t,
2293
2318
  matchUrn: this.opts.matchUrn,
2294
2319
  credential: this.opts.credential,
2295
- onAlive: () => _(Tt),
2320
+ onAlive: () => _(Ot),
2296
2321
  onState: (e) => {
2297
- a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Et);
2322
+ a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * kt);
2298
2323
  },
2299
2324
  onError: () => h()
2300
2325
  });
@@ -2317,7 +2342,7 @@ var jt = class {
2317
2342
  let n = await s(this.opts.credential);
2318
2343
  if (this.destroyed || t !== this.loadGen) return;
2319
2344
  this.setState("loading");
2320
- let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = ke(this.opts.video, (e) => {
2345
+ let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Me(this.opts.video, (e) => {
2321
2346
  this._state !== "ended" && this._state !== "error" && this.setState(e);
2322
2347
  });
2323
2348
  if (await i.load(), this.destroyed || t !== this.loadGen) {
@@ -2336,17 +2361,17 @@ var jt = class {
2336
2361
  if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
2337
2362
  let r = e.analytics?.sid;
2338
2363
  if (!r) return;
2339
- let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? at(this.opts.baseUrl);
2364
+ let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? ct(this.opts.baseUrl);
2340
2365
  if (!i) return;
2341
- let a = this.opts.video, o = new ot({
2366
+ let a = this.opts.video, o = new lt({
2342
2367
  endpoint: i,
2343
2368
  sid: r,
2344
2369
  apiKey: n,
2345
2370
  player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
2346
- sdkVersion: ft,
2347
- environment: ut(a),
2371
+ sdkVersion: ht,
2372
+ environment: pt(a),
2348
2373
  sample: () => {
2349
- let e = this.engine?.getStats() ?? L, t = a.buffered.length ? Math.max(0, a.buffered.end(a.buffered.length - 1) - a.currentTime) : 0;
2374
+ let e = this.engine?.getStats() ?? I, t = a.buffered.length ? Math.max(0, a.buffered.end(a.buffered.length - 1) - a.currentTime) : 0;
2350
2375
  return {
2351
2376
  ...e,
2352
2377
  bufferedMs: Math.round(t * 1e3),
@@ -2360,7 +2385,7 @@ var jt = class {
2360
2385
  let s = () => o.noteSeek(), c = () => o.noteVolume(a.muted, a.volume);
2361
2386
  a.addEventListener("seeking", s), a.addEventListener("volumechange", c), this.detachMediaListeners = () => {
2362
2387
  a.removeEventListener("seeking", s), a.removeEventListener("volumechange", c);
2363
- }, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()), dt().then((e) => o.noteEnvironment(e)), this.opts.autoplay === !1 && o.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
2388
+ }, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()), mt().then((e) => o.noteEnvironment(e)), this.opts.autoplay === !1 && o.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
2364
2389
  }
2365
2390
  currentPresentation() {
2366
2391
  let e = this.opts.video;
@@ -2375,7 +2400,7 @@ var jt = class {
2375
2400
  video: this.opts.video,
2376
2401
  descriptor: e,
2377
2402
  credential: t,
2378
- deviceId: A(),
2403
+ deviceId: k(),
2379
2404
  userId: this.opts.userId,
2380
2405
  lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
2381
2406
  snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
@@ -2387,7 +2412,7 @@ var jt = class {
2387
2412
  if (o === "native") return new V(a);
2388
2413
  if (o === "hls") return new U(a);
2389
2414
  if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && z(this.opts.video) && B()) return new V(a);
2390
- if (Me()) return new U(a);
2415
+ if (Fe()) return new U(a);
2391
2416
  if (z(this.opts.video)) return new V(a);
2392
2417
  throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
2393
2418
  }
@@ -2416,11 +2441,11 @@ var jt = class {
2416
2441
  }
2417
2442
  startLiveState(e) {
2418
2443
  if (this.opts.liveStateEvents === !1) return;
2419
- let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
2444
+ let t = this.opts.eventsBaseUrl ?? E(this.opts.baseUrl);
2420
2445
  if (!t) return;
2421
2446
  this.closeLiveState();
2422
2447
  let r = 0, i = !1;
2423
- this.liveStateSub = E({
2448
+ this.liveStateSub = T({
2424
2449
  eventsBaseUrl: t,
2425
2450
  matchUrn: this.opts.matchUrn,
2426
2451
  credential: this.opts.credential,
@@ -2431,7 +2456,7 @@ var jt = class {
2431
2456
  r = 0, i = !1;
2432
2457
  },
2433
2458
  onError: () => {
2434
- this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Dt && (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.`))));
2459
+ this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= At && (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.`))));
2435
2460
  }
2436
2461
  });
2437
2462
  }
@@ -2453,7 +2478,7 @@ var jt = class {
2453
2478
  scheduleRejoin(e) {
2454
2479
  !this.rejoinEnabled() || this.rejoinTimer || (this.rejoinTimer = setTimeout(() => {
2455
2480
  this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
2456
- }, Math.random() * Et));
2481
+ }, Math.random() * kt));
2457
2482
  }
2458
2483
  cancelRejoin() {
2459
2484
  this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
@@ -2477,7 +2502,7 @@ var jt = class {
2477
2502
  }
2478
2503
  t.controls = !1;
2479
2504
  let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
2480
- r && r.insertBefore(n, t), n.appendChild(t), X(n, this.opts.theme), this.container = n, this.controlBar = vt({
2505
+ r && r.insertBefore(n, t), n.appendChild(t), X(n, this.opts.theme), this.container = n, this.controlBar = xt({
2481
2506
  root: n,
2482
2507
  video: t,
2483
2508
  player: this,
@@ -2507,7 +2532,7 @@ var jt = class {
2507
2532
  }
2508
2533
  startStats() {
2509
2534
  this.stopStats();
2510
- let e = Math.max(500, this.opts.statsIntervalMs ?? Ot);
2535
+ let e = Math.max(500, this.opts.statsIntervalMs ?? jt);
2511
2536
  this.statsTimer = setInterval(() => {
2512
2537
  if (!this.engine) return;
2513
2538
  let e = this.engine.getStats();
@@ -2519,7 +2544,7 @@ var jt = class {
2519
2544
  }
2520
2545
  scheduleLicenseRefresh() {
2521
2546
  this.stopRefresh();
2522
- let e = this.opts.licenseRefreshMs ?? kt;
2547
+ let e = this.opts.licenseRefreshMs ?? Mt;
2523
2548
  !e || !this._descriptor?.drmEnabled || (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
2524
2549
  }
2525
2550
  stopRefresh() {
@@ -2544,7 +2569,7 @@ var jt = class {
2544
2569
  let e = !this.playRequested;
2545
2570
  this.playRequested = !0;
2546
2571
  let t = this.pendingStartLoad && this._state !== "ended" && this._state !== "error";
2547
- t && (this.pendingStartLoad = !1, this.setState("loading"), this.engine?.startLoad());
2572
+ this.opts.autoplay === !1 && this.analyticsSession?.notePlayIntent(), t && (this.pendingStartLoad = !1, this.setState("loading"), this.engine?.startLoad());
2548
2573
  try {
2549
2574
  await this.opts.video.play(), e && this.analyticsSession?.noteAutoplay(this.opts.video.muted ? "AUTOPLAY_RESULT_ALLOWED_MUTED" : "AUTOPLAY_RESULT_ALLOWED");
2550
2575
  } catch (n) {
@@ -2561,7 +2586,7 @@ var jt = class {
2561
2586
  this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
2562
2587
  }
2563
2588
  getStats() {
2564
- return this.engine?.getStats() ?? L;
2589
+ return this.engine?.getStats() ?? I;
2565
2590
  }
2566
2591
  getQualityLevels() {
2567
2592
  return this.engine?.getQualityLevels() ?? [];
@@ -2600,10 +2625,10 @@ var jt = class {
2600
2625
  e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
2601
2626
  }
2602
2627
  async enterFullscreen() {
2603
- return !this.destroyed && w(this.opts.video, this.container ?? void 0);
2628
+ return !this.destroyed && C(this.opts.video, this.container ?? void 0);
2604
2629
  }
2605
2630
  async exitFullscreen() {
2606
- await T(this.opts.video, this.container ?? void 0);
2631
+ await w(this.opts.video, this.container ?? void 0);
2607
2632
  }
2608
2633
  retry() {
2609
2634
  return this.reload();
@@ -2671,7 +2696,7 @@ function $(e) {
2671
2696
  }
2672
2697
  //#endregion
2673
2698
  //#region src/embed/host.ts
2674
- function Mt(e) {
2699
+ function Ft(e) {
2675
2700
  if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
2676
2701
  if (!e.src) throw Error("mountEmbed: opts.src is required");
2677
2702
  if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
@@ -2730,8 +2755,8 @@ function Mt(e) {
2730
2755
  }
2731
2756
  //#endregion
2732
2757
  //#region src/embed/page.ts
2733
- var Nt = /^[A-Za-z0-9:_.-]{1,128}$/;
2734
- function Pt() {
2758
+ var It = /^[A-Za-z0-9:_.-]{1,128}$/;
2759
+ function Lt() {
2735
2760
  let e = window.HAVIK_EMBED_CONFIG;
2736
2761
  if (e) return {
2737
2762
  baseUrl: e.baseUrl ?? "",
@@ -2753,9 +2778,9 @@ function Pt() {
2753
2778
  waitForLive: !0
2754
2779
  };
2755
2780
  }
2756
- async function Ft() {
2757
- let e = Pt();
2758
- Lt();
2781
+ async function Rt() {
2782
+ let e = Lt();
2783
+ Bt();
2759
2784
  let t = document.createElement("video");
2760
2785
  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);
2761
2786
  let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
@@ -2810,12 +2835,12 @@ async function Ft() {
2810
2835
  code: e.code,
2811
2836
  message: e.message
2812
2837
  })), e.on("autoplayblocked", () => {
2813
- i({ type: "oddin:autoplayblocked" }), It(t, e);
2838
+ i({ type: "oddin:autoplayblocked" }), zt(t, e);
2814
2839
  });
2815
2840
  }, s = async (r) => {
2816
2841
  a?.destroy(), a = null;
2817
2842
  try {
2818
- let n = await At({
2843
+ let n = await Nt({
2819
2844
  video: t,
2820
2845
  baseUrl: e.baseUrl,
2821
2846
  matchUrn: r,
@@ -2876,7 +2901,7 @@ async function Ft() {
2876
2901
  a?.retry();
2877
2902
  break;
2878
2903
  case "oddin:load":
2879
- typeof e.matchUrn == "string" && Nt.test(e.matchUrn) && s(e.matchUrn);
2904
+ typeof e.matchUrn == "string" && It.test(e.matchUrn) && s(e.matchUrn);
2880
2905
  break;
2881
2906
  case "oddin:destroy": c();
2882
2907
  }
@@ -2888,18 +2913,18 @@ async function Ft() {
2888
2913
  protocol: 1
2889
2914
  });
2890
2915
  }
2891
- function It(e, t) {
2916
+ function zt(e, t) {
2892
2917
  if (document.getElementById("havik-tap")) return;
2893
2918
  let n = document.createElement("button");
2894
2919
  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", () => {
2895
2920
  n.remove(), t.play();
2896
2921
  }), document.body.appendChild(n);
2897
2922
  }
2898
- function Lt() {
2923
+ function Bt() {
2899
2924
  let e = document.createElement("style");
2900
2925
  e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
2901
2926
  }
2902
2927
  //#endregion
2903
- export { J as ODDIN_THEME, n as PlaybackError, X as applyTheme, Ft as bootEmbed, ge as clearDeviceId, At as createPlayer, D as deriveEventsBaseUrl, Ee as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, Oe as isLowLatencyManifest, $ as isOddinMessage, ve as licenseRequestHeaders, Mt as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
2928
+ export { J as ODDIN_THEME, n as PlaybackError, X as applyTheme, Rt as bootEmbed, _e as clearDeviceId, Nt as createPlayer, E as deriveEventsBaseUrl, De as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, de as fetchCatalog, pe as fetchTournament, he as flattenMatches, k as getDeviceId, ke as isLowLatencyManifest, $ as isOddinMessage, ye as licenseRequestHeaders, Ft as mountEmbed, v as pollToLive, b as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, ge as watchStatus };
2904
2929
 
2905
2930
  //# sourceMappingURL=index.js.map