stormcloud-video-player 0.8.73 → 0.8.74

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 (61) hide show
  1. package/README.md +10 -70
  2. package/dist/stormcloud-vp.min.js +1 -1
  3. package/lib/Player.d.cts +1 -0
  4. package/lib/StormcloudPlayer.cjs +987 -273
  5. package/lib/StormcloudPlayer.cjs.map +1 -1
  6. package/lib/StormcloudPlayer.d.cts +1 -0
  7. package/lib/index.cjs +998 -278
  8. package/lib/index.cjs.map +1 -1
  9. package/lib/index.d.cts +1 -0
  10. package/lib/index.d.ts +40 -3
  11. package/lib/index.js +991 -279
  12. package/lib/index.js.map +1 -1
  13. package/lib/player/AdBreakOrchestrator.cjs +767 -67
  14. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  15. package/lib/player/AdBreakOrchestrator.d.cts +7 -9
  16. package/lib/player/AdConfigManager.cjs +314 -62
  17. package/lib/player/AdConfigManager.cjs.map +1 -1
  18. package/lib/player/AdConfigManager.d.cts +7 -12
  19. package/lib/player/AdTimingService.cjs +37 -1
  20. package/lib/player/AdTimingService.cjs.map +1 -1
  21. package/lib/player/AdTimingService.d.cts +8 -1
  22. package/lib/player/EdgePodRequest.d.cts +1 -0
  23. package/lib/player/FloorLadder.d.cts +1 -0
  24. package/lib/player/HlsEngine.d.cts +1 -0
  25. package/lib/player/OptimizedPodRequest.cjs +719 -0
  26. package/lib/player/OptimizedPodRequest.cjs.map +1 -0
  27. package/lib/player/OptimizedPodRequest.d.cts +101 -0
  28. package/lib/player/PlayerControls.d.cts +1 -0
  29. package/lib/player/Scte35CueManager.d.cts +1 -0
  30. package/lib/player/Scte35Parser.d.cts +1 -0
  31. package/lib/player/StormcloudVideoPlayer.cjs +987 -273
  32. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  33. package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
  34. package/lib/player/playerTypes.d.cts +1 -0
  35. package/lib/players/HlsPlayer.cjs +987 -273
  36. package/lib/players/HlsPlayer.cjs.map +1 -1
  37. package/lib/players/HlsPlayer.d.cts +1 -0
  38. package/lib/players/index.cjs +987 -273
  39. package/lib/players/index.cjs.map +1 -1
  40. package/lib/props.d.cts +1 -0
  41. package/lib/sdk/hlsAdPlayer.cjs +316 -51
  42. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  43. package/lib/sdk/hlsAdPlayer.d.cts +3 -1
  44. package/lib/sdk/pal.cjs +108 -83
  45. package/lib/sdk/pal.cjs.map +1 -1
  46. package/lib/sdk/pal.d.cts +1 -0
  47. package/lib/types.d.cts +9 -2
  48. package/lib/ui/StormcloudVideoPlayer.cjs +990 -278
  49. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  50. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -0
  51. package/lib/utils/ctvVastSignals.cjs +9 -7
  52. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  53. package/lib/utils/tracking.cjs +17 -3
  54. package/lib/utils/tracking.cjs.map +1 -1
  55. package/lib/utils/tracking.d.cts +2 -1
  56. package/lib/utils/vastEnvironmentSignals.cjs +9 -7
  57. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  58. package/lib/utils/vastMacros.cjs +250 -10
  59. package/lib/utils/vastMacros.cjs.map +1 -1
  60. package/lib/utils/vastMacros.d.cts +13 -4
  61. package/package.json +5 -3
@@ -465,21 +465,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
465
465
  "adid"
466
466
  ]);
467
467
  function resolveVastEnvironmentSignals(isCtv) {
468
- var _ref;
469
468
  var bridgeSignals = readNativeBridgeSignals();
470
469
  var platformDevice = readPlatformNativeDeviceId();
471
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
470
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
471
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
472
472
  var deviceId = realDeviceId;
473
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
474
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
475
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
473
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
474
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
475
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
476
476
  if (!deviceId && isCtv) {
477
477
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
478
478
  if (dpid) {
479
- var _ref1;
480
479
  deviceId = dpid;
481
480
  deviceIdType = "dpid";
482
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
481
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
483
482
  }
484
483
  }
485
484
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -844,6 +843,9 @@ function isMacroPlaceholder(value) {
844
843
  var t = value.trim();
845
844
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
846
845
  }
846
+ function validDeviceId(value) {
847
+ return value && !isMacroPlaceholder(value) ? value : void 0;
848
+ }
847
849
  function isZeroedAdId(value) {
848
850
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
849
851
  }
@@ -1376,6 +1378,198 @@ function ensureVideoAdType(rawUrl) {
1376
1378
  return rawUrl;
1377
1379
  }
1378
1380
  }
1381
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1382
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1383
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1384
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1385
+ "cust_params"
1386
+ ]);
1387
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1388
+ "PMND",
1389
+ "PMXD",
1390
+ "PMAD"
1391
+ ]);
1392
+ function hasScvpMacros(url) {
1393
+ return !!url && SCVP_MACRO_DETECT.test(url);
1394
+ }
1395
+ function safeDecode(value) {
1396
+ try {
1397
+ return decodeURIComponent(value.replace(/\+/g, " "));
1398
+ } catch (unused) {
1399
+ return value;
1400
+ }
1401
+ }
1402
+ function findScvpMacroNames(url) {
1403
+ if (!url) return [];
1404
+ var names = /* @__PURE__ */ new Set();
1405
+ var text = url;
1406
+ for(var pass = 0; pass < 3; pass++){
1407
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1408
+ names.add(String(bracketName || parenName).toUpperCase());
1409
+ return "";
1410
+ });
1411
+ var decoded = safeDecode(text);
1412
+ if (decoded === text) break;
1413
+ text = decoded;
1414
+ }
1415
+ return Array.from(names);
1416
+ }
1417
+ function resolveScvpMacroValues(ctx) {
1418
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1419
+ var values = /* @__PURE__ */ new Map();
1420
+ var set = function set(name, value) {
1421
+ if (value == null) return;
1422
+ var str = String(value).trim();
1423
+ if (str) values.set(name, str);
1424
+ };
1425
+ var toFlag = function toFlag(value) {
1426
+ return value == null ? void 0 : value ? "1" : "0";
1427
+ };
1428
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1429
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1430
+ if (deviceId && deviceIdType) {
1431
+ set("RDID", deviceId);
1432
+ set("IDTYPE", deviceIdType);
1433
+ set("IS-LAT", toFlag(ctx.limitAdTracking));
1434
+ }
1435
+ set("SID", ctx.sessionId);
1436
+ set("DTH", ctx.deviceTypeHint);
1437
+ set("GIVN", ctx.palNonce);
1438
+ set("CT-TI", ctx.programTitle);
1439
+ set("CT-CH", ctx.channelName);
1440
+ set("POD", ctx.pod);
1441
+ set("CORRELATOR", ctx.correlator);
1442
+ set("SCOR", ctx.streamCorrelator);
1443
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1444
+ if (ctx.adWillAutoPlay != null) {
1445
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1446
+ }
1447
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1448
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1449
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1450
+ return values;
1451
+ }
1452
+ var keepNone = function keepNone() {
1453
+ return false;
1454
+ };
1455
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1456
+ var out = [];
1457
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1458
+ var name = String(bracketName || parenName).toUpperCase();
1459
+ var value = values.get(name);
1460
+ if (value != null) return value;
1461
+ if (keep(name)) return match;
1462
+ unresolved.add(name);
1463
+ return "";
1464
+ };
1465
+ params.forEach(function(value, key) {
1466
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1467
+ if (whole) {
1468
+ var name = String(whole[1] || whole[2]).toUpperCase();
1469
+ var resolved = values.get(name);
1470
+ if (resolved != null) {
1471
+ out.push([
1472
+ key,
1473
+ resolved
1474
+ ]);
1475
+ } else if (keep(name)) {
1476
+ out.push([
1477
+ key,
1478
+ value
1479
+ ]);
1480
+ } else {
1481
+ unresolved.add(name);
1482
+ }
1483
+ return;
1484
+ }
1485
+ if (!SCVP_MACRO_DETECT.test(value)) {
1486
+ out.push([
1487
+ key,
1488
+ value
1489
+ ]);
1490
+ return;
1491
+ }
1492
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1493
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1494
+ if (inner.length > 0) {
1495
+ out.push([
1496
+ key,
1497
+ inner.map(function(param) {
1498
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1499
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1500
+ }).join("&")
1501
+ ]);
1502
+ }
1503
+ return;
1504
+ }
1505
+ out.push([
1506
+ key,
1507
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1508
+ ]);
1509
+ });
1510
+ return out;
1511
+ }
1512
+ function substituteScvpMacros(baseUrl, values) {
1513
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1514
+ var unresolved = /* @__PURE__ */ new Set();
1515
+ var url;
1516
+ try {
1517
+ url = new URL(normalizeVastTagUrl(baseUrl));
1518
+ } catch (unused) {
1519
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1520
+ var name = String(bracketName || parenName).toUpperCase();
1521
+ var value = values.get(name);
1522
+ if (value != null) return encodeURIComponent(value);
1523
+ if (keep(name)) return match;
1524
+ unresolved.add(name);
1525
+ return "";
1526
+ });
1527
+ return {
1528
+ url: replaced,
1529
+ unresolved: Array.from(unresolved)
1530
+ };
1531
+ }
1532
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1533
+ var search = new URLSearchParams();
1534
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1535
+ try {
1536
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1537
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1538
+ search.append(key, value);
1539
+ }
1540
+ } catch (err) {
1541
+ _didIteratorError = true;
1542
+ _iteratorError = err;
1543
+ } finally{
1544
+ try {
1545
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1546
+ _iterator.return();
1547
+ }
1548
+ } finally{
1549
+ if (_didIteratorError) {
1550
+ throw _iteratorError;
1551
+ }
1552
+ }
1553
+ }
1554
+ url.search = search.toString();
1555
+ return {
1556
+ url: url.toString(),
1557
+ unresolved: Array.from(unresolved)
1558
+ };
1559
+ }
1560
+ function applyScvpMacros(baseUrl, ctx) {
1561
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1562
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1563
+ return deferred.has(name);
1564
+ });
1565
+ }
1566
+ function stripScvpMacros(url) {
1567
+ if (findScvpMacroNames(url).length === 0) return {
1568
+ url: url,
1569
+ unresolved: []
1570
+ };
1571
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1572
+ }
1379
1573
  function applyVastMacros(baseUrl, ctx) {
1380
1574
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1381
1575
  var url;
@@ -1417,15 +1611,6 @@ function applyVastMacros(baseUrl, ctx) {
1417
1611
  }
1418
1612
  params.delete("ppos");
1419
1613
  params.delete("lip");
1420
- if (ctx.podMinDurationMs != null) {
1421
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1422
- }
1423
- if (ctx.podMaxDurationMs != null) {
1424
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1425
- }
1426
- if (ctx.podMaxAds != null) {
1427
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1428
- }
1429
1614
  var existingUrl = params.get("url") || "";
1430
1615
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1431
1616
  params.delete("url");
@@ -2255,6 +2440,309 @@ function substituteVastTrackingMacros(url) {
2255
2440
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2256
2441
  });
2257
2442
  }
2443
+ // src/player/OptimizedPodRequest.ts
2444
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2445
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2446
+ var POD_PARAM_KEYS = [
2447
+ "pmnd",
2448
+ "pmxd",
2449
+ "pmad"
2450
+ ];
2451
+ var POSITIVE_INT = /^[1-9]\d*$/;
2452
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2453
+ function nonNegativeInt(value) {
2454
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2455
+ }
2456
+ function positiveInt(value) {
2457
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2458
+ }
2459
+ function resolveAdPodConfig(config) {
2460
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2461
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2462
+ return {
2463
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2464
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2465
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2466
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2467
+ exactDuration: config.podExactDuration === true
2468
+ };
2469
+ }
2470
+ function measureBreakCapacity(timing, nowMonoMs) {
2471
+ var _timing_breakEndMonoMs;
2472
+ var scheduled = timing.scheduledBreakDurationMs;
2473
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2474
+ return void 0;
2475
+ }
2476
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2477
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2478
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2479
+ return {
2480
+ scheduledBreakDurationMs: scheduled,
2481
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2482
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2483
+ };
2484
+ }
2485
+ function resolvePodParams(input) {
2486
+ var capacity = input.capacity, config = input.config;
2487
+ var pmxd;
2488
+ var source;
2489
+ if (capacity) {
2490
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2491
+ source = "break_remaining";
2492
+ } else if (config.maxPodDurationMs != null) {
2493
+ pmxd = config.maxPodDurationMs;
2494
+ source = "configured_cap";
2495
+ } else if (input.tagMaxDurationMs != null) {
2496
+ pmxd = input.tagMaxDurationMs;
2497
+ source = "tag_cap";
2498
+ } else {
2499
+ return {
2500
+ kind: "omit"
2501
+ };
2502
+ }
2503
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2504
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2505
+ return {
2506
+ kind: "abort",
2507
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2508
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2509
+ };
2510
+ }
2511
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2512
+ return {
2513
+ kind: "send",
2514
+ params: {
2515
+ pmnd: pmnd,
2516
+ pmxd: pmxd,
2517
+ pmad: config.maxAdsPerBreak
2518
+ },
2519
+ source: source
2520
+ };
2521
+ }
2522
+ function podRequestAborted(reason, message, diagnostics) {
2523
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2524
+ error.podRequestAborted = true;
2525
+ error.reason = reason;
2526
+ error.diagnostics = diagnostics;
2527
+ return error;
2528
+ }
2529
+ function isPodRequestAbortedError(error) {
2530
+ return !!error && error.podRequestAborted === true;
2531
+ }
2532
+ function firstPositiveIntParam(params, key) {
2533
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2534
+ try {
2535
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2536
+ var value = _step.value;
2537
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2538
+ }
2539
+ } catch (err) {
2540
+ _didIteratorError = true;
2541
+ _iteratorError = err;
2542
+ } finally{
2543
+ try {
2544
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2545
+ _iterator.return();
2546
+ }
2547
+ } finally{
2548
+ if (_didIteratorError) {
2549
+ throw _iteratorError;
2550
+ }
2551
+ }
2552
+ }
2553
+ return void 0;
2554
+ }
2555
+ function isOptimizedPodUrl(url) {
2556
+ if (findScvpMacroNames(url).some(function(name) {
2557
+ return SCVP_POD_MACROS.has(name);
2558
+ })) return true;
2559
+ try {
2560
+ var params = new URL(url).searchParams;
2561
+ return POD_PARAM_KEYS.some(function(key) {
2562
+ return params.has(key);
2563
+ });
2564
+ } catch (unused) {
2565
+ return false;
2566
+ }
2567
+ }
2568
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2569
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2570
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2571
+ var capacity = ctx.capacity;
2572
+ var base = {
2573
+ breakId: ctx.breakId,
2574
+ optimizedPod: optimizedPod,
2575
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2576
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2577
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2578
+ safetyReserveMs: ctx.config.requestSafetyMs
2579
+ };
2580
+ var decision = {
2581
+ kind: "omit"
2582
+ };
2583
+ if (optimizedPod) {
2584
+ var tagMaxDurationMs;
2585
+ try {
2586
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2587
+ } catch (unused) {}
2588
+ decision = resolvePodParams({
2589
+ capacity: capacity,
2590
+ config: ctx.config,
2591
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2592
+ tagMaxDurationMs: tagMaxDurationMs
2593
+ });
2594
+ if (decision.kind === "abort") {
2595
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2596
+ }
2597
+ }
2598
+ var pod = decision.kind === "send" ? decision.params : void 0;
2599
+ var values = /* @__PURE__ */ new Map();
2600
+ if (pod) {
2601
+ values.set("PMND", String(pod.pmnd));
2602
+ values.set("PMXD", String(pod.pmxd));
2603
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2604
+ }
2605
+ var substituted = substituteScvpMacros(rawUrl, values);
2606
+ var finalUrl;
2607
+ try {
2608
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2609
+ if (pod) {
2610
+ url.searchParams.set("pmnd", String(pod.pmnd));
2611
+ url.searchParams.set("pmxd", String(pod.pmxd));
2612
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2613
+ else url.searchParams.delete("pmad");
2614
+ } else {
2615
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2616
+ try {
2617
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2618
+ var key = _step.value;
2619
+ url.searchParams.delete(key);
2620
+ }
2621
+ } catch (err) {
2622
+ _didIteratorError = true;
2623
+ _iteratorError = err;
2624
+ } finally{
2625
+ try {
2626
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2627
+ _iterator.return();
2628
+ }
2629
+ } finally{
2630
+ if (_didIteratorError) {
2631
+ throw _iteratorError;
2632
+ }
2633
+ }
2634
+ }
2635
+ }
2636
+ finalUrl = url.toString();
2637
+ } catch (unused) {
2638
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2639
+ }
2640
+ var problems = validateGamRequestUrl(finalUrl, {
2641
+ optimizedPod: !!pod,
2642
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2643
+ });
2644
+ if (problems.length > 0) {
2645
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2646
+ }
2647
+ var givn = null;
2648
+ try {
2649
+ givn = new URL(finalUrl).searchParams.get("givn");
2650
+ } catch (unused) {}
2651
+ return {
2652
+ url: finalUrl,
2653
+ diagnostics: {
2654
+ breakId: ctx.breakId,
2655
+ optimizedPod: !!pod,
2656
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2657
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2658
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2659
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2660
+ safetyReserveMs: ctx.config.requestSafetyMs,
2661
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2662
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2663
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2664
+ palNoncePresent: !!givn,
2665
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2666
+ strippedMacros: substituted.unresolved.filter(function(name) {
2667
+ return !SCVP_POD_MACROS.has(name);
2668
+ })
2669
+ }
2670
+ };
2671
+ }
2672
+ function validateGamRequestUrl(url, expect) {
2673
+ var problems = [];
2674
+ var leftover = findScvpMacroNames(url);
2675
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2676
+ var params;
2677
+ try {
2678
+ params = new URL(url).searchParams;
2679
+ } catch (unused) {
2680
+ return problems.concat("URL could not be parsed");
2681
+ }
2682
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2683
+ try {
2684
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2685
+ var key = _step.value;
2686
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2687
+ }
2688
+ } catch (err) {
2689
+ _didIteratorError = true;
2690
+ _iteratorError = err;
2691
+ } finally{
2692
+ try {
2693
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2694
+ _iterator.return();
2695
+ }
2696
+ } finally{
2697
+ if (_didIteratorError) {
2698
+ throw _iteratorError;
2699
+ }
2700
+ }
2701
+ }
2702
+ if (!expect.optimizedPod) {
2703
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2704
+ try {
2705
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2706
+ var key1 = _step1.value;
2707
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2708
+ }
2709
+ } catch (err) {
2710
+ _didIteratorError1 = true;
2711
+ _iteratorError1 = err;
2712
+ } finally{
2713
+ try {
2714
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2715
+ _iterator1.return();
2716
+ }
2717
+ } finally{
2718
+ if (_didIteratorError1) {
2719
+ throw _iteratorError1;
2720
+ }
2721
+ }
2722
+ }
2723
+ return problems;
2724
+ }
2725
+ var pmxd = params.get("pmxd");
2726
+ var pmnd = params.get("pmnd");
2727
+ var pmad = params.get("pmad");
2728
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2729
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2730
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2731
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2732
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2733
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2734
+ }
2735
+ return problems;
2736
+ }
2737
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2738
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2739
+ return {
2740
+ vastAdCount: vastAdCount,
2741
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2742
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2743
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2744
+ };
2745
+ }
2258
2746
  // src/sdk/hlsAdPlayer.ts
2259
2747
  var LINEAR_TRACKING_EVENTS = [
2260
2748
  "creativeView",
@@ -2335,6 +2823,7 @@ function toVastMediaErrorCode(error) {
2335
2823
  return VAST_ERROR_MEDIA_DISPLAY;
2336
2824
  }
2337
2825
  }
2826
+ var gamCredentialsMode = "include";
2338
2827
  function createHlsAdPlayer(contentVideo, options) {
2339
2828
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2340
2829
  var adPlaying = false;
@@ -3206,9 +3695,9 @@ function createHlsAdPlayer(contentVideo, options) {
3206
3695
  }
3207
3696
  }
3208
3697
  function fetchVastXml(vastTagUrl) {
3209
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3698
+ var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam", finalizeRequestUrl = arguments.length > 3 ? arguments[3] : void 0;
3210
3699
  return _async_to_generator(function() {
3211
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3700
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3212
3701
  return _ts_generator(this, function(_state) {
3213
3702
  switch(_state.label){
3214
3703
  case 0:
@@ -3222,13 +3711,32 @@ function createHlsAdPlayer(contentVideo, options) {
3222
3711
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3223
3712
  startedAt = Date.now();
3224
3713
  attempt = 0;
3714
+ resolveDispatchUrl = function resolveDispatchUrl() {
3715
+ if (kind === "wrapper") return vastTagUrl;
3716
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3717
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3718
+ if (unresolved.length > 0) {
3719
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3720
+ }
3721
+ return url;
3722
+ };
3225
3723
  requestVast = function requestVast(creds) {
3226
3724
  return _async_to_generator(function() {
3227
- var response;
3725
+ var pending, response;
3228
3726
  return _ts_generator(this, function(_state) {
3229
3727
  switch(_state.label){
3230
3728
  case 0:
3231
3729
  attempt++;
3730
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3731
+ mode: "cors",
3732
+ credentials: creds,
3733
+ headers: {
3734
+ "Accept": "application/xml, text/xml, */*"
3735
+ },
3736
+ referrerPolicy: "no-referrer-when-downgrade"
3737
+ }, controller ? {
3738
+ signal: controller.signal
3739
+ } : {}));
3232
3740
  if (kind !== "wrapper") {
3233
3741
  logFunnel("".concat(kind, "_http_request_sent"), {
3234
3742
  attempt: attempt,
@@ -3237,16 +3745,7 @@ function createHlsAdPlayer(contentVideo, options) {
3237
3745
  }
3238
3746
  return [
3239
3747
  4,
3240
- fetch(vastTagUrl, _object_spread({
3241
- mode: "cors",
3242
- credentials: creds,
3243
- headers: {
3244
- "Accept": "application/xml, text/xml, */*"
3245
- },
3246
- referrerPolicy: "no-referrer-when-downgrade"
3247
- }, controller ? {
3248
- signal: controller.signal
3249
- } : {}))
3748
+ pending
3250
3749
  ];
3251
3750
  case 1:
3252
3751
  response = _state.sent();
@@ -3270,9 +3769,9 @@ function createHlsAdPlayer(contentVideo, options) {
3270
3769
  case 1:
3271
3770
  _state.trys.push([
3272
3771
  1,
3273
- 10,
3274
- 11,
3275
- 12
3772
+ 7,
3773
+ 8,
3774
+ 9
3276
3775
  ]);
3277
3776
  _state.label = 2;
3278
3777
  case 2:
@@ -3280,7 +3779,7 @@ function createHlsAdPlayer(contentVideo, options) {
3280
3779
  2,
3281
3780
  4,
3282
3781
  ,
3283
- 8
3782
+ 5
3284
3783
  ]);
3285
3784
  return [
3286
3785
  4,
@@ -3290,36 +3789,21 @@ function createHlsAdPlayer(contentVideo, options) {
3290
3789
  response = _state.sent();
3291
3790
  return [
3292
3791
  3,
3293
- 8
3792
+ 5
3294
3793
  ];
3295
3794
  case 4:
3296
3795
  error = _state.sent();
3297
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3298
- 3,
3299
- 6
3300
- ];
3301
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3302
- logFunnel("vast_credentials_retry", {
3303
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3304
- });
3305
- return [
3306
- 4,
3307
- requestVast("omit")
3308
- ];
3309
- case 5:
3310
- response = _state.sent();
3311
- return [
3312
- 3,
3313
- 7
3314
- ];
3315
- case 6:
3796
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3797
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3798
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3799
+ logFunnel("gam_credentials_mode_changed", {
3800
+ from: credentials,
3801
+ to: gamCredentialsMode,
3802
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3803
+ });
3804
+ }
3316
3805
  throw error;
3317
- case 7:
3318
- return [
3319
- 3,
3320
- 8
3321
- ];
3322
- case 8:
3806
+ case 5:
3323
3807
  if (!response.ok) {
3324
3808
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3325
3809
  }
@@ -3327,12 +3811,12 @@ function createHlsAdPlayer(contentVideo, options) {
3327
3811
  4,
3328
3812
  response.text()
3329
3813
  ];
3330
- case 9:
3814
+ case 6:
3331
3815
  return [
3332
3816
  2,
3333
3817
  _state.sent()
3334
3818
  ];
3335
- case 10:
3819
+ case 7:
3336
3820
  error1 = _state.sent();
3337
3821
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3338
3822
  if (pendingRequestAbortReason) {
@@ -3341,13 +3825,13 @@ function createHlsAdPlayer(contentVideo, options) {
3341
3825
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3342
3826
  }
3343
3827
  throw error1;
3344
- case 11:
3828
+ case 8:
3345
3829
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3346
3830
  if (controller) pendingVastRequests.delete(controller);
3347
3831
  return [
3348
3832
  7
3349
3833
  ];
3350
- case 12:
3834
+ case 9:
3351
3835
  return [
3352
3836
  2
3353
3837
  ];
@@ -3480,7 +3964,7 @@ function createHlsAdPlayer(contentVideo, options) {
3480
3964
  });
3481
3965
  }
3482
3966
  function fetchAndParsePod(vastTagUrl) {
3483
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3967
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3484
3968
  return _async_to_generator(function() {
3485
3969
  var _root_getAttribute, _root_getAttribute1, isEdge, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, candidates, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
3486
3970
  return _ts_generator(this, function(_state) {
@@ -3490,7 +3974,7 @@ function createHlsAdPlayer(contentVideo, options) {
3490
3974
  isEdge = source === "edge";
3491
3975
  return [
3492
3976
  4,
3493
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3977
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3494
3978
  ];
3495
3979
  case 1:
3496
3980
  vastXml = _state.sent();
@@ -4813,7 +5297,7 @@ function createHlsAdPlayer(contentVideo, options) {
4813
5297
  case 2:
4814
5298
  return [
4815
5299
  4,
4816
- fetchAndParsePod(vastTagUrl, source)
5300
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4817
5301
  ];
4818
5302
  case 3:
4819
5303
  ads = _state.sent();
@@ -5390,95 +5874,38 @@ function getOrCreateNonceLoader(allowStorage) {
5390
5874
  function createPalNonceManager() {
5391
5875
  var currentNonce = "";
5392
5876
  var currentNonceManager;
5877
+ var pendingNonce;
5393
5878
  return {
5394
5879
  generateNonce: function generateNonce() {
5395
- return _async_to_generator(function() {
5396
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5397
- var _arguments = arguments;
5398
- return _ts_generator(this, function(_state) {
5399
- switch(_state.label){
5400
- case 0:
5401
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5402
- _state.label = 1;
5403
- case 1:
5404
- _state.trys.push([
5405
- 1,
5406
- 4,
5407
- ,
5408
- 5
5409
- ]);
5410
- return [
5411
- 4,
5412
- loadPalSdk()
5413
- ];
5414
- case 2:
5415
- _state.sent();
5416
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5417
- goog = window.goog;
5418
- request = new goog.pal.NonceRequest();
5419
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5420
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5421
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5422
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5423
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5424
- request.iconsSupported = true;
5425
- request.playerType = "StormcloudVideoPlayer";
5426
- request.playerVersion = "1.0";
5427
- request.supportedApiFrameworks = "2,7,9";
5428
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5429
- request.videoWidth = options.videoWidth || 640;
5430
- request.videoHeight = options.videoHeight || 480;
5431
- if (options.ppid) request.ppid = options.ppid;
5432
- if (options.sessionId) request.sessionId = options.sessionId;
5433
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5434
- adWillAutoPlay: request.adWillAutoPlay,
5435
- adWillPlayMuted: request.adWillPlayMuted,
5436
- playerVolume: request.playerVolume,
5437
- continuousPlayback: request.continuousPlayback,
5438
- descriptionUrl: request.descriptionUrl,
5439
- iconsSupported: request.iconsSupported,
5440
- playerType: request.playerType,
5441
- playerVersion: request.playerVersion,
5442
- supportedApiFrameworks: request.supportedApiFrameworks,
5443
- url: request.url,
5444
- videoWidth: request.videoWidth,
5445
- videoHeight: request.videoHeight,
5446
- ppid: request.ppid,
5447
- sessionId: request.sessionId
5448
- }, null, 2));
5449
- return [
5450
- 4,
5451
- loader.loadNonceManager(request)
5452
- ];
5453
- case 3:
5454
- manager = _state.sent();
5455
- currentNonceManager = manager;
5456
- currentNonce = manager.getNonce();
5457
- console.log("[PAL] Nonce generated successfully");
5458
- return [
5459
- 2,
5460
- currentNonce
5461
- ];
5462
- case 4:
5463
- error = _state.sent();
5464
- console.warn("[PAL] Failed to generate nonce:", error);
5465
- currentNonce = "";
5466
- currentNonceManager = void 0;
5467
- return [
5468
- 2,
5469
- ""
5470
- ];
5471
- case 5:
5472
- return [
5473
- 2
5474
- ];
5475
- }
5476
- });
5477
- }).apply(this, arguments);
5880
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5881
+ var run = generate(options);
5882
+ pendingNonce = run;
5883
+ var settle = function settle() {
5884
+ if (pendingNonce === run) pendingNonce = void 0;
5885
+ };
5886
+ run.then(settle, settle);
5887
+ return run;
5478
5888
  },
5479
5889
  getCurrentNonce: function getCurrentNonce() {
5480
5890
  return currentNonce;
5481
5891
  },
5892
+ waitForNonce: function waitForNonce(maxWaitMs) {
5893
+ if (currentNonce) return Promise.resolve(currentNonce);
5894
+ var pending = pendingNonce;
5895
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5896
+ return new Promise(function(resolve) {
5897
+ var timer = setTimeout(function() {
5898
+ return resolve(currentNonce);
5899
+ }, maxWaitMs);
5900
+ pending.then(function(nonce) {
5901
+ clearTimeout(timer);
5902
+ resolve(nonce);
5903
+ }, function() {
5904
+ clearTimeout(timer);
5905
+ resolve("");
5906
+ });
5907
+ });
5908
+ },
5482
5909
  injectNonce: function injectNonce(vastTagUrl) {
5483
5910
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5484
5911
  try {
@@ -5515,8 +5942,90 @@ function createPalNonceManager() {
5515
5942
  reset: function reset() {
5516
5943
  currentNonce = "";
5517
5944
  currentNonceManager = void 0;
5945
+ pendingNonce = void 0;
5518
5946
  }
5519
5947
  };
5948
+ function generate(options) {
5949
+ return _async_to_generator(function() {
5950
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5951
+ return _ts_generator(this, function(_state) {
5952
+ switch(_state.label){
5953
+ case 0:
5954
+ _state.trys.push([
5955
+ 0,
5956
+ 3,
5957
+ ,
5958
+ 4
5959
+ ]);
5960
+ return [
5961
+ 4,
5962
+ loadPalSdk()
5963
+ ];
5964
+ case 1:
5965
+ _state.sent();
5966
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5967
+ goog = window.goog;
5968
+ request = new goog.pal.NonceRequest();
5969
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5970
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5971
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5972
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5973
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5974
+ request.iconsSupported = true;
5975
+ request.playerType = "StormcloudVideoPlayer";
5976
+ request.playerVersion = "1.0";
5977
+ request.supportedApiFrameworks = "2,7,9";
5978
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5979
+ request.videoWidth = options.videoWidth || 640;
5980
+ request.videoHeight = options.videoHeight || 480;
5981
+ if (options.ppid) request.ppid = options.ppid;
5982
+ if (options.sessionId) request.sessionId = options.sessionId;
5983
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5984
+ adWillAutoPlay: request.adWillAutoPlay,
5985
+ adWillPlayMuted: request.adWillPlayMuted,
5986
+ playerVolume: request.playerVolume,
5987
+ continuousPlayback: request.continuousPlayback,
5988
+ descriptionUrl: request.descriptionUrl,
5989
+ iconsSupported: request.iconsSupported,
5990
+ playerType: request.playerType,
5991
+ playerVersion: request.playerVersion,
5992
+ supportedApiFrameworks: request.supportedApiFrameworks,
5993
+ url: request.url,
5994
+ videoWidth: request.videoWidth,
5995
+ videoHeight: request.videoHeight,
5996
+ ppid: request.ppid,
5997
+ sessionId: request.sessionId
5998
+ }, null, 2));
5999
+ return [
6000
+ 4,
6001
+ loader.loadNonceManager(request)
6002
+ ];
6003
+ case 2:
6004
+ manager = _state.sent();
6005
+ currentNonceManager = manager;
6006
+ currentNonce = manager.getNonce();
6007
+ console.log("[PAL] Nonce generated successfully");
6008
+ return [
6009
+ 2,
6010
+ currentNonce
6011
+ ];
6012
+ case 3:
6013
+ error = _state.sent();
6014
+ console.warn("[PAL] Failed to generate nonce:", error);
6015
+ currentNonce = "";
6016
+ currentNonceManager = void 0;
6017
+ return [
6018
+ 2,
6019
+ ""
6020
+ ];
6021
+ case 4:
6022
+ return [
6023
+ 2
6024
+ ];
6025
+ }
6026
+ });
6027
+ })();
6028
+ }
5520
6029
  }
5521
6030
  // src/utils/trackingIngest.ts
5522
6031
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5599,7 +6108,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5599
6108
  // src/utils/tracking.ts
5600
6109
  var cachedBrowserId = null;
5601
6110
  function buildAnalyticsContext(config) {
6111
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5602
6112
  var context = {};
6113
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6114
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6115
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6116
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6117
+ if (contentChannel) context.contentChannel = contentChannel;
6118
+ if (contentTitle) context.contentTitle = contentTitle;
5603
6119
  if (config.debugAdTiming) {
5604
6120
  context.debugAdTiming = true;
5605
6121
  }
@@ -6090,12 +6606,19 @@ function sendAdImpressionTracking(_0, _1) {
6090
6606
  4,
6091
6607
  ingestPlayerTracking(licenseKey, "impressions", {
6092
6608
  events: [
6093
- {
6609
+ _object_spread({
6094
6610
  player_id: metricEvent.player_id,
6095
6611
  ad_played_count: 1,
6096
6612
  ad_url: adImpressionInfo.adUrl,
6097
- capture_at: adImpressionInfo.timestamp
6098
- }
6613
+ capture_at: adImpressionInfo.timestamp,
6614
+ source: "gam"
6615
+ }, context.contentNetwork ? {
6616
+ content_network: context.contentNetwork
6617
+ } : {}, context.contentChannel ? {
6618
+ content_channel: context.contentChannel
6619
+ } : {}, context.contentTitle ? {
6620
+ content_title: context.contentTitle
6621
+ } : {})
6099
6622
  ]
6100
6623
  })
6101
6624
  ];
@@ -7444,6 +7967,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7444
7967
  return Scte35CueManager;
7445
7968
  }();
7446
7969
  // src/player/AdConfigManager.ts
7970
+ function withDeferredPodParams(rawUrl, deferNonce) {
7971
+ try {
7972
+ var url = new URL(rawUrl);
7973
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7974
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7975
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7976
+ if (deferNonce && !url.searchParams.get("givn")) {
7977
+ url.searchParams.delete("paln");
7978
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7979
+ }
7980
+ return url.toString();
7981
+ } catch (unused) {
7982
+ return rawUrl;
7983
+ }
7984
+ }
7447
7985
  var AdConfigManager = /*#__PURE__*/ function() {
7448
7986
  function AdConfigManager(config, video) {
7449
7987
  _class_call_check(this, AdConfigManager);
@@ -7454,8 +7992,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7454
7992
  this.podCounter = 0;
7455
7993
  this.podAssignedByPrefetch = false;
7456
7994
  this.lastHeartbeatTime = 0;
7457
- this.defaultPodMaxAds = 6;
7458
- this.defaultPodMaxDurationMs = 12e4;
7995
+ this.defaultEdgePodMaxAds = 6;
7996
+ this.palNonceDispatchWaitMs = 1500;
7459
7997
  this.config = config;
7460
7998
  this.video = video;
7461
7999
  }
@@ -7483,7 +8021,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7483
8021
  key: "fetchAdConfiguration",
7484
8022
  value: function fetchAdConfiguration() {
7485
8023
  return _async_to_generator(function() {
7486
- var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
8024
+ var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
7487
8025
  return _ts_generator(this, function(_state) {
7488
8026
  switch(_state.label){
7489
8027
  case 0:
@@ -7504,28 +8042,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7504
8042
  2
7505
8043
  ];
7506
8044
  case 2:
7507
- vastMode = this.config.vastMode || "default";
7508
- if (this.debug) {
7509
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7510
- }
7511
- if (vastMode === "adstorm") {
7512
- if (!this.config.licenseKey) {
7513
- if (this.debug) {
7514
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7515
- }
7516
- return [
7517
- 2
7518
- ];
7519
- }
7520
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7521
- this.apiVastTagUrl = vastEndpoint;
7522
- if (this.debug) {
7523
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7524
- }
7525
- return [
7526
- 2
7527
- ];
7528
- }
7529
8045
  if (this.config.vastTagUrl) {
7530
8046
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7531
8047
  if (this.debug) {
@@ -7535,7 +8051,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7535
8051
  2
7536
8052
  ];
7537
8053
  }
7538
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
8054
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7539
8055
  if (this.debug) {
7540
8056
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7541
8057
  }
@@ -7882,16 +8398,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7882
8398
  }
7883
8399
  },
7884
8400
  {
7885
- key: "resolvePodParams",
7886
- value: function resolvePodParams(breakDurationMs) {
7887
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7888
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7889
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7890
- return {
7891
- maxAds: maxAds,
7892
- minDurationMs: minDurationMs,
7893
- maxDurationMs: maxDurationMs
7894
- };
8401
+ key: "resolveAdPodConfig",
8402
+ value: function resolveAdPodConfig1() {
8403
+ return resolveAdPodConfig(this.config);
8404
+ }
8405
+ },
8406
+ {
8407
+ key: "resolveEdgeMaxAds",
8408
+ value: function resolveEdgeMaxAds() {
8409
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8410
+ return (_this_resolveAdPodConfig_maxAdsPerBreak = this.resolveAdPodConfig().maxAdsPerBreak) !== null && _this_resolveAdPodConfig_maxAdsPerBreak !== void 0 ? _this_resolveAdPodConfig_maxAdsPerBreak : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultEdgePodMaxAds;
7895
8411
  }
7896
8412
  },
7897
8413
  {
@@ -7908,17 +8424,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7908
8424
  },
7909
8425
  {
7910
8426
  key: "generatePodVastUrl",
7911
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7912
- var _podParams_maxDurationMs;
8427
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7913
8428
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7914
8429
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7915
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8430
+ var macroContext = _object_spread_props(_object_spread({
7916
8431
  correlator: this.viewCorrelator,
7917
8432
  streamCorrelator: this.streamCorrelator,
7918
8433
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7919
- podMaxAds: podParams.maxAds,
7920
- podMinDurationMs: podParams.minDurationMs,
7921
- podMaxDurationMs: podParams.maxDurationMs,
7922
8434
  isCtv: envSignals.isCtv,
7923
8435
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7924
8436
  adWillPlayMuted: adWillPlayMuted,
@@ -7934,13 +8446,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7934
8446
  } : {}, this.config.channelName ? {
7935
8447
  channelName: this.config.channelName
7936
8448
  } : {}), {
7937
- consent: this.consentSignals
7938
- }));
7939
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7940
- console.log("[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=".concat(this.podCounter, ", pmad=").concat(podParams.maxAds, ", pmnd=").concat(podParams.minDurationMs, ", pmxd=").concat((_podParams_maxDurationMs = podParams.maxDurationMs) !== null && _podParams_maxDurationMs !== void 0 ? _podParams_maxDurationMs : "?", "):"), finalUrl);
8449
+ consent: this.consentSignals,
8450
+ palNonce: palNonce.getCurrentNonce() || void 0
8451
+ });
8452
+ var nonceReady = !!macroContext.palNonce;
8453
+ var finalUrl;
8454
+ if (hasScvpMacros(baseUrl)) {
8455
+ var deferred = new Set(SCVP_POD_MACROS);
8456
+ if (!nonceReady) deferred.add("GIVN");
8457
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8458
+ if (unresolved.length > 0) {
8459
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8460
+ }
8461
+ finalUrl = ensureVideoAdType(url);
8462
+ } else {
8463
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8464
+ }
8465
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7941
8466
  return finalUrl;
7942
8467
  }
7943
8468
  },
8469
+ {
8470
+ key: "completeDeferredRequestSignals",
8471
+ value: function completeDeferredRequestSignals(url, palNonce) {
8472
+ return _async_to_generator(function() {
8473
+ var nonce, _tmp;
8474
+ return _ts_generator(this, function(_state) {
8475
+ switch(_state.label){
8476
+ case 0:
8477
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8478
+ 2,
8479
+ url
8480
+ ];
8481
+ _tmp = palNonce.getCurrentNonce();
8482
+ if (_tmp) return [
8483
+ 3,
8484
+ 2
8485
+ ];
8486
+ return [
8487
+ 4,
8488
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8489
+ ];
8490
+ case 1:
8491
+ _tmp = _state.sent();
8492
+ _state.label = 2;
8493
+ case 2:
8494
+ nonce = _tmp;
8495
+ if (!nonce) return [
8496
+ 2,
8497
+ url
8498
+ ];
8499
+ return [
8500
+ 2,
8501
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8502
+ [
8503
+ "GIVN",
8504
+ nonce
8505
+ ]
8506
+ ]), function(name) {
8507
+ return name !== "GIVN";
8508
+ }).url
8509
+ ];
8510
+ }
8511
+ });
8512
+ }).call(this);
8513
+ }
8514
+ },
7944
8515
  {
7945
8516
  // --- Tracking ---
7946
8517
  key: "initializeTracking",
@@ -7988,6 +8559,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7988
8559
  return AdConfigManager;
7989
8560
  }();
7990
8561
  // src/player/AdTimingService.ts
8562
+ function monotonicNow() {
8563
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8564
+ }
7991
8565
  var AdTimingService = /*#__PURE__*/ function() {
7992
8566
  function AdTimingService(config, video, callbacks) {
7993
8567
  _class_call_check(this, AdTimingService);
@@ -8118,6 +8692,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8118
8692
  },
8119
8693
  {
8120
8694
  // --- Duration boundary ---
8695
+ key: "beginBreakTiming",
8696
+ value: function beginBreakTiming(startWallClockMs) {
8697
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8698
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8699
+ this.breakEndMonoMs = void 0;
8700
+ }
8701
+ },
8702
+ {
8703
+ key: "markBreakEndedNow",
8704
+ value: function markBreakEndedNow() {
8705
+ this.scteAdBreakEndWallClockMs = Date.now();
8706
+ this.breakEndMonoMs = monotonicNow();
8707
+ }
8708
+ },
8709
+ {
8121
8710
  key: "setAdBreakDurationBoundary",
8122
8711
  value: function setAdBreakDurationBoundary(durationMs) {
8123
8712
  this.expectedAdBreakDurationMs = durationMs;
@@ -8126,6 +8715,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8126
8715
  } else {
8127
8716
  this.scteAdBreakEndWallClockMs = void 0;
8128
8717
  }
8718
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8719
+ }
8720
+ },
8721
+ {
8722
+ key: "getBreakTimingSnapshot",
8723
+ value: function getBreakTimingSnapshot() {
8724
+ return {
8725
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8726
+ breakStartMonoMs: this.breakStartMonoMs,
8727
+ breakEndMonoMs: this.breakEndMonoMs,
8728
+ playedDurationMs: this.adBreakPlayedDurationMs
8729
+ };
8129
8730
  }
8130
8731
  },
8131
8732
  {
@@ -8539,6 +9140,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8539
9140
  this.expectedAdBreakDurationMs = void 0;
8540
9141
  this.currentAdBreakStartWallClockMs = void 0;
8541
9142
  this.scteAdBreakEndWallClockMs = void 0;
9143
+ this.breakStartMonoMs = void 0;
9144
+ this.breakEndMonoMs = void 0;
8542
9145
  this.adBreakPlayedDurationMs = 0;
8543
9146
  this.currentAdIndex = 0;
8544
9147
  this.totalAdsInBreak = 0;
@@ -9552,9 +10155,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9552
10155
  // ───────────────────────────────────────────────────────────────
9553
10156
  key: "nextAdRequestUrl",
9554
10157
  value: function nextAdRequestUrl(baseVastUrl) {
9555
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9556
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9557
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10158
+ return this.host.generatePodVastUrl(baseVastUrl);
9558
10159
  }
9559
10160
  },
9560
10161
  {
@@ -9817,7 +10418,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9817
10418
  key: "handleAdStart",
9818
10419
  value: function handleAdStart(marker) {
9819
10420
  return _async_to_generator(function() {
9820
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10421
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9821
10422
  return _ts_generator(this, function(_state) {
9822
10423
  switch(_state.label){
9823
10424
  case 0:
@@ -9869,8 +10470,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9869
10470
  }
9870
10471
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9871
10472
  epoch = this.timing.adBreakEpoch;
9872
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9873
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10473
+ if (!(adBreakDurationMs == null)) return [
9874
10474
  3,
9875
10475
  2
9876
10476
  ];
@@ -9926,7 +10526,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9926
10526
  }
9927
10527
  return [
9928
10528
  4,
9929
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10529
+ this.startOptimizedPod(baseVastUrl)
9930
10530
  ];
9931
10531
  case 6:
9932
10532
  podPlayed = _state.sent();
@@ -9994,9 +10594,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9994
10594
  value: // ───────────────────────────────────────────────────────────────
9995
10595
  // Optimized pod (single multi-ad request)
9996
10596
  // ───────────────────────────────────────────────────────────────
9997
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10597
+ function startOptimizedPod(baseVastUrl) {
9998
10598
  return _async_to_generator(function() {
9999
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10599
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
10000
10600
  return _ts_generator(this, function(_state) {
10001
10601
  switch(_state.label){
10002
10602
  case 0:
@@ -10005,7 +10605,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10005
10605
  podUrl = this.pendingAdBreak.vastUrls[0];
10006
10606
  this.clearPendingAdBreak();
10007
10607
  } else {
10008
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10608
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
10009
10609
  }
10010
10610
  if (!podUrl) {
10011
10611
  return [
@@ -10029,9 +10629,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10029
10629
  case 1:
10030
10630
  _state.trys.push([
10031
10631
  1,
10032
- 5,
10632
+ 9,
10033
10633
  ,
10034
- 6
10634
+ 10
10035
10635
  ]);
10036
10636
  return [
10037
10637
  4,
@@ -10043,15 +10643,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10043
10643
  2,
10044
10644
  true
10045
10645
  ];
10646
+ return [
10647
+ 4,
10648
+ this.host.completeGamRequestSignals(requestUrl)
10649
+ ];
10650
+ case 3:
10651
+ requestUrl = _state.sent();
10652
+ if (this.isStale(epoch, generation)) return [
10653
+ 2,
10654
+ true
10655
+ ];
10046
10656
  this.timing.startAdRequestWatchdog(requestToken);
10657
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10658
+ _state.label = 4;
10659
+ case 4:
10660
+ _state.trys.push([
10661
+ 4,
10662
+ ,
10663
+ 6,
10664
+ 7
10665
+ ]);
10047
10666
  return [
10048
10667
  4,
10049
10668
  this.callController(function() {
10050
- return adPlayer.requestAds(requestUrl);
10669
+ return adPlayer.requestAds(requestUrl, {
10670
+ finalizeRequestUrl: finalizeRequestUrl
10671
+ });
10051
10672
  })
10052
10673
  ];
10053
- case 3:
10674
+ case 5:
10054
10675
  _state.sent();
10676
+ return [
10677
+ 3,
10678
+ 7
10679
+ ];
10680
+ case 6:
10681
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10682
+ return [
10683
+ 7
10684
+ ];
10685
+ case 7:
10055
10686
  this.timing.clearAdRequestWatchdog();
10056
10687
  if (this.isStale(epoch, generation)) {
10057
10688
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10079,7 +10710,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10079
10710
  }
10080
10711
  sendAdLoadedTracking(this.host.config.licenseKey, {
10081
10712
  source: "hls",
10082
- vastUrl: requestUrl,
10713
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10083
10714
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10084
10715
  }, this.analyticsContext).catch(function() {});
10085
10716
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10089,7 +10720,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10089
10720
  return adPlayer.play();
10090
10721
  })
10091
10722
  ];
10092
- case 4:
10723
+ case 8:
10093
10724
  _state.sent();
10094
10725
  if (this.isStale(epoch, generation)) return [
10095
10726
  2,
@@ -10103,7 +10734,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10103
10734
  2,
10104
10735
  true
10105
10736
  ];
10106
- case 5:
10737
+ case 9:
10107
10738
  error = _state.sent();
10108
10739
  this.timing.clearAdRequestWatchdog();
10109
10740
  this.timing.clearAdFailsafeTimer();
@@ -10123,12 +10754,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10123
10754
  if (this.debug) {
10124
10755
  console.warn("[POD] Optimized pod request/play failed:", error);
10125
10756
  }
10757
+ if (this.handlePodRequestNotSent(error)) return [
10758
+ 2,
10759
+ false
10760
+ ];
10126
10761
  this.recordRequestFailure(error, podUrl);
10127
10762
  return [
10128
10763
  2,
10129
10764
  false
10130
10765
  ];
10131
- case 6:
10766
+ case 10:
10132
10767
  return [
10133
10768
  2
10134
10769
  ];
@@ -10174,17 +10809,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10174
10809
  }
10175
10810
  },
10176
10811
  {
10177
- /**
10178
- * Builds the next Edge request from the budget left right now, or marks Edge
10179
- * exhausted for this break. Synchronous on purpose: callers must reach the
10180
- * REQUESTING state in the same tick so a second completion event cannot race
10181
- * in a parallel request.
10182
- */ key: "prepareEdgePodRequest",
10812
+ key: "prepareEdgePodRequest",
10183
10813
  value: function prepareEdgePodRequest() {
10184
10814
  var baseUrl = this.host.getEdgePodBaseUrl();
10185
10815
  if (!baseUrl) return void 0;
10186
10816
  var remainingMs = this.timing.getRemainingAdMs();
10187
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10817
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10188
10818
  if (remainingAds < 1) {
10189
10819
  this.markEdgeExhausted("ad_capacity_reached", {
10190
10820
  adsInBreak: this.timing.totalAdsInBreak
@@ -10263,7 +10893,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10263
10893
  ];
10264
10894
  }
10265
10895
  remainingMs = this.timing.getRemainingAdMs();
10266
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10896
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10267
10897
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10268
10898
  podCount = adPlayer.limitPodToBudget ? adPlayer.limitPodToBudget(remainingMs + overrunAllowanceMs, remainingAds) : (_ref = (_adPlayer_getPodAdCount = adPlayer.getPodAdCount) === null || _adPlayer_getPodAdCount === void 0 ? void 0 : _adPlayer_getPodAdCount.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0;
10269
10899
  if (classifyEdgeVastResponse({
@@ -10610,7 +11240,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10610
11240
  {
10611
11241
  key: "noteVastUrlGenerated",
10612
11242
  value: function noteVastUrlGenerated(url, source) {
10613
- var _ref, _ref1, _ref2, _ref3, _ref4;
11243
+ var _ref, _ref1;
10614
11244
  var params;
10615
11245
  try {
10616
11246
  params = new URL(url).searchParams;
@@ -10620,9 +11250,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10620
11250
  requestId: void 0,
10621
11251
  source: source,
10622
11252
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10623
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10624
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10625
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11253
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11254
+ return SCVP_POD_MACROS.has(name);
11255
+ }),
10626
11256
  adType: adType
10627
11257
  });
10628
11258
  if (adType === "audio" || adType === "audio_video") {
@@ -10663,10 +11293,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10663
11293
  if (diag && !diag.failureReason) {
10664
11294
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10665
11295
  }
11296
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11297
+ return SCVP_POD_MACROS.has(name);
11298
+ }) ? diag.dispatchedUrl : vastTagUrl;
10666
11299
  if (this.timing.isTemporaryAdError(error)) {
10667
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11300
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10668
11301
  } else if (outcome !== "discarded_budget") {
10669
- this.timing.failedVastUrls.add(vastTagUrl);
11302
+ this.timing.failedVastUrls.add(failureKey);
10670
11303
  }
10671
11304
  this.countFunnelStage("request_outcome:".concat(outcome));
10672
11305
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10692,6 +11325,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10692
11325
  switch(payload.stage){
10693
11326
  case "gam_http_request_sent":
10694
11327
  diag.gamRequestSent++;
11328
+ this.logPodDispatch(diag);
10695
11329
  break;
10696
11330
  case "edge_http_request_sent":
10697
11331
  diag.edgeRequestSent++;
@@ -10743,8 +11377,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10743
11377
  if (gamReturnedAdWithoutImpression) {
10744
11378
  this.countFunnelStage("gam_ad_without_impression");
10745
11379
  }
10746
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10747
- "startedAt"
11380
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11381
+ "startedAt",
11382
+ "dispatchedUrl",
11383
+ "podDispatchLogged"
10748
11384
  ]);
10749
11385
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10750
11386
  durationMs: Date.now() - startedAt,
@@ -10756,24 +11392,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10756
11392
  // ───────────────────────────────────────────────────────────────
10757
11393
  // Single ad playback
10758
11394
  // ───────────────────────────────────────────────────────────────
10759
- key: "withCurrentPodBudget",
10760
- value: function withCurrentPodBudget(rawVastTagUrl) {
10761
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10762
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10763
- if (!(remaining > 0)) return vastTagUrl;
10764
- try {
10765
- var url = new URL(vastTagUrl);
10766
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10767
- var maxMs = Math.round(remaining);
10768
- url.searchParams.set("pmxd", String(maxMs));
10769
- var minMs = Number(url.searchParams.get("pmnd"));
10770
- if (Number.isFinite(minMs) && minMs > maxMs) {
10771
- url.searchParams.set("pmnd", String(maxMs));
10772
- }
10773
- return url.toString();
10774
- } catch (unused) {
10775
- return vastTagUrl;
10776
- }
11395
+ key: "createGamDispatchFinalizer",
11396
+ value: function createGamDispatchFinalizer(requestToken) {
11397
+ var _this = this;
11398
+ var breakId = this.timing.adBreakEpoch;
11399
+ var config = this.adConfig.resolveAdPodConfig();
11400
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11401
+ return function(url) {
11402
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11403
+ var diag = _this.requestDiagnostics.get(requestToken);
11404
+ try {
11405
+ var result = finalizeGamRequestUrl(url, {
11406
+ breakId: breakId,
11407
+ capacity: capacity,
11408
+ config: config,
11409
+ minUsablePmxdMs: minUsablePmxdMs
11410
+ });
11411
+ if (diag) {
11412
+ diag.pod = result.diagnostics;
11413
+ diag.dispatchedUrl = result.url;
11414
+ diag.podDispatchLogged = false;
11415
+ }
11416
+ _this.currentVastUrl = result.url;
11417
+ return result.url;
11418
+ } catch (error) {
11419
+ if (diag && isPodRequestAbortedError(error)) {
11420
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11421
+ }
11422
+ throw error;
11423
+ }
11424
+ };
11425
+ }
11426
+ },
11427
+ {
11428
+ key: "logPodDispatch",
11429
+ value: function logPodDispatch(diag) {
11430
+ if (!diag.pod || diag.podDispatchLogged) return;
11431
+ diag.podDispatchLogged = true;
11432
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11433
+ }
11434
+ },
11435
+ {
11436
+ key: "recordPodResponseDiagnostics",
11437
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11438
+ var _diag_vastAdCount, _ref;
11439
+ var _adPlayer_getPodTotalDurationMs;
11440
+ var diag = this.requestDiagnostics.get(requestToken);
11441
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11442
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11443
+ diag.podResponse = computePodResponseDiagnostics(diag.pod.pmxdSent, (_diag_vastAdCount = diag.vastAdCount) !== null && _diag_vastAdCount !== void 0 ? _diag_vastAdCount : 0, (_ref = (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0);
11444
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11445
+ pmxdSent: diag.pod.pmxdSent
11446
+ }, diag.podResponse));
11447
+ }
11448
+ },
11449
+ {
11450
+ key: "handlePodRequestNotSent",
11451
+ value: function handlePodRequestNotSent(error) {
11452
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11453
+ var aborted = error;
11454
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11455
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11456
+ reason: aborted.reason,
11457
+ errorMessage: aborted.message
11458
+ }, aborted.diagnostics));
11459
+ return true;
10777
11460
  }
10778
11461
  },
10779
11462
  {
@@ -10993,7 +11676,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10993
11676
  value: function playSingleAd(vastTagUrl) {
10994
11677
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10995
11678
  return _async_to_generator(function() {
10996
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11679
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10997
11680
  return _ts_generator(this, function(_state) {
10998
11681
  switch(_state.label){
10999
11682
  case 0:
@@ -11031,19 +11714,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11031
11714
  requestToken = ++this.timing.adRequestTokenCounter;
11032
11715
  this.timing.activeAdRequestToken = requestToken;
11033
11716
  ap = this.host.getAdPlayer();
11034
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
11035
11717
  this.currentPodSource = "gam";
11036
11718
  this.setSlotState("REQUESTING", trigger);
11037
11719
  this.beginFunnelRequest(ap, requestToken, trigger);
11038
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11720
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
11039
11721
  this.currentVastUrl = requestUrl;
11040
11722
  _state.label = 1;
11041
11723
  case 1:
11042
11724
  _state.trys.push([
11043
11725
  1,
11044
- 5,
11726
+ 9,
11045
11727
  ,
11046
- 6
11728
+ 10
11047
11729
  ]);
11048
11730
  return [
11049
11731
  4,
@@ -11054,15 +11736,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11054
11736
  if (this.isStale(epoch, generation)) return [
11055
11737
  2
11056
11738
  ];
11739
+ return [
11740
+ 4,
11741
+ this.host.completeGamRequestSignals(requestUrl)
11742
+ ];
11743
+ case 3:
11744
+ requestUrl = _state.sent();
11745
+ if (this.isStale(epoch, generation)) return [
11746
+ 2
11747
+ ];
11057
11748
  this.timing.startAdRequestWatchdog(requestToken);
11749
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11750
+ _state.label = 4;
11751
+ case 4:
11752
+ _state.trys.push([
11753
+ 4,
11754
+ ,
11755
+ 6,
11756
+ 7
11757
+ ]);
11058
11758
  return [
11059
11759
  4,
11060
11760
  this.callController(function() {
11061
- return ap.requestAds(requestUrl);
11761
+ return ap.requestAds(requestUrl, {
11762
+ finalizeRequestUrl: finalizeRequestUrl
11763
+ });
11062
11764
  })
11063
11765
  ];
11064
- case 3:
11766
+ case 5:
11065
11767
  _state.sent();
11768
+ return [
11769
+ 3,
11770
+ 7
11771
+ ];
11772
+ case 6:
11773
+ this.recordPodResponseDiagnostics(requestToken, ap);
11774
+ return [
11775
+ 7
11776
+ ];
11777
+ case 7:
11066
11778
  this.timing.clearAdRequestWatchdog();
11067
11779
  if (this.isStale(epoch, generation)) {
11068
11780
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11074,7 +11786,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11074
11786
  }
11075
11787
  sendAdLoadedTracking(this.host.config.licenseKey, {
11076
11788
  source: "hls",
11077
- vastUrl: requestUrl,
11789
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11078
11790
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11079
11791
  }, this.analyticsContext).catch(function() {});
11080
11792
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11095,7 +11807,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11095
11807
  return ap.play();
11096
11808
  })
11097
11809
  ];
11098
- case 4:
11810
+ case 8:
11099
11811
  _state.sent();
11100
11812
  if (this.isStale(epoch, generation)) return [
11101
11813
  2
@@ -11107,9 +11819,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11107
11819
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11108
11820
  return [
11109
11821
  3,
11110
- 6
11822
+ 10
11111
11823
  ];
11112
- case 5:
11824
+ case 9:
11113
11825
  error = _state.sent();
11114
11826
  this.timing.clearAdRequestWatchdog();
11115
11827
  this.timing.clearAdFailsafeTimer();
@@ -11126,12 +11838,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11126
11838
  ];
11127
11839
  }
11128
11840
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11841
+ if (this.handlePodRequestNotSent(error)) throw error;
11129
11842
  this.recordRequestFailure(error, vastTagUrl);
11130
11843
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11131
11844
  this.recreateAdController("discarded_budget");
11132
11845
  }
11133
11846
  throw error;
11134
- case 6:
11847
+ case 10:
11135
11848
  return [
11136
11849
  2
11137
11850
  ];
@@ -11193,7 +11906,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11193
11906
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11194
11907
  requestFailed: count("request_failed"),
11195
11908
  requestAbortedTimeout: count("request_aborted_timeout"),
11196
- credentialsRetries: count("vast_credentials_retry"),
11909
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11197
11910
  wrapperFailures: count("wrapper_fetch:failure"),
11198
11911
  noSupportedMedia: count("vast_no_supported_media"),
11199
11912
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11729,8 +12442,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11729
12442
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11730
12443
  return requiresMediaPipelineResetAfterAds();
11731
12444
  },
11732
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11733
- return _this.generatePodVastUrl(base, breakDurationMs);
12445
+ generatePodVastUrl: function generatePodVastUrl(base) {
12446
+ return _this.generatePodVastUrl(base);
12447
+ },
12448
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12449
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11734
12450
  },
11735
12451
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11736
12452
  return _this.edgePodBaseUrl;
@@ -11854,9 +12570,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11854
12570
  },
11855
12571
  {
11856
12572
  key: "generatePodVastUrl",
11857
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11858
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11859
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12573
+ value: function generatePodVastUrl(baseUrl) {
12574
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11860
12575
  }
11861
12576
  },
11862
12577
  {
@@ -12210,7 +12925,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12210
12925
  activeAdRequest: this.timing.activeAdRequestToken !== null
12211
12926
  });
12212
12927
  }
12213
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12928
+ this.timing.markBreakEndedNow();
12214
12929
  this.timing.clearAdStartTimer();
12215
12930
  this.timing.clearAdStopTimer();
12216
12931
  if (adPlaying) {
@@ -12237,7 +12952,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12237
12952
  this.adBreak.inAdBreak = true;
12238
12953
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12239
12954
  this.cueManager.scheduledScte35BreakKey = void 0;
12240
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12955
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12241
12956
  this.timing.setAdBreakDurationBoundary(durationMs);
12242
12957
  this.adBreak.handleAdStart(marker);
12243
12958
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12283,9 +12998,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12283
12998
  }
12284
12999
  this.adConfig.beginNewAdPod();
12285
13000
  this.adConfig.podAssignedByPrefetch = true;
12286
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12287
13001
  var generatedUrls = [
12288
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
13002
+ this.generatePodVastUrl(baseVastUrl)
12289
13003
  ];
12290
13004
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12291
13005
  marker: marker
@@ -12384,7 +13098,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12384
13098
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12385
13099
  this.adBreak.showAds = true;
12386
13100
  this.adBreak.inAdBreak = true;
12387
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13101
+ this.timing.beginBreakTiming(Date.now());
12388
13102
  if (durationMs > 0) {
12389
13103
  this.timing.setAdBreakDurationBoundary(durationMs);
12390
13104
  }