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
@@ -429,21 +429,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
429
429
  "adid"
430
430
  ]);
431
431
  function resolveVastEnvironmentSignals(isCtv) {
432
- var _ref;
433
432
  var bridgeSignals = readNativeBridgeSignals();
434
433
  var platformDevice = readPlatformNativeDeviceId();
435
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
434
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
435
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
436
436
  var deviceId = realDeviceId;
437
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
438
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
439
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
437
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
438
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
439
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
440
440
  if (!deviceId && isCtv) {
441
441
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
442
442
  if (dpid) {
443
- var _ref1;
444
443
  deviceId = dpid;
445
444
  deviceIdType = "dpid";
446
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
445
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
447
446
  }
448
447
  }
449
448
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -808,6 +807,9 @@ function isMacroPlaceholder(value) {
808
807
  var t = value.trim();
809
808
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
810
809
  }
810
+ function validDeviceId(value) {
811
+ return value && !isMacroPlaceholder(value) ? value : void 0;
812
+ }
811
813
  function isZeroedAdId(value) {
812
814
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
813
815
  }
@@ -1340,6 +1342,198 @@ function ensureVideoAdType(rawUrl) {
1340
1342
  return rawUrl;
1341
1343
  }
1342
1344
  }
1345
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1346
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1347
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1348
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1349
+ "cust_params"
1350
+ ]);
1351
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1352
+ "PMND",
1353
+ "PMXD",
1354
+ "PMAD"
1355
+ ]);
1356
+ function hasScvpMacros(url) {
1357
+ return !!url && SCVP_MACRO_DETECT.test(url);
1358
+ }
1359
+ function safeDecode(value) {
1360
+ try {
1361
+ return decodeURIComponent(value.replace(/\+/g, " "));
1362
+ } catch (unused) {
1363
+ return value;
1364
+ }
1365
+ }
1366
+ function findScvpMacroNames(url) {
1367
+ if (!url) return [];
1368
+ var names = /* @__PURE__ */ new Set();
1369
+ var text = url;
1370
+ for(var pass = 0; pass < 3; pass++){
1371
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1372
+ names.add(String(bracketName || parenName).toUpperCase());
1373
+ return "";
1374
+ });
1375
+ var decoded = safeDecode(text);
1376
+ if (decoded === text) break;
1377
+ text = decoded;
1378
+ }
1379
+ return Array.from(names);
1380
+ }
1381
+ function resolveScvpMacroValues(ctx) {
1382
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1383
+ var values = /* @__PURE__ */ new Map();
1384
+ var set = function set(name, value) {
1385
+ if (value == null) return;
1386
+ var str = String(value).trim();
1387
+ if (str) values.set(name, str);
1388
+ };
1389
+ var toFlag = function toFlag(value) {
1390
+ return value == null ? void 0 : value ? "1" : "0";
1391
+ };
1392
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1393
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1394
+ if (deviceId && deviceIdType) {
1395
+ set("RDID", deviceId);
1396
+ set("IDTYPE", deviceIdType);
1397
+ set("IS-LAT", toFlag(ctx.limitAdTracking));
1398
+ }
1399
+ set("SID", ctx.sessionId);
1400
+ set("DTH", ctx.deviceTypeHint);
1401
+ set("GIVN", ctx.palNonce);
1402
+ set("CT-TI", ctx.programTitle);
1403
+ set("CT-CH", ctx.channelName);
1404
+ set("POD", ctx.pod);
1405
+ set("CORRELATOR", ctx.correlator);
1406
+ set("SCOR", ctx.streamCorrelator);
1407
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1408
+ if (ctx.adWillAutoPlay != null) {
1409
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1410
+ }
1411
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1412
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1413
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1414
+ return values;
1415
+ }
1416
+ var keepNone = function keepNone() {
1417
+ return false;
1418
+ };
1419
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1420
+ var out = [];
1421
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1422
+ var name = String(bracketName || parenName).toUpperCase();
1423
+ var value = values.get(name);
1424
+ if (value != null) return value;
1425
+ if (keep(name)) return match;
1426
+ unresolved.add(name);
1427
+ return "";
1428
+ };
1429
+ params.forEach(function(value, key) {
1430
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1431
+ if (whole) {
1432
+ var name = String(whole[1] || whole[2]).toUpperCase();
1433
+ var resolved = values.get(name);
1434
+ if (resolved != null) {
1435
+ out.push([
1436
+ key,
1437
+ resolved
1438
+ ]);
1439
+ } else if (keep(name)) {
1440
+ out.push([
1441
+ key,
1442
+ value
1443
+ ]);
1444
+ } else {
1445
+ unresolved.add(name);
1446
+ }
1447
+ return;
1448
+ }
1449
+ if (!SCVP_MACRO_DETECT.test(value)) {
1450
+ out.push([
1451
+ key,
1452
+ value
1453
+ ]);
1454
+ return;
1455
+ }
1456
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1457
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1458
+ if (inner.length > 0) {
1459
+ out.push([
1460
+ key,
1461
+ inner.map(function(param) {
1462
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1463
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1464
+ }).join("&")
1465
+ ]);
1466
+ }
1467
+ return;
1468
+ }
1469
+ out.push([
1470
+ key,
1471
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1472
+ ]);
1473
+ });
1474
+ return out;
1475
+ }
1476
+ function substituteScvpMacros(baseUrl, values) {
1477
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1478
+ var unresolved = /* @__PURE__ */ new Set();
1479
+ var url;
1480
+ try {
1481
+ url = new URL(normalizeVastTagUrl(baseUrl));
1482
+ } catch (unused) {
1483
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1484
+ var name = String(bracketName || parenName).toUpperCase();
1485
+ var value = values.get(name);
1486
+ if (value != null) return encodeURIComponent(value);
1487
+ if (keep(name)) return match;
1488
+ unresolved.add(name);
1489
+ return "";
1490
+ });
1491
+ return {
1492
+ url: replaced,
1493
+ unresolved: Array.from(unresolved)
1494
+ };
1495
+ }
1496
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1497
+ var search = new URLSearchParams();
1498
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1499
+ try {
1500
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1501
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1502
+ search.append(key, value);
1503
+ }
1504
+ } catch (err) {
1505
+ _didIteratorError = true;
1506
+ _iteratorError = err;
1507
+ } finally{
1508
+ try {
1509
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1510
+ _iterator.return();
1511
+ }
1512
+ } finally{
1513
+ if (_didIteratorError) {
1514
+ throw _iteratorError;
1515
+ }
1516
+ }
1517
+ }
1518
+ url.search = search.toString();
1519
+ return {
1520
+ url: url.toString(),
1521
+ unresolved: Array.from(unresolved)
1522
+ };
1523
+ }
1524
+ function applyScvpMacros(baseUrl, ctx) {
1525
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1526
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1527
+ return deferred.has(name);
1528
+ });
1529
+ }
1530
+ function stripScvpMacros(url) {
1531
+ if (findScvpMacroNames(url).length === 0) return {
1532
+ url: url,
1533
+ unresolved: []
1534
+ };
1535
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1536
+ }
1343
1537
  function applyVastMacros(baseUrl, ctx) {
1344
1538
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1345
1539
  var url;
@@ -1381,15 +1575,6 @@ function applyVastMacros(baseUrl, ctx) {
1381
1575
  }
1382
1576
  params.delete("ppos");
1383
1577
  params.delete("lip");
1384
- if (ctx.podMinDurationMs != null) {
1385
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1386
- }
1387
- if (ctx.podMaxDurationMs != null) {
1388
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1389
- }
1390
- if (ctx.podMaxAds != null) {
1391
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1392
- }
1393
1578
  var existingUrl = params.get("url") || "";
1394
1579
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1395
1580
  params.delete("url");
@@ -2219,6 +2404,309 @@ function substituteVastTrackingMacros(url) {
2219
2404
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2220
2405
  });
2221
2406
  }
2407
+ // src/player/OptimizedPodRequest.ts
2408
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2409
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2410
+ var POD_PARAM_KEYS = [
2411
+ "pmnd",
2412
+ "pmxd",
2413
+ "pmad"
2414
+ ];
2415
+ var POSITIVE_INT = /^[1-9]\d*$/;
2416
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2417
+ function nonNegativeInt(value) {
2418
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2419
+ }
2420
+ function positiveInt(value) {
2421
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2422
+ }
2423
+ function resolveAdPodConfig(config) {
2424
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2425
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2426
+ return {
2427
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2428
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2429
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2430
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2431
+ exactDuration: config.podExactDuration === true
2432
+ };
2433
+ }
2434
+ function measureBreakCapacity(timing, nowMonoMs) {
2435
+ var _timing_breakEndMonoMs;
2436
+ var scheduled = timing.scheduledBreakDurationMs;
2437
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2438
+ return void 0;
2439
+ }
2440
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2441
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2442
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2443
+ return {
2444
+ scheduledBreakDurationMs: scheduled,
2445
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2446
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2447
+ };
2448
+ }
2449
+ function resolvePodParams(input) {
2450
+ var capacity = input.capacity, config = input.config;
2451
+ var pmxd;
2452
+ var source;
2453
+ if (capacity) {
2454
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2455
+ source = "break_remaining";
2456
+ } else if (config.maxPodDurationMs != null) {
2457
+ pmxd = config.maxPodDurationMs;
2458
+ source = "configured_cap";
2459
+ } else if (input.tagMaxDurationMs != null) {
2460
+ pmxd = input.tagMaxDurationMs;
2461
+ source = "tag_cap";
2462
+ } else {
2463
+ return {
2464
+ kind: "omit"
2465
+ };
2466
+ }
2467
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2468
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2469
+ return {
2470
+ kind: "abort",
2471
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2472
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2473
+ };
2474
+ }
2475
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2476
+ return {
2477
+ kind: "send",
2478
+ params: {
2479
+ pmnd: pmnd,
2480
+ pmxd: pmxd,
2481
+ pmad: config.maxAdsPerBreak
2482
+ },
2483
+ source: source
2484
+ };
2485
+ }
2486
+ function podRequestAborted(reason, message, diagnostics) {
2487
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2488
+ error.podRequestAborted = true;
2489
+ error.reason = reason;
2490
+ error.diagnostics = diagnostics;
2491
+ return error;
2492
+ }
2493
+ function isPodRequestAbortedError(error) {
2494
+ return !!error && error.podRequestAborted === true;
2495
+ }
2496
+ function firstPositiveIntParam(params, key) {
2497
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2498
+ try {
2499
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2500
+ var value = _step.value;
2501
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2502
+ }
2503
+ } catch (err) {
2504
+ _didIteratorError = true;
2505
+ _iteratorError = err;
2506
+ } finally{
2507
+ try {
2508
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2509
+ _iterator.return();
2510
+ }
2511
+ } finally{
2512
+ if (_didIteratorError) {
2513
+ throw _iteratorError;
2514
+ }
2515
+ }
2516
+ }
2517
+ return void 0;
2518
+ }
2519
+ function isOptimizedPodUrl(url) {
2520
+ if (findScvpMacroNames(url).some(function(name) {
2521
+ return SCVP_POD_MACROS.has(name);
2522
+ })) return true;
2523
+ try {
2524
+ var params = new URL(url).searchParams;
2525
+ return POD_PARAM_KEYS.some(function(key) {
2526
+ return params.has(key);
2527
+ });
2528
+ } catch (unused) {
2529
+ return false;
2530
+ }
2531
+ }
2532
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2533
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2534
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2535
+ var capacity = ctx.capacity;
2536
+ var base = {
2537
+ breakId: ctx.breakId,
2538
+ optimizedPod: optimizedPod,
2539
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2540
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2541
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2542
+ safetyReserveMs: ctx.config.requestSafetyMs
2543
+ };
2544
+ var decision = {
2545
+ kind: "omit"
2546
+ };
2547
+ if (optimizedPod) {
2548
+ var tagMaxDurationMs;
2549
+ try {
2550
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2551
+ } catch (unused) {}
2552
+ decision = resolvePodParams({
2553
+ capacity: capacity,
2554
+ config: ctx.config,
2555
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2556
+ tagMaxDurationMs: tagMaxDurationMs
2557
+ });
2558
+ if (decision.kind === "abort") {
2559
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2560
+ }
2561
+ }
2562
+ var pod = decision.kind === "send" ? decision.params : void 0;
2563
+ var values = /* @__PURE__ */ new Map();
2564
+ if (pod) {
2565
+ values.set("PMND", String(pod.pmnd));
2566
+ values.set("PMXD", String(pod.pmxd));
2567
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2568
+ }
2569
+ var substituted = substituteScvpMacros(rawUrl, values);
2570
+ var finalUrl;
2571
+ try {
2572
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2573
+ if (pod) {
2574
+ url.searchParams.set("pmnd", String(pod.pmnd));
2575
+ url.searchParams.set("pmxd", String(pod.pmxd));
2576
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2577
+ else url.searchParams.delete("pmad");
2578
+ } else {
2579
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2580
+ try {
2581
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2582
+ var key = _step.value;
2583
+ url.searchParams.delete(key);
2584
+ }
2585
+ } catch (err) {
2586
+ _didIteratorError = true;
2587
+ _iteratorError = err;
2588
+ } finally{
2589
+ try {
2590
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2591
+ _iterator.return();
2592
+ }
2593
+ } finally{
2594
+ if (_didIteratorError) {
2595
+ throw _iteratorError;
2596
+ }
2597
+ }
2598
+ }
2599
+ }
2600
+ finalUrl = url.toString();
2601
+ } catch (unused) {
2602
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2603
+ }
2604
+ var problems = validateGamRequestUrl(finalUrl, {
2605
+ optimizedPod: !!pod,
2606
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2607
+ });
2608
+ if (problems.length > 0) {
2609
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2610
+ }
2611
+ var givn = null;
2612
+ try {
2613
+ givn = new URL(finalUrl).searchParams.get("givn");
2614
+ } catch (unused) {}
2615
+ return {
2616
+ url: finalUrl,
2617
+ diagnostics: {
2618
+ breakId: ctx.breakId,
2619
+ optimizedPod: !!pod,
2620
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2621
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2622
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2623
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2624
+ safetyReserveMs: ctx.config.requestSafetyMs,
2625
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2626
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2627
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2628
+ palNoncePresent: !!givn,
2629
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2630
+ strippedMacros: substituted.unresolved.filter(function(name) {
2631
+ return !SCVP_POD_MACROS.has(name);
2632
+ })
2633
+ }
2634
+ };
2635
+ }
2636
+ function validateGamRequestUrl(url, expect) {
2637
+ var problems = [];
2638
+ var leftover = findScvpMacroNames(url);
2639
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2640
+ var params;
2641
+ try {
2642
+ params = new URL(url).searchParams;
2643
+ } catch (unused) {
2644
+ return problems.concat("URL could not be parsed");
2645
+ }
2646
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2647
+ try {
2648
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2649
+ var key = _step.value;
2650
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2651
+ }
2652
+ } catch (err) {
2653
+ _didIteratorError = true;
2654
+ _iteratorError = err;
2655
+ } finally{
2656
+ try {
2657
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2658
+ _iterator.return();
2659
+ }
2660
+ } finally{
2661
+ if (_didIteratorError) {
2662
+ throw _iteratorError;
2663
+ }
2664
+ }
2665
+ }
2666
+ if (!expect.optimizedPod) {
2667
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2668
+ try {
2669
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2670
+ var key1 = _step1.value;
2671
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2672
+ }
2673
+ } catch (err) {
2674
+ _didIteratorError1 = true;
2675
+ _iteratorError1 = err;
2676
+ } finally{
2677
+ try {
2678
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2679
+ _iterator1.return();
2680
+ }
2681
+ } finally{
2682
+ if (_didIteratorError1) {
2683
+ throw _iteratorError1;
2684
+ }
2685
+ }
2686
+ }
2687
+ return problems;
2688
+ }
2689
+ var pmxd = params.get("pmxd");
2690
+ var pmnd = params.get("pmnd");
2691
+ var pmad = params.get("pmad");
2692
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2693
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2694
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2695
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2696
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2697
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2698
+ }
2699
+ return problems;
2700
+ }
2701
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2702
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2703
+ return {
2704
+ vastAdCount: vastAdCount,
2705
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2706
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2707
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2708
+ };
2709
+ }
2222
2710
  // src/sdk/hlsAdPlayer.ts
2223
2711
  var LINEAR_TRACKING_EVENTS = [
2224
2712
  "creativeView",
@@ -2299,6 +2787,7 @@ function toVastMediaErrorCode(error) {
2299
2787
  return VAST_ERROR_MEDIA_DISPLAY;
2300
2788
  }
2301
2789
  }
2790
+ var gamCredentialsMode = "include";
2302
2791
  function createHlsAdPlayer(contentVideo, options) {
2303
2792
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2304
2793
  var adPlaying = false;
@@ -3170,9 +3659,9 @@ function createHlsAdPlayer(contentVideo, options) {
3170
3659
  }
3171
3660
  }
3172
3661
  function fetchVastXml(vastTagUrl) {
3173
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3662
+ 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;
3174
3663
  return _async_to_generator(function() {
3175
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3664
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3176
3665
  return _ts_generator(this, function(_state) {
3177
3666
  switch(_state.label){
3178
3667
  case 0:
@@ -3186,13 +3675,32 @@ function createHlsAdPlayer(contentVideo, options) {
3186
3675
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3187
3676
  startedAt = Date.now();
3188
3677
  attempt = 0;
3678
+ resolveDispatchUrl = function resolveDispatchUrl() {
3679
+ if (kind === "wrapper") return vastTagUrl;
3680
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3681
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3682
+ if (unresolved.length > 0) {
3683
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3684
+ }
3685
+ return url;
3686
+ };
3189
3687
  requestVast = function requestVast(creds) {
3190
3688
  return _async_to_generator(function() {
3191
- var response;
3689
+ var pending, response;
3192
3690
  return _ts_generator(this, function(_state) {
3193
3691
  switch(_state.label){
3194
3692
  case 0:
3195
3693
  attempt++;
3694
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3695
+ mode: "cors",
3696
+ credentials: creds,
3697
+ headers: {
3698
+ "Accept": "application/xml, text/xml, */*"
3699
+ },
3700
+ referrerPolicy: "no-referrer-when-downgrade"
3701
+ }, controller ? {
3702
+ signal: controller.signal
3703
+ } : {}));
3196
3704
  if (kind !== "wrapper") {
3197
3705
  logFunnel("".concat(kind, "_http_request_sent"), {
3198
3706
  attempt: attempt,
@@ -3201,16 +3709,7 @@ function createHlsAdPlayer(contentVideo, options) {
3201
3709
  }
3202
3710
  return [
3203
3711
  4,
3204
- fetch(vastTagUrl, _object_spread({
3205
- mode: "cors",
3206
- credentials: creds,
3207
- headers: {
3208
- "Accept": "application/xml, text/xml, */*"
3209
- },
3210
- referrerPolicy: "no-referrer-when-downgrade"
3211
- }, controller ? {
3212
- signal: controller.signal
3213
- } : {}))
3712
+ pending
3214
3713
  ];
3215
3714
  case 1:
3216
3715
  response = _state.sent();
@@ -3234,9 +3733,9 @@ function createHlsAdPlayer(contentVideo, options) {
3234
3733
  case 1:
3235
3734
  _state.trys.push([
3236
3735
  1,
3237
- 10,
3238
- 11,
3239
- 12
3736
+ 7,
3737
+ 8,
3738
+ 9
3240
3739
  ]);
3241
3740
  _state.label = 2;
3242
3741
  case 2:
@@ -3244,7 +3743,7 @@ function createHlsAdPlayer(contentVideo, options) {
3244
3743
  2,
3245
3744
  4,
3246
3745
  ,
3247
- 8
3746
+ 5
3248
3747
  ]);
3249
3748
  return [
3250
3749
  4,
@@ -3254,36 +3753,21 @@ function createHlsAdPlayer(contentVideo, options) {
3254
3753
  response = _state.sent();
3255
3754
  return [
3256
3755
  3,
3257
- 8
3756
+ 5
3258
3757
  ];
3259
3758
  case 4:
3260
3759
  error = _state.sent();
3261
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3262
- 3,
3263
- 6
3264
- ];
3265
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3266
- logFunnel("vast_credentials_retry", {
3267
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3268
- });
3269
- return [
3270
- 4,
3271
- requestVast("omit")
3272
- ];
3273
- case 5:
3274
- response = _state.sent();
3275
- return [
3276
- 3,
3277
- 7
3278
- ];
3279
- case 6:
3760
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3761
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3762
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3763
+ logFunnel("gam_credentials_mode_changed", {
3764
+ from: credentials,
3765
+ to: gamCredentialsMode,
3766
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3767
+ });
3768
+ }
3280
3769
  throw error;
3281
- case 7:
3282
- return [
3283
- 3,
3284
- 8
3285
- ];
3286
- case 8:
3770
+ case 5:
3287
3771
  if (!response.ok) {
3288
3772
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3289
3773
  }
@@ -3291,12 +3775,12 @@ function createHlsAdPlayer(contentVideo, options) {
3291
3775
  4,
3292
3776
  response.text()
3293
3777
  ];
3294
- case 9:
3778
+ case 6:
3295
3779
  return [
3296
3780
  2,
3297
3781
  _state.sent()
3298
3782
  ];
3299
- case 10:
3783
+ case 7:
3300
3784
  error1 = _state.sent();
3301
3785
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3302
3786
  if (pendingRequestAbortReason) {
@@ -3305,13 +3789,13 @@ function createHlsAdPlayer(contentVideo, options) {
3305
3789
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3306
3790
  }
3307
3791
  throw error1;
3308
- case 11:
3792
+ case 8:
3309
3793
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3310
3794
  if (controller) pendingVastRequests.delete(controller);
3311
3795
  return [
3312
3796
  7
3313
3797
  ];
3314
- case 12:
3798
+ case 9:
3315
3799
  return [
3316
3800
  2
3317
3801
  ];
@@ -3444,7 +3928,7 @@ function createHlsAdPlayer(contentVideo, options) {
3444
3928
  });
3445
3929
  }
3446
3930
  function fetchAndParsePod(vastTagUrl) {
3447
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3931
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3448
3932
  return _async_to_generator(function() {
3449
3933
  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;
3450
3934
  return _ts_generator(this, function(_state) {
@@ -3454,7 +3938,7 @@ function createHlsAdPlayer(contentVideo, options) {
3454
3938
  isEdge = source === "edge";
3455
3939
  return [
3456
3940
  4,
3457
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3941
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3458
3942
  ];
3459
3943
  case 1:
3460
3944
  vastXml = _state.sent();
@@ -4777,7 +5261,7 @@ function createHlsAdPlayer(contentVideo, options) {
4777
5261
  case 2:
4778
5262
  return [
4779
5263
  4,
4780
- fetchAndParsePod(vastTagUrl, source)
5264
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4781
5265
  ];
4782
5266
  case 3:
4783
5267
  ads = _state.sent();
@@ -5354,95 +5838,38 @@ function getOrCreateNonceLoader(allowStorage) {
5354
5838
  function createPalNonceManager() {
5355
5839
  var currentNonce = "";
5356
5840
  var currentNonceManager;
5841
+ var pendingNonce;
5357
5842
  return {
5358
5843
  generateNonce: function generateNonce() {
5359
- return _async_to_generator(function() {
5360
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5361
- var _arguments = arguments;
5362
- return _ts_generator(this, function(_state) {
5363
- switch(_state.label){
5364
- case 0:
5365
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5366
- _state.label = 1;
5367
- case 1:
5368
- _state.trys.push([
5369
- 1,
5370
- 4,
5371
- ,
5372
- 5
5373
- ]);
5374
- return [
5375
- 4,
5376
- loadPalSdk()
5377
- ];
5378
- case 2:
5379
- _state.sent();
5380
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5381
- goog = window.goog;
5382
- request = new goog.pal.NonceRequest();
5383
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5384
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5385
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5386
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5387
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5388
- request.iconsSupported = true;
5389
- request.playerType = "StormcloudVideoPlayer";
5390
- request.playerVersion = "1.0";
5391
- request.supportedApiFrameworks = "2,7,9";
5392
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5393
- request.videoWidth = options.videoWidth || 640;
5394
- request.videoHeight = options.videoHeight || 480;
5395
- if (options.ppid) request.ppid = options.ppid;
5396
- if (options.sessionId) request.sessionId = options.sessionId;
5397
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5398
- adWillAutoPlay: request.adWillAutoPlay,
5399
- adWillPlayMuted: request.adWillPlayMuted,
5400
- playerVolume: request.playerVolume,
5401
- continuousPlayback: request.continuousPlayback,
5402
- descriptionUrl: request.descriptionUrl,
5403
- iconsSupported: request.iconsSupported,
5404
- playerType: request.playerType,
5405
- playerVersion: request.playerVersion,
5406
- supportedApiFrameworks: request.supportedApiFrameworks,
5407
- url: request.url,
5408
- videoWidth: request.videoWidth,
5409
- videoHeight: request.videoHeight,
5410
- ppid: request.ppid,
5411
- sessionId: request.sessionId
5412
- }, null, 2));
5413
- return [
5414
- 4,
5415
- loader.loadNonceManager(request)
5416
- ];
5417
- case 3:
5418
- manager = _state.sent();
5419
- currentNonceManager = manager;
5420
- currentNonce = manager.getNonce();
5421
- console.log("[PAL] Nonce generated successfully");
5422
- return [
5423
- 2,
5424
- currentNonce
5425
- ];
5426
- case 4:
5427
- error = _state.sent();
5428
- console.warn("[PAL] Failed to generate nonce:", error);
5429
- currentNonce = "";
5430
- currentNonceManager = void 0;
5431
- return [
5432
- 2,
5433
- ""
5434
- ];
5435
- case 5:
5436
- return [
5437
- 2
5438
- ];
5439
- }
5440
- });
5441
- }).apply(this, arguments);
5844
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5845
+ var run = generate(options);
5846
+ pendingNonce = run;
5847
+ var settle = function settle() {
5848
+ if (pendingNonce === run) pendingNonce = void 0;
5849
+ };
5850
+ run.then(settle, settle);
5851
+ return run;
5442
5852
  },
5443
5853
  getCurrentNonce: function getCurrentNonce() {
5444
5854
  return currentNonce;
5445
5855
  },
5856
+ waitForNonce: function waitForNonce(maxWaitMs) {
5857
+ if (currentNonce) return Promise.resolve(currentNonce);
5858
+ var pending = pendingNonce;
5859
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5860
+ return new Promise(function(resolve) {
5861
+ var timer = setTimeout(function() {
5862
+ return resolve(currentNonce);
5863
+ }, maxWaitMs);
5864
+ pending.then(function(nonce) {
5865
+ clearTimeout(timer);
5866
+ resolve(nonce);
5867
+ }, function() {
5868
+ clearTimeout(timer);
5869
+ resolve("");
5870
+ });
5871
+ });
5872
+ },
5446
5873
  injectNonce: function injectNonce(vastTagUrl) {
5447
5874
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5448
5875
  try {
@@ -5479,8 +5906,90 @@ function createPalNonceManager() {
5479
5906
  reset: function reset() {
5480
5907
  currentNonce = "";
5481
5908
  currentNonceManager = void 0;
5909
+ pendingNonce = void 0;
5482
5910
  }
5483
5911
  };
5912
+ function generate(options) {
5913
+ return _async_to_generator(function() {
5914
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5915
+ return _ts_generator(this, function(_state) {
5916
+ switch(_state.label){
5917
+ case 0:
5918
+ _state.trys.push([
5919
+ 0,
5920
+ 3,
5921
+ ,
5922
+ 4
5923
+ ]);
5924
+ return [
5925
+ 4,
5926
+ loadPalSdk()
5927
+ ];
5928
+ case 1:
5929
+ _state.sent();
5930
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5931
+ goog = window.goog;
5932
+ request = new goog.pal.NonceRequest();
5933
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5934
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5935
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5936
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5937
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5938
+ request.iconsSupported = true;
5939
+ request.playerType = "StormcloudVideoPlayer";
5940
+ request.playerVersion = "1.0";
5941
+ request.supportedApiFrameworks = "2,7,9";
5942
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5943
+ request.videoWidth = options.videoWidth || 640;
5944
+ request.videoHeight = options.videoHeight || 480;
5945
+ if (options.ppid) request.ppid = options.ppid;
5946
+ if (options.sessionId) request.sessionId = options.sessionId;
5947
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5948
+ adWillAutoPlay: request.adWillAutoPlay,
5949
+ adWillPlayMuted: request.adWillPlayMuted,
5950
+ playerVolume: request.playerVolume,
5951
+ continuousPlayback: request.continuousPlayback,
5952
+ descriptionUrl: request.descriptionUrl,
5953
+ iconsSupported: request.iconsSupported,
5954
+ playerType: request.playerType,
5955
+ playerVersion: request.playerVersion,
5956
+ supportedApiFrameworks: request.supportedApiFrameworks,
5957
+ url: request.url,
5958
+ videoWidth: request.videoWidth,
5959
+ videoHeight: request.videoHeight,
5960
+ ppid: request.ppid,
5961
+ sessionId: request.sessionId
5962
+ }, null, 2));
5963
+ return [
5964
+ 4,
5965
+ loader.loadNonceManager(request)
5966
+ ];
5967
+ case 2:
5968
+ manager = _state.sent();
5969
+ currentNonceManager = manager;
5970
+ currentNonce = manager.getNonce();
5971
+ console.log("[PAL] Nonce generated successfully");
5972
+ return [
5973
+ 2,
5974
+ currentNonce
5975
+ ];
5976
+ case 3:
5977
+ error = _state.sent();
5978
+ console.warn("[PAL] Failed to generate nonce:", error);
5979
+ currentNonce = "";
5980
+ currentNonceManager = void 0;
5981
+ return [
5982
+ 2,
5983
+ ""
5984
+ ];
5985
+ case 4:
5986
+ return [
5987
+ 2
5988
+ ];
5989
+ }
5990
+ });
5991
+ })();
5992
+ }
5484
5993
  }
5485
5994
  // src/utils/trackingIngest.ts
5486
5995
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5563,7 +6072,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5563
6072
  // src/utils/tracking.ts
5564
6073
  var cachedBrowserId = null;
5565
6074
  function buildAnalyticsContext(config) {
6075
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5566
6076
  var context = {};
6077
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6078
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6079
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6080
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6081
+ if (contentChannel) context.contentChannel = contentChannel;
6082
+ if (contentTitle) context.contentTitle = contentTitle;
5567
6083
  if (config.debugAdTiming) {
5568
6084
  context.debugAdTiming = true;
5569
6085
  }
@@ -6054,12 +6570,19 @@ function sendAdImpressionTracking(_0, _1) {
6054
6570
  4,
6055
6571
  ingestPlayerTracking(licenseKey, "impressions", {
6056
6572
  events: [
6057
- {
6573
+ _object_spread({
6058
6574
  player_id: metricEvent.player_id,
6059
6575
  ad_played_count: 1,
6060
6576
  ad_url: adImpressionInfo.adUrl,
6061
- capture_at: adImpressionInfo.timestamp
6062
- }
6577
+ capture_at: adImpressionInfo.timestamp,
6578
+ source: "gam"
6579
+ }, context.contentNetwork ? {
6580
+ content_network: context.contentNetwork
6581
+ } : {}, context.contentChannel ? {
6582
+ content_channel: context.contentChannel
6583
+ } : {}, context.contentTitle ? {
6584
+ content_title: context.contentTitle
6585
+ } : {})
6063
6586
  ]
6064
6587
  })
6065
6588
  ];
@@ -7408,6 +7931,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7408
7931
  return Scte35CueManager;
7409
7932
  }();
7410
7933
  // src/player/AdConfigManager.ts
7934
+ function withDeferredPodParams(rawUrl, deferNonce) {
7935
+ try {
7936
+ var url = new URL(rawUrl);
7937
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7938
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7939
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7940
+ if (deferNonce && !url.searchParams.get("givn")) {
7941
+ url.searchParams.delete("paln");
7942
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7943
+ }
7944
+ return url.toString();
7945
+ } catch (unused) {
7946
+ return rawUrl;
7947
+ }
7948
+ }
7411
7949
  var AdConfigManager = /*#__PURE__*/ function() {
7412
7950
  function AdConfigManager(config, video) {
7413
7951
  _class_call_check(this, AdConfigManager);
@@ -7418,8 +7956,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7418
7956
  this.podCounter = 0;
7419
7957
  this.podAssignedByPrefetch = false;
7420
7958
  this.lastHeartbeatTime = 0;
7421
- this.defaultPodMaxAds = 6;
7422
- this.defaultPodMaxDurationMs = 12e4;
7959
+ this.defaultEdgePodMaxAds = 6;
7960
+ this.palNonceDispatchWaitMs = 1500;
7423
7961
  this.config = config;
7424
7962
  this.video = video;
7425
7963
  }
@@ -7447,7 +7985,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7447
7985
  key: "fetchAdConfiguration",
7448
7986
  value: function fetchAdConfiguration() {
7449
7987
  return _async_to_generator(function() {
7450
- 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;
7988
+ 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;
7451
7989
  return _ts_generator(this, function(_state) {
7452
7990
  switch(_state.label){
7453
7991
  case 0:
@@ -7468,28 +8006,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7468
8006
  2
7469
8007
  ];
7470
8008
  case 2:
7471
- vastMode = this.config.vastMode || "default";
7472
- if (this.debug) {
7473
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7474
- }
7475
- if (vastMode === "adstorm") {
7476
- if (!this.config.licenseKey) {
7477
- if (this.debug) {
7478
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7479
- }
7480
- return [
7481
- 2
7482
- ];
7483
- }
7484
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7485
- this.apiVastTagUrl = vastEndpoint;
7486
- if (this.debug) {
7487
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7488
- }
7489
- return [
7490
- 2
7491
- ];
7492
- }
7493
8009
  if (this.config.vastTagUrl) {
7494
8010
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7495
8011
  if (this.debug) {
@@ -7499,7 +8015,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7499
8015
  2
7500
8016
  ];
7501
8017
  }
7502
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
8018
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7503
8019
  if (this.debug) {
7504
8020
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7505
8021
  }
@@ -7846,16 +8362,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7846
8362
  }
7847
8363
  },
7848
8364
  {
7849
- key: "resolvePodParams",
7850
- value: function resolvePodParams(breakDurationMs) {
7851
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7852
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7853
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7854
- return {
7855
- maxAds: maxAds,
7856
- minDurationMs: minDurationMs,
7857
- maxDurationMs: maxDurationMs
7858
- };
8365
+ key: "resolveAdPodConfig",
8366
+ value: function resolveAdPodConfig1() {
8367
+ return resolveAdPodConfig(this.config);
8368
+ }
8369
+ },
8370
+ {
8371
+ key: "resolveEdgeMaxAds",
8372
+ value: function resolveEdgeMaxAds() {
8373
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8374
+ 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;
7859
8375
  }
7860
8376
  },
7861
8377
  {
@@ -7872,17 +8388,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7872
8388
  },
7873
8389
  {
7874
8390
  key: "generatePodVastUrl",
7875
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7876
- var _podParams_maxDurationMs;
8391
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7877
8392
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7878
8393
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7879
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8394
+ var macroContext = _object_spread_props(_object_spread({
7880
8395
  correlator: this.viewCorrelator,
7881
8396
  streamCorrelator: this.streamCorrelator,
7882
8397
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7883
- podMaxAds: podParams.maxAds,
7884
- podMinDurationMs: podParams.minDurationMs,
7885
- podMaxDurationMs: podParams.maxDurationMs,
7886
8398
  isCtv: envSignals.isCtv,
7887
8399
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7888
8400
  adWillPlayMuted: adWillPlayMuted,
@@ -7898,13 +8410,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7898
8410
  } : {}, this.config.channelName ? {
7899
8411
  channelName: this.config.channelName
7900
8412
  } : {}), {
7901
- consent: this.consentSignals
7902
- }));
7903
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7904
- 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);
8413
+ consent: this.consentSignals,
8414
+ palNonce: palNonce.getCurrentNonce() || void 0
8415
+ });
8416
+ var nonceReady = !!macroContext.palNonce;
8417
+ var finalUrl;
8418
+ if (hasScvpMacros(baseUrl)) {
8419
+ var deferred = new Set(SCVP_POD_MACROS);
8420
+ if (!nonceReady) deferred.add("GIVN");
8421
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8422
+ if (unresolved.length > 0) {
8423
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8424
+ }
8425
+ finalUrl = ensureVideoAdType(url);
8426
+ } else {
8427
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8428
+ }
8429
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7905
8430
  return finalUrl;
7906
8431
  }
7907
8432
  },
8433
+ {
8434
+ key: "completeDeferredRequestSignals",
8435
+ value: function completeDeferredRequestSignals(url, palNonce) {
8436
+ return _async_to_generator(function() {
8437
+ var nonce, _tmp;
8438
+ return _ts_generator(this, function(_state) {
8439
+ switch(_state.label){
8440
+ case 0:
8441
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8442
+ 2,
8443
+ url
8444
+ ];
8445
+ _tmp = palNonce.getCurrentNonce();
8446
+ if (_tmp) return [
8447
+ 3,
8448
+ 2
8449
+ ];
8450
+ return [
8451
+ 4,
8452
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8453
+ ];
8454
+ case 1:
8455
+ _tmp = _state.sent();
8456
+ _state.label = 2;
8457
+ case 2:
8458
+ nonce = _tmp;
8459
+ if (!nonce) return [
8460
+ 2,
8461
+ url
8462
+ ];
8463
+ return [
8464
+ 2,
8465
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8466
+ [
8467
+ "GIVN",
8468
+ nonce
8469
+ ]
8470
+ ]), function(name) {
8471
+ return name !== "GIVN";
8472
+ }).url
8473
+ ];
8474
+ }
8475
+ });
8476
+ }).call(this);
8477
+ }
8478
+ },
7908
8479
  {
7909
8480
  // --- Tracking ---
7910
8481
  key: "initializeTracking",
@@ -7952,6 +8523,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7952
8523
  return AdConfigManager;
7953
8524
  }();
7954
8525
  // src/player/AdTimingService.ts
8526
+ function monotonicNow() {
8527
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8528
+ }
7955
8529
  var AdTimingService = /*#__PURE__*/ function() {
7956
8530
  function AdTimingService(config, video, callbacks) {
7957
8531
  _class_call_check(this, AdTimingService);
@@ -8082,6 +8656,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8082
8656
  },
8083
8657
  {
8084
8658
  // --- Duration boundary ---
8659
+ key: "beginBreakTiming",
8660
+ value: function beginBreakTiming(startWallClockMs) {
8661
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8662
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8663
+ this.breakEndMonoMs = void 0;
8664
+ }
8665
+ },
8666
+ {
8667
+ key: "markBreakEndedNow",
8668
+ value: function markBreakEndedNow() {
8669
+ this.scteAdBreakEndWallClockMs = Date.now();
8670
+ this.breakEndMonoMs = monotonicNow();
8671
+ }
8672
+ },
8673
+ {
8085
8674
  key: "setAdBreakDurationBoundary",
8086
8675
  value: function setAdBreakDurationBoundary(durationMs) {
8087
8676
  this.expectedAdBreakDurationMs = durationMs;
@@ -8090,6 +8679,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8090
8679
  } else {
8091
8680
  this.scteAdBreakEndWallClockMs = void 0;
8092
8681
  }
8682
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8683
+ }
8684
+ },
8685
+ {
8686
+ key: "getBreakTimingSnapshot",
8687
+ value: function getBreakTimingSnapshot() {
8688
+ return {
8689
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8690
+ breakStartMonoMs: this.breakStartMonoMs,
8691
+ breakEndMonoMs: this.breakEndMonoMs,
8692
+ playedDurationMs: this.adBreakPlayedDurationMs
8693
+ };
8093
8694
  }
8094
8695
  },
8095
8696
  {
@@ -8503,6 +9104,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8503
9104
  this.expectedAdBreakDurationMs = void 0;
8504
9105
  this.currentAdBreakStartWallClockMs = void 0;
8505
9106
  this.scteAdBreakEndWallClockMs = void 0;
9107
+ this.breakStartMonoMs = void 0;
9108
+ this.breakEndMonoMs = void 0;
8506
9109
  this.adBreakPlayedDurationMs = 0;
8507
9110
  this.currentAdIndex = 0;
8508
9111
  this.totalAdsInBreak = 0;
@@ -9516,9 +10119,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9516
10119
  // ───────────────────────────────────────────────────────────────
9517
10120
  key: "nextAdRequestUrl",
9518
10121
  value: function nextAdRequestUrl(baseVastUrl) {
9519
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9520
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9521
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10122
+ return this.host.generatePodVastUrl(baseVastUrl);
9522
10123
  }
9523
10124
  },
9524
10125
  {
@@ -9781,7 +10382,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9781
10382
  key: "handleAdStart",
9782
10383
  value: function handleAdStart(marker) {
9783
10384
  return _async_to_generator(function() {
9784
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10385
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9785
10386
  return _ts_generator(this, function(_state) {
9786
10387
  switch(_state.label){
9787
10388
  case 0:
@@ -9833,8 +10434,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9833
10434
  }
9834
10435
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9835
10436
  epoch = this.timing.adBreakEpoch;
9836
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9837
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10437
+ if (!(adBreakDurationMs == null)) return [
9838
10438
  3,
9839
10439
  2
9840
10440
  ];
@@ -9890,7 +10490,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9890
10490
  }
9891
10491
  return [
9892
10492
  4,
9893
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10493
+ this.startOptimizedPod(baseVastUrl)
9894
10494
  ];
9895
10495
  case 6:
9896
10496
  podPlayed = _state.sent();
@@ -9958,9 +10558,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9958
10558
  value: // ───────────────────────────────────────────────────────────────
9959
10559
  // Optimized pod (single multi-ad request)
9960
10560
  // ───────────────────────────────────────────────────────────────
9961
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10561
+ function startOptimizedPod(baseVastUrl) {
9962
10562
  return _async_to_generator(function() {
9963
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10563
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
9964
10564
  return _ts_generator(this, function(_state) {
9965
10565
  switch(_state.label){
9966
10566
  case 0:
@@ -9969,7 +10569,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9969
10569
  podUrl = this.pendingAdBreak.vastUrls[0];
9970
10570
  this.clearPendingAdBreak();
9971
10571
  } else {
9972
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10572
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
9973
10573
  }
9974
10574
  if (!podUrl) {
9975
10575
  return [
@@ -9993,9 +10593,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9993
10593
  case 1:
9994
10594
  _state.trys.push([
9995
10595
  1,
9996
- 5,
10596
+ 9,
9997
10597
  ,
9998
- 6
10598
+ 10
9999
10599
  ]);
10000
10600
  return [
10001
10601
  4,
@@ -10007,15 +10607,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10007
10607
  2,
10008
10608
  true
10009
10609
  ];
10610
+ return [
10611
+ 4,
10612
+ this.host.completeGamRequestSignals(requestUrl)
10613
+ ];
10614
+ case 3:
10615
+ requestUrl = _state.sent();
10616
+ if (this.isStale(epoch, generation)) return [
10617
+ 2,
10618
+ true
10619
+ ];
10010
10620
  this.timing.startAdRequestWatchdog(requestToken);
10621
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10622
+ _state.label = 4;
10623
+ case 4:
10624
+ _state.trys.push([
10625
+ 4,
10626
+ ,
10627
+ 6,
10628
+ 7
10629
+ ]);
10011
10630
  return [
10012
10631
  4,
10013
10632
  this.callController(function() {
10014
- return adPlayer.requestAds(requestUrl);
10633
+ return adPlayer.requestAds(requestUrl, {
10634
+ finalizeRequestUrl: finalizeRequestUrl
10635
+ });
10015
10636
  })
10016
10637
  ];
10017
- case 3:
10638
+ case 5:
10018
10639
  _state.sent();
10640
+ return [
10641
+ 3,
10642
+ 7
10643
+ ];
10644
+ case 6:
10645
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10646
+ return [
10647
+ 7
10648
+ ];
10649
+ case 7:
10019
10650
  this.timing.clearAdRequestWatchdog();
10020
10651
  if (this.isStale(epoch, generation)) {
10021
10652
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10043,7 +10674,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10043
10674
  }
10044
10675
  sendAdLoadedTracking(this.host.config.licenseKey, {
10045
10676
  source: "hls",
10046
- vastUrl: requestUrl,
10677
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10047
10678
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10048
10679
  }, this.analyticsContext).catch(function() {});
10049
10680
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10053,7 +10684,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10053
10684
  return adPlayer.play();
10054
10685
  })
10055
10686
  ];
10056
- case 4:
10687
+ case 8:
10057
10688
  _state.sent();
10058
10689
  if (this.isStale(epoch, generation)) return [
10059
10690
  2,
@@ -10067,7 +10698,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10067
10698
  2,
10068
10699
  true
10069
10700
  ];
10070
- case 5:
10701
+ case 9:
10071
10702
  error = _state.sent();
10072
10703
  this.timing.clearAdRequestWatchdog();
10073
10704
  this.timing.clearAdFailsafeTimer();
@@ -10087,12 +10718,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10087
10718
  if (this.debug) {
10088
10719
  console.warn("[POD] Optimized pod request/play failed:", error);
10089
10720
  }
10721
+ if (this.handlePodRequestNotSent(error)) return [
10722
+ 2,
10723
+ false
10724
+ ];
10090
10725
  this.recordRequestFailure(error, podUrl);
10091
10726
  return [
10092
10727
  2,
10093
10728
  false
10094
10729
  ];
10095
- case 6:
10730
+ case 10:
10096
10731
  return [
10097
10732
  2
10098
10733
  ];
@@ -10138,17 +10773,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10138
10773
  }
10139
10774
  },
10140
10775
  {
10141
- /**
10142
- * Builds the next Edge request from the budget left right now, or marks Edge
10143
- * exhausted for this break. Synchronous on purpose: callers must reach the
10144
- * REQUESTING state in the same tick so a second completion event cannot race
10145
- * in a parallel request.
10146
- */ key: "prepareEdgePodRequest",
10776
+ key: "prepareEdgePodRequest",
10147
10777
  value: function prepareEdgePodRequest() {
10148
10778
  var baseUrl = this.host.getEdgePodBaseUrl();
10149
10779
  if (!baseUrl) return void 0;
10150
10780
  var remainingMs = this.timing.getRemainingAdMs();
10151
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10781
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10152
10782
  if (remainingAds < 1) {
10153
10783
  this.markEdgeExhausted("ad_capacity_reached", {
10154
10784
  adsInBreak: this.timing.totalAdsInBreak
@@ -10227,7 +10857,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10227
10857
  ];
10228
10858
  }
10229
10859
  remainingMs = this.timing.getRemainingAdMs();
10230
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10860
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10231
10861
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10232
10862
  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;
10233
10863
  if (classifyEdgeVastResponse({
@@ -10574,7 +11204,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10574
11204
  {
10575
11205
  key: "noteVastUrlGenerated",
10576
11206
  value: function noteVastUrlGenerated(url, source) {
10577
- var _ref, _ref1, _ref2, _ref3, _ref4;
11207
+ var _ref, _ref1;
10578
11208
  var params;
10579
11209
  try {
10580
11210
  params = new URL(url).searchParams;
@@ -10584,9 +11214,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10584
11214
  requestId: void 0,
10585
11215
  source: source,
10586
11216
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10587
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10588
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10589
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11217
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11218
+ return SCVP_POD_MACROS.has(name);
11219
+ }),
10590
11220
  adType: adType
10591
11221
  });
10592
11222
  if (adType === "audio" || adType === "audio_video") {
@@ -10627,10 +11257,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10627
11257
  if (diag && !diag.failureReason) {
10628
11258
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10629
11259
  }
11260
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11261
+ return SCVP_POD_MACROS.has(name);
11262
+ }) ? diag.dispatchedUrl : vastTagUrl;
10630
11263
  if (this.timing.isTemporaryAdError(error)) {
10631
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11264
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10632
11265
  } else if (outcome !== "discarded_budget") {
10633
- this.timing.failedVastUrls.add(vastTagUrl);
11266
+ this.timing.failedVastUrls.add(failureKey);
10634
11267
  }
10635
11268
  this.countFunnelStage("request_outcome:".concat(outcome));
10636
11269
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10656,6 +11289,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10656
11289
  switch(payload.stage){
10657
11290
  case "gam_http_request_sent":
10658
11291
  diag.gamRequestSent++;
11292
+ this.logPodDispatch(diag);
10659
11293
  break;
10660
11294
  case "edge_http_request_sent":
10661
11295
  diag.edgeRequestSent++;
@@ -10707,8 +11341,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10707
11341
  if (gamReturnedAdWithoutImpression) {
10708
11342
  this.countFunnelStage("gam_ad_without_impression");
10709
11343
  }
10710
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10711
- "startedAt"
11344
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11345
+ "startedAt",
11346
+ "dispatchedUrl",
11347
+ "podDispatchLogged"
10712
11348
  ]);
10713
11349
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10714
11350
  durationMs: Date.now() - startedAt,
@@ -10720,24 +11356,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10720
11356
  // ───────────────────────────────────────────────────────────────
10721
11357
  // Single ad playback
10722
11358
  // ───────────────────────────────────────────────────────────────
10723
- key: "withCurrentPodBudget",
10724
- value: function withCurrentPodBudget(rawVastTagUrl) {
10725
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10726
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10727
- if (!(remaining > 0)) return vastTagUrl;
10728
- try {
10729
- var url = new URL(vastTagUrl);
10730
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10731
- var maxMs = Math.round(remaining);
10732
- url.searchParams.set("pmxd", String(maxMs));
10733
- var minMs = Number(url.searchParams.get("pmnd"));
10734
- if (Number.isFinite(minMs) && minMs > maxMs) {
10735
- url.searchParams.set("pmnd", String(maxMs));
10736
- }
10737
- return url.toString();
10738
- } catch (unused) {
10739
- return vastTagUrl;
10740
- }
11359
+ key: "createGamDispatchFinalizer",
11360
+ value: function createGamDispatchFinalizer(requestToken) {
11361
+ var _this = this;
11362
+ var breakId = this.timing.adBreakEpoch;
11363
+ var config = this.adConfig.resolveAdPodConfig();
11364
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11365
+ return function(url) {
11366
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11367
+ var diag = _this.requestDiagnostics.get(requestToken);
11368
+ try {
11369
+ var result = finalizeGamRequestUrl(url, {
11370
+ breakId: breakId,
11371
+ capacity: capacity,
11372
+ config: config,
11373
+ minUsablePmxdMs: minUsablePmxdMs
11374
+ });
11375
+ if (diag) {
11376
+ diag.pod = result.diagnostics;
11377
+ diag.dispatchedUrl = result.url;
11378
+ diag.podDispatchLogged = false;
11379
+ }
11380
+ _this.currentVastUrl = result.url;
11381
+ return result.url;
11382
+ } catch (error) {
11383
+ if (diag && isPodRequestAbortedError(error)) {
11384
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11385
+ }
11386
+ throw error;
11387
+ }
11388
+ };
11389
+ }
11390
+ },
11391
+ {
11392
+ key: "logPodDispatch",
11393
+ value: function logPodDispatch(diag) {
11394
+ if (!diag.pod || diag.podDispatchLogged) return;
11395
+ diag.podDispatchLogged = true;
11396
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11397
+ }
11398
+ },
11399
+ {
11400
+ key: "recordPodResponseDiagnostics",
11401
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11402
+ var _diag_vastAdCount, _ref;
11403
+ var _adPlayer_getPodTotalDurationMs;
11404
+ var diag = this.requestDiagnostics.get(requestToken);
11405
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11406
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11407
+ 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);
11408
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11409
+ pmxdSent: diag.pod.pmxdSent
11410
+ }, diag.podResponse));
11411
+ }
11412
+ },
11413
+ {
11414
+ key: "handlePodRequestNotSent",
11415
+ value: function handlePodRequestNotSent(error) {
11416
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11417
+ var aborted = error;
11418
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11419
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11420
+ reason: aborted.reason,
11421
+ errorMessage: aborted.message
11422
+ }, aborted.diagnostics));
11423
+ return true;
10741
11424
  }
10742
11425
  },
10743
11426
  {
@@ -10957,7 +11640,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10957
11640
  value: function playSingleAd(vastTagUrl) {
10958
11641
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10959
11642
  return _async_to_generator(function() {
10960
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11643
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10961
11644
  return _ts_generator(this, function(_state) {
10962
11645
  switch(_state.label){
10963
11646
  case 0:
@@ -10995,19 +11678,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10995
11678
  requestToken = ++this.timing.adRequestTokenCounter;
10996
11679
  this.timing.activeAdRequestToken = requestToken;
10997
11680
  ap = this.host.getAdPlayer();
10998
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
10999
11681
  this.currentPodSource = "gam";
11000
11682
  this.setSlotState("REQUESTING", trigger);
11001
11683
  this.beginFunnelRequest(ap, requestToken, trigger);
11002
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11684
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
11003
11685
  this.currentVastUrl = requestUrl;
11004
11686
  _state.label = 1;
11005
11687
  case 1:
11006
11688
  _state.trys.push([
11007
11689
  1,
11008
- 5,
11690
+ 9,
11009
11691
  ,
11010
- 6
11692
+ 10
11011
11693
  ]);
11012
11694
  return [
11013
11695
  4,
@@ -11018,15 +11700,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11018
11700
  if (this.isStale(epoch, generation)) return [
11019
11701
  2
11020
11702
  ];
11703
+ return [
11704
+ 4,
11705
+ this.host.completeGamRequestSignals(requestUrl)
11706
+ ];
11707
+ case 3:
11708
+ requestUrl = _state.sent();
11709
+ if (this.isStale(epoch, generation)) return [
11710
+ 2
11711
+ ];
11021
11712
  this.timing.startAdRequestWatchdog(requestToken);
11713
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11714
+ _state.label = 4;
11715
+ case 4:
11716
+ _state.trys.push([
11717
+ 4,
11718
+ ,
11719
+ 6,
11720
+ 7
11721
+ ]);
11022
11722
  return [
11023
11723
  4,
11024
11724
  this.callController(function() {
11025
- return ap.requestAds(requestUrl);
11725
+ return ap.requestAds(requestUrl, {
11726
+ finalizeRequestUrl: finalizeRequestUrl
11727
+ });
11026
11728
  })
11027
11729
  ];
11028
- case 3:
11730
+ case 5:
11029
11731
  _state.sent();
11732
+ return [
11733
+ 3,
11734
+ 7
11735
+ ];
11736
+ case 6:
11737
+ this.recordPodResponseDiagnostics(requestToken, ap);
11738
+ return [
11739
+ 7
11740
+ ];
11741
+ case 7:
11030
11742
  this.timing.clearAdRequestWatchdog();
11031
11743
  if (this.isStale(epoch, generation)) {
11032
11744
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11038,7 +11750,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11038
11750
  }
11039
11751
  sendAdLoadedTracking(this.host.config.licenseKey, {
11040
11752
  source: "hls",
11041
- vastUrl: requestUrl,
11753
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11042
11754
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11043
11755
  }, this.analyticsContext).catch(function() {});
11044
11756
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11059,7 +11771,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11059
11771
  return ap.play();
11060
11772
  })
11061
11773
  ];
11062
- case 4:
11774
+ case 8:
11063
11775
  _state.sent();
11064
11776
  if (this.isStale(epoch, generation)) return [
11065
11777
  2
@@ -11071,9 +11783,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11071
11783
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11072
11784
  return [
11073
11785
  3,
11074
- 6
11786
+ 10
11075
11787
  ];
11076
- case 5:
11788
+ case 9:
11077
11789
  error = _state.sent();
11078
11790
  this.timing.clearAdRequestWatchdog();
11079
11791
  this.timing.clearAdFailsafeTimer();
@@ -11090,12 +11802,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11090
11802
  ];
11091
11803
  }
11092
11804
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11805
+ if (this.handlePodRequestNotSent(error)) throw error;
11093
11806
  this.recordRequestFailure(error, vastTagUrl);
11094
11807
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11095
11808
  this.recreateAdController("discarded_budget");
11096
11809
  }
11097
11810
  throw error;
11098
- case 6:
11811
+ case 10:
11099
11812
  return [
11100
11813
  2
11101
11814
  ];
@@ -11157,7 +11870,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11157
11870
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11158
11871
  requestFailed: count("request_failed"),
11159
11872
  requestAbortedTimeout: count("request_aborted_timeout"),
11160
- credentialsRetries: count("vast_credentials_retry"),
11873
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11161
11874
  wrapperFailures: count("wrapper_fetch:failure"),
11162
11875
  noSupportedMedia: count("vast_no_supported_media"),
11163
11876
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11693,8 +12406,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11693
12406
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11694
12407
  return requiresMediaPipelineResetAfterAds();
11695
12408
  },
11696
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11697
- return _this.generatePodVastUrl(base, breakDurationMs);
12409
+ generatePodVastUrl: function generatePodVastUrl(base) {
12410
+ return _this.generatePodVastUrl(base);
12411
+ },
12412
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12413
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11698
12414
  },
11699
12415
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11700
12416
  return _this.edgePodBaseUrl;
@@ -11818,9 +12534,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11818
12534
  },
11819
12535
  {
11820
12536
  key: "generatePodVastUrl",
11821
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11822
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11823
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12537
+ value: function generatePodVastUrl(baseUrl) {
12538
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11824
12539
  }
11825
12540
  },
11826
12541
  {
@@ -12174,7 +12889,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12174
12889
  activeAdRequest: this.timing.activeAdRequestToken !== null
12175
12890
  });
12176
12891
  }
12177
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12892
+ this.timing.markBreakEndedNow();
12178
12893
  this.timing.clearAdStartTimer();
12179
12894
  this.timing.clearAdStopTimer();
12180
12895
  if (adPlaying) {
@@ -12201,7 +12916,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12201
12916
  this.adBreak.inAdBreak = true;
12202
12917
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12203
12918
  this.cueManager.scheduledScte35BreakKey = void 0;
12204
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12919
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12205
12920
  this.timing.setAdBreakDurationBoundary(durationMs);
12206
12921
  this.adBreak.handleAdStart(marker);
12207
12922
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12247,9 +12962,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12247
12962
  }
12248
12963
  this.adConfig.beginNewAdPod();
12249
12964
  this.adConfig.podAssignedByPrefetch = true;
12250
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12251
12965
  var generatedUrls = [
12252
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
12966
+ this.generatePodVastUrl(baseVastUrl)
12253
12967
  ];
12254
12968
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12255
12969
  marker: marker
@@ -12348,7 +13062,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12348
13062
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12349
13063
  this.adBreak.showAds = true;
12350
13064
  this.adBreak.inAdBreak = true;
12351
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13065
+ this.timing.beginBreakTiming(Date.now());
12352
13066
  if (durationMs > 0) {
12353
13067
  this.timing.setAdBreakDurationBoundary(durationMs);
12354
13068
  }