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
package/lib/index.js CHANGED
@@ -363,21 +363,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
363
363
  "adid"
364
364
  ]);
365
365
  function resolveVastEnvironmentSignals(isCtv) {
366
- var _ref;
367
366
  var bridgeSignals = readNativeBridgeSignals();
368
367
  var platformDevice = readPlatformNativeDeviceId();
369
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
368
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
369
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
370
370
  var deviceId = realDeviceId;
371
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
372
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
373
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
371
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
372
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
373
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
374
374
  if (!deviceId && isCtv) {
375
375
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
376
376
  if (dpid) {
377
- var _ref1;
378
377
  deviceId = dpid;
379
378
  deviceIdType = "dpid";
380
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
379
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
381
380
  }
382
381
  }
383
382
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -742,6 +741,9 @@ function isMacroPlaceholder(value) {
742
741
  var t = value.trim();
743
742
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
744
743
  }
744
+ function validDeviceId(value) {
745
+ return value && !isMacroPlaceholder(value) ? value : void 0;
746
+ }
745
747
  function isZeroedAdId(value) {
746
748
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
747
749
  }
@@ -1274,6 +1276,198 @@ function ensureVideoAdType(rawUrl) {
1274
1276
  return rawUrl;
1275
1277
  }
1276
1278
  }
1279
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1280
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1281
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1282
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1283
+ "cust_params"
1284
+ ]);
1285
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1286
+ "PMND",
1287
+ "PMXD",
1288
+ "PMAD"
1289
+ ]);
1290
+ function hasScvpMacros(url) {
1291
+ return !!url && SCVP_MACRO_DETECT.test(url);
1292
+ }
1293
+ function safeDecode(value) {
1294
+ try {
1295
+ return decodeURIComponent(value.replace(/\+/g, " "));
1296
+ } catch (unused) {
1297
+ return value;
1298
+ }
1299
+ }
1300
+ function findScvpMacroNames(url) {
1301
+ if (!url) return [];
1302
+ var names = /* @__PURE__ */ new Set();
1303
+ var text = url;
1304
+ for(var pass = 0; pass < 3; pass++){
1305
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1306
+ names.add(String(bracketName || parenName).toUpperCase());
1307
+ return "";
1308
+ });
1309
+ var decoded = safeDecode(text);
1310
+ if (decoded === text) break;
1311
+ text = decoded;
1312
+ }
1313
+ return Array.from(names);
1314
+ }
1315
+ function resolveScvpMacroValues(ctx) {
1316
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1317
+ var values = /* @__PURE__ */ new Map();
1318
+ var set = function set(name, value) {
1319
+ if (value == null) return;
1320
+ var str = String(value).trim();
1321
+ if (str) values.set(name, str);
1322
+ };
1323
+ var toFlag = function toFlag(value) {
1324
+ return value == null ? void 0 : value ? "1" : "0";
1325
+ };
1326
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1327
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1328
+ if (deviceId && deviceIdType) {
1329
+ set("RDID", deviceId);
1330
+ set("IDTYPE", deviceIdType);
1331
+ set("IS-LAT", toFlag(ctx.limitAdTracking));
1332
+ }
1333
+ set("SID", ctx.sessionId);
1334
+ set("DTH", ctx.deviceTypeHint);
1335
+ set("GIVN", ctx.palNonce);
1336
+ set("CT-TI", ctx.programTitle);
1337
+ set("CT-CH", ctx.channelName);
1338
+ set("POD", ctx.pod);
1339
+ set("CORRELATOR", ctx.correlator);
1340
+ set("SCOR", ctx.streamCorrelator);
1341
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1342
+ if (ctx.adWillAutoPlay != null) {
1343
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1344
+ }
1345
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1346
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1347
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1348
+ return values;
1349
+ }
1350
+ var keepNone = function keepNone() {
1351
+ return false;
1352
+ };
1353
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1354
+ var out = [];
1355
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1356
+ var name = String(bracketName || parenName).toUpperCase();
1357
+ var value = values.get(name);
1358
+ if (value != null) return value;
1359
+ if (keep(name)) return match;
1360
+ unresolved.add(name);
1361
+ return "";
1362
+ };
1363
+ params.forEach(function(value, key) {
1364
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1365
+ if (whole) {
1366
+ var name = String(whole[1] || whole[2]).toUpperCase();
1367
+ var resolved = values.get(name);
1368
+ if (resolved != null) {
1369
+ out.push([
1370
+ key,
1371
+ resolved
1372
+ ]);
1373
+ } else if (keep(name)) {
1374
+ out.push([
1375
+ key,
1376
+ value
1377
+ ]);
1378
+ } else {
1379
+ unresolved.add(name);
1380
+ }
1381
+ return;
1382
+ }
1383
+ if (!SCVP_MACRO_DETECT.test(value)) {
1384
+ out.push([
1385
+ key,
1386
+ value
1387
+ ]);
1388
+ return;
1389
+ }
1390
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1391
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1392
+ if (inner.length > 0) {
1393
+ out.push([
1394
+ key,
1395
+ inner.map(function(param) {
1396
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1397
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1398
+ }).join("&")
1399
+ ]);
1400
+ }
1401
+ return;
1402
+ }
1403
+ out.push([
1404
+ key,
1405
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1406
+ ]);
1407
+ });
1408
+ return out;
1409
+ }
1410
+ function substituteScvpMacros(baseUrl, values) {
1411
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1412
+ var unresolved = /* @__PURE__ */ new Set();
1413
+ var url;
1414
+ try {
1415
+ url = new URL(normalizeVastTagUrl(baseUrl));
1416
+ } catch (unused) {
1417
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1418
+ var name = String(bracketName || parenName).toUpperCase();
1419
+ var value = values.get(name);
1420
+ if (value != null) return encodeURIComponent(value);
1421
+ if (keep(name)) return match;
1422
+ unresolved.add(name);
1423
+ return "";
1424
+ });
1425
+ return {
1426
+ url: replaced,
1427
+ unresolved: Array.from(unresolved)
1428
+ };
1429
+ }
1430
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1431
+ var search = new URLSearchParams();
1432
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1433
+ try {
1434
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1435
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1436
+ search.append(key, value);
1437
+ }
1438
+ } catch (err) {
1439
+ _didIteratorError = true;
1440
+ _iteratorError = err;
1441
+ } finally{
1442
+ try {
1443
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1444
+ _iterator.return();
1445
+ }
1446
+ } finally{
1447
+ if (_didIteratorError) {
1448
+ throw _iteratorError;
1449
+ }
1450
+ }
1451
+ }
1452
+ url.search = search.toString();
1453
+ return {
1454
+ url: url.toString(),
1455
+ unresolved: Array.from(unresolved)
1456
+ };
1457
+ }
1458
+ function applyScvpMacros(baseUrl, ctx) {
1459
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1460
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1461
+ return deferred.has(name);
1462
+ });
1463
+ }
1464
+ function stripScvpMacros(url) {
1465
+ if (findScvpMacroNames(url).length === 0) return {
1466
+ url: url,
1467
+ unresolved: []
1468
+ };
1469
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1470
+ }
1277
1471
  function applyVastMacros(baseUrl, ctx) {
1278
1472
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1279
1473
  var url;
@@ -1315,15 +1509,6 @@ function applyVastMacros(baseUrl, ctx) {
1315
1509
  }
1316
1510
  params.delete("ppos");
1317
1511
  params.delete("lip");
1318
- if (ctx.podMinDurationMs != null) {
1319
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1320
- }
1321
- if (ctx.podMaxDurationMs != null) {
1322
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1323
- }
1324
- if (ctx.podMaxAds != null) {
1325
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1326
- }
1327
1512
  var existingUrl = params.get("url") || "";
1328
1513
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1329
1514
  params.delete("url");
@@ -2177,6 +2362,309 @@ function substituteVastTrackingMacros(url) {
2177
2362
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2178
2363
  });
2179
2364
  }
2365
+ // src/player/OptimizedPodRequest.ts
2366
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2367
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2368
+ var POD_PARAM_KEYS = [
2369
+ "pmnd",
2370
+ "pmxd",
2371
+ "pmad"
2372
+ ];
2373
+ var POSITIVE_INT = /^[1-9]\d*$/;
2374
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2375
+ function nonNegativeInt(value) {
2376
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2377
+ }
2378
+ function positiveInt(value) {
2379
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2380
+ }
2381
+ function resolveAdPodConfig(config) {
2382
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2383
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2384
+ return {
2385
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2386
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2387
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2388
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2389
+ exactDuration: config.podExactDuration === true
2390
+ };
2391
+ }
2392
+ function measureBreakCapacity(timing, nowMonoMs) {
2393
+ var _timing_breakEndMonoMs;
2394
+ var scheduled = timing.scheduledBreakDurationMs;
2395
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2396
+ return void 0;
2397
+ }
2398
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2399
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2400
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2401
+ return {
2402
+ scheduledBreakDurationMs: scheduled,
2403
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2404
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2405
+ };
2406
+ }
2407
+ function resolvePodParams(input) {
2408
+ var capacity = input.capacity, config = input.config;
2409
+ var pmxd;
2410
+ var source;
2411
+ if (capacity) {
2412
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2413
+ source = "break_remaining";
2414
+ } else if (config.maxPodDurationMs != null) {
2415
+ pmxd = config.maxPodDurationMs;
2416
+ source = "configured_cap";
2417
+ } else if (input.tagMaxDurationMs != null) {
2418
+ pmxd = input.tagMaxDurationMs;
2419
+ source = "tag_cap";
2420
+ } else {
2421
+ return {
2422
+ kind: "omit"
2423
+ };
2424
+ }
2425
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2426
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2427
+ return {
2428
+ kind: "abort",
2429
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2430
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2431
+ };
2432
+ }
2433
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2434
+ return {
2435
+ kind: "send",
2436
+ params: {
2437
+ pmnd: pmnd,
2438
+ pmxd: pmxd,
2439
+ pmad: config.maxAdsPerBreak
2440
+ },
2441
+ source: source
2442
+ };
2443
+ }
2444
+ function podRequestAborted(reason, message, diagnostics) {
2445
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2446
+ error.podRequestAborted = true;
2447
+ error.reason = reason;
2448
+ error.diagnostics = diagnostics;
2449
+ return error;
2450
+ }
2451
+ function isPodRequestAbortedError(error) {
2452
+ return !!error && error.podRequestAborted === true;
2453
+ }
2454
+ function firstPositiveIntParam(params, key) {
2455
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2456
+ try {
2457
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2458
+ var value = _step.value;
2459
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2460
+ }
2461
+ } catch (err) {
2462
+ _didIteratorError = true;
2463
+ _iteratorError = err;
2464
+ } finally{
2465
+ try {
2466
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2467
+ _iterator.return();
2468
+ }
2469
+ } finally{
2470
+ if (_didIteratorError) {
2471
+ throw _iteratorError;
2472
+ }
2473
+ }
2474
+ }
2475
+ return void 0;
2476
+ }
2477
+ function isOptimizedPodUrl(url) {
2478
+ if (findScvpMacroNames(url).some(function(name) {
2479
+ return SCVP_POD_MACROS.has(name);
2480
+ })) return true;
2481
+ try {
2482
+ var params = new URL(url).searchParams;
2483
+ return POD_PARAM_KEYS.some(function(key) {
2484
+ return params.has(key);
2485
+ });
2486
+ } catch (unused) {
2487
+ return false;
2488
+ }
2489
+ }
2490
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2491
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2492
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2493
+ var capacity = ctx.capacity;
2494
+ var base = {
2495
+ breakId: ctx.breakId,
2496
+ optimizedPod: optimizedPod,
2497
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2498
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2499
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2500
+ safetyReserveMs: ctx.config.requestSafetyMs
2501
+ };
2502
+ var decision = {
2503
+ kind: "omit"
2504
+ };
2505
+ if (optimizedPod) {
2506
+ var tagMaxDurationMs;
2507
+ try {
2508
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2509
+ } catch (unused) {}
2510
+ decision = resolvePodParams({
2511
+ capacity: capacity,
2512
+ config: ctx.config,
2513
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2514
+ tagMaxDurationMs: tagMaxDurationMs
2515
+ });
2516
+ if (decision.kind === "abort") {
2517
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2518
+ }
2519
+ }
2520
+ var pod = decision.kind === "send" ? decision.params : void 0;
2521
+ var values = /* @__PURE__ */ new Map();
2522
+ if (pod) {
2523
+ values.set("PMND", String(pod.pmnd));
2524
+ values.set("PMXD", String(pod.pmxd));
2525
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2526
+ }
2527
+ var substituted = substituteScvpMacros(rawUrl, values);
2528
+ var finalUrl;
2529
+ try {
2530
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2531
+ if (pod) {
2532
+ url.searchParams.set("pmnd", String(pod.pmnd));
2533
+ url.searchParams.set("pmxd", String(pod.pmxd));
2534
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2535
+ else url.searchParams.delete("pmad");
2536
+ } else {
2537
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2538
+ try {
2539
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2540
+ var key = _step.value;
2541
+ url.searchParams.delete(key);
2542
+ }
2543
+ } catch (err) {
2544
+ _didIteratorError = true;
2545
+ _iteratorError = err;
2546
+ } finally{
2547
+ try {
2548
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2549
+ _iterator.return();
2550
+ }
2551
+ } finally{
2552
+ if (_didIteratorError) {
2553
+ throw _iteratorError;
2554
+ }
2555
+ }
2556
+ }
2557
+ }
2558
+ finalUrl = url.toString();
2559
+ } catch (unused) {
2560
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2561
+ }
2562
+ var problems = validateGamRequestUrl(finalUrl, {
2563
+ optimizedPod: !!pod,
2564
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2565
+ });
2566
+ if (problems.length > 0) {
2567
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2568
+ }
2569
+ var givn = null;
2570
+ try {
2571
+ givn = new URL(finalUrl).searchParams.get("givn");
2572
+ } catch (unused) {}
2573
+ return {
2574
+ url: finalUrl,
2575
+ diagnostics: {
2576
+ breakId: ctx.breakId,
2577
+ optimizedPod: !!pod,
2578
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2579
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2580
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2581
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2582
+ safetyReserveMs: ctx.config.requestSafetyMs,
2583
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2584
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2585
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2586
+ palNoncePresent: !!givn,
2587
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2588
+ strippedMacros: substituted.unresolved.filter(function(name) {
2589
+ return !SCVP_POD_MACROS.has(name);
2590
+ })
2591
+ }
2592
+ };
2593
+ }
2594
+ function validateGamRequestUrl(url, expect) {
2595
+ var problems = [];
2596
+ var leftover = findScvpMacroNames(url);
2597
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2598
+ var params;
2599
+ try {
2600
+ params = new URL(url).searchParams;
2601
+ } catch (unused) {
2602
+ return problems.concat("URL could not be parsed");
2603
+ }
2604
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2605
+ try {
2606
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2607
+ var key = _step.value;
2608
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2609
+ }
2610
+ } catch (err) {
2611
+ _didIteratorError = true;
2612
+ _iteratorError = err;
2613
+ } finally{
2614
+ try {
2615
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2616
+ _iterator.return();
2617
+ }
2618
+ } finally{
2619
+ if (_didIteratorError) {
2620
+ throw _iteratorError;
2621
+ }
2622
+ }
2623
+ }
2624
+ if (!expect.optimizedPod) {
2625
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2626
+ try {
2627
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2628
+ var key1 = _step1.value;
2629
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2630
+ }
2631
+ } catch (err) {
2632
+ _didIteratorError1 = true;
2633
+ _iteratorError1 = err;
2634
+ } finally{
2635
+ try {
2636
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2637
+ _iterator1.return();
2638
+ }
2639
+ } finally{
2640
+ if (_didIteratorError1) {
2641
+ throw _iteratorError1;
2642
+ }
2643
+ }
2644
+ }
2645
+ return problems;
2646
+ }
2647
+ var pmxd = params.get("pmxd");
2648
+ var pmnd = params.get("pmnd");
2649
+ var pmad = params.get("pmad");
2650
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2651
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2652
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2653
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2654
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2655
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2656
+ }
2657
+ return problems;
2658
+ }
2659
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2660
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2661
+ return {
2662
+ vastAdCount: vastAdCount,
2663
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2664
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2665
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2666
+ };
2667
+ }
2180
2668
  // src/sdk/hlsAdPlayer.ts
2181
2669
  var LINEAR_TRACKING_EVENTS = [
2182
2670
  "creativeView",
@@ -2257,6 +2745,7 @@ function toVastMediaErrorCode(error) {
2257
2745
  return VAST_ERROR_MEDIA_DISPLAY;
2258
2746
  }
2259
2747
  }
2748
+ var gamCredentialsMode = "include";
2260
2749
  function createHlsAdPlayer(contentVideo, options) {
2261
2750
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2262
2751
  var adPlaying = false;
@@ -3128,9 +3617,9 @@ function createHlsAdPlayer(contentVideo, options) {
3128
3617
  }
3129
3618
  }
3130
3619
  function fetchVastXml(vastTagUrl) {
3131
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3620
+ 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;
3132
3621
  return _async_to_generator(function() {
3133
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3622
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3134
3623
  return _ts_generator(this, function(_state) {
3135
3624
  switch(_state.label){
3136
3625
  case 0:
@@ -3144,13 +3633,32 @@ function createHlsAdPlayer(contentVideo, options) {
3144
3633
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3145
3634
  startedAt = Date.now();
3146
3635
  attempt = 0;
3636
+ resolveDispatchUrl = function resolveDispatchUrl() {
3637
+ if (kind === "wrapper") return vastTagUrl;
3638
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3639
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3640
+ if (unresolved.length > 0) {
3641
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3642
+ }
3643
+ return url;
3644
+ };
3147
3645
  requestVast = function requestVast(creds) {
3148
3646
  return _async_to_generator(function() {
3149
- var response;
3647
+ var pending, response;
3150
3648
  return _ts_generator(this, function(_state) {
3151
3649
  switch(_state.label){
3152
3650
  case 0:
3153
3651
  attempt++;
3652
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3653
+ mode: "cors",
3654
+ credentials: creds,
3655
+ headers: {
3656
+ "Accept": "application/xml, text/xml, */*"
3657
+ },
3658
+ referrerPolicy: "no-referrer-when-downgrade"
3659
+ }, controller ? {
3660
+ signal: controller.signal
3661
+ } : {}));
3154
3662
  if (kind !== "wrapper") {
3155
3663
  logFunnel("".concat(kind, "_http_request_sent"), {
3156
3664
  attempt: attempt,
@@ -3159,16 +3667,7 @@ function createHlsAdPlayer(contentVideo, options) {
3159
3667
  }
3160
3668
  return [
3161
3669
  4,
3162
- fetch(vastTagUrl, _object_spread({
3163
- mode: "cors",
3164
- credentials: creds,
3165
- headers: {
3166
- "Accept": "application/xml, text/xml, */*"
3167
- },
3168
- referrerPolicy: "no-referrer-when-downgrade"
3169
- }, controller ? {
3170
- signal: controller.signal
3171
- } : {}))
3670
+ pending
3172
3671
  ];
3173
3672
  case 1:
3174
3673
  response = _state.sent();
@@ -3192,9 +3691,9 @@ function createHlsAdPlayer(contentVideo, options) {
3192
3691
  case 1:
3193
3692
  _state.trys.push([
3194
3693
  1,
3195
- 10,
3196
- 11,
3197
- 12
3694
+ 7,
3695
+ 8,
3696
+ 9
3198
3697
  ]);
3199
3698
  _state.label = 2;
3200
3699
  case 2:
@@ -3202,7 +3701,7 @@ function createHlsAdPlayer(contentVideo, options) {
3202
3701
  2,
3203
3702
  4,
3204
3703
  ,
3205
- 8
3704
+ 5
3206
3705
  ]);
3207
3706
  return [
3208
3707
  4,
@@ -3212,36 +3711,21 @@ function createHlsAdPlayer(contentVideo, options) {
3212
3711
  response = _state.sent();
3213
3712
  return [
3214
3713
  3,
3215
- 8
3714
+ 5
3216
3715
  ];
3217
3716
  case 4:
3218
3717
  error = _state.sent();
3219
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3220
- 3,
3221
- 6
3222
- ];
3223
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3224
- logFunnel("vast_credentials_retry", {
3225
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3226
- });
3227
- return [
3228
- 4,
3229
- requestVast("omit")
3230
- ];
3231
- case 5:
3232
- response = _state.sent();
3233
- return [
3234
- 3,
3235
- 7
3236
- ];
3237
- case 6:
3718
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3719
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3720
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3721
+ logFunnel("gam_credentials_mode_changed", {
3722
+ from: credentials,
3723
+ to: gamCredentialsMode,
3724
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3725
+ });
3726
+ }
3238
3727
  throw error;
3239
- case 7:
3240
- return [
3241
- 3,
3242
- 8
3243
- ];
3244
- case 8:
3728
+ case 5:
3245
3729
  if (!response.ok) {
3246
3730
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3247
3731
  }
@@ -3249,12 +3733,12 @@ function createHlsAdPlayer(contentVideo, options) {
3249
3733
  4,
3250
3734
  response.text()
3251
3735
  ];
3252
- case 9:
3736
+ case 6:
3253
3737
  return [
3254
3738
  2,
3255
3739
  _state.sent()
3256
3740
  ];
3257
- case 10:
3741
+ case 7:
3258
3742
  error1 = _state.sent();
3259
3743
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3260
3744
  if (pendingRequestAbortReason) {
@@ -3263,13 +3747,13 @@ function createHlsAdPlayer(contentVideo, options) {
3263
3747
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3264
3748
  }
3265
3749
  throw error1;
3266
- case 11:
3750
+ case 8:
3267
3751
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3268
3752
  if (controller) pendingVastRequests.delete(controller);
3269
3753
  return [
3270
3754
  7
3271
3755
  ];
3272
- case 12:
3756
+ case 9:
3273
3757
  return [
3274
3758
  2
3275
3759
  ];
@@ -3402,7 +3886,7 @@ function createHlsAdPlayer(contentVideo, options) {
3402
3886
  });
3403
3887
  }
3404
3888
  function fetchAndParsePod(vastTagUrl) {
3405
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3889
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3406
3890
  return _async_to_generator(function() {
3407
3891
  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;
3408
3892
  return _ts_generator(this, function(_state) {
@@ -3412,7 +3896,7 @@ function createHlsAdPlayer(contentVideo, options) {
3412
3896
  isEdge = source === "edge";
3413
3897
  return [
3414
3898
  4,
3415
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3899
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3416
3900
  ];
3417
3901
  case 1:
3418
3902
  vastXml = _state.sent();
@@ -4735,7 +5219,7 @@ function createHlsAdPlayer(contentVideo, options) {
4735
5219
  case 2:
4736
5220
  return [
4737
5221
  4,
4738
- fetchAndParsePod(vastTagUrl, source)
5222
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4739
5223
  ];
4740
5224
  case 3:
4741
5225
  ads = _state.sent();
@@ -5312,95 +5796,38 @@ function getOrCreateNonceLoader(allowStorage) {
5312
5796
  function createPalNonceManager() {
5313
5797
  var currentNonce = "";
5314
5798
  var currentNonceManager;
5799
+ var pendingNonce;
5315
5800
  return {
5316
5801
  generateNonce: function generateNonce() {
5317
- return _async_to_generator(function() {
5318
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5319
- var _arguments = arguments;
5320
- return _ts_generator(this, function(_state) {
5321
- switch(_state.label){
5322
- case 0:
5323
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5324
- _state.label = 1;
5325
- case 1:
5326
- _state.trys.push([
5327
- 1,
5328
- 4,
5329
- ,
5330
- 5
5331
- ]);
5332
- return [
5333
- 4,
5334
- loadPalSdk()
5335
- ];
5336
- case 2:
5337
- _state.sent();
5338
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5339
- goog = window.goog;
5340
- request = new goog.pal.NonceRequest();
5341
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5342
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5343
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5344
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5345
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5346
- request.iconsSupported = true;
5347
- request.playerType = "StormcloudVideoPlayer";
5348
- request.playerVersion = "1.0";
5349
- request.supportedApiFrameworks = "2,7,9";
5350
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5351
- request.videoWidth = options.videoWidth || 640;
5352
- request.videoHeight = options.videoHeight || 480;
5353
- if (options.ppid) request.ppid = options.ppid;
5354
- if (options.sessionId) request.sessionId = options.sessionId;
5355
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5356
- adWillAutoPlay: request.adWillAutoPlay,
5357
- adWillPlayMuted: request.adWillPlayMuted,
5358
- playerVolume: request.playerVolume,
5359
- continuousPlayback: request.continuousPlayback,
5360
- descriptionUrl: request.descriptionUrl,
5361
- iconsSupported: request.iconsSupported,
5362
- playerType: request.playerType,
5363
- playerVersion: request.playerVersion,
5364
- supportedApiFrameworks: request.supportedApiFrameworks,
5365
- url: request.url,
5366
- videoWidth: request.videoWidth,
5367
- videoHeight: request.videoHeight,
5368
- ppid: request.ppid,
5369
- sessionId: request.sessionId
5370
- }, null, 2));
5371
- return [
5372
- 4,
5373
- loader.loadNonceManager(request)
5374
- ];
5375
- case 3:
5376
- manager = _state.sent();
5377
- currentNonceManager = manager;
5378
- currentNonce = manager.getNonce();
5379
- console.log("[PAL] Nonce generated successfully");
5380
- return [
5381
- 2,
5382
- currentNonce
5383
- ];
5384
- case 4:
5385
- error = _state.sent();
5386
- console.warn("[PAL] Failed to generate nonce:", error);
5387
- currentNonce = "";
5388
- currentNonceManager = void 0;
5389
- return [
5390
- 2,
5391
- ""
5392
- ];
5393
- case 5:
5394
- return [
5395
- 2
5396
- ];
5397
- }
5398
- });
5399
- }).apply(this, arguments);
5802
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5803
+ var run = generate(options);
5804
+ pendingNonce = run;
5805
+ var settle = function settle() {
5806
+ if (pendingNonce === run) pendingNonce = void 0;
5807
+ };
5808
+ run.then(settle, settle);
5809
+ return run;
5400
5810
  },
5401
5811
  getCurrentNonce: function getCurrentNonce() {
5402
5812
  return currentNonce;
5403
5813
  },
5814
+ waitForNonce: function waitForNonce(maxWaitMs) {
5815
+ if (currentNonce) return Promise.resolve(currentNonce);
5816
+ var pending = pendingNonce;
5817
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5818
+ return new Promise(function(resolve) {
5819
+ var timer = setTimeout(function() {
5820
+ return resolve(currentNonce);
5821
+ }, maxWaitMs);
5822
+ pending.then(function(nonce) {
5823
+ clearTimeout(timer);
5824
+ resolve(nonce);
5825
+ }, function() {
5826
+ clearTimeout(timer);
5827
+ resolve("");
5828
+ });
5829
+ });
5830
+ },
5404
5831
  injectNonce: function injectNonce(vastTagUrl) {
5405
5832
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5406
5833
  try {
@@ -5437,8 +5864,90 @@ function createPalNonceManager() {
5437
5864
  reset: function reset() {
5438
5865
  currentNonce = "";
5439
5866
  currentNonceManager = void 0;
5867
+ pendingNonce = void 0;
5440
5868
  }
5441
5869
  };
5870
+ function generate(options) {
5871
+ return _async_to_generator(function() {
5872
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5873
+ return _ts_generator(this, function(_state) {
5874
+ switch(_state.label){
5875
+ case 0:
5876
+ _state.trys.push([
5877
+ 0,
5878
+ 3,
5879
+ ,
5880
+ 4
5881
+ ]);
5882
+ return [
5883
+ 4,
5884
+ loadPalSdk()
5885
+ ];
5886
+ case 1:
5887
+ _state.sent();
5888
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5889
+ goog = window.goog;
5890
+ request = new goog.pal.NonceRequest();
5891
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5892
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5893
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5894
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5895
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5896
+ request.iconsSupported = true;
5897
+ request.playerType = "StormcloudVideoPlayer";
5898
+ request.playerVersion = "1.0";
5899
+ request.supportedApiFrameworks = "2,7,9";
5900
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5901
+ request.videoWidth = options.videoWidth || 640;
5902
+ request.videoHeight = options.videoHeight || 480;
5903
+ if (options.ppid) request.ppid = options.ppid;
5904
+ if (options.sessionId) request.sessionId = options.sessionId;
5905
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5906
+ adWillAutoPlay: request.adWillAutoPlay,
5907
+ adWillPlayMuted: request.adWillPlayMuted,
5908
+ playerVolume: request.playerVolume,
5909
+ continuousPlayback: request.continuousPlayback,
5910
+ descriptionUrl: request.descriptionUrl,
5911
+ iconsSupported: request.iconsSupported,
5912
+ playerType: request.playerType,
5913
+ playerVersion: request.playerVersion,
5914
+ supportedApiFrameworks: request.supportedApiFrameworks,
5915
+ url: request.url,
5916
+ videoWidth: request.videoWidth,
5917
+ videoHeight: request.videoHeight,
5918
+ ppid: request.ppid,
5919
+ sessionId: request.sessionId
5920
+ }, null, 2));
5921
+ return [
5922
+ 4,
5923
+ loader.loadNonceManager(request)
5924
+ ];
5925
+ case 2:
5926
+ manager = _state.sent();
5927
+ currentNonceManager = manager;
5928
+ currentNonce = manager.getNonce();
5929
+ console.log("[PAL] Nonce generated successfully");
5930
+ return [
5931
+ 2,
5932
+ currentNonce
5933
+ ];
5934
+ case 3:
5935
+ error = _state.sent();
5936
+ console.warn("[PAL] Failed to generate nonce:", error);
5937
+ currentNonce = "";
5938
+ currentNonceManager = void 0;
5939
+ return [
5940
+ 2,
5941
+ ""
5942
+ ];
5943
+ case 4:
5944
+ return [
5945
+ 2
5946
+ ];
5947
+ }
5948
+ });
5949
+ })();
5950
+ }
5442
5951
  }
5443
5952
  // src/utils/trackingIngest.ts
5444
5953
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5527,7 +6036,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5527
6036
  // src/utils/tracking.ts
5528
6037
  var cachedBrowserId = null;
5529
6038
  function buildAnalyticsContext(config) {
6039
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5530
6040
  var context = {};
6041
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6042
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6043
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6044
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6045
+ if (contentChannel) context.contentChannel = contentChannel;
6046
+ if (contentTitle) context.contentTitle = contentTitle;
5531
6047
  if (config.debugAdTiming) {
5532
6048
  context.debugAdTiming = true;
5533
6049
  }
@@ -6018,12 +6534,19 @@ function sendAdImpressionTracking(_0, _1) {
6018
6534
  4,
6019
6535
  ingestPlayerTracking(licenseKey, "impressions", {
6020
6536
  events: [
6021
- {
6537
+ _object_spread({
6022
6538
  player_id: metricEvent.player_id,
6023
6539
  ad_played_count: 1,
6024
6540
  ad_url: adImpressionInfo.adUrl,
6025
- capture_at: adImpressionInfo.timestamp
6026
- }
6541
+ capture_at: adImpressionInfo.timestamp,
6542
+ source: "gam"
6543
+ }, context.contentNetwork ? {
6544
+ content_network: context.contentNetwork
6545
+ } : {}, context.contentChannel ? {
6546
+ content_channel: context.contentChannel
6547
+ } : {}, context.contentTitle ? {
6548
+ content_title: context.contentTitle
6549
+ } : {})
6027
6550
  ]
6028
6551
  })
6029
6552
  ];
@@ -7376,6 +7899,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7376
7899
  return Scte35CueManager;
7377
7900
  }();
7378
7901
  // src/player/AdConfigManager.ts
7902
+ function withDeferredPodParams(rawUrl, deferNonce) {
7903
+ try {
7904
+ var url = new URL(rawUrl);
7905
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7906
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7907
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7908
+ if (deferNonce && !url.searchParams.get("givn")) {
7909
+ url.searchParams.delete("paln");
7910
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7911
+ }
7912
+ return url.toString();
7913
+ } catch (unused) {
7914
+ return rawUrl;
7915
+ }
7916
+ }
7379
7917
  var AdConfigManager = /*#__PURE__*/ function() {
7380
7918
  "use strict";
7381
7919
  function AdConfigManager(config, video) {
@@ -7387,8 +7925,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7387
7925
  this.podCounter = 0;
7388
7926
  this.podAssignedByPrefetch = false;
7389
7927
  this.lastHeartbeatTime = 0;
7390
- this.defaultPodMaxAds = 6;
7391
- this.defaultPodMaxDurationMs = 12e4;
7928
+ this.defaultEdgePodMaxAds = 6;
7929
+ this.palNonceDispatchWaitMs = 1500;
7392
7930
  this.config = config;
7393
7931
  this.video = video;
7394
7932
  }
@@ -7416,7 +7954,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7416
7954
  key: "fetchAdConfiguration",
7417
7955
  value: function fetchAdConfiguration() {
7418
7956
  return _async_to_generator(function() {
7419
- 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;
7957
+ 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;
7420
7958
  return _ts_generator(this, function(_state) {
7421
7959
  switch(_state.label){
7422
7960
  case 0:
@@ -7437,28 +7975,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7437
7975
  2
7438
7976
  ];
7439
7977
  case 2:
7440
- vastMode = this.config.vastMode || "default";
7441
- if (this.debug) {
7442
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7443
- }
7444
- if (vastMode === "adstorm") {
7445
- if (!this.config.licenseKey) {
7446
- if (this.debug) {
7447
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7448
- }
7449
- return [
7450
- 2
7451
- ];
7452
- }
7453
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7454
- this.apiVastTagUrl = vastEndpoint;
7455
- if (this.debug) {
7456
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7457
- }
7458
- return [
7459
- 2
7460
- ];
7461
- }
7462
7978
  if (this.config.vastTagUrl) {
7463
7979
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7464
7980
  if (this.debug) {
@@ -7468,7 +7984,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7468
7984
  2
7469
7985
  ];
7470
7986
  }
7471
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
7987
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7472
7988
  if (this.debug) {
7473
7989
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7474
7990
  }
@@ -7815,16 +8331,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7815
8331
  }
7816
8332
  },
7817
8333
  {
7818
- key: "resolvePodParams",
7819
- value: function resolvePodParams(breakDurationMs) {
7820
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7821
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7822
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7823
- return {
7824
- maxAds: maxAds,
7825
- minDurationMs: minDurationMs,
7826
- maxDurationMs: maxDurationMs
7827
- };
8334
+ key: "resolveAdPodConfig",
8335
+ value: function resolveAdPodConfig1() {
8336
+ return resolveAdPodConfig(this.config);
8337
+ }
8338
+ },
8339
+ {
8340
+ key: "resolveEdgeMaxAds",
8341
+ value: function resolveEdgeMaxAds() {
8342
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8343
+ 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;
7828
8344
  }
7829
8345
  },
7830
8346
  {
@@ -7841,17 +8357,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7841
8357
  },
7842
8358
  {
7843
8359
  key: "generatePodVastUrl",
7844
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7845
- var _podParams_maxDurationMs;
8360
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7846
8361
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7847
8362
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7848
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8363
+ var macroContext = _object_spread_props(_object_spread({
7849
8364
  correlator: this.viewCorrelator,
7850
8365
  streamCorrelator: this.streamCorrelator,
7851
8366
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7852
- podMaxAds: podParams.maxAds,
7853
- podMinDurationMs: podParams.minDurationMs,
7854
- podMaxDurationMs: podParams.maxDurationMs,
7855
8367
  isCtv: envSignals.isCtv,
7856
8368
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7857
8369
  adWillPlayMuted: adWillPlayMuted,
@@ -7867,13 +8379,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7867
8379
  } : {}, this.config.channelName ? {
7868
8380
  channelName: this.config.channelName
7869
8381
  } : {}), {
7870
- consent: this.consentSignals
7871
- }));
7872
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7873
- 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);
8382
+ consent: this.consentSignals,
8383
+ palNonce: palNonce.getCurrentNonce() || void 0
8384
+ });
8385
+ var nonceReady = !!macroContext.palNonce;
8386
+ var finalUrl;
8387
+ if (hasScvpMacros(baseUrl)) {
8388
+ var deferred = new Set(SCVP_POD_MACROS);
8389
+ if (!nonceReady) deferred.add("GIVN");
8390
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8391
+ if (unresolved.length > 0) {
8392
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8393
+ }
8394
+ finalUrl = ensureVideoAdType(url);
8395
+ } else {
8396
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8397
+ }
8398
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7874
8399
  return finalUrl;
7875
8400
  }
7876
8401
  },
8402
+ {
8403
+ key: "completeDeferredRequestSignals",
8404
+ value: function completeDeferredRequestSignals(url, palNonce) {
8405
+ return _async_to_generator(function() {
8406
+ var nonce, _tmp;
8407
+ return _ts_generator(this, function(_state) {
8408
+ switch(_state.label){
8409
+ case 0:
8410
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8411
+ 2,
8412
+ url
8413
+ ];
8414
+ _tmp = palNonce.getCurrentNonce();
8415
+ if (_tmp) return [
8416
+ 3,
8417
+ 2
8418
+ ];
8419
+ return [
8420
+ 4,
8421
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8422
+ ];
8423
+ case 1:
8424
+ _tmp = _state.sent();
8425
+ _state.label = 2;
8426
+ case 2:
8427
+ nonce = _tmp;
8428
+ if (!nonce) return [
8429
+ 2,
8430
+ url
8431
+ ];
8432
+ return [
8433
+ 2,
8434
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8435
+ [
8436
+ "GIVN",
8437
+ nonce
8438
+ ]
8439
+ ]), function(name) {
8440
+ return name !== "GIVN";
8441
+ }).url
8442
+ ];
8443
+ }
8444
+ });
8445
+ }).call(this);
8446
+ }
8447
+ },
7877
8448
  {
7878
8449
  // --- Tracking ---
7879
8450
  key: "initializeTracking",
@@ -7921,6 +8492,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7921
8492
  return AdConfigManager;
7922
8493
  }();
7923
8494
  // src/player/AdTimingService.ts
8495
+ function monotonicNow() {
8496
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8497
+ }
7924
8498
  var AdTimingService = /*#__PURE__*/ function() {
7925
8499
  "use strict";
7926
8500
  function AdTimingService(config, video, callbacks) {
@@ -8052,6 +8626,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8052
8626
  },
8053
8627
  {
8054
8628
  // --- Duration boundary ---
8629
+ key: "beginBreakTiming",
8630
+ value: function beginBreakTiming(startWallClockMs) {
8631
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8632
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8633
+ this.breakEndMonoMs = void 0;
8634
+ }
8635
+ },
8636
+ {
8637
+ key: "markBreakEndedNow",
8638
+ value: function markBreakEndedNow() {
8639
+ this.scteAdBreakEndWallClockMs = Date.now();
8640
+ this.breakEndMonoMs = monotonicNow();
8641
+ }
8642
+ },
8643
+ {
8055
8644
  key: "setAdBreakDurationBoundary",
8056
8645
  value: function setAdBreakDurationBoundary(durationMs) {
8057
8646
  this.expectedAdBreakDurationMs = durationMs;
@@ -8060,6 +8649,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8060
8649
  } else {
8061
8650
  this.scteAdBreakEndWallClockMs = void 0;
8062
8651
  }
8652
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8653
+ }
8654
+ },
8655
+ {
8656
+ key: "getBreakTimingSnapshot",
8657
+ value: function getBreakTimingSnapshot() {
8658
+ return {
8659
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8660
+ breakStartMonoMs: this.breakStartMonoMs,
8661
+ breakEndMonoMs: this.breakEndMonoMs,
8662
+ playedDurationMs: this.adBreakPlayedDurationMs
8663
+ };
8063
8664
  }
8064
8665
  },
8065
8666
  {
@@ -8473,6 +9074,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8473
9074
  this.expectedAdBreakDurationMs = void 0;
8474
9075
  this.currentAdBreakStartWallClockMs = void 0;
8475
9076
  this.scteAdBreakEndWallClockMs = void 0;
9077
+ this.breakStartMonoMs = void 0;
9078
+ this.breakEndMonoMs = void 0;
8476
9079
  this.adBreakPlayedDurationMs = 0;
8477
9080
  this.currentAdIndex = 0;
8478
9081
  this.totalAdsInBreak = 0;
@@ -9489,9 +10092,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9489
10092
  // ───────────────────────────────────────────────────────────────
9490
10093
  key: "nextAdRequestUrl",
9491
10094
  value: function nextAdRequestUrl(baseVastUrl) {
9492
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9493
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9494
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10095
+ return this.host.generatePodVastUrl(baseVastUrl);
9495
10096
  }
9496
10097
  },
9497
10098
  {
@@ -9754,7 +10355,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9754
10355
  key: "handleAdStart",
9755
10356
  value: function handleAdStart(marker) {
9756
10357
  return _async_to_generator(function() {
9757
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10358
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9758
10359
  return _ts_generator(this, function(_state) {
9759
10360
  switch(_state.label){
9760
10361
  case 0:
@@ -9806,8 +10407,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9806
10407
  }
9807
10408
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9808
10409
  epoch = this.timing.adBreakEpoch;
9809
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9810
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10410
+ if (!(adBreakDurationMs == null)) return [
9811
10411
  3,
9812
10412
  2
9813
10413
  ];
@@ -9863,7 +10463,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9863
10463
  }
9864
10464
  return [
9865
10465
  4,
9866
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10466
+ this.startOptimizedPod(baseVastUrl)
9867
10467
  ];
9868
10468
  case 6:
9869
10469
  podPlayed = _state.sent();
@@ -9931,9 +10531,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9931
10531
  value: // ───────────────────────────────────────────────────────────────
9932
10532
  // Optimized pod (single multi-ad request)
9933
10533
  // ───────────────────────────────────────────────────────────────
9934
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10534
+ function startOptimizedPod(baseVastUrl) {
9935
10535
  return _async_to_generator(function() {
9936
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10536
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
9937
10537
  return _ts_generator(this, function(_state) {
9938
10538
  switch(_state.label){
9939
10539
  case 0:
@@ -9942,7 +10542,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9942
10542
  podUrl = this.pendingAdBreak.vastUrls[0];
9943
10543
  this.clearPendingAdBreak();
9944
10544
  } else {
9945
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10545
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
9946
10546
  }
9947
10547
  if (!podUrl) {
9948
10548
  return [
@@ -9966,9 +10566,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9966
10566
  case 1:
9967
10567
  _state.trys.push([
9968
10568
  1,
9969
- 5,
10569
+ 9,
9970
10570
  ,
9971
- 6
10571
+ 10
9972
10572
  ]);
9973
10573
  return [
9974
10574
  4,
@@ -9980,15 +10580,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9980
10580
  2,
9981
10581
  true
9982
10582
  ];
10583
+ return [
10584
+ 4,
10585
+ this.host.completeGamRequestSignals(requestUrl)
10586
+ ];
10587
+ case 3:
10588
+ requestUrl = _state.sent();
10589
+ if (this.isStale(epoch, generation)) return [
10590
+ 2,
10591
+ true
10592
+ ];
9983
10593
  this.timing.startAdRequestWatchdog(requestToken);
10594
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10595
+ _state.label = 4;
10596
+ case 4:
10597
+ _state.trys.push([
10598
+ 4,
10599
+ ,
10600
+ 6,
10601
+ 7
10602
+ ]);
9984
10603
  return [
9985
10604
  4,
9986
10605
  this.callController(function() {
9987
- return adPlayer.requestAds(requestUrl);
10606
+ return adPlayer.requestAds(requestUrl, {
10607
+ finalizeRequestUrl: finalizeRequestUrl
10608
+ });
9988
10609
  })
9989
10610
  ];
9990
- case 3:
10611
+ case 5:
9991
10612
  _state.sent();
10613
+ return [
10614
+ 3,
10615
+ 7
10616
+ ];
10617
+ case 6:
10618
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10619
+ return [
10620
+ 7
10621
+ ];
10622
+ case 7:
9992
10623
  this.timing.clearAdRequestWatchdog();
9993
10624
  if (this.isStale(epoch, generation)) {
9994
10625
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10016,7 +10647,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10016
10647
  }
10017
10648
  sendAdLoadedTracking(this.host.config.licenseKey, {
10018
10649
  source: "hls",
10019
- vastUrl: requestUrl,
10650
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10020
10651
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10021
10652
  }, this.analyticsContext).catch(function() {});
10022
10653
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10026,7 +10657,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10026
10657
  return adPlayer.play();
10027
10658
  })
10028
10659
  ];
10029
- case 4:
10660
+ case 8:
10030
10661
  _state.sent();
10031
10662
  if (this.isStale(epoch, generation)) return [
10032
10663
  2,
@@ -10040,7 +10671,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10040
10671
  2,
10041
10672
  true
10042
10673
  ];
10043
- case 5:
10674
+ case 9:
10044
10675
  error = _state.sent();
10045
10676
  this.timing.clearAdRequestWatchdog();
10046
10677
  this.timing.clearAdFailsafeTimer();
@@ -10060,12 +10691,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10060
10691
  if (this.debug) {
10061
10692
  console.warn("[POD] Optimized pod request/play failed:", error);
10062
10693
  }
10694
+ if (this.handlePodRequestNotSent(error)) return [
10695
+ 2,
10696
+ false
10697
+ ];
10063
10698
  this.recordRequestFailure(error, podUrl);
10064
10699
  return [
10065
10700
  2,
10066
10701
  false
10067
10702
  ];
10068
- case 6:
10703
+ case 10:
10069
10704
  return [
10070
10705
  2
10071
10706
  ];
@@ -10111,17 +10746,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10111
10746
  }
10112
10747
  },
10113
10748
  {
10114
- /**
10115
- * Builds the next Edge request from the budget left right now, or marks Edge
10116
- * exhausted for this break. Synchronous on purpose: callers must reach the
10117
- * REQUESTING state in the same tick so a second completion event cannot race
10118
- * in a parallel request.
10119
- */ key: "prepareEdgePodRequest",
10749
+ key: "prepareEdgePodRequest",
10120
10750
  value: function prepareEdgePodRequest() {
10121
10751
  var baseUrl = this.host.getEdgePodBaseUrl();
10122
10752
  if (!baseUrl) return void 0;
10123
10753
  var remainingMs = this.timing.getRemainingAdMs();
10124
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10754
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10125
10755
  if (remainingAds < 1) {
10126
10756
  this.markEdgeExhausted("ad_capacity_reached", {
10127
10757
  adsInBreak: this.timing.totalAdsInBreak
@@ -10200,7 +10830,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10200
10830
  ];
10201
10831
  }
10202
10832
  remainingMs = this.timing.getRemainingAdMs();
10203
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10833
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10204
10834
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10205
10835
  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;
10206
10836
  if (classifyEdgeVastResponse({
@@ -10547,7 +11177,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10547
11177
  {
10548
11178
  key: "noteVastUrlGenerated",
10549
11179
  value: function noteVastUrlGenerated(url, source) {
10550
- var _ref, _ref1, _ref2, _ref3, _ref4;
11180
+ var _ref, _ref1;
10551
11181
  var params;
10552
11182
  try {
10553
11183
  params = new URL(url).searchParams;
@@ -10557,9 +11187,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10557
11187
  requestId: void 0,
10558
11188
  source: source,
10559
11189
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10560
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10561
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10562
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11190
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11191
+ return SCVP_POD_MACROS.has(name);
11192
+ }),
10563
11193
  adType: adType
10564
11194
  });
10565
11195
  if (adType === "audio" || adType === "audio_video") {
@@ -10600,10 +11230,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10600
11230
  if (diag && !diag.failureReason) {
10601
11231
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10602
11232
  }
11233
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11234
+ return SCVP_POD_MACROS.has(name);
11235
+ }) ? diag.dispatchedUrl : vastTagUrl;
10603
11236
  if (this.timing.isTemporaryAdError(error)) {
10604
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11237
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10605
11238
  } else if (outcome !== "discarded_budget") {
10606
- this.timing.failedVastUrls.add(vastTagUrl);
11239
+ this.timing.failedVastUrls.add(failureKey);
10607
11240
  }
10608
11241
  this.countFunnelStage("request_outcome:".concat(outcome));
10609
11242
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10629,6 +11262,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10629
11262
  switch(payload.stage){
10630
11263
  case "gam_http_request_sent":
10631
11264
  diag.gamRequestSent++;
11265
+ this.logPodDispatch(diag);
10632
11266
  break;
10633
11267
  case "edge_http_request_sent":
10634
11268
  diag.edgeRequestSent++;
@@ -10680,8 +11314,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10680
11314
  if (gamReturnedAdWithoutImpression) {
10681
11315
  this.countFunnelStage("gam_ad_without_impression");
10682
11316
  }
10683
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10684
- "startedAt"
11317
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11318
+ "startedAt",
11319
+ "dispatchedUrl",
11320
+ "podDispatchLogged"
10685
11321
  ]);
10686
11322
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10687
11323
  durationMs: Date.now() - startedAt,
@@ -10693,24 +11329,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10693
11329
  // ───────────────────────────────────────────────────────────────
10694
11330
  // Single ad playback
10695
11331
  // ───────────────────────────────────────────────────────────────
10696
- key: "withCurrentPodBudget",
10697
- value: function withCurrentPodBudget(rawVastTagUrl) {
10698
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10699
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10700
- if (!(remaining > 0)) return vastTagUrl;
10701
- try {
10702
- var url = new URL(vastTagUrl);
10703
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10704
- var maxMs = Math.round(remaining);
10705
- url.searchParams.set("pmxd", String(maxMs));
10706
- var minMs = Number(url.searchParams.get("pmnd"));
10707
- if (Number.isFinite(minMs) && minMs > maxMs) {
10708
- url.searchParams.set("pmnd", String(maxMs));
10709
- }
10710
- return url.toString();
10711
- } catch (unused) {
10712
- return vastTagUrl;
10713
- }
11332
+ key: "createGamDispatchFinalizer",
11333
+ value: function createGamDispatchFinalizer(requestToken) {
11334
+ var _this = this;
11335
+ var breakId = this.timing.adBreakEpoch;
11336
+ var config = this.adConfig.resolveAdPodConfig();
11337
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11338
+ return function(url) {
11339
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11340
+ var diag = _this.requestDiagnostics.get(requestToken);
11341
+ try {
11342
+ var result = finalizeGamRequestUrl(url, {
11343
+ breakId: breakId,
11344
+ capacity: capacity,
11345
+ config: config,
11346
+ minUsablePmxdMs: minUsablePmxdMs
11347
+ });
11348
+ if (diag) {
11349
+ diag.pod = result.diagnostics;
11350
+ diag.dispatchedUrl = result.url;
11351
+ diag.podDispatchLogged = false;
11352
+ }
11353
+ _this.currentVastUrl = result.url;
11354
+ return result.url;
11355
+ } catch (error) {
11356
+ if (diag && isPodRequestAbortedError(error)) {
11357
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11358
+ }
11359
+ throw error;
11360
+ }
11361
+ };
11362
+ }
11363
+ },
11364
+ {
11365
+ key: "logPodDispatch",
11366
+ value: function logPodDispatch(diag) {
11367
+ if (!diag.pod || diag.podDispatchLogged) return;
11368
+ diag.podDispatchLogged = true;
11369
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11370
+ }
11371
+ },
11372
+ {
11373
+ key: "recordPodResponseDiagnostics",
11374
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11375
+ var _diag_vastAdCount, _ref;
11376
+ var _adPlayer_getPodTotalDurationMs;
11377
+ var diag = this.requestDiagnostics.get(requestToken);
11378
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11379
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11380
+ 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);
11381
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11382
+ pmxdSent: diag.pod.pmxdSent
11383
+ }, diag.podResponse));
11384
+ }
11385
+ },
11386
+ {
11387
+ key: "handlePodRequestNotSent",
11388
+ value: function handlePodRequestNotSent(error) {
11389
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11390
+ var aborted = error;
11391
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11392
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11393
+ reason: aborted.reason,
11394
+ errorMessage: aborted.message
11395
+ }, aborted.diagnostics));
11396
+ return true;
10714
11397
  }
10715
11398
  },
10716
11399
  {
@@ -10930,7 +11613,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10930
11613
  value: function playSingleAd(vastTagUrl) {
10931
11614
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10932
11615
  return _async_to_generator(function() {
10933
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11616
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10934
11617
  return _ts_generator(this, function(_state) {
10935
11618
  switch(_state.label){
10936
11619
  case 0:
@@ -10968,19 +11651,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10968
11651
  requestToken = ++this.timing.adRequestTokenCounter;
10969
11652
  this.timing.activeAdRequestToken = requestToken;
10970
11653
  ap = this.host.getAdPlayer();
10971
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
10972
11654
  this.currentPodSource = "gam";
10973
11655
  this.setSlotState("REQUESTING", trigger);
10974
11656
  this.beginFunnelRequest(ap, requestToken, trigger);
10975
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11657
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
10976
11658
  this.currentVastUrl = requestUrl;
10977
11659
  _state.label = 1;
10978
11660
  case 1:
10979
11661
  _state.trys.push([
10980
11662
  1,
10981
- 5,
11663
+ 9,
10982
11664
  ,
10983
- 6
11665
+ 10
10984
11666
  ]);
10985
11667
  return [
10986
11668
  4,
@@ -10991,15 +11673,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10991
11673
  if (this.isStale(epoch, generation)) return [
10992
11674
  2
10993
11675
  ];
11676
+ return [
11677
+ 4,
11678
+ this.host.completeGamRequestSignals(requestUrl)
11679
+ ];
11680
+ case 3:
11681
+ requestUrl = _state.sent();
11682
+ if (this.isStale(epoch, generation)) return [
11683
+ 2
11684
+ ];
10994
11685
  this.timing.startAdRequestWatchdog(requestToken);
11686
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11687
+ _state.label = 4;
11688
+ case 4:
11689
+ _state.trys.push([
11690
+ 4,
11691
+ ,
11692
+ 6,
11693
+ 7
11694
+ ]);
10995
11695
  return [
10996
11696
  4,
10997
11697
  this.callController(function() {
10998
- return ap.requestAds(requestUrl);
11698
+ return ap.requestAds(requestUrl, {
11699
+ finalizeRequestUrl: finalizeRequestUrl
11700
+ });
10999
11701
  })
11000
11702
  ];
11001
- case 3:
11703
+ case 5:
11002
11704
  _state.sent();
11705
+ return [
11706
+ 3,
11707
+ 7
11708
+ ];
11709
+ case 6:
11710
+ this.recordPodResponseDiagnostics(requestToken, ap);
11711
+ return [
11712
+ 7
11713
+ ];
11714
+ case 7:
11003
11715
  this.timing.clearAdRequestWatchdog();
11004
11716
  if (this.isStale(epoch, generation)) {
11005
11717
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11011,7 +11723,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11011
11723
  }
11012
11724
  sendAdLoadedTracking(this.host.config.licenseKey, {
11013
11725
  source: "hls",
11014
- vastUrl: requestUrl,
11726
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11015
11727
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11016
11728
  }, this.analyticsContext).catch(function() {});
11017
11729
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11032,7 +11744,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11032
11744
  return ap.play();
11033
11745
  })
11034
11746
  ];
11035
- case 4:
11747
+ case 8:
11036
11748
  _state.sent();
11037
11749
  if (this.isStale(epoch, generation)) return [
11038
11750
  2
@@ -11044,9 +11756,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11044
11756
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11045
11757
  return [
11046
11758
  3,
11047
- 6
11759
+ 10
11048
11760
  ];
11049
- case 5:
11761
+ case 9:
11050
11762
  error = _state.sent();
11051
11763
  this.timing.clearAdRequestWatchdog();
11052
11764
  this.timing.clearAdFailsafeTimer();
@@ -11063,12 +11775,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11063
11775
  ];
11064
11776
  }
11065
11777
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11778
+ if (this.handlePodRequestNotSent(error)) throw error;
11066
11779
  this.recordRequestFailure(error, vastTagUrl);
11067
11780
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11068
11781
  this.recreateAdController("discarded_budget");
11069
11782
  }
11070
11783
  throw error;
11071
- case 6:
11784
+ case 10:
11072
11785
  return [
11073
11786
  2
11074
11787
  ];
@@ -11130,7 +11843,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11130
11843
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11131
11844
  requestFailed: count("request_failed"),
11132
11845
  requestAbortedTimeout: count("request_aborted_timeout"),
11133
- credentialsRetries: count("vast_credentials_retry"),
11846
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11134
11847
  wrapperFailures: count("wrapper_fetch:failure"),
11135
11848
  noSupportedMedia: count("vast_no_supported_media"),
11136
11849
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11667,8 +12380,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11667
12380
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11668
12381
  return requiresMediaPipelineResetAfterAds();
11669
12382
  },
11670
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11671
- return _this.generatePodVastUrl(base, breakDurationMs);
12383
+ generatePodVastUrl: function generatePodVastUrl(base) {
12384
+ return _this.generatePodVastUrl(base);
12385
+ },
12386
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12387
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11672
12388
  },
11673
12389
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11674
12390
  return _this.edgePodBaseUrl;
@@ -11792,9 +12508,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11792
12508
  },
11793
12509
  {
11794
12510
  key: "generatePodVastUrl",
11795
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11796
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11797
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12511
+ value: function generatePodVastUrl(baseUrl) {
12512
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11798
12513
  }
11799
12514
  },
11800
12515
  {
@@ -12148,7 +12863,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12148
12863
  activeAdRequest: this.timing.activeAdRequestToken !== null
12149
12864
  });
12150
12865
  }
12151
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12866
+ this.timing.markBreakEndedNow();
12152
12867
  this.timing.clearAdStartTimer();
12153
12868
  this.timing.clearAdStopTimer();
12154
12869
  if (adPlaying) {
@@ -12175,7 +12890,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12175
12890
  this.adBreak.inAdBreak = true;
12176
12891
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12177
12892
  this.cueManager.scheduledScte35BreakKey = void 0;
12178
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12893
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12179
12894
  this.timing.setAdBreakDurationBoundary(durationMs);
12180
12895
  this.adBreak.handleAdStart(marker);
12181
12896
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12221,9 +12936,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12221
12936
  }
12222
12937
  this.adConfig.beginNewAdPod();
12223
12938
  this.adConfig.podAssignedByPrefetch = true;
12224
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12225
12939
  var generatedUrls = [
12226
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
12940
+ this.generatePodVastUrl(baseVastUrl)
12227
12941
  ];
12228
12942
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12229
12943
  marker: marker
@@ -12322,7 +13036,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12322
13036
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12323
13037
  this.adBreak.showAds = true;
12324
13038
  this.adBreak.inAdBreak = true;
12325
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13039
+ this.timing.beginBreakTiming(Date.now());
12326
13040
  if (durationMs > 0) {
12327
13041
  this.timing.setAdBreakDurationBoundary(durationMs);
12328
13042
  }
@@ -12594,7 +13308,6 @@ var CRITICAL_PROPS = [
12594
13308
  "vmapUrl",
12595
13309
  "lowLatencyMode",
12596
13310
  "driftToleranceMs",
12597
- "vastMode",
12598
13311
  "ctvAdRequest",
12599
13312
  "adFloorMinCents",
12600
13313
  "adFloorMaxCents",
@@ -12603,7 +13316,7 @@ var CRITICAL_PROPS = [
12603
13316
  var CONTROLS_HIDE_DELAY = 3e3;
12604
13317
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
12605
13318
  var StormcloudVideoPlayerComponent = React.memo(function(props) {
12606
- var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, maxAdBreakExtensionMs = props.maxAdBreakExtensionMs, adFloorLadderEnabled = props.adFloorLadderEnabled, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, enableEdgePodRequest = props.enableEdgePodRequest, edgePodUrl = props.edgePodUrl, restVideoAttrs = _object_without_properties(props, [
13319
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, vastTagUrl = props.vastTagUrl, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, contentNetwork = props.contentNetwork, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, maxAdBreakExtensionMs = props.maxAdBreakExtensionMs, adFloorLadderEnabled = props.adFloorLadderEnabled, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, enableEdgePodRequest = props.enableEdgePodRequest, edgePodUrl = props.edgePodUrl, restVideoAttrs = _object_without_properties(props, [
12607
13320
  "src",
12608
13321
  "autoplay",
12609
13322
  "muted",
@@ -12629,7 +13342,6 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12629
13342
  "poster",
12630
13343
  "children",
12631
13344
  "licenseKey",
12632
- "vastMode",
12633
13345
  "vastTagUrl",
12634
13346
  "isVmap",
12635
13347
  "vmapUrl",
@@ -12637,6 +13349,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12637
13349
  "ctvAdRequest",
12638
13350
  "programTitle",
12639
13351
  "channelName",
13352
+ "contentNetwork",
12640
13353
  "minRemainingMsToStartAd",
12641
13354
  "minRemainingMsToRequestAd",
12642
13355
  "maxNoFillsPerBreak",
@@ -12795,7 +13508,6 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12795
13508
  vmapUrl,
12796
13509
  lowLatencyMode,
12797
13510
  driftToleranceMs,
12798
- vastMode,
12799
13511
  adFloorMinCents,
12800
13512
  adFloorMaxCents,
12801
13513
  adFloorStepCents
@@ -12837,7 +13549,6 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12837
13549
  if (onFullscreenToggle !== void 0) cfg.onFullscreenToggle = onFullscreenToggle;
12838
13550
  if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
12839
13551
  if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
12840
- if (vastMode !== void 0) cfg.vastMode = vastMode;
12841
13552
  if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;
12842
13553
  if (isVmap !== void 0) cfg.isVmap = isVmap;
12843
13554
  if (vmapUrl !== void 0) cfg.vmapUrl = vmapUrl;
@@ -12845,6 +13556,7 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12845
13556
  if (ctvAdRequest !== void 0) cfg.ctvAdRequest = ctvAdRequest;
12846
13557
  if (programTitle !== void 0) cfg.programTitle = programTitle;
12847
13558
  if (channelName !== void 0) cfg.channelName = channelName;
13559
+ if (contentNetwork !== void 0) cfg.contentNetwork = contentNetwork;
12848
13560
  if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
12849
13561
  if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
12850
13562
  if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
@@ -15178,5 +15890,5 @@ var createStormcloudPlayer = function createStormcloudPlayer(playerList, fallbac
15178
15890
  };
15179
15891
  var StormcloudPlayer = createStormcloudPlayer(players_default, players_default[players_default.length - 1]);
15180
15892
  var StormcloudPlayer_default = StormcloudPlayer;
15181
- export { DEFAULT_FLOOR_LADDER_BOUNDS, DEFAULT_TRACKING_INGEST_CONFIG, DEFAULT_WEB_FLOOR_LADDER_CONFIG, IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, applyTrackingIngestConfig, buildAnalyticsContext, canPlay, configureTrackingIngest, createHlsAdPlayer, createPalNonceManager, createStormcloudPlayer, StormcloudVideoPlayerComponent as default, detectBrowser, fixedFloorSelector, generateFloorLevels, getBrowserConfigOverrides, getBrowserID, getClientInfo, ingestPlayerTracking, initializePolyfills, isMediaStream, isTrackingIngestEnabled, lazy, logBrowserInfo, merge, omit, parseQuery, players_default as players, randomString, requiresMediaPipelineResetAfterAds, resolveFloorLadderBounds, sendAdDetectTracking, sendAdImpressionTracking, sendAdLoadedTracking, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode, trackingIngestConfig, validateFloorCents, validateFloorLadderConfig };
15893
+ export { DEFAULT_FLOOR_LADDER_BOUNDS, DEFAULT_REQUEST_SAFETY_MS, DEFAULT_TRACKING_INGEST_CONFIG, DEFAULT_WEB_FLOOR_LADDER_CONFIG, GAM_AD_OPPORTUNITY_DURATION_MS, IS_BROWSER, IS_GLOBAL, IS_IOS, IS_SAFARI, SUPPORTS_DASH, SUPPORTS_HLS, StormcloudPlayer_default as StormcloudPlayer, StormcloudVideoPlayer, StormcloudVideoPlayerComponent, applyTrackingIngestConfig, buildAnalyticsContext, canPlay, configureTrackingIngest, createHlsAdPlayer, createPalNonceManager, createStormcloudPlayer, StormcloudVideoPlayerComponent as default, detectBrowser, fixedFloorSelector, generateFloorLevels, getBrowserConfigOverrides, getBrowserID, getClientInfo, ingestPlayerTracking, initializePolyfills, isMediaStream, isTrackingIngestEnabled, lazy, logBrowserInfo, merge, omit, parseQuery, players_default as players, randomString, requiresMediaPipelineResetAfterAds, resolveFloorLadderBounds, sendAdDetectTracking, sendAdImpressionTracking, sendAdLoadedTracking, sendHeartbeat, sendInitialTracking, supportsFeature, supportsModernJS, supportsWebKitPresentationMode, trackingIngestConfig, validateFloorCents, validateFloorLadderConfig };
15182
15894
  //# sourceMappingURL=index.js.map