stormcloud-video-player 0.8.69 → 0.8.70

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.
package/lib/index.js CHANGED
@@ -2487,7 +2487,7 @@ function createHlsAdPlayer(contentVideo, options) {
2487
2487
  img.onload = null;
2488
2488
  img.onerror = null;
2489
2489
  inFlightBeacons.delete(img);
2490
- console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingUrl));
2490
+ console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingHost));
2491
2491
  if (outcome !== "load") {
2492
2492
  logFunnel("tracking_request_settled", {
2493
2493
  reason: outcome,
@@ -2505,7 +2505,7 @@ function createHlsAdPlayer(contentVideo, options) {
2505
2505
  return release("timeout");
2506
2506
  }, BEACON_TIMEOUT_MS);
2507
2507
  img.src = trackingUrl;
2508
- console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingUrl));
2508
+ console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingHost));
2509
2509
  logFunnel("tracking_request_created", {
2510
2510
  trackingHost: trackingHost,
2511
2511
  errorCode: options2 === null || options2 === void 0 ? void 0 : options2.errorCode
@@ -2959,7 +2959,7 @@ function createHlsAdPlayer(contentVideo, options) {
2959
2959
  });
2960
2960
  }
2961
2961
  if (parsed.type === "wrapper") {
2962
- console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
2962
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(redactUrl(parsed.vastAdTagUri)));
2963
2963
  }
2964
2964
  return parsed;
2965
2965
  }
@@ -3151,8 +3151,8 @@ function createHlsAdPlayer(contentVideo, options) {
3151
3151
  switch(_state.label){
3152
3152
  case 0:
3153
3153
  attempt++;
3154
- if (kind === "gam") {
3155
- logFunnel("gam_http_request_sent", {
3154
+ if (kind !== "wrapper") {
3155
+ logFunnel("".concat(kind, "_http_request_sent"), {
3156
3156
  attempt: attempt,
3157
3157
  credentials: creds
3158
3158
  });
@@ -3172,8 +3172,8 @@ function createHlsAdPlayer(contentVideo, options) {
3172
3172
  ];
3173
3173
  case 1:
3174
3174
  response = _state.sent();
3175
- if (kind === "gam") {
3176
- logFunnel("gam_response_received", {
3175
+ if (kind !== "wrapper") {
3176
+ logFunnel("".concat(kind, "_response_received"), {
3177
3177
  attempt: attempt,
3178
3178
  httpStatus: response.status,
3179
3179
  ok: response.ok,
@@ -3343,8 +3343,7 @@ function createHlsAdPlayer(contentVideo, options) {
3343
3343
  elapsedMs: Date.now() - fetchStartedAt
3344
3344
  });
3345
3345
  }
3346
- console.log("[HlsAdPlayer] VAST XML received");
3347
- console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
3346
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
3348
3347
  parsed = parseVastXml(vastXml);
3349
3348
  if (parsed.type === "empty") {
3350
3349
  ;
@@ -3385,16 +3384,35 @@ function createHlsAdPlayer(contentVideo, options) {
3385
3384
  });
3386
3385
  }).apply(this, arguments);
3387
3386
  }
3387
+ function isEdgeEmptySentinelAd(adElement) {
3388
+ var _textOf;
3389
+ if ((adElement.getAttribute("id") || "").trim().toLowerCase() === "empty") {
3390
+ return true;
3391
+ }
3392
+ var inLine = adElement.querySelector(":scope > InLine");
3393
+ if (!inLine) return false;
3394
+ if (/^no ad available$/i.test((_textOf = textOf(inLine.querySelector(":scope > AdTitle"))) !== null && _textOf !== void 0 ? _textOf : "")) {
3395
+ return true;
3396
+ }
3397
+ var durations = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear > Duration")).map(function(el) {
3398
+ return parseVastTime(textOf(el));
3399
+ });
3400
+ return durations.length > 0 && durations.every(function(seconds) {
3401
+ return seconds === 0;
3402
+ });
3403
+ }
3388
3404
  function fetchAndParsePod(vastTagUrl) {
3405
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3389
3406
  return _async_to_generator(function() {
3390
- var _root_getAttribute, _root_getAttribute1, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
3407
+ 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;
3391
3408
  return _ts_generator(this, function(_state) {
3392
3409
  switch(_state.label){
3393
3410
  case 0:
3394
3411
  lastPodAdElementCount = 0;
3412
+ isEdge = source === "edge";
3395
3413
  return [
3396
3414
  4,
3397
- fetchVastXml(vastTagUrl)
3415
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3398
3416
  ];
3399
3417
  case 1:
3400
3418
  vastXml = _state.sent();
@@ -3417,7 +3435,6 @@ function createHlsAdPlayer(contentVideo, options) {
3417
3435
  }
3418
3436
  xmlDoc = parseXml(vastXml);
3419
3437
  if (!xmlDoc) {
3420
- console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
3421
3438
  logFunnel("vast_parsed", {
3422
3439
  adElementCount: 0,
3423
3440
  reason: "xml_parse_error"
@@ -3489,12 +3506,24 @@ function createHlsAdPlayer(contentVideo, options) {
3489
3506
  });
3490
3507
  })();
3491
3508
  };
3492
- podElements = adElements.filter(function(el) {
3509
+ candidates = adElements;
3510
+ if (isEdge) {
3511
+ candidates = adElements.filter(function(el) {
3512
+ return !isEdgeEmptySentinelAd(el);
3513
+ });
3514
+ if (candidates.length < adElements.length) {
3515
+ logFunnel("edge_empty_sentinel", {
3516
+ sentinelCount: adElements.length - candidates.length,
3517
+ adElementCount: adElements.length
3518
+ });
3519
+ }
3520
+ }
3521
+ podElements = candidates.filter(function(el) {
3493
3522
  return getAdSequence(el) !== void 0;
3494
3523
  }).sort(function(a, b) {
3495
3524
  return getAdSequence(a) - getAdSequence(b);
3496
3525
  });
3497
- buffet = adElements.filter(function(el) {
3526
+ buffet = candidates.filter(function(el) {
3498
3527
  return getAdSequence(el) === void 0;
3499
3528
  });
3500
3529
  resolveAll = function resolveAll(elements) {
@@ -3651,7 +3680,9 @@ function createHlsAdPlayer(contentVideo, options) {
3651
3680
  lastPodAdElementCount = adElements.length;
3652
3681
  return [
3653
3682
  2,
3654
- ads
3683
+ isEdge ? ads.filter(function(ad) {
3684
+ return ad.duration > 0;
3685
+ }) : ads
3655
3686
  ];
3656
3687
  }
3657
3688
  });
@@ -4652,13 +4683,14 @@ function createHlsAdPlayer(contentVideo, options) {
4652
4683
  contentVideo[AD_CONTAINER_PROP] = adContainerEl;
4653
4684
  attachContainerHandlers();
4654
4685
  },
4655
- requestAds: function requestAds(vastTagUrl) {
4686
+ requestAds: function requestAds(vastTagUrl, requestOptions) {
4656
4687
  return _async_to_generator(function() {
4657
- var ads, preloaded, error;
4688
+ var _ref, source, ads, preloaded, error;
4658
4689
  return _ts_generator(this, function(_state) {
4659
4690
  switch(_state.label){
4660
4691
  case 0:
4661
- console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
4692
+ source = (_ref = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.source) !== null && _ref !== void 0 ? _ref : "gam";
4693
+ console.log("[HlsAdPlayer] Requesting ads (".concat(source, "):"), redactUrl(vastTagUrl));
4662
4694
  if (adPlaying) {
4663
4695
  console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
4664
4696
  return [
@@ -4703,7 +4735,7 @@ function createHlsAdPlayer(contentVideo, options) {
4703
4735
  case 2:
4704
4736
  return [
4705
4737
  4,
4706
- fetchAndParsePod(vastTagUrl)
4738
+ fetchAndParsePod(vastTagUrl, source)
4707
4739
  ];
4708
4740
  case 3:
4709
4741
  ads = _state.sent();
@@ -5113,6 +5145,75 @@ function createHlsAdPlayer(contentVideo, options) {
5113
5145
  return podAds.reduce(function(total, ad) {
5114
5146
  return total + (ad.duration > 0 ? ad.duration * 1e3 : 0);
5115
5147
  }, 0);
5148
+ },
5149
+ limitPodToBudget: function limitPodToBudget(maxDurationMs, maxAds) {
5150
+ if (adPlaying) return podAds.length;
5151
+ var kept = [];
5152
+ var dropped = [];
5153
+ var totalMs = 0;
5154
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
5155
+ try {
5156
+ for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
5157
+ var ad = _step.value;
5158
+ var durationMs = Math.round(ad.duration * 1e3);
5159
+ if (kept.length < maxAds && totalMs + durationMs <= maxDurationMs) {
5160
+ kept.push(ad);
5161
+ totalMs += durationMs;
5162
+ } else {
5163
+ dropped.push(ad);
5164
+ }
5165
+ }
5166
+ } catch (err) {
5167
+ _didIteratorError = true;
5168
+ _iteratorError = err;
5169
+ } finally{
5170
+ try {
5171
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
5172
+ _iterator.return();
5173
+ }
5174
+ } finally{
5175
+ if (_didIteratorError) {
5176
+ throw _iteratorError;
5177
+ }
5178
+ }
5179
+ }
5180
+ if (dropped.length > 0) {
5181
+ logFunnel("pod_trimmed_to_budget", {
5182
+ keptCount: kept.length,
5183
+ droppedCount: dropped.length,
5184
+ keptDurationMs: totalMs,
5185
+ maxDurationMs: maxDurationMs,
5186
+ maxAds: maxAds
5187
+ });
5188
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
5189
+ try {
5190
+ for(var _iterator1 = dropped[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
5191
+ var ad1 = _step1.value;
5192
+ resolvedAds.add(ad1);
5193
+ fireTrackingPixels(ad1.trackingUrls.notUsed, {
5194
+ ad: ad1
5195
+ });
5196
+ }
5197
+ } catch (err) {
5198
+ _didIteratorError1 = true;
5199
+ _iteratorError1 = err;
5200
+ } finally{
5201
+ try {
5202
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
5203
+ _iterator1.return();
5204
+ }
5205
+ } finally{
5206
+ if (_didIteratorError1) {
5207
+ throw _iteratorError1;
5208
+ }
5209
+ }
5210
+ }
5211
+ }
5212
+ podAds = kept;
5213
+ podIndex = 0;
5214
+ currentAd = kept[0];
5215
+ currentAdMediaFile = void 0;
5216
+ return kept.length;
5116
5217
  }
5117
5218
  };
5118
5219
  }
@@ -9125,6 +9226,59 @@ var HlsEngine = /*#__PURE__*/ function() {
9125
9226
  ]);
9126
9227
  return HlsEngine;
9127
9228
  }();
9229
+ // src/player/EdgePodRequest.ts
9230
+ var EDGE_POD_MAX_ADS = 10;
9231
+ var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
9232
+ function resolveEdgePodBaseUrl(config) {
9233
+ var _config_edgePodUrl;
9234
+ if (config.enableEdgePodRequest !== true) return void 0;
9235
+ var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
9236
+ if (!raw) {
9237
+ console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
9238
+ return void 0;
9239
+ }
9240
+ try {
9241
+ var url = new URL(raw);
9242
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
9243
+ throw new Error("unsupported protocol ".concat(url.protocol));
9244
+ }
9245
+ return url.toString();
9246
+ } catch (unused) {
9247
+ console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
9248
+ return void 0;
9249
+ }
9250
+ }
9251
+ function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
9252
+ var url = new URL(baseUrl);
9253
+ var maxMs = Math.max(0, Math.floor(remainingMs));
9254
+ var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
9255
+ url.searchParams.set("pmxd", String(maxMs));
9256
+ url.searchParams.set("pmad", String(maxAds));
9257
+ url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
9258
+ url.searchParams.set("count", String(maxAds));
9259
+ return url.toString();
9260
+ }
9261
+ function classifyEdgeVastResponse(result) {
9262
+ var _ref;
9263
+ var _result_error;
9264
+ if (result.error == null) {
9265
+ return result.podAdCount > 0 ? "fill" : "no_fill";
9266
+ }
9267
+ var message = (_ref = (_result_error = result.error) === null || _result_error === void 0 ? void 0 : _result_error.message) !== null && _ref !== void 0 ? _ref : String(result.error);
9268
+ if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
9269
+ return "no_fill";
9270
+ }
9271
+ return "invalid";
9272
+ }
9273
+ function describeEdgeUrl(url) {
9274
+ try {
9275
+ var parsed = new URL(url);
9276
+ return "".concat(parsed.origin).concat(parsed.pathname);
9277
+ } catch (unused) {
9278
+ var _url_split_;
9279
+ return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
9280
+ }
9281
+ }
9128
9282
  // src/player/PlayerControls.ts
9129
9283
  function getAdAudioVolume(adPlayer) {
9130
9284
  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
@@ -9284,6 +9438,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9284
9438
  this.controllerCallInFlight = false;
9285
9439
  this.playbackStartedForCurrentRequest = false;
9286
9440
  this.opportunityEpoch = -1;
9441
+ this.edgeExhaustedForBreak = false;
9442
+ this.edgeRequestsInBreak = 0;
9287
9443
  this.adPodQueue = [];
9288
9444
  this.defaultMinRemainingMsToRequestAd = 1e4;
9289
9445
  this.defaultMaxNoFillsPerBreak = 2;
@@ -9434,7 +9590,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9434
9590
  _this.timing.clearAdRequestWatchdog();
9435
9591
  _this.timing.activeAdRequestToken = null;
9436
9592
  _this.showAds = true;
9437
- _this.timing.resetGamNoFillCounter();
9593
+ if (_this.currentPodSource !== "edge") {
9594
+ _this.timing.resetGamNoFillCounter();
9595
+ }
9438
9596
  if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
9439
9597
  _this.timing.scheduleAdStopAtBreakBoundary();
9440
9598
  if (_this.debug) {
@@ -9566,6 +9724,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9566
9724
  key: "beginVmapBreak",
9567
9725
  value: function beginVmapBreak(breakKey, position) {
9568
9726
  this.breakSource = "vmap";
9727
+ this.resetEdgeStateForBreak();
9569
9728
  this.followUpBaseVastUrl = void 0;
9570
9729
  this.unusableResponsesInBreak = 0;
9571
9730
  this.timing.totalAdRequestsInBreak = 0;
@@ -9577,7 +9736,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9577
9736
  key: "handleAdStart",
9578
9737
  value: function handleAdStart(marker) {
9579
9738
  return _async_to_generator(function() {
9580
- var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
9739
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
9581
9740
  return _ts_generator(this, function(_state) {
9582
9741
  switch(_state.label){
9583
9742
  case 0:
@@ -9591,7 +9750,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9591
9750
  ];
9592
9751
  }
9593
9752
  baseVastUrl = this.adConfig.apiVastTagUrl;
9594
- if (!baseVastUrl) {
9753
+ edgeConfigured = !!this.host.getEdgePodBaseUrl();
9754
+ if (!baseVastUrl && !edgeConfigured) {
9595
9755
  console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
9596
9756
  this.clearPendingAdBreak();
9597
9757
  return [
@@ -9607,6 +9767,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9607
9767
  this.breakSource = "scte35";
9608
9768
  this.followUpBaseVastUrl = baseVastUrl;
9609
9769
  this.unusableResponsesInBreak = 0;
9770
+ this.resetEdgeStateForBreak();
9610
9771
  this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
9611
9772
  if (this.adConfig.podAssignedByPrefetch) {
9612
9773
  this.adConfig.podAssignedByPrefetch = false;
@@ -9628,7 +9789,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9628
9789
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9629
9790
  epoch = this.timing.adBreakEpoch;
9630
9791
  hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9631
- if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
9792
+ if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
9632
9793
  3,
9633
9794
  2
9634
9795
  ];
@@ -9647,11 +9808,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9647
9808
  mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
9648
9809
  console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
9649
9810
  }
9811
+ if (!edgeConfigured) return [
9812
+ 3,
9813
+ 5
9814
+ ];
9815
+ edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
9816
+ if (!edgeUrl) return [
9817
+ 3,
9818
+ 4
9819
+ ];
9820
+ this.clearPendingAdBreak();
9650
9821
  return [
9651
9822
  4,
9652
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
9823
+ this.runEdgePod(edgeUrl, "edge_break_start")
9653
9824
  ];
9654
9825
  case 3:
9826
+ outcome = _state.sent();
9827
+ this.continueAfterEdgeOutcome(outcome, epoch);
9828
+ return [
9829
+ 2
9830
+ ];
9831
+ case 4:
9832
+ if (!this.edgeExhaustedForBreak) {
9833
+ this.markEdgeExhausted("not_eligible_at_break_start", {
9834
+ isLive: this.isLiveBreak(),
9835
+ durationMs: this.timing.expectedAdBreakDurationMs
9836
+ });
9837
+ }
9838
+ _state.label = 5;
9839
+ case 5:
9840
+ if (!baseVastUrl) {
9841
+ this.requestNextAd("no_gam_source");
9842
+ return [
9843
+ 2
9844
+ ];
9845
+ }
9846
+ return [
9847
+ 4,
9848
+ this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
9849
+ ];
9850
+ case 6:
9655
9851
  podPlayed = _state.sent();
9656
9852
  if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
9657
9853
  this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
@@ -9743,6 +9939,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9743
9939
  adPlayer = this.host.getAdPlayer();
9744
9940
  requestToken = ++this.timing.adRequestTokenCounter;
9745
9941
  this.timing.activeAdRequestToken = requestToken;
9942
+ this.currentPodSource = "gam";
9746
9943
  this.setSlotState("REQUESTING", "initial_pod");
9747
9944
  this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
9748
9945
  requestUrl = this.applyOpportunityFloor(podUrl);
@@ -9859,6 +10056,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9859
10056
  }).call(this);
9860
10057
  }
9861
10058
  },
10059
+ {
10060
+ // ───────────────────────────────────────────────────────────────
10061
+ // Edge-first pods (live SCTE-35 only, GAM fallback)
10062
+ // ───────────────────────────────────────────────────────────────
10063
+ key: "resetEdgeStateForBreak",
10064
+ value: function resetEdgeStateForBreak() {
10065
+ this.edgeExhaustedForBreak = false;
10066
+ this.edgeRequestsInBreak = 0;
10067
+ this.currentPodSource = void 0;
10068
+ }
10069
+ },
10070
+ {
10071
+ key: "isLiveBreak",
10072
+ value: function isLiveBreak() {
10073
+ return this.host.isLiveStream() || this.host.config.isLiveStream === true;
10074
+ }
10075
+ },
10076
+ {
10077
+ key: "canRequestEdge",
10078
+ value: function canRequestEdge() {
10079
+ return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
10080
+ }
10081
+ },
10082
+ {
10083
+ key: "markEdgeExhausted",
10084
+ value: function markEdgeExhausted(reason) {
10085
+ var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
10086
+ this.edgeExhaustedForBreak = true;
10087
+ this.countFunnelStage("edge_fallback:".concat(reason));
10088
+ this.logOrchestratorFunnel("edge_exhausted", _object_spread({
10089
+ reason: reason,
10090
+ edgeRequests: this.edgeRequestsInBreak,
10091
+ remainingMs: this.timing.getRemainingAdMs()
10092
+ }, extra));
10093
+ }
10094
+ },
10095
+ {
10096
+ /**
10097
+ * Builds the next Edge request from the budget left right now, or marks Edge
10098
+ * exhausted for this break. Synchronous on purpose: callers must reach the
10099
+ * REQUESTING state in the same tick so a second completion event cannot race
10100
+ * in a parallel request.
10101
+ */ key: "prepareEdgePodRequest",
10102
+ value: function prepareEdgePodRequest() {
10103
+ var baseUrl = this.host.getEdgePodBaseUrl();
10104
+ if (!baseUrl) return void 0;
10105
+ var remainingMs = this.timing.getRemainingAdMs();
10106
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10107
+ if (remainingAds < 1) {
10108
+ this.markEdgeExhausted("ad_capacity_reached", {
10109
+ adsInBreak: this.timing.totalAdsInBreak
10110
+ });
10111
+ return void 0;
10112
+ }
10113
+ if (remainingMs < this.getMinRemainingMsToRequestAd()) {
10114
+ this.markEdgeExhausted("insufficient_break_time", {
10115
+ remainingMs: remainingMs
10116
+ });
10117
+ return void 0;
10118
+ }
10119
+ try {
10120
+ return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
10121
+ } catch (unused) {
10122
+ this.markEdgeExhausted("invalid_edge_url");
10123
+ return void 0;
10124
+ }
10125
+ }
10126
+ },
10127
+ {
10128
+ key: "runEdgePod",
10129
+ value: function runEdgePod(requestUrl, trigger) {
10130
+ return _async_to_generator(function() {
10131
+ var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
10132
+ return _ts_generator(this, function(_state) {
10133
+ switch(_state.label){
10134
+ case 0:
10135
+ epoch = this.timing.adBreakEpoch;
10136
+ this.recreateAdController("new_request");
10137
+ generation = this.controllerGeneration;
10138
+ adPlayer = this.host.getAdPlayer();
10139
+ requestToken = ++this.timing.adRequestTokenCounter;
10140
+ this.timing.activeAdRequestToken = requestToken;
10141
+ this.currentPodSource = "edge";
10142
+ this.edgeRequestsInBreak++;
10143
+ this.setSlotState("REQUESTING", trigger);
10144
+ this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
10145
+ this.currentVastUrl = requestUrl;
10146
+ params = new URL(requestUrl).searchParams;
10147
+ this.logOrchestratorFunnel("edge_request_sent", {
10148
+ trigger: trigger,
10149
+ attempt: this.edgeRequestsInBreak,
10150
+ endpoint: describeEdgeUrl(requestUrl),
10151
+ pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
10152
+ pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
10153
+ });
10154
+ _state.label = 1;
10155
+ case 1:
10156
+ _state.trys.push([
10157
+ 1,
10158
+ 4,
10159
+ ,
10160
+ 5
10161
+ ]);
10162
+ this.timing.startAdRequestWatchdog(requestToken);
10163
+ return [
10164
+ 4,
10165
+ this.callController(function() {
10166
+ return adPlayer.requestAds(requestUrl, {
10167
+ source: "edge"
10168
+ });
10169
+ })
10170
+ ];
10171
+ case 2:
10172
+ _state.sent();
10173
+ this.timing.clearAdRequestWatchdog();
10174
+ if (this.isStale(epoch, generation)) {
10175
+ this.logOrchestratorFunnel("stale_request_result_ignored", {
10176
+ requestId: requestToken,
10177
+ source: "edge"
10178
+ });
10179
+ return [
10180
+ 2,
10181
+ "stale"
10182
+ ];
10183
+ }
10184
+ remainingMs = this.timing.getRemainingAdMs();
10185
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10186
+ podCount = adPlayer.limitPodToBudget ? adPlayer.limitPodToBudget(remainingMs, remainingAds) : (_ref = (_adPlayer_getPodAdCount = adPlayer.getPodAdCount) === null || _adPlayer_getPodAdCount === void 0 ? void 0 : _adPlayer_getPodAdCount.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0;
10187
+ if (classifyEdgeVastResponse({
10188
+ podAdCount: podCount
10189
+ }) !== "fill") {
10190
+ throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
10191
+ }
10192
+ this.setSlotState("READY", "edge_vast_ready");
10193
+ this.logOrchestratorFunnel("edge_fill", {
10194
+ podAdCount: podCount,
10195
+ podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
10196
+ remainingMs: remainingMs
10197
+ });
10198
+ sendAdLoadedTracking(this.host.config.licenseKey, {
10199
+ source: "hls",
10200
+ vastUrl: requestUrl,
10201
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10202
+ }, this.analyticsContext).catch(function() {});
10203
+ this.timing.startAdFailsafeTimer(requestToken);
10204
+ return [
10205
+ 4,
10206
+ this.callController(function() {
10207
+ return adPlayer.play();
10208
+ })
10209
+ ];
10210
+ case 3:
10211
+ _state.sent();
10212
+ if (this.isStale(epoch, generation)) return [
10213
+ 2,
10214
+ "stale"
10215
+ ];
10216
+ if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
10217
+ this.timing.scheduleAdStopAtBreakBoundary();
10218
+ }
10219
+ adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
10220
+ return [
10221
+ 2,
10222
+ "fill"
10223
+ ];
10224
+ case 4:
10225
+ error = _state.sent();
10226
+ this.timing.clearAdRequestWatchdog();
10227
+ this.timing.clearAdFailsafeTimer();
10228
+ if (this.timing.activeAdRequestToken === requestToken) {
10229
+ this.timing.activeAdRequestToken = null;
10230
+ }
10231
+ errorMessage = error === null || error === void 0 ? void 0 : error.message;
10232
+ if (this.isStale(epoch, generation)) {
10233
+ this.logOrchestratorFunnel("stale_request_result_ignored", {
10234
+ requestId: requestToken,
10235
+ source: "edge",
10236
+ errorMessage: errorMessage
10237
+ });
10238
+ return [
10239
+ 2,
10240
+ "stale"
10241
+ ];
10242
+ }
10243
+ classification = classifyEdgeVastResponse({
10244
+ podAdCount: 0,
10245
+ error: error
10246
+ });
10247
+ diag = this.requestDiagnostics.get(requestToken);
10248
+ if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
10249
+ this.markEdgeExhausted("edge_".concat(classification), {
10250
+ errorMessage: errorMessage
10251
+ });
10252
+ return [
10253
+ 2,
10254
+ "fallback"
10255
+ ];
10256
+ case 5:
10257
+ return [
10258
+ 2
10259
+ ];
10260
+ }
10261
+ });
10262
+ }).call(this);
10263
+ }
10264
+ },
10265
+ {
10266
+ key: "continueAfterEdgeOutcome",
10267
+ value: function continueAfterEdgeOutcome(outcome, epoch) {
10268
+ if (outcome !== "fallback") return;
10269
+ if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
10270
+ if (this.debug) {
10271
+ console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
10272
+ }
10273
+ this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
10274
+ this.requestNextAd("edge_fallback");
10275
+ }
10276
+ },
9862
10277
  {
9863
10278
  // ───────────────────────────────────────────────────────────────
9864
10279
  // Next-ad scheduling (single flight)
@@ -9914,7 +10329,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9914
10329
  value: function getStopRequestingReason(remainingMs) {
9915
10330
  if (this.breakSource === "vmap") {
9916
10331
  if (this.adPodQueue.length === 0) return "vmap_queue_empty";
9917
- } else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
10332
+ } else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
9918
10333
  return "no_follow_up_source";
9919
10334
  }
9920
10335
  if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
@@ -9926,7 +10341,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9926
10341
  if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
9927
10342
  return "request_cap";
9928
10343
  }
9929
- if (this.timing.isGamInCooldown()) {
10344
+ if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
9930
10345
  return "gam_cooldown";
9931
10346
  }
9932
10347
  if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
@@ -10020,10 +10435,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10020
10435
  key: "requestFollowUpAd",
10021
10436
  value: function requestFollowUpAd(trigger) {
10022
10437
  return _async_to_generator(function() {
10023
- var url, epoch, unused;
10438
+ var edgeUrl, epoch2, outcome, url, epoch, unused;
10024
10439
  return _ts_generator(this, function(_state) {
10025
10440
  switch(_state.label){
10026
10441
  case 0:
10442
+ if (!this.canRequestEdge()) return [
10443
+ 3,
10444
+ 2
10445
+ ];
10446
+ edgeUrl = this.prepareEdgePodRequest();
10447
+ if (!edgeUrl) {
10448
+ this.requestNextAd("".concat(trigger, ":edge_unavailable"));
10449
+ return [
10450
+ 2
10451
+ ];
10452
+ }
10453
+ epoch2 = this.timing.adBreakEpoch;
10454
+ return [
10455
+ 4,
10456
+ this.runEdgePod(edgeUrl, "edge_".concat(trigger))
10457
+ ];
10458
+ case 1:
10459
+ outcome = _state.sent();
10460
+ this.continueAfterEdgeOutcome(outcome, epoch2);
10461
+ return [
10462
+ 2
10463
+ ];
10464
+ case 2:
10027
10465
  if (this.breakSource === "vmap") {
10028
10466
  url = this.adPodQueue.shift();
10029
10467
  } else if (this.followUpBaseVastUrl) {
@@ -10034,32 +10472,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10034
10472
  ];
10035
10473
  this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
10036
10474
  epoch = this.timing.adBreakEpoch;
10037
- _state.label = 1;
10038
- case 1:
10475
+ _state.label = 3;
10476
+ case 3:
10039
10477
  _state.trys.push([
10040
- 1,
10041
10478
  3,
10479
+ 5,
10042
10480
  ,
10043
- 4
10481
+ 6
10044
10482
  ]);
10045
10483
  return [
10046
10484
  4,
10047
10485
  this.playSingleAd(url, trigger)
10048
10486
  ];
10049
- case 2:
10487
+ case 4:
10050
10488
  _state.sent();
10051
10489
  return [
10052
10490
  3,
10053
- 4
10491
+ 6
10054
10492
  ];
10055
- case 3:
10493
+ case 5:
10056
10494
  unused = _state.sent();
10057
10495
  this.continueAfterRequestFailure(epoch);
10058
10496
  return [
10059
10497
  3,
10060
- 4
10498
+ 6
10061
10499
  ];
10062
- case 4:
10500
+ case 6:
10063
10501
  return [
10064
10502
  2
10065
10503
  ];
@@ -10172,7 +10610,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10172
10610
  case "gam_http_request_sent":
10173
10611
  diag.gamRequestSent++;
10174
10612
  break;
10613
+ case "edge_http_request_sent":
10614
+ diag.edgeRequestSent++;
10615
+ break;
10175
10616
  case "gam_response_received":
10617
+ case "edge_response_received":
10176
10618
  diag.vastHttpStatus = payload.httpStatus;
10177
10619
  break;
10178
10620
  case "vast_parsed":
@@ -10359,6 +10801,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10359
10801
  {
10360
10802
  key: "beginFunnelRequest",
10361
10803
  value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
10804
+ var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
10362
10805
  var _adPlayer_setFunnelContext;
10363
10806
  if (this.controllerCallInFlight) {
10364
10807
  this.logOrchestratorFunnel("duplicate_request_detected", {
@@ -10373,7 +10816,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10373
10816
  requestId: requestToken,
10374
10817
  controllerId: this.controllerGeneration,
10375
10818
  trigger: trigger,
10819
+ source: source,
10376
10820
  gamRequestSent: 0,
10821
+ edgeRequestSent: 0,
10377
10822
  wrapperDepth: 0,
10378
10823
  inlineResolved: false,
10379
10824
  mediaCandidateCount: 0,
@@ -10504,6 +10949,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10504
10949
  this.timing.activeAdRequestToken = requestToken;
10505
10950
  ap = this.host.getAdPlayer();
10506
10951
  budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
10952
+ this.currentPodSource = "gam";
10507
10953
  this.setSlotState("REQUESTING", trigger);
10508
10954
  this.beginFunnelRequest(ap, requestToken, trigger);
10509
10955
  requestUrl = this.applyOpportunityFloor(budgetedUrl);
@@ -10651,6 +11097,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10651
11097
  requests: requests,
10652
11098
  requestRetries: requestRetries,
10653
11099
  gamResponses: count("gam_response_received"),
11100
+ edgeRequests: count("edge_request_sent"),
11101
+ edgeFills: count("edge_fill"),
11102
+ edgeEmptySentinels: count("edge_empty_sentinel"),
11103
+ edgeFallbacks: countPrefix("edge_fallback:"),
10654
11104
  requestsSuppressed: count("request_suppressed"),
10655
11105
  duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
10656
11106
  filled: count("vast_received"),
@@ -10747,6 +11197,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10747
11197
  this.breakSource = void 0;
10748
11198
  this.followUpBaseVastUrl = void 0;
10749
11199
  this.unusableResponsesInBreak = 0;
11200
+ this.resetEdgeStateForBreak();
10750
11201
  adPlayer.stop().catch(function() {});
10751
11202
  if (!alreadyEnded) this.logBreakFunnel(reason);
10752
11203
  this.opportunityFloor = void 0;
@@ -11060,7 +11511,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11060
11511
  });
11061
11512
  return;
11062
11513
  }
11063
- this.timing.consecutiveFailures++;
11514
+ if (this.currentPodSource === "edge") {
11515
+ this.markEdgeExhausted("edge_playback_failed", {
11516
+ reason: reason
11517
+ });
11518
+ } else {
11519
+ this.timing.consecutiveFailures++;
11520
+ }
11064
11521
  var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
11065
11522
  if (diag && !diag.failureReason) diag.failureReason = reason;
11066
11523
  if (this.debug) {
@@ -11091,7 +11548,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11091
11548
  if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
11092
11549
  if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
11093
11550
  this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
11551
+ this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
11094
11552
  this.warnOnInvalidFloorLadder(this.floorLadder.validate());
11553
+ this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
11095
11554
  this.adPlayer = this.createAdPlayer(false);
11096
11555
  this.palNonce = createPalNonceManager();
11097
11556
  this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
@@ -11191,11 +11650,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11191
11650
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11192
11651
  return _this.generatePodVastUrl(base, breakDurationMs);
11193
11652
  },
11653
+ getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11654
+ return _this.edgePodBaseUrl;
11655
+ },
11194
11656
  getFloorSnapshot: function getFloorSnapshot(position) {
11195
- return _this.floorLadder.snapshotFor({
11657
+ return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
11196
11658
  position: position,
11197
11659
  isCtv: _this.isCtvEnvironment()
11198
- });
11660
+ }) : void 0;
11199
11661
  },
11200
11662
  onAdClick: function onAdClick() {
11201
11663
  return _this.palNonce.sendAdClick();
@@ -11246,11 +11708,24 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11246
11708
  return report;
11247
11709
  }
11248
11710
  },
11711
+ {
11712
+ key: "setAdFloorLadderEnabled",
11713
+ value: function setAdFloorLadderEnabled(enabled) {
11714
+ this.floorLadderEnabled = enabled;
11715
+ if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
11716
+ }
11717
+ },
11718
+ {
11719
+ key: "isAdFloorLadderEnabled",
11720
+ value: function isAdFloorLadderEnabled() {
11721
+ return this.floorLadderEnabled;
11722
+ }
11723
+ },
11249
11724
  {
11250
11725
  key: "warnOnInvalidFloorLadder",
11251
11726
  value: function warnOnInvalidFloorLadder(report) {
11252
11727
  var config = this.floorLadder.get();
11253
- if (report.ok || !config.enabled) return;
11728
+ if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
11254
11729
  console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
11255
11730
  errors: report.errors,
11256
11731
  configurationVersion: config.configurationVersion,
@@ -11983,6 +12458,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11983
12458
  this.timing.destroy();
11984
12459
  this.adBreak.clearPendingAdBreak();
11985
12460
  this.placeholder.destroy();
12461
+ 0;
11986
12462
  if (this.timeUpdateHandler) {
11987
12463
  this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
11988
12464
  delete this.timeUpdateHandler;
@@ -12083,12 +12559,14 @@ var CRITICAL_PROPS = [
12083
12559
  "ctvAdRequest",
12084
12560
  "adFloorMinCents",
12085
12561
  "adFloorMaxCents",
12086
- "adFloorStepCents"
12562
+ "adFloorStepCents",
12563
+ "enableEdgePodRequest",
12564
+ "edgePodUrl"
12087
12565
  ];
12088
12566
  var CONTROLS_HIDE_DELAY = 3e3;
12089
12567
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
12090
12568
  var StormcloudVideoPlayerComponent = React.memo(function(props) {
12091
- 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, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, restVideoAttrs = _object_without_properties(props, [
12569
+ 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, 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, [
12092
12570
  "src",
12093
12571
  "autoplay",
12094
12572
  "muted",
@@ -12125,10 +12603,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12125
12603
  "minRemainingMsToStartAd",
12126
12604
  "minRemainingMsToRequestAd",
12127
12605
  "maxNoFillsPerBreak",
12606
+ "adFloorLadderEnabled",
12128
12607
  "adFloorLadder",
12129
12608
  "adFloorMinCents",
12130
12609
  "adFloorMaxCents",
12131
- "adFloorStepCents"
12610
+ "adFloorStepCents",
12611
+ "enableEdgePodRequest",
12612
+ "edgePodUrl"
12132
12613
  ]);
12133
12614
  var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
12134
12615
  var videoRef = useRef(null);
@@ -12279,7 +12760,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12279
12760
  vastMode,
12280
12761
  adFloorMinCents,
12281
12762
  adFloorMaxCents,
12282
- adFloorStepCents
12763
+ adFloorStepCents,
12764
+ enableEdgePodRequest,
12765
+ edgePodUrl
12283
12766
  ]);
12284
12767
  useEffect(function() {
12285
12768
  if (typeof window === "undefined") return;
@@ -12329,10 +12812,13 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12329
12812
  if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
12330
12813
  if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
12331
12814
  if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
12815
+ if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
12332
12816
  if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
12333
12817
  if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
12334
12818
  if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
12335
12819
  if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
12820
+ if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
12821
+ if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
12336
12822
  var player = new StormcloudVideoPlayer(cfg);
12337
12823
  playerRef.current = player;
12338
12824
  appliedFloorLadderKeyRef.current = adFloorLadderKey;
@@ -12381,6 +12867,14 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
12381
12867
  }, [
12382
12868
  adFloorLadderKey
12383
12869
  ]);
12870
+ useEffect(function() {
12871
+ if (!playerRef.current) return;
12872
+ var enabled = adFloorLadderEnabled === true;
12873
+ if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
12874
+ playerRef.current.setAdFloorLadderEnabled(enabled);
12875
+ }, [
12876
+ adFloorLadderEnabled
12877
+ ]);
12384
12878
  useEffect(function() {
12385
12879
  if (!playerRef.current) return;
12386
12880
  var checkAdStatus = function checkAdStatus() {
@@ -13457,6 +13951,9 @@ var StormcloudVideoPlayerComponent = React.memo(function(props) {
13457
13951
  }
13458
13952
  }
13459
13953
  }
13954
+ if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled) {
13955
+ return false;
13956
+ }
13460
13957
  if (JSON.stringify((_prevProps_adFloorLadder = prevProps.adFloorLadder) !== null && _prevProps_adFloorLadder !== void 0 ? _prevProps_adFloorLadder : null) !== JSON.stringify((_nextProps_adFloorLadder = nextProps.adFloorLadder) !== null && _nextProps_adFloorLadder !== void 0 ? _nextProps_adFloorLadder : null)) {
13461
13958
  return false;
13462
13959
  }