stormcloud-video-player 0.8.54 → 0.8.55

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.
Files changed (70) hide show
  1. package/dist/stormcloud-vp.min.js +1 -1
  2. package/lib/index.cjs +124 -101
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.d.cts +1 -0
  5. package/lib/index.d.ts +1 -0
  6. package/lib/index.js +124 -101
  7. package/lib/index.js.map +1 -1
  8. package/lib/player/AdBreakOrchestrator.cjs +69 -66
  9. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  10. package/lib/player/AdBreakOrchestrator.d.cts +1 -1
  11. package/lib/player/AdConfigManager.cjs +38 -33
  12. package/lib/player/AdConfigManager.cjs.map +1 -1
  13. package/lib/player/AdConfigManager.d.cts +1 -1
  14. package/lib/player/AdTimingService.cjs +18 -25
  15. package/lib/player/AdTimingService.cjs.map +1 -1
  16. package/lib/player/AdTimingService.d.cts +1 -1
  17. package/lib/player/HlsEngine.cjs +12 -21
  18. package/lib/player/HlsEngine.cjs.map +1 -1
  19. package/lib/player/HlsEngine.d.cts +1 -1
  20. package/lib/player/PlaceholderLayer.cjs +1 -3
  21. package/lib/player/PlaceholderLayer.cjs.map +1 -1
  22. package/lib/player/PlayerControls.cjs.map +1 -1
  23. package/lib/player/PlayerControls.d.cts +1 -1
  24. package/lib/player/Scte35CueManager.cjs +2 -4
  25. package/lib/player/Scte35CueManager.cjs.map +1 -1
  26. package/lib/player/Scte35CueManager.d.cts +1 -1
  27. package/lib/player/Scte35Parser.cjs +6 -12
  28. package/lib/player/Scte35Parser.cjs.map +1 -1
  29. package/lib/player/Scte35Parser.d.cts +1 -1
  30. package/lib/player/StormcloudVideoPlayer.cjs +114 -87
  31. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  32. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  33. package/lib/player/playerTypes.cjs.map +1 -1
  34. package/lib/player/playerTypes.d.cts +1 -1
  35. package/lib/players/FilePlayer.cjs +17 -26
  36. package/lib/players/FilePlayer.cjs.map +1 -1
  37. package/lib/players/HlsPlayer.cjs +124 -101
  38. package/lib/players/HlsPlayer.cjs.map +1 -1
  39. package/lib/players/HlsPlayer.d.cts +1 -1
  40. package/lib/players/index.cjs +124 -101
  41. package/lib/players/index.cjs.map +1 -1
  42. package/lib/sdk/hlsAdPlayer.cjs +42 -19
  43. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  44. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  45. package/lib/sdk/pal.cjs +6 -9
  46. package/lib/sdk/pal.cjs.map +1 -1
  47. package/lib/{types-cTqIKw_D.d.cts → types-DpbgEvSH.d.cts} +1 -0
  48. package/lib/ui/StormcloudVideoPlayer.cjs +114 -87
  49. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  50. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  51. package/lib/utils/browserCompat.cjs +3 -6
  52. package/lib/utils/browserCompat.cjs.map +1 -1
  53. package/lib/utils/ctvVastSignals.cjs +3 -6
  54. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  55. package/lib/utils/devUrl.cjs.map +1 -1
  56. package/lib/utils/mqttClient.cjs +1 -3
  57. package/lib/utils/mqttClient.cjs.map +1 -1
  58. package/lib/utils/mqttConfig.cjs +1 -3
  59. package/lib/utils/mqttConfig.cjs.map +1 -1
  60. package/lib/utils/polyfills.cjs +4 -7
  61. package/lib/utils/polyfills.cjs.map +1 -1
  62. package/lib/utils/tracking.cjs +27 -20
  63. package/lib/utils/tracking.cjs.map +1 -1
  64. package/lib/utils/tracking.d.cts +1 -1
  65. package/lib/utils/vastEnvironmentSignals.cjs +7 -6
  66. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  67. package/lib/utils/vastEnvironmentSignals.d.cts +2 -1
  68. package/lib/utils/vastMacros.cjs +4 -2
  69. package/lib/utils/vastMacros.cjs.map +1 -1
  70. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { A as AdController } from '../types-cTqIKw_D.cjs';
1
+ import { A as AdController } from '../types-DpbgEvSH.cjs';
2
2
  import Hls from 'hls.js';
3
3
 
4
4
  declare function createHlsAdPlayer(contentVideo: HTMLVideoElement, options?: {
package/lib/sdk/pal.cjs CHANGED
@@ -7,11 +7,8 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
7
7
  reject(error);
8
8
  return;
9
9
  }
10
- if (info.done) {
11
- resolve(value);
12
- } else {
13
- Promise.resolve(value).then(_next, _throw);
14
- }
10
+ if (info.done) resolve(value);
11
+ else Promise.resolve(value).then(_next, _throw);
15
12
  }
16
13
  function _async_to_generator(fn) {
17
14
  return function() {
@@ -28,10 +25,6 @@ function _async_to_generator(fn) {
28
25
  });
29
26
  };
30
27
  }
31
- function _type_of(obj) {
32
- "@swc/helpers - typeof";
33
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
34
- }
35
28
  function _ts_generator(thisArg, body) {
36
29
  var f, y, t, _ = {
37
30
  label: 0,
@@ -131,6 +124,10 @@ function _ts_generator(thisArg, body) {
131
124
  };
132
125
  }
133
126
  }
127
+ function _type_of(obj) {
128
+ "@swc/helpers - typeof";
129
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
130
+ }
134
131
  var __defProp = Object.defineProperty;
135
132
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
136
133
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/pal.cjs","../../src/sdk/pal.ts","../../src/utils/devUrl.ts"],"names":["__getOwnPropDesc","Object","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","__defProp","enumerable","__copyProps","to","from","except","desc","key","call","__toCommonJS","mod","value","pal_exports","createPalNonceManager","module","exports","PRIVATE_HOST_PATTERNS","isLocalDevHost","hostname","host","replace","toLowerCase","endsWith","some","pattern","test","toDevSafeUrl","rawUrl","url","URL","protocol"],"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/sdk/pal.ts\nvar pal_exports = {};\n__export(pal_exports, {\n createPalNonceManager: () => createPalNonceManager\n});\nmodule.exports = __toCommonJS(pal_exports);\n\n// src/utils/devUrl.ts\nvar PRIVATE_HOST_PATTERNS = [\n /^localhost$/i,\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^0\\.0\\.0\\.0$/,\n /^::1$/,\n /^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/,\n /^172\\.(1[6-9]|2\\d|3[0-1])\\.\\d{1,3}\\.\\d{1,3}$/\n];\nfunction isLocalDevHost(hostname) {\n const host = hostname.replace(/^\\[/, \"\").replace(/\\]$/, \"\").toLowerCase();\n if (!host) return false;\n if (host.endsWith(\".local\") || host.endsWith(\".localhost\")) return true;\n return PRIVATE_HOST_PATTERNS.some((pattern) => pattern.test(host));\n}\nfunction toDevSafeUrl(rawUrl) {\n if (!rawUrl) return rawUrl ?? \"\";\n let url;\n try {\n url = new URL(rawUrl);\n } catch {\n return rawUrl;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return rawUrl;\n }\n if (!isLocalDevHost(url.hostname)) {\n return rawUrl;\n }\n const cleanPath = url.pathname.replace(/\\/{2,}/g, \"/\") || \"/index.html\";\n return `file://${cleanPath}`;\n}\n\n// src/sdk/pal.ts\nvar PAL_SDK_URL = \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\nvar _nonceLoader;\nvar _palLoadPromise;\nfunction loadPalSdk() {\n if (typeof window !== \"undefined\" && window.goog?.pal) {\n return Promise.resolve();\n }\n if (_palLoadPromise) return _palLoadPromise;\n _palLoadPromise = new Promise((resolve, reject) => {\n const existing = document.querySelector(\n 'script[data-pal=\"true\"]'\n );\n if (existing) {\n if (window.goog?.pal) {\n resolve();\n return;\n }\n const timeout = setTimeout(\n () => reject(new Error(\"PAL SDK load timeout\")),\n 1e4\n );\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"PAL SDK load failed\"));\n });\n return;\n }\n const script = document.createElement(\"script\");\n script.src = PAL_SDK_URL;\n script.async = true;\n script.setAttribute(\"data-pal\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n document.head.appendChild(script);\n });\n return _palLoadPromise;\n}\nfunction getOrCreateNonceLoader() {\n if (_nonceLoader) return _nonceLoader;\n const goog = window.goog;\n const consentSettings = new goog.pal.ConsentSettings();\n consentSettings.allowStorage = true;\n _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n return _nonceLoader;\n}\nfunction createPalNonceManager() {\n let currentNonce = \"\";\n let currentNonceManager;\n return {\n async generateNonce(options = {}) {\n try {\n await loadPalSdk();\n const loader = getOrCreateNonceLoader();\n const goog = window.goog;\n const request = new goog.pal.NonceRequest();\n request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n request.playerVolume = options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n request.continuousPlayback = options.continuousPlayback ?? true;\n request.descriptionUrl = toDevSafeUrl(\n options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.iconsSupported = true;\n request.playerType = \"StormcloudVideoPlayer\";\n request.playerVersion = \"1.0\";\n request.supportedApiFrameworks = \"2,7,9\";\n request.url = toDevSafeUrl(\n options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.videoWidth = options.videoWidth || 640;\n request.videoHeight = options.videoHeight || 480;\n if (options.ppid) request.ppid = options.ppid;\n if (options.sessionId) request.sessionId = options.sessionId;\n console.log(\n \"[PAL] NonceRequest before generateNonce:\",\n JSON.stringify({\n adWillAutoPlay: request.adWillAutoPlay,\n adWillPlayMuted: request.adWillPlayMuted,\n playerVolume: request.playerVolume,\n continuousPlayback: request.continuousPlayback,\n descriptionUrl: request.descriptionUrl,\n iconsSupported: request.iconsSupported,\n playerType: request.playerType,\n playerVersion: request.playerVersion,\n supportedApiFrameworks: request.supportedApiFrameworks,\n url: request.url,\n videoWidth: request.videoWidth,\n videoHeight: request.videoHeight,\n ppid: request.ppid,\n sessionId: request.sessionId\n }, null, 2)\n );\n const manager = await loader.loadNonceManager(request);\n currentNonceManager = manager;\n currentNonce = manager.getNonce();\n console.log(\"[PAL] Nonce generated successfully\");\n return currentNonce;\n } catch (error) {\n console.warn(\"[PAL] Failed to generate nonce:\", error);\n currentNonce = \"\";\n currentNonceManager = void 0;\n return \"\";\n }\n },\n getCurrentNonce() {\n return currentNonce;\n },\n injectNonce(vastTagUrl) {\n if (!currentNonce || !vastTagUrl) return vastTagUrl;\n try {\n const url = new URL(vastTagUrl);\n url.searchParams.delete(\"paln\");\n url.searchParams.set(\"givn\", currentNonce);\n return url.toString();\n } catch {\n let base = vastTagUrl.replace(/([?&])paln=[^&]*/g, \"\").replace(/[?&]$/, \"\");\n const sep = base.includes(\"?\") ? \"&\" : \"?\";\n return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n }\n },\n sendPlaybackStart() {\n try {\n currentNonceManager?.sendPlaybackStart();\n } catch {\n }\n },\n sendPlaybackEnd() {\n try {\n currentNonceManager?.sendPlaybackEnd();\n } catch {\n }\n },\n sendAdClick() {\n try {\n currentNonceManager?.sendAdClick();\n } catch {\n }\n },\n sendAdTouch(event) {\n try {\n currentNonceManager?.sendAdTouch(event);\n } catch {\n }\n },\n reset() {\n currentNonce = \"\";\n currentNonceManager = void 0;\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createPalNonceManager\n});\n","import { toDevSafeUrl } from \"../utils/devUrl\";\n\ndeclare global {\n interface Window {\n goog?: any;\n }\n}\n\nconst PAL_SDK_URL =\n \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\n\nlet _nonceLoader: any | undefined;\nlet _palLoadPromise: Promise<void> | undefined;\n\nfunction loadPalSdk(): Promise<void> {\n if (typeof window !== \"undefined\" && window.goog?.pal) {\n return Promise.resolve();\n }\n\n if (_palLoadPromise) return _palLoadPromise;\n\n _palLoadPromise = new Promise<void>((resolve, reject) => {\n const existing = document.querySelector(\n 'script[data-pal=\"true\"]'\n ) as HTMLScriptElement | null;\n\n if (existing) {\n if (window.goog?.pal) {\n resolve();\n return;\n }\n const timeout = setTimeout(\n () => reject(new Error(\"PAL SDK load timeout\")),\n 10000\n );\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"PAL SDK load failed\"));\n });\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = PAL_SDK_URL;\n script.async = true;\n script.setAttribute(\"data-pal\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n document.head.appendChild(script);\n });\n\n return _palLoadPromise;\n}\n\nfunction getOrCreateNonceLoader(): any {\n if (_nonceLoader) return _nonceLoader;\n const goog = window.goog;\n const consentSettings = new goog.pal.ConsentSettings();\n consentSettings.allowStorage = true;\n _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n return _nonceLoader;\n}\n\nexport interface PalNonceOptions {\n videoWidth?: number;\n videoHeight?: number;\n descriptionUrl?: string;\n ppid?: string;\n sessionId?: string;\n adWillAutoPlay?: boolean;\n adWillPlayMuted?: boolean;\n playerVolume?: number;\n continuousPlayback?: boolean;\n}\n\nexport interface PalNonceManager {\n generateNonce(options?: PalNonceOptions): Promise<string>;\n\n getCurrentNonce(): string;\n\n injectNonce(vastTagUrl: string): string;\n\n sendPlaybackStart(): void;\n\n sendPlaybackEnd(): void;\n\n sendAdClick(): void;\n\n sendAdTouch(event: MouseEvent | TouchEvent): void;\n\n reset(): void;\n}\n\nexport function createPalNonceManager(): PalNonceManager {\n let currentNonce = \"\";\n let currentNonceManager: any | undefined;\n\n return {\n async generateNonce(options: PalNonceOptions = {}): Promise<string> {\n try {\n await loadPalSdk();\n\n const loader = getOrCreateNonceLoader();\n const goog = window.goog;\n\n const request = new goog.pal.NonceRequest();\n request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n request.playerVolume =\n options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n request.continuousPlayback = options.continuousPlayback ?? true;\n request.descriptionUrl = toDevSafeUrl(\n options.descriptionUrl ||\n (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.iconsSupported = true;\n request.playerType = \"StormcloudVideoPlayer\";\n request.playerVersion = \"1.0\";\n request.supportedApiFrameworks = \"2,7,9\";\n request.url = toDevSafeUrl(\n options.descriptionUrl ||\n (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.videoWidth = options.videoWidth || 640;\n request.videoHeight = options.videoHeight || 480;\n\n if (options.ppid) request.ppid = options.ppid;\n if (options.sessionId) request.sessionId = options.sessionId;\n\n console.log(\n \"[PAL] NonceRequest before generateNonce:\",\n JSON.stringify({\n adWillAutoPlay: request.adWillAutoPlay,\n adWillPlayMuted: request.adWillPlayMuted,\n playerVolume: request.playerVolume,\n continuousPlayback: request.continuousPlayback,\n descriptionUrl: request.descriptionUrl,\n iconsSupported: request.iconsSupported,\n playerType: request.playerType,\n playerVersion: request.playerVersion,\n supportedApiFrameworks: request.supportedApiFrameworks,\n url: request.url,\n videoWidth: request.videoWidth,\n videoHeight: request.videoHeight,\n ppid: request.ppid,\n sessionId: request.sessionId,\n }, null, 2)\n );\n\n const manager = await loader.loadNonceManager(request);\n currentNonceManager = manager;\n currentNonce = manager.getNonce() as string;\n\n console.log(\"[PAL] Nonce generated successfully\");\n return currentNonce;\n } catch (error) {\n console.warn(\"[PAL] Failed to generate nonce:\", error);\n currentNonce = \"\";\n currentNonceManager = undefined;\n return \"\";\n }\n },\n\n getCurrentNonce(): string {\n return currentNonce;\n },\n\n injectNonce(vastTagUrl: string): string {\n if (!currentNonce || !vastTagUrl) return vastTagUrl;\n\n try {\n const url = new URL(vastTagUrl);\n url.searchParams.delete(\"paln\");\n url.searchParams.set(\"givn\", currentNonce);\n return url.toString();\n } catch {\n let base = vastTagUrl\n .replace(/([?&])paln=[^&]*/g, \"\")\n .replace(/[?&]$/, \"\");\n const sep = base.includes(\"?\") ? \"&\" : \"?\";\n return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n }\n },\n\n sendPlaybackStart(): void {\n try {\n currentNonceManager?.sendPlaybackStart();\n } catch {}\n },\n\n sendPlaybackEnd(): void {\n try {\n currentNonceManager?.sendPlaybackEnd();\n } catch {}\n },\n\n sendAdClick(): void {\n try {\n currentNonceManager?.sendAdClick();\n } catch {}\n },\n\n sendAdTouch(event: MouseEvent | TouchEvent): void {\n try {\n currentNonceManager?.sendAdTouch(event);\n } catch {}\n },\n\n reset(): void {\n currentNonce = \"\";\n currentNonceManager = undefined;\n },\n };\n}\n","const PRIVATE_HOST_PATTERNS: RegExp[] = [\n /^localhost$/i,\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^0\\.0\\.0\\.0$/,\n /^::1$/,\n /^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/,\n /^172\\.(1[6-9]|2\\d|3[0-1])\\.\\d{1,3}\\.\\d{1,3}$/,\n];\n\nexport function isLocalDevHost(hostname: string): boolean {\n const host = hostname.replace(/^\\[/, \"\").replace(/\\]$/, \"\").toLowerCase();\n if (!host) return false;\n if (host.endsWith(\".local\") || host.endsWith(\".localhost\")) return true;\n return PRIVATE_HOST_PATTERNS.some((pattern) => pattern.test(host));\n}\n\nexport function toDevSafeUrl(rawUrl: string | undefined): string {\n if (!rawUrl) return rawUrl ?? \"\";\n\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return rawUrl;\n }\n\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return rawUrl;\n }\n\n if (!isLocalDevHost(url.hostname)) {\n return rawUrl;\n }\n\n const cleanPath = url.pathname.replace(/\\/{2,}/g, \"/\") || \"/index.html\";\n return `file://${cleanPath}`;\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/pal.cjs"],"names":[],"mappings":"AAAA","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/sdk/pal.ts\nvar pal_exports = {};\n__export(pal_exports, {\n createPalNonceManager: () => createPalNonceManager\n});\nmodule.exports = __toCommonJS(pal_exports);\n\n// src/utils/devUrl.ts\nvar PRIVATE_HOST_PATTERNS = [\n /^localhost$/i,\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^0\\.0\\.0\\.0$/,\n /^::1$/,\n /^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n /^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/,\n /^172\\.(1[6-9]|2\\d|3[0-1])\\.\\d{1,3}\\.\\d{1,3}$/\n];\nfunction isLocalDevHost(hostname) {\n const host = hostname.replace(/^\\[/, \"\").replace(/\\]$/, \"\").toLowerCase();\n if (!host) return false;\n if (host.endsWith(\".local\") || host.endsWith(\".localhost\")) return true;\n return PRIVATE_HOST_PATTERNS.some((pattern) => pattern.test(host));\n}\nfunction toDevSafeUrl(rawUrl) {\n if (!rawUrl) return rawUrl ?? \"\";\n let url;\n try {\n url = new URL(rawUrl);\n } catch {\n return rawUrl;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return rawUrl;\n }\n if (!isLocalDevHost(url.hostname)) {\n return rawUrl;\n }\n const cleanPath = url.pathname.replace(/\\/{2,}/g, \"/\") || \"/index.html\";\n return `file://${cleanPath}`;\n}\n\n// src/sdk/pal.ts\nvar PAL_SDK_URL = \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\nvar _nonceLoader;\nvar _palLoadPromise;\nfunction loadPalSdk() {\n if (typeof window !== \"undefined\" && window.goog?.pal) {\n return Promise.resolve();\n }\n if (_palLoadPromise) return _palLoadPromise;\n _palLoadPromise = new Promise((resolve, reject) => {\n const existing = document.querySelector(\n 'script[data-pal=\"true\"]'\n );\n if (existing) {\n if (window.goog?.pal) {\n resolve();\n return;\n }\n const timeout = setTimeout(\n () => reject(new Error(\"PAL SDK load timeout\")),\n 1e4\n );\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"PAL SDK load failed\"));\n });\n return;\n }\n const script = document.createElement(\"script\");\n script.src = PAL_SDK_URL;\n script.async = true;\n script.setAttribute(\"data-pal\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n document.head.appendChild(script);\n });\n return _palLoadPromise;\n}\nfunction getOrCreateNonceLoader() {\n if (_nonceLoader) return _nonceLoader;\n const goog = window.goog;\n const consentSettings = new goog.pal.ConsentSettings();\n consentSettings.allowStorage = true;\n _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n return _nonceLoader;\n}\nfunction createPalNonceManager() {\n let currentNonce = \"\";\n let currentNonceManager;\n return {\n async generateNonce(options = {}) {\n try {\n await loadPalSdk();\n const loader = getOrCreateNonceLoader();\n const goog = window.goog;\n const request = new goog.pal.NonceRequest();\n request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n request.playerVolume = options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n request.continuousPlayback = options.continuousPlayback ?? true;\n request.descriptionUrl = toDevSafeUrl(\n options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.iconsSupported = true;\n request.playerType = \"StormcloudVideoPlayer\";\n request.playerVersion = \"1.0\";\n request.supportedApiFrameworks = \"2,7,9\";\n request.url = toDevSafeUrl(\n options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n );\n request.videoWidth = options.videoWidth || 640;\n request.videoHeight = options.videoHeight || 480;\n if (options.ppid) request.ppid = options.ppid;\n if (options.sessionId) request.sessionId = options.sessionId;\n console.log(\n \"[PAL] NonceRequest before generateNonce:\",\n JSON.stringify({\n adWillAutoPlay: request.adWillAutoPlay,\n adWillPlayMuted: request.adWillPlayMuted,\n playerVolume: request.playerVolume,\n continuousPlayback: request.continuousPlayback,\n descriptionUrl: request.descriptionUrl,\n iconsSupported: request.iconsSupported,\n playerType: request.playerType,\n playerVersion: request.playerVersion,\n supportedApiFrameworks: request.supportedApiFrameworks,\n url: request.url,\n videoWidth: request.videoWidth,\n videoHeight: request.videoHeight,\n ppid: request.ppid,\n sessionId: request.sessionId\n }, null, 2)\n );\n const manager = await loader.loadNonceManager(request);\n currentNonceManager = manager;\n currentNonce = manager.getNonce();\n console.log(\"[PAL] Nonce generated successfully\");\n return currentNonce;\n } catch (error) {\n console.warn(\"[PAL] Failed to generate nonce:\", error);\n currentNonce = \"\";\n currentNonceManager = void 0;\n return \"\";\n }\n },\n getCurrentNonce() {\n return currentNonce;\n },\n injectNonce(vastTagUrl) {\n if (!currentNonce || !vastTagUrl) return vastTagUrl;\n try {\n const url = new URL(vastTagUrl);\n url.searchParams.delete(\"paln\");\n url.searchParams.set(\"givn\", currentNonce);\n return url.toString();\n } catch {\n let base = vastTagUrl.replace(/([?&])paln=[^&]*/g, \"\").replace(/[?&]$/, \"\");\n const sep = base.includes(\"?\") ? \"&\" : \"?\";\n return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n }\n },\n sendPlaybackStart() {\n try {\n currentNonceManager?.sendPlaybackStart();\n } catch {\n }\n },\n sendPlaybackEnd() {\n try {\n currentNonceManager?.sendPlaybackEnd();\n } catch {\n }\n },\n sendAdClick() {\n try {\n currentNonceManager?.sendAdClick();\n } catch {\n }\n },\n sendAdTouch(event) {\n try {\n currentNonceManager?.sendAdTouch(event);\n } catch {\n }\n },\n reset() {\n currentNonce = \"\";\n currentNonceManager = void 0;\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createPalNonceManager\n});\n"]}
@@ -125,6 +125,7 @@ interface AdLoadedInfo {
125
125
  interface AdImpressionInfo {
126
126
  source: "vast" | "hls";
127
127
  adIndex: number;
128
+ adId?: string;
128
129
  adUrl?: string;
129
130
  durationSeconds?: number;
130
131
  timestamp: string;
@@ -18,11 +18,8 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
18
18
  reject(error);
19
19
  return;
20
20
  }
21
- if (info.done) {
22
- resolve(value);
23
- } else {
24
- Promise.resolve(value).then(_next, _throw);
25
- }
21
+ if (info.done) resolve(value);
22
+ else Promise.resolve(value).then(_next, _throw);
26
23
  }
27
24
  function _async_to_generator(fn) {
28
25
  return function() {
@@ -40,9 +37,7 @@ function _async_to_generator(fn) {
40
37
  };
41
38
  }
42
39
  function _class_call_check(instance, Constructor) {
43
- if (!(instance instanceof Constructor)) {
44
- throw new TypeError("Cannot call a class as a function");
45
- }
40
+ if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
46
41
  }
47
42
  function _defineProperties(target, props) {
48
43
  for(var i = 0; i < props.length; i++){
@@ -66,20 +61,19 @@ function _define_property(obj, key, value) {
66
61
  configurable: true,
67
62
  writable: true
68
63
  });
69
- } else {
70
- obj[key] = value;
71
- }
64
+ } else obj[key] = value;
72
65
  return obj;
73
66
  }
74
67
  function _instanceof(left, right) {
68
+ "@swc/helpers - instanceof";
75
69
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
76
70
  return !!right[Symbol.hasInstance](left);
77
- } else {
78
- return left instanceof right;
79
- }
71
+ } else return left instanceof right;
80
72
  }
81
73
  function _iterable_to_array(iter) {
82
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
74
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
75
+ return Array.from(iter);
76
+ }
83
77
  }
84
78
  function _iterable_to_array_limit(arr, i) {
85
79
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
@@ -106,10 +100,10 @@ function _iterable_to_array_limit(arr, i) {
106
100
  return _arr;
107
101
  }
108
102
  function _non_iterable_rest() {
109
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
103
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
110
104
  }
111
105
  function _non_iterable_spread() {
112
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
106
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
113
107
  }
114
108
  function _object_spread(target) {
115
109
  for(var i = 1; i < arguments.length; i++){
@@ -141,9 +135,8 @@ function ownKeys(object, enumerableOnly) {
141
135
  }
142
136
  function _object_spread_props(target, source) {
143
137
  source = source != null ? source : {};
144
- if (Object.getOwnPropertyDescriptors) {
145
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
146
- } else {
138
+ if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
139
+ else {
147
140
  ownKeys(Object(source)).forEach(function(key) {
148
141
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
149
142
  });
@@ -192,18 +185,6 @@ function _sliced_to_array(arr, i) {
192
185
  function _to_consumable_array(arr) {
193
186
  return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
194
187
  }
195
- function _type_of(obj) {
196
- "@swc/helpers - typeof";
197
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
198
- }
199
- function _unsupported_iterable_to_array(o, minLen) {
200
- if (!o) return;
201
- if (typeof o === "string") return _array_like_to_array(o, minLen);
202
- var n = Object.prototype.toString.call(o).slice(8, -1);
203
- if (n === "Object" && o.constructor) n = o.constructor.name;
204
- if (n === "Map" || n === "Set") return Array.from(n);
205
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
206
- }
207
188
  function _ts_generator(thisArg, body) {
208
189
  var f, y, t, _ = {
209
190
  label: 0,
@@ -305,18 +286,36 @@ function _ts_generator(thisArg, body) {
305
286
  }
306
287
  function _ts_values(o) {
307
288
  var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
308
- if (m) return m.call(o);
309
- if (o && typeof o.length === "number") return {
310
- next: function() {
311
- if (o && i >= o.length) o = void 0;
312
- return {
313
- value: o && o[i++],
314
- done: !o
315
- };
316
- }
317
- };
289
+ if (m) {
290
+ return m.call(o);
291
+ }
292
+ if (o && typeof o.length === "number") {
293
+ return {
294
+ next: function() {
295
+ if (o && i >= o.length) {
296
+ o = void 0;
297
+ }
298
+ return {
299
+ value: o && o[i++],
300
+ done: !o
301
+ };
302
+ }
303
+ };
304
+ }
318
305
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
319
306
  }
307
+ function _type_of(obj) {
308
+ "@swc/helpers - typeof";
309
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
310
+ }
311
+ function _unsupported_iterable_to_array(o, minLen) {
312
+ if (!o) return;
313
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
314
+ var n = Object.prototype.toString.call(o).slice(8, -1);
315
+ if (n === "Object" && o.constructor) n = o.constructor.name;
316
+ if (n === "Map" || n === "Set") return Array.from(n);
317
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
318
+ }
320
319
  var __create = Object.create;
321
320
  var __defProp = Object.defineProperty;
322
321
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -577,6 +576,7 @@ function createHlsAdPlayer(contentVideo, options) {
577
576
  var adContainerEl = (_contentVideo_AD_CONTAINER_PROP = contentVideo[AD_CONTAINER_PROP]) !== null && _contentVideo_AD_CONTAINER_PROP !== void 0 ? _contentVideo_AD_CONTAINER_PROP : void 0;
578
577
  var adEventHandlers = [];
579
578
  var currentAd;
579
+ var currentAdMediaUrl;
580
580
  var podAds = [];
581
581
  var podIndex = 0;
582
582
  var sessionId;
@@ -1394,9 +1394,9 @@ function createHlsAdPlayer(contentVideo, options) {
1394
1394
  delete contentVideo.dataset.stormcloudAdPlaying;
1395
1395
  }
1396
1396
  }
1397
- function resetQuartileTracking(preserveImpression) {
1397
+ function resetQuartileTracking() {
1398
1398
  trackingFired = {
1399
- impression: preserveImpression ? trackingFired.impression : false,
1399
+ impression: false,
1400
1400
  start: false,
1401
1401
  firstQuartile: false,
1402
1402
  midpoint: false,
@@ -1404,6 +1404,27 @@ function createHlsAdPlayer(contentVideo, options) {
1404
1404
  complete: false
1405
1405
  };
1406
1406
  }
1407
+ function markCreativeRendered(reason) {
1408
+ if (!currentAd || trackingFired.impression) return;
1409
+ trackingFired.impression = true;
1410
+ fireTrackingPixels(currentAd.trackingUrls.impression);
1411
+ console.log("[HlsAdPlayer] Impression (pod ".concat(podIndex + 1, "/").concat(podAds.length || 1, ", reason: ").concat(reason, "): ").concat(currentAd.title));
1412
+ emit("ad_impression", {
1413
+ adId: currentAd.id,
1414
+ title: currentAd.title,
1415
+ durationSeconds: currentAd.duration,
1416
+ mediaUrl: currentAdMediaUrl,
1417
+ podIndex: podIndex,
1418
+ podSize: podAds.length || 1,
1419
+ reason: reason
1420
+ });
1421
+ }
1422
+ function canDetectBlackFrames() {
1423
+ if (!adVideoElement) return false;
1424
+ if (requiresMediaPipelineResetAfterAds()) return false;
1425
+ if (isRvfcSupported(adVideoElement)) return true;
1426
+ return getDecodedVideoFrameCount(adVideoElement) !== void 0;
1427
+ }
1407
1428
  function isRvfcSupported(video) {
1408
1429
  return typeof video.requestVideoFrameCallback === "function";
1409
1430
  }
@@ -1466,6 +1487,7 @@ function createHlsAdPlayer(contentVideo, options) {
1466
1487
  if (!mediaFile) {
1467
1488
  throw new Error("No media file available for ad");
1468
1489
  }
1490
+ currentAdMediaUrl = mediaFile.url;
1469
1491
  var isHlsAd = isHlsMediaFile(mediaFile);
1470
1492
  console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad (pod ").concat(podIndex + 1, "/").concat(podAds.length || 1, ") from: ").concat(mediaFile.url));
1471
1493
  if (isHlsAd && import_hls.default.isSupported()) {
@@ -1509,10 +1531,9 @@ function createHlsAdPlayer(contentVideo, options) {
1509
1531
  }
1510
1532
  podIndex++;
1511
1533
  currentAd = podAds[podIndex];
1512
- resetQuartileTracking(false);
1534
+ currentAdMediaUrl = void 0;
1535
+ resetQuartileTracking();
1513
1536
  if (currentAd) {
1514
- fireTrackingPixels(currentAd.trackingUrls.impression);
1515
- trackingFired.impression = true;
1516
1537
  console.log("[HlsAdPlayer] Advancing to next pod ad (".concat(podIndex + 1, "/").concat(podAds.length, "): ").concat(currentAd.title, ", duration: ").concat(currentAd.duration, "s"));
1517
1538
  }
1518
1539
  clearStallWatchdog();
@@ -1607,6 +1628,7 @@ function createHlsAdPlayer(contentVideo, options) {
1607
1628
  if (!adPlaying) return;
1608
1629
  sawDecodedVideoFrame = true;
1609
1630
  markRvfcReliable();
1631
+ markCreativeRendered("first_presented_frame");
1610
1632
  };
1611
1633
  try {
1612
1634
  videoFrameCallbackHandle = rvfc.call(adVideoElement, onPresentedFrame);
@@ -1641,6 +1663,7 @@ function createHlsAdPlayer(contentVideo, options) {
1641
1663
  if (decodedFrames !== void 0 && decodedFrames > 0) {
1642
1664
  sawDecodedVideoFrame = true;
1643
1665
  markFrameCounterReliable();
1666
+ markCreativeRendered("decoded_frames");
1644
1667
  } else if (adVideoElement.currentTime >= BLACKFRAME_MIN_PLAYBACK_S) {
1645
1668
  var timeAdvancing = adVideoElement.currentTime > lastAdProgressPosition + 0.05;
1646
1669
  if (isRvfcSupported(adVideoElement) && timeAdvancing && isRvfcReliable()) {
@@ -1653,6 +1676,9 @@ function createHlsAdPlayer(contentVideo, options) {
1653
1676
  }
1654
1677
  }
1655
1678
  }
1679
+ if (!trackingFired.impression && !adVideoElement.paused && adVideoElement.currentTime >= BLACKFRAME_MIN_PLAYBACK_S && (sawDecodedVideoFrame || !canDetectBlackFrames())) {
1680
+ markCreativeRendered(sawDecodedVideoFrame ? "decoded_frames" : "sustained_playback");
1681
+ }
1656
1682
  if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
1657
1683
  noteAdProgress();
1658
1684
  return;
@@ -1791,11 +1817,9 @@ function createHlsAdPlayer(contentVideo, options) {
1791
1817
  podAds = ads;
1792
1818
  podIndex = 0;
1793
1819
  currentAd = ads[0];
1820
+ currentAdMediaUrl = void 0;
1821
+ resetQuartileTracking();
1794
1822
  console.log("[HlsAdPlayer] Pod parsed: ".concat(ads.length, ' ad(s), first="').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.title, '", duration=').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.duration, "s"));
1795
- if (currentAd) {
1796
- fireTrackingPixels(currentAd.trackingUrls.impression);
1797
- trackingFired.impression = true;
1798
- }
1799
1823
  return [
1800
1824
  2,
1801
1825
  Promise.resolve()
@@ -1835,7 +1859,7 @@ function createHlsAdPlayer(contentVideo, options) {
1835
1859
  contentVideo[AD_VIDEO_PROP] = adVideoElement;
1836
1860
  }
1837
1861
  setupAdEventListeners();
1838
- resetQuartileTracking(true);
1862
+ resetQuartileTracking();
1839
1863
  contentVolume = contentVideo.volume;
1840
1864
  originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1841
1865
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -1925,6 +1949,7 @@ function createHlsAdPlayer(contentVideo, options) {
1925
1949
  }
1926
1950
  }
1927
1951
  currentAd = void 0;
1952
+ currentAdMediaUrl = void 0;
1928
1953
  podAds = [];
1929
1954
  podIndex = 0;
1930
1955
  return [
@@ -3239,7 +3264,7 @@ function buildPlayerMetricEvent() {
3239
3264
  if (debugAdTiming) {
3240
3265
  console.log("[StormcloudVideoPlayer] playerId: ", playerId);
3241
3266
  }
3242
- captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
3267
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : (/* @__PURE__ */ new Date()).toISOString();
3243
3268
  return [
3244
3269
  2,
3245
3270
  _object_spread({
@@ -3258,8 +3283,19 @@ function buildPlayerMetricEvent() {
3258
3283
  }).apply(this, arguments);
3259
3284
  }
3260
3285
  function publishTracking(licenseKey, channel, body) {
3286
+ var debug = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false;
3261
3287
  ensureMQTTClient();
3262
- publishMQTT(buildPlayerTopic(licenseKey, channel), body);
3288
+ var topic = buildPlayerTopic(licenseKey, channel);
3289
+ var published = publishMQTT(topic, body);
3290
+ if (debug) {
3291
+ console.log("[StormcloudVideoPlayer] publishTracking:", JSON.stringify({
3292
+ licenseKey: licenseKey,
3293
+ channel: channel,
3294
+ topic: topic,
3295
+ body: body,
3296
+ published: published
3297
+ }, null, 2));
3298
+ }
3263
3299
  }
3264
3300
  function sendInitialTracking(_0) {
3265
3301
  return _async_to_generator(function(licenseKey) {
@@ -3293,7 +3329,7 @@ function sendInitialTracking(_0) {
3293
3329
  events: [
3294
3330
  metricEvent
3295
3331
  ]
3296
- });
3332
+ }, !!context.debugAdTiming);
3297
3333
  return [
3298
3334
  3,
3299
3335
  4
@@ -3403,7 +3439,7 @@ function sendAdLoadedTracking(_0, _1) {
3403
3439
  }
3404
3440
  function sendAdImpressionTracking(_0, _1) {
3405
3441
  return _async_to_generator(function(licenseKey, adImpressionInfo) {
3406
- var context, metricEvent, error;
3442
+ var context, _adImpressionInfo_adUrl, metricEvent, error;
3407
3443
  var _arguments = arguments;
3408
3444
  return _ts_generator(this, function(_state) {
3409
3445
  switch(_state.label){
@@ -3428,17 +3464,18 @@ function sendAdImpressionTracking(_0, _1) {
3428
3464
  ];
3429
3465
  case 2:
3430
3466
  metricEvent = _state.sent();
3431
- publishTracking(licenseKey, "heartbeat", metricEvent);
3467
+ publishTracking(licenseKey, "heartbeat", metricEvent, !!context.debugAdTiming);
3432
3468
  publishTracking(licenseKey, "impressions", {
3433
3469
  events: [
3434
3470
  {
3471
+ event_id: createUuid(),
3435
3472
  player_id: metricEvent.player_id,
3436
3473
  ad_played_count: 1,
3437
- ad_url: adImpressionInfo.adUrl,
3474
+ ad_url: (_adImpressionInfo_adUrl = adImpressionInfo.adUrl) !== null && _adImpressionInfo_adUrl !== void 0 ? _adImpressionInfo_adUrl : adImpressionInfo.adId,
3438
3475
  capture_at: adImpressionInfo.timestamp
3439
3476
  }
3440
3477
  ]
3441
- });
3478
+ }, !!context.debugAdTiming);
3442
3479
  return [
3443
3480
  3,
3444
3481
  4
@@ -3483,7 +3520,7 @@ function sendHeartbeat(_0) {
3483
3520
  ];
3484
3521
  case 2:
3485
3522
  heartbeatData = _state.sent();
3486
- publishTracking(licenseKey, "heartbeat", heartbeatData);
3523
+ publishTracking(licenseKey, "heartbeat", heartbeatData, !!context.debugAdTiming);
3487
3524
  return [
3488
3525
  3,
3489
3526
  4
@@ -6316,7 +6353,7 @@ var AdTimingService = /*#__PURE__*/ function() {
6316
6353
  var _this_callbacks_getAdState = this.callbacks.getAdState(), inAdBreak = _this_callbacks_getAdState.inAdBreak, showAds = _this_callbacks_getAdState.showAds, adPlaying = _this_callbacks_getAdState.adPlaying;
6317
6354
  console.log("[StormcloudVideoPlayer][AdState]", _object_spread({
6318
6355
  event: event,
6319
- timestamp: /* @__PURE__ */ new Date().toISOString(),
6356
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6320
6357
  showAds: showAds,
6321
6358
  adPlaying: adPlaying,
6322
6359
  inAdBreak: inAdBreak,
@@ -7277,27 +7314,22 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
7277
7314
  console.log("[POD] Playing pod ad ".concat((payload === null || payload === void 0 ? void 0 : payload.index) != null ? payload.index + 1 : "?", "/").concat((_ref = payload === null || payload === void 0 ? void 0 : payload.total) !== null && _ref !== void 0 ? _ref : "?"));
7278
7315
  }
7279
7316
  });
7280
- adPlayer.on("all_ads_completed", function() {
7281
- sendAdImpressionTracking(_this.host.config.licenseKey, {
7317
+ adPlayer.on("ad_impression", function(payload) {
7318
+ var impressionInfo = {
7282
7319
  source: "hls",
7283
7320
  adIndex: _this.timing.currentAdIndex,
7284
- timestamp: /* @__PURE__ */ new Date().toISOString()
7285
- }, _this.analyticsContext).catch(function() {});
7286
- _this.timing.recordPlayedAdDuration(_this.host.getAdPlayer());
7287
- var remaining = _this.timing.getRemainingAdMs();
7288
- _this.timing.consecutiveFailures = 0;
7289
- if (_this.debug) {
7290
- console.log("[StormcloudVideoPlayer] all_ads_completed event received - remaining=".concat(remaining, "ms, queued ads=").concat(_this.adRequestQueue.length), _this.adRequestQueue.length > 0 ? {
7291
- queuedUrls: _to_consumable_array(_this.adRequestQueue)
7292
- } : {});
7321
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7322
+ };
7323
+ if (payload === null || payload === void 0 ? void 0 : payload.adId) impressionInfo.adId = payload.adId;
7324
+ if (payload === null || payload === void 0 ? void 0 : payload.mediaUrl) impressionInfo.adUrl = payload.mediaUrl;
7325
+ if ((payload === null || payload === void 0 ? void 0 : payload.durationSeconds) != null) {
7326
+ impressionInfo.durationSeconds = payload.durationSeconds;
7293
7327
  }
7294
- if (_this.inAdBreak) {
7295
- if (_this.timing.hasTimeToStartAnotherAd()) {
7296
- _this.tryNextAvailableAdWithRateLimit();
7297
- } else {
7298
- _this.handleAdPodComplete();
7328
+ sendAdImpressionTracking(_this.host.config.licenseKey, impressionInfo, _this.analyticsContext).catch(function(error) {
7329
+ if (_this.debug) {
7330
+ console.warn("[AdBreakOrchestrator] Failed to send ad impression tracking:", error);
7299
7331
  }
7300
- }
7332
+ });
7301
7333
  });
7302
7334
  adPlayer.on("ad_error", function(errorPayload) {
7303
7335
  var errorMessage = "Ad playback failed";
@@ -7340,11 +7372,6 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
7340
7372
  }
7341
7373
  });
7342
7374
  adPlayer.on("content_resume", function() {
7343
- sendAdImpressionTracking(_this.host.config.licenseKey, {
7344
- source: "hls",
7345
- adIndex: _this.timing.currentAdIndex,
7346
- timestamp: /* @__PURE__ */ new Date().toISOString()
7347
- }, _this.analyticsContext).catch(function() {});
7348
7375
  if (!_this.host.video.muted) {
7349
7376
  _this.host.video.muted = true;
7350
7377
  if (_this.debug) {
@@ -7582,7 +7609,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
7582
7609
  sendAdLoadedTracking(this.host.config.licenseKey, {
7583
7610
  source: "hls",
7584
7611
  vastUrl: podUrl,
7585
- timestamp: /* @__PURE__ */ new Date().toISOString()
7612
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7586
7613
  }, this.analyticsContext).catch(function() {});
7587
7614
  this.timing.startAdFailsafeTimer(requestToken);
7588
7615
  return [
@@ -8102,7 +8129,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8102
8129
  sendAdLoadedTracking(this.host.config.licenseKey, {
8103
8130
  source: "hls",
8104
8131
  vastUrl: vastTagUrl,
8105
- timestamp: /* @__PURE__ */ new Date().toISOString()
8132
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8106
8133
  }, this.analyticsContext).catch(function() {});
8107
8134
  this.timing.clearAdRequestWatchdog();
8108
8135
  if (this.timing.activeAdRequestToken !== requestToken) return [
@@ -9083,7 +9110,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
9083
9110
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
9084
9111
  sendAdDetectTracking(this.config.licenseKey, _object_spread({
9085
9112
  source: "scte35",
9086
- timestamp: /* @__PURE__ */ new Date().toISOString()
9113
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
9087
9114
  }, detectPayload), buildAnalyticsContext(this.config)).catch(function() {});
9088
9115
  }
9089
9116
  var hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;
@@ -9259,7 +9286,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
9259
9286
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
9260
9287
  sendAdDetectTracking(this.config.licenseKey, _object_spread({
9261
9288
  source: "scte35",
9262
- timestamp: /* @__PURE__ */ new Date().toISOString()
9289
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
9263
9290
  }, detectPayload), buildAnalyticsContext(this.config)).catch(function() {});
9264
9291
  if (this.debug) {
9265
9292
  console.log("[PREFETCH] Starting ad prefetch for upcoming ad break");