stormcloud-video-player 0.7.4 → 0.7.5

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/lib/index.d.cts CHANGED
@@ -36,6 +36,12 @@ interface StormcloudVideoPlayerConfig {
36
36
  adTransitionGapMs?: number;
37
37
  singlePipelineMode?: boolean;
38
38
  }
39
+ interface Scte35Marker {
40
+ type: "start" | "end" | "progress";
41
+ ptsSeconds?: number;
42
+ durationSeconds?: number;
43
+ raw?: unknown;
44
+ }
39
45
  interface AdController {
40
46
  initialize: () => void;
41
47
  requestAds: () => Promise<void>;
@@ -111,6 +117,7 @@ interface VastBidResponse {
111
117
  durationSec?: number;
112
118
  }
113
119
 
120
+ type DebugLogLevel = "info" | "warn" | "error";
114
121
  declare class StormcloudVideoPlayer {
115
122
  private readonly video;
116
123
  private readonly config;
@@ -167,6 +174,8 @@ declare class StormcloudVideoPlayer {
167
174
  private preloadedTokens;
168
175
  private fillerVideo;
169
176
  private fillerBreakTimerId;
177
+ private debugLogEntries;
178
+ private scteMarkerHistory;
170
179
  constructor(config: StormcloudVideoPlayerConfig);
171
180
  private adRequest;
172
181
  load(): Promise<void>;
@@ -226,6 +235,22 @@ declare class StormcloudVideoPlayer {
226
235
  private clearAdFailsafeTimer;
227
236
  private logAdState;
228
237
  private getRemainingAdMs;
238
+ private pushScteMarker;
239
+ private pushDebugLog;
240
+ getRecentScteMarkers(): ReadonlyArray<{
241
+ timestampMs: number;
242
+ type: Scte35Marker["type"];
243
+ ptsSeconds?: number;
244
+ durationSeconds?: number;
245
+ raw?: unknown;
246
+ }>;
247
+ getDebugLogs(): ReadonlyArray<{
248
+ timestampMs: number;
249
+ level: DebugLogLevel;
250
+ category: string;
251
+ message: string;
252
+ details?: Record<string, unknown>;
253
+ }>;
229
254
  toggleMute(): void;
230
255
  toggleFullscreen(): Promise<void>;
231
256
  isMuted(): boolean;
package/lib/index.d.ts CHANGED
@@ -36,6 +36,12 @@ interface StormcloudVideoPlayerConfig {
36
36
  adTransitionGapMs?: number;
37
37
  singlePipelineMode?: boolean;
38
38
  }
39
+ interface Scte35Marker {
40
+ type: "start" | "end" | "progress";
41
+ ptsSeconds?: number;
42
+ durationSeconds?: number;
43
+ raw?: unknown;
44
+ }
39
45
  interface AdController {
40
46
  initialize: () => void;
41
47
  requestAds: () => Promise<void>;
@@ -111,6 +117,7 @@ interface VastBidResponse {
111
117
  durationSec?: number;
112
118
  }
113
119
 
120
+ type DebugLogLevel = "info" | "warn" | "error";
114
121
  declare class StormcloudVideoPlayer {
115
122
  private readonly video;
116
123
  private readonly config;
@@ -167,6 +174,8 @@ declare class StormcloudVideoPlayer {
167
174
  private preloadedTokens;
168
175
  private fillerVideo;
169
176
  private fillerBreakTimerId;
177
+ private debugLogEntries;
178
+ private scteMarkerHistory;
170
179
  constructor(config: StormcloudVideoPlayerConfig);
171
180
  private adRequest;
172
181
  load(): Promise<void>;
@@ -226,6 +235,22 @@ declare class StormcloudVideoPlayer {
226
235
  private clearAdFailsafeTimer;
227
236
  private logAdState;
228
237
  private getRemainingAdMs;
238
+ private pushScteMarker;
239
+ private pushDebugLog;
240
+ getRecentScteMarkers(): ReadonlyArray<{
241
+ timestampMs: number;
242
+ type: Scte35Marker["type"];
243
+ ptsSeconds?: number;
244
+ durationSeconds?: number;
245
+ raw?: unknown;
246
+ }>;
247
+ getDebugLogs(): ReadonlyArray<{
248
+ timestampMs: number;
249
+ level: DebugLogLevel;
250
+ category: string;
251
+ message: string;
252
+ details?: Record<string, unknown>;
253
+ }>;
229
254
  toggleMute(): void;
230
255
  toggleFullscreen(): Promise<void>;
231
256
  isMuted(): boolean;
package/lib/index.js CHANGED
@@ -513,8 +513,8 @@ var UNSUPPORTED_VIDEO_EXTENSIONS = [
513
513
  var REQUEST_TIMEOUT_MS = 5e3;
514
514
  var REQUEST_MAX_RETRIES = 3;
515
515
  var REQUEST_RETRY_BACKOFF_MS = 1500;
516
- var AD_LAYER_Z_INDEX = "2147483646";
517
- var COUNTDOWN_Z_INDEX = "2147483647";
516
+ var AD_LAYER_Z_INDEX = "30";
517
+ var COUNTDOWN_Z_INDEX = "31";
518
518
  var STALL_TIMEOUT_MS = 8e3;
519
519
  function getFileExtension(url) {
520
520
  try {
@@ -1218,7 +1218,7 @@ function createAdStormPlayer(contentVideo, options) {
1218
1218
  container.style.isolation = "isolate";
1219
1219
  var countdown = document.createElement("div");
1220
1220
  countdown.style.position = "absolute";
1221
- countdown.style.right = "12px";
1221
+ countdown.style.left = "12px";
1222
1222
  countdown.style.top = "12px";
1223
1223
  countdown.style.padding = "4px 8px";
1224
1224
  countdown.style.borderRadius = "4px";
@@ -1669,7 +1669,7 @@ function createAdStormPlayer(contentVideo, options) {
1669
1669
  container.style.isolation = "isolate";
1670
1670
  var countdown = document.createElement("div");
1671
1671
  countdown.style.position = "absolute";
1672
- countdown.style.right = "12px";
1672
+ countdown.style.left = "12px";
1673
1673
  countdown.style.top = "12px";
1674
1674
  countdown.style.padding = "4px 8px";
1675
1675
  countdown.style.borderRadius = "4px";
@@ -2792,6 +2792,7 @@ function supportsFeature(feature) {
2792
2792
  }
2793
2793
  }
2794
2794
  // src/player/StormcloudVideoPlayer.ts
2795
+ var DEBUG_HISTORY_LIMIT = 120;
2795
2796
  var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2796
2797
  "use strict";
2797
2798
  function StormcloudVideoPlayer(config) {
@@ -2835,6 +2836,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2835
2836
  this.adRequestMaxRetries = 3;
2836
2837
  this.adRequestRetryBackoffMs = 1500;
2837
2838
  this.preloadedTokens = [];
2839
+ this.debugLogEntries = [];
2840
+ this.scteMarkerHistory = [];
2838
2841
  initializePolyfills();
2839
2842
  var browserOverrides = getBrowserConfigOverrides();
2840
2843
  this.config = _object_spread({}, browserOverrides, config);
@@ -3341,6 +3344,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3341
3344
  errorMessage += ". Caused by: ".concat(causeMessage);
3342
3345
  }
3343
3346
  }
3347
+ _this.pushDebugLog("error", "ad", errorMessage, _object_spread({}, errorPayload ? {
3348
+ payload: errorPayload
3349
+ } : {}));
3344
3350
  console.error("[AD-ERROR]", errorMessage, errorPayload || "");
3345
3351
  _this.adLayer.stop().catch(function() {});
3346
3352
  _this.handleAdFailure();
@@ -3782,6 +3788,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3782
3788
  value: function onScte35Marker(marker) {
3783
3789
  var _this = this;
3784
3790
  if (this.config.disableAds) return;
3791
+ this.pushScteMarker(marker);
3792
+ this.pushDebugLog("info", "scte35", "SCTE-35 marker detected", {
3793
+ type: marker.type,
3794
+ ptsSeconds: marker.ptsSeconds,
3795
+ durationSeconds: marker.durationSeconds,
3796
+ currentTime: this.video.currentTime
3797
+ });
3785
3798
  if (this.config.debugAdTiming) {
3786
3799
  console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
3787
3800
  type: marker.type,
@@ -5650,6 +5663,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5650
5663
  if (!this.config.debugAdTiming) {
5651
5664
  return;
5652
5665
  }
5666
+ this.pushDebugLog("info", "ad-state", event, extra);
5653
5667
  console.log("[StormcloudVideoPlayer][AdState]", _object_spread({
5654
5668
  event: event,
5655
5669
  timestamp: /* @__PURE__ */ new Date().toISOString(),
@@ -5669,6 +5683,59 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5669
5683
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
5670
5684
  }
5671
5685
  },
5686
+ {
5687
+ key: "pushScteMarker",
5688
+ value: function pushScteMarker(marker) {
5689
+ if (!this.config.debugAdTiming) return;
5690
+ this.scteMarkerHistory.push({
5691
+ timestampMs: Date.now(),
5692
+ marker: marker
5693
+ });
5694
+ if (this.scteMarkerHistory.length > DEBUG_HISTORY_LIMIT) {
5695
+ this.scteMarkerHistory = this.scteMarkerHistory.slice(-DEBUG_HISTORY_LIMIT);
5696
+ }
5697
+ }
5698
+ },
5699
+ {
5700
+ key: "pushDebugLog",
5701
+ value: function pushDebugLog(level, category, message, details) {
5702
+ if (!this.config.debugAdTiming) return;
5703
+ this.debugLogEntries.push(_object_spread({
5704
+ timestampMs: Date.now(),
5705
+ level: level,
5706
+ category: category,
5707
+ message: message
5708
+ }, details ? {
5709
+ details: details
5710
+ } : {}));
5711
+ if (this.debugLogEntries.length > DEBUG_HISTORY_LIMIT) {
5712
+ this.debugLogEntries = this.debugLogEntries.slice(-DEBUG_HISTORY_LIMIT);
5713
+ }
5714
+ }
5715
+ },
5716
+ {
5717
+ key: "getRecentScteMarkers",
5718
+ value: function getRecentScteMarkers() {
5719
+ return this.scteMarkerHistory.map(function(entry) {
5720
+ return _object_spread({
5721
+ timestampMs: entry.timestampMs,
5722
+ type: entry.marker.type
5723
+ }, entry.marker.ptsSeconds !== void 0 ? {
5724
+ ptsSeconds: entry.marker.ptsSeconds
5725
+ } : {}, entry.marker.durationSeconds !== void 0 ? {
5726
+ durationSeconds: entry.marker.durationSeconds
5727
+ } : {}, entry.marker.raw !== void 0 ? {
5728
+ raw: entry.marker.raw
5729
+ } : {});
5730
+ });
5731
+ }
5732
+ },
5733
+ {
5734
+ key: "getDebugLogs",
5735
+ value: function getDebugLogs() {
5736
+ return this.debugLogEntries.slice();
5737
+ }
5738
+ },
5672
5739
  {
5673
5740
  key: "toggleMute",
5674
5741
  value: function toggleMute() {
@@ -5914,13 +5981,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5914
5981
  (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.destroy();
5915
5982
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
5916
5983
  this.consecutiveFailures = 0;
5984
+ this.debugLogEntries = [];
5985
+ this.scteMarkerHistory = [];
5917
5986
  }
5918
5987
  }
5919
5988
  ]);
5920
5989
  return StormcloudVideoPlayer;
5921
5990
  }();
5922
5991
  // src/ui/StormcloudVideoPlayer.tsx
5923
- import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress } from "react-icons/fa";
5992
+ import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress, FaCog, FaTimes } from "react-icons/fa";
5924
5993
  // src/ui/OverlayRenderer.tsx
5925
5994
  import React, { useEffect, useRef, useState, useCallback } from "react";
5926
5995
  // src/utils/overlays.ts
@@ -7027,10 +7096,12 @@ var CRITICAL_PROPS = [
7027
7096
  "allowNativeHls",
7028
7097
  "licenseKey",
7029
7098
  "lowLatencyMode",
7030
- "driftToleranceMs"
7099
+ "driftToleranceMs",
7100
+ "debugAdTiming"
7031
7101
  ];
7032
7102
  var CONTROLS_HIDE_DELAY = 3e3;
7033
7103
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
7104
+ var DEBUG_PANEL_MARKER_LIMIT = 12;
7034
7105
  var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7035
7106
  var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, swirlProjectId = props.swirlProjectId, restVideoAttrs = _object_without_properties(props, [
7036
7107
  "src",
@@ -7093,6 +7164,8 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7093
7164
  var _React2_useState18 = _sliced_to_array(React2.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _React2_useState18[0], setViewportWidth = _React2_useState18[1];
7094
7165
  var _React2_useState19 = _sliced_to_array(React2.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _React2_useState19[0], setIsPortrait = _React2_useState19[1];
7095
7166
  var _React2_useState20 = _sliced_to_array(React2.useState(DEFAULT_PLAYER_ASPECT_RATIO), 2), playerAspectRatio = _React2_useState20[0], setPlayerAspectRatio = _React2_useState20[1];
7167
+ var _React2_useState21 = _sliced_to_array(React2.useState(false), 2), showDebugPanel = _React2_useState21[0], setShowDebugPanel = _React2_useState21[1];
7168
+ var _React2_useState22 = _sliced_to_array(React2.useState([]), 2), debugMarkers = _React2_useState22[0], setDebugMarkers = _React2_useState22[1];
7096
7169
  var getResponsiveScale = function getResponsiveScale() {
7097
7170
  if (viewportWidth < 480) return 0.7;
7098
7171
  if (viewportWidth < 768) return 0.8;
@@ -7100,6 +7173,28 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7100
7173
  return 1;
7101
7174
  };
7102
7175
  var responsiveScale = getResponsiveScale();
7176
+ var formatDebugClock = function formatDebugClock(timestampMs) {
7177
+ try {
7178
+ var localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
7179
+ return new Date(timestampMs).toLocaleTimeString("en-GB", {
7180
+ hour12: false,
7181
+ hour: "2-digit",
7182
+ minute: "2-digit",
7183
+ second: "2-digit",
7184
+ timeZone: localTimeZone
7185
+ });
7186
+ } catch (unused) {
7187
+ return "--:--:--";
7188
+ }
7189
+ };
7190
+ var formatDebugRaw = function formatDebugRaw(raw) {
7191
+ if (!raw || (typeof raw === "undefined" ? "undefined" : _type_of(raw)) !== "object") return "";
7192
+ var obj = raw;
7193
+ if (typeof obj.tag === "string") return obj.tag;
7194
+ if (typeof obj.id3 === "string") return "ID3";
7195
+ if (typeof obj.splice_command_type === "number") return "binary splice";
7196
+ return "marker";
7197
+ };
7103
7198
  var resetControlsTimer = useCallback2(function() {
7104
7199
  if (controlsTimerRef.current) {
7105
7200
  clearTimeout(controlsTimerRef.current);
@@ -7482,6 +7577,26 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7482
7577
  }
7483
7578
  };
7484
7579
  }, []);
7580
+ useEffect2(function() {
7581
+ if (!debugAdTiming) {
7582
+ setShowDebugPanel(false);
7583
+ setDebugMarkers([]);
7584
+ return;
7585
+ }
7586
+ var updateDebugData = function updateDebugData() {
7587
+ var player = playerRef.current;
7588
+ if (!player) return;
7589
+ setDebugMarkers(player.getRecentScteMarkers().slice(-DEBUG_PANEL_MARKER_LIMIT).reverse());
7590
+ };
7591
+ updateDebugData();
7592
+ var interval = window.setInterval(updateDebugData, 500);
7593
+ return function() {
7594
+ return clearInterval(interval);
7595
+ };
7596
+ }, [
7597
+ debugAdTiming,
7598
+ criticalPropsKey
7599
+ ]);
7485
7600
  var handleWrapperMouseMove = useCallback2(function() {
7486
7601
  resetControlsTimer();
7487
7602
  }, [
@@ -7500,7 +7615,7 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7500
7615
  return /* @__PURE__ */ jsxs2(Fragment2, {
7501
7616
  children: [
7502
7617
  /* @__PURE__ */ jsx2("style", {
7503
- children: "\n @keyframes sc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes sc-loading-glow {\n 0%, 100% { opacity: 0.85; transform: scale(1); }\n 50% { opacity: 1; transform: scale(1.05); }\n }\n @keyframes sc-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n @keyframes sc-fade-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .sc-wrapper:fullscreen,\n .sc-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .sc-ctrl-btn {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n padding: 8px;\n transition: background 0.15s ease, opacity 0.15s ease;\n opacity: 0.9;\n }\n .sc-ctrl-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .sc-ctrl-btn:active {\n opacity: 0.7;\n }\n .sc-controls-bar {\n transition: opacity 0.35s ease, transform 0.35s ease;\n }\n .sc-progress-track:hover .sc-progress-thumb {\n transform: translate(-50%, -50%) scale(1) !important;\n }\n .sc-loading-hidden .sc-loading-indicator {\n display: none !important;\n }\n "
7618
+ children: "\n @keyframes sc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes sc-loading-glow {\n 0%, 100% { opacity: 0.85; transform: scale(1); }\n 50% { opacity: 1; transform: scale(1.05); }\n }\n @keyframes sc-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n @keyframes sc-fade-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .sc-wrapper:fullscreen,\n .sc-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .sc-ctrl-btn {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n padding: 8px;\n transition: background 0.15s ease, opacity 0.15s ease;\n opacity: 0.9;\n }\n .sc-ctrl-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .sc-ctrl-btn:active {\n opacity: 0.7;\n }\n .sc-controls-bar {\n transition: opacity 0.35s ease, transform 0.35s ease;\n }\n .sc-progress-track:hover .sc-progress-thumb {\n transform: translate(-50%, -50%) scale(1) !important;\n }\n .sc-loading-hidden .sc-loading-indicator {\n display: none !important;\n }\n .sc-debug-scroll::-webkit-scrollbar {\n width: 8px;\n }\n .sc-debug-scroll::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.22);\n border-radius: 4px;\n }\n .sc-debug-scroll {\n overflow-x: hidden !important;\n }\n "
7504
7619
  }),
7505
7620
  /* @__PURE__ */ jsxs2("div", {
7506
7621
  ref: wrapperRef,
@@ -7742,6 +7857,181 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7742
7857
  })
7743
7858
  ]
7744
7859
  }),
7860
+ debugAdTiming && !showLicenseWarning && !showDebugPanel && /* @__PURE__ */ jsx2("button", {
7861
+ className: "sc-ctrl-btn",
7862
+ onClick: function onClick() {
7863
+ setShowDebugPanel(function(prev) {
7864
+ return !prev;
7865
+ });
7866
+ resetControlsTimer();
7867
+ },
7868
+ style: {
7869
+ position: "absolute",
7870
+ top: "".concat(12 * responsiveScale, "px"),
7871
+ right: "".concat(12 * responsiveScale, "px"),
7872
+ zIndex: 61,
7873
+ width: "".concat(34 * responsiveScale, "px"),
7874
+ height: "".concat(34 * responsiveScale, "px"),
7875
+ borderRadius: "50%",
7876
+ background: showDebugPanel ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.55)",
7877
+ border: "1px solid rgba(255, 255, 255, 0.2)",
7878
+ backdropFilter: "blur(12px)",
7879
+ WebkitBackdropFilter: "blur(12px)"
7880
+ },
7881
+ title: showDebugPanel ? "Hide debug panel" : "Show debug panel",
7882
+ children: /* @__PURE__ */ jsx2(FaCog, {
7883
+ size: Math.max(12, 15 * responsiveScale)
7884
+ })
7885
+ }),
7886
+ debugAdTiming && showDebugPanel && !showLicenseWarning && /* @__PURE__ */ jsxs2("div", {
7887
+ style: {
7888
+ position: "absolute",
7889
+ top: "".concat(12 * responsiveScale, "px"),
7890
+ right: "".concat(12 * responsiveScale, "px"),
7891
+ width: "".concat(Math.min(440, Math.max(320, viewportWidth * 0.42)), "px"),
7892
+ maxWidth: "92vw",
7893
+ height: isPortrait ? "52vh" : "420px",
7894
+ maxHeight: "58vh",
7895
+ zIndex: 60,
7896
+ background: "rgba(10, 10, 10, 0.74)",
7897
+ border: "1px solid rgba(255, 255, 255, 0.14)",
7898
+ borderRadius: "12px",
7899
+ boxShadow: "0 16px 48px rgba(0, 0, 0, 0.45)",
7900
+ backdropFilter: "blur(16px)",
7901
+ WebkitBackdropFilter: "blur(16px)",
7902
+ color: "rgba(255,255,255,0.94)",
7903
+ overflow: "hidden"
7904
+ },
7905
+ children: [
7906
+ /* @__PURE__ */ jsxs2("div", {
7907
+ style: {
7908
+ display: "flex",
7909
+ alignItems: "center",
7910
+ justifyContent: "space-between",
7911
+ padding: "10px 12px",
7912
+ borderBottom: "1px solid rgba(255,255,255,0.1)"
7913
+ },
7914
+ children: [
7915
+ /* @__PURE__ */ jsx2("div", {
7916
+ style: {
7917
+ fontSize: "13px",
7918
+ fontWeight: 700,
7919
+ letterSpacing: "0.02em"
7920
+ },
7921
+ children: "Debug Ad Timing"
7922
+ }),
7923
+ /* @__PURE__ */ jsx2("button", {
7924
+ className: "sc-ctrl-btn",
7925
+ onClick: function onClick() {
7926
+ return setShowDebugPanel(false);
7927
+ },
7928
+ style: {
7929
+ padding: "4px",
7930
+ borderRadius: "6px",
7931
+ minWidth: "26px",
7932
+ minHeight: "26px"
7933
+ },
7934
+ title: "Close panel",
7935
+ children: /* @__PURE__ */ jsx2(FaTimes, {
7936
+ size: 12
7937
+ })
7938
+ })
7939
+ ]
7940
+ }),
7941
+ /* @__PURE__ */ jsx2("div", {
7942
+ className: "sc-debug-scroll",
7943
+ style: {
7944
+ padding: "10px 12px 12px",
7945
+ overflowY: "auto",
7946
+ overflowX: "hidden",
7947
+ height: "calc(100% - 46px)",
7948
+ display: "grid",
7949
+ gap: "12px"
7950
+ },
7951
+ children: /* @__PURE__ */ jsxs2("div", {
7952
+ children: [
7953
+ /* @__PURE__ */ jsx2("div", {
7954
+ style: {
7955
+ fontSize: "11px",
7956
+ fontWeight: 700,
7957
+ textTransform: "uppercase",
7958
+ letterSpacing: "0.08em",
7959
+ color: "rgba(255,255,255,0.68)",
7960
+ marginBottom: "8px"
7961
+ },
7962
+ children: "SCTE-35 markers"
7963
+ }),
7964
+ /* @__PURE__ */ jsx2("div", {
7965
+ style: {
7966
+ display: "grid",
7967
+ gap: "6px"
7968
+ },
7969
+ children: debugMarkers.length === 0 ? /* @__PURE__ */ jsx2("div", {
7970
+ style: {
7971
+ fontSize: "12px",
7972
+ color: "rgba(255,255,255,0.55)"
7973
+ },
7974
+ children: "No markers detected yet."
7975
+ }) : debugMarkers.map(function(entry, idx) {
7976
+ return /* @__PURE__ */ jsxs2("div", {
7977
+ style: {
7978
+ display: "grid",
7979
+ gridTemplateColumns: "56px 52px 1fr",
7980
+ gap: "8px",
7981
+ alignItems: "center",
7982
+ fontFamily: "'SF Mono', 'Cascadia Code', monospace",
7983
+ fontSize: "11px",
7984
+ background: "rgba(255,255,255,0.05)",
7985
+ border: "1px solid rgba(255,255,255,0.08)",
7986
+ borderRadius: "8px",
7987
+ padding: "6px 8px"
7988
+ },
7989
+ children: [
7990
+ /* @__PURE__ */ jsx2("span", {
7991
+ style: {
7992
+ color: "rgba(255,255,255,0.68)"
7993
+ },
7994
+ children: formatDebugClock(entry.timestampMs)
7995
+ }),
7996
+ /* @__PURE__ */ jsx2("span", {
7997
+ style: {
7998
+ textTransform: "uppercase",
7999
+ fontWeight: 700,
8000
+ color: entry.type === "start" ? "#34d399" : entry.type === "end" ? "#f87171" : "#fbbf24"
8001
+ },
8002
+ children: entry.type
8003
+ }),
8004
+ /* @__PURE__ */ jsx2("span", {
8005
+ style: {
8006
+ color: "rgba(255,255,255,0.88)"
8007
+ },
8008
+ children: /* @__PURE__ */ jsxs2("span", {
8009
+ style: {
8010
+ display: "inline-block",
8011
+ maxWidth: "100%",
8012
+ verticalAlign: "bottom",
8013
+ overflow: "hidden",
8014
+ textOverflow: "ellipsis",
8015
+ whiteSpace: "nowrap"
8016
+ },
8017
+ children: [
8018
+ entry.durationSeconds != null ? "dur:".concat(entry.durationSeconds.toFixed(2), "s") : "dur:-",
8019
+ " ",
8020
+ entry.ptsSeconds != null ? "pts:".concat(entry.ptsSeconds.toFixed(2)) : "pts:-",
8021
+ " ",
8022
+ formatDebugRaw(entry.raw)
8023
+ ]
8024
+ })
8025
+ })
8026
+ ]
8027
+ }, "".concat(entry.timestampMs, "-").concat(idx));
8028
+ })
8029
+ })
8030
+ ]
8031
+ })
8032
+ })
8033
+ ]
8034
+ }),
7745
8035
  shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ jsxs2("div", {
7746
8036
  className: "sc-controls-bar",
7747
8037
  style: {