stormcloud-video-player 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,392 @@
1
+ "use strict";
2
+ function _array_like_to_array(arr, len) {
3
+ if (len == null || len > arr.length) len = arr.length;
4
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
5
+ return arr2;
6
+ }
7
+ function _array_with_holes(arr) {
8
+ if (Array.isArray(arr)) return arr;
9
+ }
10
+ function _iterable_to_array_limit(arr, i) {
11
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
12
+ if (_i == null) return;
13
+ var _arr = [];
14
+ var _n = true;
15
+ var _d = false;
16
+ var _s, _e;
17
+ try {
18
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
19
+ _arr.push(_s.value);
20
+ if (i && _arr.length === i) break;
21
+ }
22
+ } catch (err) {
23
+ _d = true;
24
+ _e = err;
25
+ } finally{
26
+ try {
27
+ if (!_n && _i["return"] != null) _i["return"]();
28
+ } finally{
29
+ if (_d) throw _e;
30
+ }
31
+ }
32
+ return _arr;
33
+ }
34
+ function _non_iterable_rest() {
35
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
36
+ }
37
+ function _sliced_to_array(arr, i) {
38
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
39
+ }
40
+ function _type_of(obj) {
41
+ "@swc/helpers - typeof";
42
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
43
+ }
44
+ function _unsupported_iterable_to_array(o, minLen) {
45
+ if (!o) return;
46
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
47
+ var n = Object.prototype.toString.call(o).slice(8, -1);
48
+ if (n === "Object" && o.constructor) n = o.constructor.name;
49
+ if (n === "Map" || n === "Set") return Array.from(n);
50
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
51
+ }
52
+ var __defProp = Object.defineProperty;
53
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
54
+ var __getOwnPropNames = Object.getOwnPropertyNames;
55
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
56
+ var __export = function __export(target, all) {
57
+ for(var name in all)__defProp(target, name, {
58
+ get: all[name],
59
+ enumerable: true
60
+ });
61
+ };
62
+ var __copyProps = function __copyProps(to, from, except, desc) {
63
+ if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
64
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
65
+ try {
66
+ var _loop = function() {
67
+ var key = _step.value;
68
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
69
+ get: function get() {
70
+ return from[key];
71
+ },
72
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
73
+ });
74
+ };
75
+ for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
76
+ } catch (err) {
77
+ _didIteratorError = true;
78
+ _iteratorError = err;
79
+ } finally{
80
+ try {
81
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
82
+ _iterator.return();
83
+ }
84
+ } finally{
85
+ if (_didIteratorError) {
86
+ throw _iteratorError;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ return to;
92
+ };
93
+ var __toCommonJS = function __toCommonJS(mod) {
94
+ return __copyProps(__defProp({}, "__esModule", {
95
+ value: true
96
+ }), mod);
97
+ };
98
+ // src/ui/OverlayRenderer.tsx
99
+ var OverlayRenderer_exports = {};
100
+ __export(OverlayRenderer_exports, {
101
+ OverlayRenderer: function OverlayRenderer1() {
102
+ return OverlayRenderer;
103
+ }
104
+ });
105
+ module.exports = __toCommonJS(OverlayRenderer_exports);
106
+ var import_react = require("react");
107
+ // src/utils/overlays.ts
108
+ var OVERLAY_API_BASE = "https://adstorm.co/api-adstorm-dev";
109
+ function timeStringToSeconds(timeStr) {
110
+ if (!timeStr) return 0;
111
+ var parts = timeStr.split(":");
112
+ if (parts.length >= 3) {
113
+ var _parts_, _parts_1, _parts_2;
114
+ var hours = parseInt((_parts_ = parts[0]) !== null && _parts_ !== void 0 ? _parts_ : "0", 10) || 0;
115
+ var minutes = parseInt((_parts_1 = parts[1]) !== null && _parts_1 !== void 0 ? _parts_1 : "0", 10) || 0;
116
+ var secStr = (_parts_2 = parts[2]) !== null && _parts_2 !== void 0 ? _parts_2 : "0";
117
+ var dotIdx = secStr.indexOf(".");
118
+ var seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;
119
+ var msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : "";
120
+ var ms = msFrag ? parseInt(msFrag.padEnd(3, "0").substring(0, 3), 10) || 0 : 0;
121
+ return hours * 3600 + minutes * 60 + seconds + ms / 1e3;
122
+ }
123
+ if (parts.length === 2) {
124
+ var _parts_3, _parts_4;
125
+ var minutes1 = parseInt((_parts_3 = parts[0]) !== null && _parts_3 !== void 0 ? _parts_3 : "0", 10) || 0;
126
+ var secStr1 = (_parts_4 = parts[1]) !== null && _parts_4 !== void 0 ? _parts_4 : "0";
127
+ var dotIdx1 = secStr1.indexOf(".");
128
+ var seconds1 = parseInt(dotIdx1 >= 0 ? secStr1.substring(0, dotIdx1) : secStr1, 10) || 0;
129
+ var msFrag1 = dotIdx1 >= 0 ? secStr1.substring(dotIdx1 + 1) : "";
130
+ var ms1 = msFrag1 ? parseInt(msFrag1.padEnd(3, "0").substring(0, 3), 10) || 0 : 0;
131
+ return minutes1 * 60 + seconds1 + ms1 / 1e3;
132
+ }
133
+ var num = parseFloat(timeStr);
134
+ return isFinite(num) ? Math.max(0, num) : 0;
135
+ }
136
+ function isOverlayActive(overlay, currentTime) {
137
+ if (!overlay.visible) return false;
138
+ var startSec = timeStringToSeconds(overlay.start_time);
139
+ var durationSec = timeStringToSeconds(overlay.duration);
140
+ if (durationSec <= 0) return false;
141
+ return currentTime >= startSec && currentTime < startSec + durationSec;
142
+ }
143
+ function resolveImageUrl(imageUrl) {
144
+ var apiBaseUrl = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : OVERLAY_API_BASE;
145
+ if (!imageUrl) return "";
146
+ if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
147
+ return imageUrl;
148
+ }
149
+ if (imageUrl.startsWith("/")) {
150
+ try {
151
+ var url = new URL(apiBaseUrl);
152
+ return "".concat(url.origin).concat(imageUrl);
153
+ } catch (unused) {
154
+ return imageUrl;
155
+ }
156
+ }
157
+ return "".concat(apiBaseUrl, "/").concat(imageUrl);
158
+ }
159
+ // src/ui/OverlayRenderer.tsx
160
+ var import_jsx_runtime = require("react/jsx-runtime");
161
+ function computeVideoDimensions(video) {
162
+ var nativeWidth = video.videoWidth;
163
+ var nativeHeight = video.videoHeight;
164
+ if (!nativeWidth || !nativeHeight) return null;
165
+ var displayWidth = video.offsetWidth;
166
+ var displayHeight = video.offsetHeight;
167
+ if (!displayWidth || !displayHeight) return null;
168
+ var videoAspect = nativeWidth / nativeHeight;
169
+ var displayAspect = displayWidth / displayHeight;
170
+ var renderWidth;
171
+ var renderHeight;
172
+ var offsetX;
173
+ var offsetY;
174
+ if (videoAspect > displayAspect) {
175
+ renderWidth = displayWidth;
176
+ renderHeight = displayWidth / videoAspect;
177
+ offsetX = 0;
178
+ offsetY = (displayHeight - renderHeight) / 2;
179
+ } else {
180
+ renderHeight = displayHeight;
181
+ renderWidth = displayHeight * videoAspect;
182
+ offsetX = (displayWidth - renderWidth) / 2;
183
+ offsetY = 0;
184
+ }
185
+ return {
186
+ nativeWidth: nativeWidth,
187
+ nativeHeight: nativeHeight,
188
+ displayWidth: renderWidth,
189
+ displayHeight: renderHeight,
190
+ offsetX: offsetX,
191
+ offsetY: offsetY,
192
+ scaleX: renderWidth / nativeWidth,
193
+ scaleY: renderHeight / nativeHeight
194
+ };
195
+ }
196
+ function ImageOverlay(param) {
197
+ var overlay = param.overlay;
198
+ var src = resolveImageUrl(overlay.image_url || "");
199
+ if (!src) return null;
200
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
201
+ src: src,
202
+ alt: overlay.name,
203
+ draggable: false,
204
+ style: {
205
+ width: "100%",
206
+ height: "100%",
207
+ objectFit: "contain",
208
+ display: "block",
209
+ pointerEvents: "none",
210
+ userSelect: "none"
211
+ }
212
+ });
213
+ }
214
+ function TextOverlay(param) {
215
+ var overlay = param.overlay;
216
+ var text = overlay.content || "";
217
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
218
+ style: {
219
+ width: "100%",
220
+ height: "100%",
221
+ display: "flex",
222
+ alignItems: "center",
223
+ justifyContent: "center",
224
+ color: "#ffffff",
225
+ fontSize: "clamp(10px, 1.4vw, 20px)",
226
+ fontFamily: "Roboto, 'Segoe UI', Arial, sans-serif",
227
+ fontWeight: 600,
228
+ textAlign: "center",
229
+ padding: "4px 8px",
230
+ boxSizing: "border-box",
231
+ wordBreak: "break-word",
232
+ textShadow: "0 1px 4px rgba(0,0,0,0.7)",
233
+ pointerEvents: "none",
234
+ userSelect: "none",
235
+ lineHeight: 1.3
236
+ },
237
+ children: text
238
+ });
239
+ }
240
+ function ScrollerOverlay(param) {
241
+ var overlay = param.overlay;
242
+ var _ref, _ref1, _ref2, _ref3, _ref4;
243
+ var cfg = overlay.scroller_config;
244
+ var text = (cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && cfg.custom_text ? cfg.custom_text : overlay.content || (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text) || "";
245
+ var scrollSpeed = (_ref = cfg === null || cfg === void 0 ? void 0 : cfg.scroll_speed) !== null && _ref !== void 0 ? _ref : 50;
246
+ var direction = (_ref1 = cfg === null || cfg === void 0 ? void 0 : cfg.direction) !== null && _ref1 !== void 0 ? _ref1 : "left";
247
+ var fontSize = (cfg === null || cfg === void 0 ? void 0 : cfg.font_size) ? "".concat(cfg.font_size, "px") : "clamp(10px, 1.2vw, 18px)";
248
+ var fontFamily = (cfg === null || cfg === void 0 ? void 0 : cfg.font_family) || "Roboto, 'Segoe UI', Arial, sans-serif";
249
+ var fontWeight = (cfg === null || cfg === void 0 ? void 0 : cfg.font_weight) || "600";
250
+ var textColor = (cfg === null || cfg === void 0 ? void 0 : cfg.text_color) || "#ffffff";
251
+ var bgColor = (cfg === null || cfg === void 0 ? void 0 : cfg.background_color) || "transparent";
252
+ var bgOpacity = (cfg === null || cfg === void 0 ? void 0 : cfg.background_opacity) !== void 0 ? cfg.background_opacity / 100 : 0;
253
+ var borderColor = (cfg === null || cfg === void 0 ? void 0 : cfg.border_color) || "transparent";
254
+ var borderWidth = (_ref2 = cfg === null || cfg === void 0 ? void 0 : cfg.border_width) !== null && _ref2 !== void 0 ? _ref2 : 0;
255
+ var borderRadius = (_ref3 = cfg === null || cfg === void 0 ? void 0 : cfg.border_radius) !== null && _ref3 !== void 0 ? _ref3 : 0;
256
+ var padding = (_ref4 = cfg === null || cfg === void 0 ? void 0 : cfg.padding) !== null && _ref4 !== void 0 ? _ref4 : 4;
257
+ var isVertical = direction === "up" || direction === "down";
258
+ var isReverse = direction === "right" || direction === "down";
259
+ var durationSec = Math.max(3, 120 - scrollSpeed);
260
+ var animId = "sc-scroller-".concat(overlay.id);
261
+ var keyframes = isVertical ? "@keyframes ".concat(animId, " {\n 0% { transform: translateY(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateY(").concat(isReverse ? "100%" : "-100%", "); }\n }") : "@keyframes ".concat(animId, " {\n 0% { transform: translateX(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateX(").concat(isReverse ? "100%" : "-100%", "); }\n }");
262
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
263
+ children: [
264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", {
265
+ children: keyframes
266
+ }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
268
+ style: {
269
+ width: "100%",
270
+ height: "100%",
271
+ overflow: "hidden",
272
+ display: "flex",
273
+ alignItems: "center",
274
+ backgroundColor: bgOpacity > 0 ? "rgba(".concat(hexToRgb(bgColor), ", ").concat(bgOpacity, ")") : void 0,
275
+ border: borderWidth > 0 ? "".concat(borderWidth, "px solid ").concat(borderColor) : void 0,
276
+ borderRadius: borderRadius > 0 ? "".concat(borderRadius, "px") : void 0,
277
+ padding: "".concat(padding, "px"),
278
+ boxSizing: "border-box",
279
+ pointerEvents: "none"
280
+ },
281
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
282
+ style: {
283
+ whiteSpace: "nowrap",
284
+ fontSize: fontSize,
285
+ fontFamily: fontFamily,
286
+ fontWeight: fontWeight,
287
+ color: textColor,
288
+ animation: "".concat(animId, " ").concat(durationSec, "s linear infinite"),
289
+ textShadow: "0 1px 4px rgba(0,0,0,0.5)",
290
+ userSelect: "none"
291
+ },
292
+ children: text
293
+ })
294
+ })
295
+ ]
296
+ });
297
+ }
298
+ function hexToRgb(hex) {
299
+ if (!hex || !hex.startsWith("#")) return "0,0,0";
300
+ var clean = hex.slice(1);
301
+ var num = parseInt(clean.length === 3 ? clean.replace(/./g, "$&$&") : clean, 16);
302
+ return "".concat(num >> 16 & 255, ",").concat(num >> 8 & 255, ",").concat(num & 255);
303
+ }
304
+ var OverlayRenderer = function OverlayRenderer(param) {
305
+ var overlays = param.overlays, currentTime = param.currentTime, videoRef = param.videoRef, coordinateSpace = param.coordinateSpace;
306
+ var _ref = _sliced_to_array((0, import_react.useState)(null), 2), dims = _ref[0], setDims = _ref[1];
307
+ var rafRef = (0, import_react.useRef)(null);
308
+ var updateDims = (0, import_react.useCallback)(function() {
309
+ var video = videoRef.current;
310
+ if (video) {
311
+ var computed = computeVideoDimensions(video);
312
+ setDims(function(prev) {
313
+ if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {
314
+ return prev;
315
+ }
316
+ return computed;
317
+ });
318
+ }
319
+ }, [
320
+ videoRef
321
+ ]);
322
+ (0, import_react.useEffect)(function() {
323
+ updateDims();
324
+ var interval = setInterval(updateDims, 500);
325
+ var handleResize = function handleResize() {
326
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
327
+ rafRef.current = requestAnimationFrame(updateDims);
328
+ };
329
+ window.addEventListener("resize", handleResize);
330
+ return function() {
331
+ clearInterval(interval);
332
+ window.removeEventListener("resize", handleResize);
333
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
334
+ };
335
+ }, [
336
+ updateDims
337
+ ]);
338
+ var activeOverlays = overlays.filter(function(o) {
339
+ return isOverlayActive(o, currentTime);
340
+ });
341
+ if (!dims || activeOverlays.length === 0) return null;
342
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
343
+ "aria-hidden": "true",
344
+ style: {
345
+ position: "absolute",
346
+ left: "".concat(dims.offsetX, "px"),
347
+ top: "".concat(dims.offsetY, "px"),
348
+ width: "".concat(dims.displayWidth, "px"),
349
+ height: "".concat(dims.displayHeight, "px"),
350
+ pointerEvents: "none",
351
+ overflow: "hidden",
352
+ zIndex: 8
353
+ },
354
+ children: activeOverlays.map(function(overlay) {
355
+ var scaleX = (coordinateSpace === null || coordinateSpace === void 0 ? void 0 : coordinateSpace.width) ? dims.displayWidth / coordinateSpace.width : dims.scaleX;
356
+ var scaleY = (coordinateSpace === null || coordinateSpace === void 0 ? void 0 : coordinateSpace.height) ? dims.displayHeight / coordinateSpace.height : dims.scaleY;
357
+ var left = overlay.x * scaleX;
358
+ var top = overlay.y * scaleY;
359
+ var width = overlay.width * scaleX;
360
+ var height = overlay.height * scaleY;
361
+ var opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;
362
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
363
+ style: {
364
+ position: "absolute",
365
+ left: "".concat(left, "px"),
366
+ top: "".concat(top, "px"),
367
+ width: "".concat(width, "px"),
368
+ height: "".concat(height, "px"),
369
+ opacity: opacity,
370
+ zIndex: overlay.z_index,
371
+ overflow: "hidden"
372
+ },
373
+ children: [
374
+ overlay.type === "image" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, {
375
+ overlay: overlay
376
+ }),
377
+ overlay.type === "text" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, {
378
+ overlay: overlay
379
+ }),
380
+ overlay.type === "scroller" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, {
381
+ overlay: overlay
382
+ })
383
+ ]
384
+ }, overlay.id);
385
+ })
386
+ });
387
+ };
388
+ // Annotate the CommonJS export names for ESM import in node:
389
+ 0 && (module.exports = {
390
+ OverlayRenderer: OverlayRenderer
391
+ });
392
+ //# sourceMappingURL=OverlayRenderer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/OverlayRenderer.cjs","../../src/ui/OverlayRenderer.tsx","../../src/utils/overlays.ts"],"names":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toCommonJS","mod","value","OverlayRenderer_exports","OverlayRenderer","module","exports","import_react","require","OVERLAY_API_BASE","timeStringToSeconds","timeStr","parts","split","length","hours","parseInt","minutes","secStr","dotIdx","indexOf","seconds","substring","msFrag","ms","padEnd","isFinite","num","Math","max","isOverlayActive","overlay","currentTime","visible","startSec","durationSec","start_time","duration","resolveImageUrl","imageUrl","apiBaseUrl","startsWith","url","URL","origin","import_jsx_runtime","nativeWidth","video","videoWidth","nativeHeight","videoHeight","displayWidth","offsetWidth","displayHeight","offsetHeight","videoAspect","displayAspect","renderWidth","renderHeight","offsetX","offsetY","scaleX","scaleY","ImageOverlay","src","image_url","jsx","alt","draggable","style","width","height","objectFit","display","pointerEvents","userSelect","TextOverlay","text","content","justifyContent","fontSize","fontFamily","fontWeight","textAlign","padding","boxSizing","wordBreak","textShadow","lineHeight","children","ScrollerOverlay","cfg","scroller_config","use_custom_text","custom_text","scrollSpeed","scroll_speed","direction","font_size","font_family","font_weight","textColor","text_color","bgColor","background_color","bgOpacity","background_opacity","borderColor","border_color","borderWidth","border_width","borderRadius","border_radius","isVertical","isReverse","animId","id","keyframes","jsxs","Fragment","overflow","alignItems","backgroundColor","hexToRgb","border","whiteSpace","color","animation","hex","clean","slice","replace","overlays","videoRef","coordinateSpace","useState","dims","setDims","rafRef","useRef","updateDims","useCallback","current","computed","computeVideoDimensions","prev"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/OverlayRenderer.tsx\nvar OverlayRenderer_exports = {};\n__export(OverlayRenderer_exports, {\n OverlayRenderer: () => OverlayRenderer\n});\nmodule.exports = __toCommonJS(OverlayRenderer_exports);\nvar import_react = require(\"react\");\n\n// src/utils/overlays.ts\nvar OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\nfunction timeStringToSeconds(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(\":\");\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1e3;\n }\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1e3;\n }\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\nfunction isOverlayActive(overlay, currentTime) {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\nfunction resolveImageUrl(imageUrl, apiBaseUrl = OVERLAY_API_BASE) {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n\n// src/ui/OverlayRenderer.tsx\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nfunction computeVideoDimensions(video) {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n let renderWidth;\n let renderHeight;\n let offsetX;\n let offsetY;\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight\n };\n}\nfunction ImageOverlay({ overlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src,\n alt: overlay.name,\n draggable: false,\n style: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\"\n }\n }\n );\n}\nfunction TextOverlay({ overlay }) {\n const text = overlay.content || \"\";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3\n },\n children: text\n }\n );\n}\nfunction ScrollerOverlay({ overlay }) {\n const cfg = overlay.scroller_config;\n const text = cfg?.use_custom_text && cfg.custom_text ? cfg.custom_text : overlay.content || cfg?.custom_text || \"\";\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== void 0 ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n const durationSec = Math.max(3, 120 - scrollSpeed);\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }` : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: keyframes }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor: bgOpacity > 0 ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})` : void 0,\n border: borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : void 0,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : void 0,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\"\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\"\n },\n children: text\n }\n )\n }\n )\n ] });\n}\nfunction hexToRgb(hex) {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${num >> 16 & 255},${num >> 8 & 255},${num & 255}`;\n}\nvar OverlayRenderer = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace\n}) => {\n const [dims, setDims] = (0, import_react.useState)(null);\n const rafRef = (0, import_react.useRef)(null);\n const updateDims = (0, import_react.useCallback)(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n (0, import_react.useEffect)(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n const activeOverlays = overlays.filter(\n (o) => isOverlayActive(o, currentTime)\n );\n if (!dims || activeOverlays.length === 0) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n \"aria-hidden\": \"true\",\n style: {\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8\n },\n children: activeOverlays.map((overlay) => {\n const scaleX = coordinateSpace?.width ? dims.displayWidth / coordinateSpace.width : dims.scaleX;\n const scaleY = coordinateSpace?.height ? dims.displayHeight / coordinateSpace.height : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\"\n },\n children: [\n overlay.type === \"image\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, { overlay }),\n overlay.type === \"text\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, { overlay }),\n overlay.type === \"scroller\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, { overlay })\n ]\n },\n overlay.id\n );\n })\n }\n );\n};\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n OverlayRenderer\n});\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n type SwirlOverlay,\n isOverlayActive,\n resolveImageUrl,\n} from \"../utils/overlays\";\n\ninterface VideoDimensions {\n nativeWidth: number;\n nativeHeight: number;\n displayWidth: number;\n displayHeight: number;\n offsetX: number;\n offsetY: number;\n scaleX: number;\n scaleY: number;\n}\n\ninterface OverlayRendererProps {\n overlays: SwirlOverlay[];\n currentTime: number;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n coordinateSpace?: { width: number; height: number } | null;\n}\n\nfunction computeVideoDimensions(\n video: HTMLVideoElement\n): VideoDimensions | null {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n\n let renderWidth: number;\n let renderHeight: number;\n let offsetX: number;\n let offsetY: number;\n\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight,\n };\n}\n\nfunction ImageOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return (\n <img\n src={src}\n alt={overlay.name}\n draggable={false}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n );\n}\n\nfunction TextOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const text = overlay.content || \"\";\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3,\n }}\n >\n {text}\n </div>\n );\n}\n\nfunction ScrollerOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const cfg = overlay.scroller_config;\n const text =\n cfg?.use_custom_text && cfg.custom_text\n ? cfg.custom_text\n : overlay.content || cfg?.custom_text || \"\";\n\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== undefined ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n const durationSec = Math.max(3, 120 - scrollSpeed);\n\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical\n ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }`\n : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n\n return (\n <>\n <style>{keyframes}</style>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor:\n bgOpacity > 0\n ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`\n : undefined,\n border:\n borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : undefined,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : undefined,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\",\n }}\n >\n {text}\n </div>\n </div>\n </>\n );\n}\n\nfunction hexToRgb(hex: string): string {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${(num >> 16) & 255},${(num >> 8) & 255},${num & 255}`;\n}\n\nexport const OverlayRenderer: React.FC<OverlayRendererProps> = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n}) => {\n const [dims, setDims] = useState<VideoDimensions | null>(null);\n const rafRef = useRef<number | null>(null);\n\n const updateDims = useCallback(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (\n !computed ||\n (prev &&\n prev.nativeWidth === computed.nativeWidth &&\n prev.nativeHeight === computed.nativeHeight &&\n prev.displayWidth === computed.displayWidth &&\n prev.displayHeight === computed.displayHeight &&\n prev.offsetX === computed.offsetX &&\n prev.offsetY === computed.offsetY)\n ) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n\n useEffect(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n\n const activeOverlays = overlays.filter((o) =>\n isOverlayActive(o, currentTime)\n );\n\n if (!dims || activeOverlays.length === 0) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8,\n }}\n >\n {activeOverlays.map((overlay) => {\n const scaleX =\n coordinateSpace?.width\n ? dims.displayWidth / coordinateSpace.width\n : dims.scaleX;\n const scaleY =\n coordinateSpace?.height\n ? dims.displayHeight / coordinateSpace.height\n : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n\n return (\n <div\n key={overlay.id}\n style={{\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\",\n }}\n >\n {overlay.type === \"image\" && (\n <ImageOverlay overlay={overlay} />\n )}\n {overlay.type === \"text\" && <TextOverlay overlay={overlay} />}\n {overlay.type === \"scroller\" && (\n <ScrollerOverlay overlay={overlay} />\n )}\n </div>\n );\n })}\n </div>\n );\n};\n","const OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\n\nexport interface OverlayCoordinateSpace {\n width: number;\n height: number;\n}\n\nexport interface SwirlScrollerConfig {\n rss_url?: string;\n update_interval?: number;\n scroll_speed?: number;\n direction?: string;\n font_size?: number;\n font_family?: string;\n font_weight?: string;\n text_color?: string;\n background_color?: string;\n background_opacity?: number;\n border_color?: string;\n border_width?: number;\n border_radius?: number;\n padding?: number;\n margin?: number;\n show_title?: boolean;\n show_description?: boolean;\n show_timestamp?: boolean;\n show_author?: boolean;\n show_category?: boolean;\n max_items?: number;\n item_spacing?: number;\n fade_in_out?: boolean;\n fade_distance?: number;\n auto_refresh?: boolean;\n use_custom_text?: boolean;\n custom_text?: string;\n}\n\nexport interface SwirlOverlay {\n id: number;\n project_id: number;\n name: string;\n type: \"image\" | \"text\" | \"scroller\" | string;\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n opacity: number;\n start_time: string;\n duration: string;\n content?: string;\n image_url?: string;\n scroller_config?: SwirlScrollerConfig;\n z_index: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport function timeStringToSeconds(timeStr: string): number {\n if (!timeStr) return 0;\n\n const parts = timeStr.split(\":\");\n\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1000;\n }\n\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1000;\n }\n\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\n\nexport function isOverlayActive(\n overlay: SwirlOverlay,\n currentTime: number\n): boolean {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\n\nexport async function fetchProjectOverlays(\n projectId: number,\n apiBaseUrl: string = OVERLAY_API_BASE\n): Promise<SwirlOverlay[]> {\n const response = await fetch(\n `${apiBaseUrl}/adstorm/swirl/projects/${projectId}/overlays`\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch overlays: ${response.status} ${response.statusText}`\n );\n }\n const data = await response.json();\n return Array.isArray(data) ? data : [];\n}\n\nexport function resolveImageUrl(\n imageUrl: string,\n apiBaseUrl: string = OVERLAY_API_BASE\n): string {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { SwirlOverlay } from '../utils/overlays.cjs';
3
+
4
+ interface OverlayRendererProps {
5
+ overlays: SwirlOverlay[];
6
+ currentTime: number;
7
+ videoRef: React.RefObject<HTMLVideoElement | null>;
8
+ coordinateSpace?: {
9
+ width: number;
10
+ height: number;
11
+ } | null;
12
+ }
13
+ declare const OverlayRenderer: React.FC<OverlayRendererProps>;
14
+
15
+ export { OverlayRenderer };