@dolby-optiview/ads-sdk-core 1.0.0-beta.1

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 (187) hide show
  1. package/dist/OptiViewAds.d.ts +190 -0
  2. package/dist/OptiViewAds.js +1 -0
  3. package/dist/config/keys.d.ts +23 -0
  4. package/dist/config/keys.js +1 -0
  5. package/dist/diagnostics/DiagnosticBuffer.d.ts +33 -0
  6. package/dist/diagnostics/DiagnosticBuffer.js +1 -0
  7. package/dist/diagnostics/DiagnosticEvent.d.ts +71 -0
  8. package/dist/diagnostics/DiagnosticEvent.js +1 -0
  9. package/dist/diagnostics/debugLog.d.ts +8 -0
  10. package/dist/diagnostics/debugLog.js +1 -0
  11. package/dist/diagnostics/errorCodes.d.ts +45 -0
  12. package/dist/diagnostics/errorCodes.js +1 -0
  13. package/dist/diagnostics/index.d.ts +6 -0
  14. package/dist/diagnostics/index.js +1 -0
  15. package/dist/diagnostics/playbackErrorContext.d.ts +22 -0
  16. package/dist/diagnostics/playbackErrorContext.js +1 -0
  17. package/dist/generated/diagnosticCodes.d.ts +487 -0
  18. package/dist/generated/diagnosticCodes.js +1 -0
  19. package/dist/generated/version.d.ts +5 -0
  20. package/dist/generated/version.js +1 -0
  21. package/dist/id3/buildId3.d.ts +25 -0
  22. package/dist/id3/buildId3.js +1 -0
  23. package/dist/id3/index.d.ts +3 -0
  24. package/dist/id3/index.js +1 -0
  25. package/dist/id3/parseId3Geob.d.ts +28 -0
  26. package/dist/id3/parseId3Geob.js +1 -0
  27. package/dist/index.d.ts +45 -0
  28. package/dist/index.js +1 -0
  29. package/dist/interfaces/PlayerAdapter.d.ts +163 -0
  30. package/dist/interfaces/PlayerAdapter.js +1 -0
  31. package/dist/internal/index.d.ts +1 -0
  32. package/dist/internal/index.js +1 -0
  33. package/dist/server/index.d.ts +20 -0
  34. package/dist/server/index.js +1 -0
  35. package/dist/services/AdBreakSequencer.d.ts +146 -0
  36. package/dist/services/AdBreakSequencer.js +1 -0
  37. package/dist/services/AdPlayerController.d.ts +495 -0
  38. package/dist/services/AdPlayerController.js +1 -0
  39. package/dist/services/BreakScheduler.d.ts +215 -0
  40. package/dist/services/BreakScheduler.js +1 -0
  41. package/dist/services/BreakTransitionTimer.d.ts +48 -0
  42. package/dist/services/BreakTransitionTimer.js +1 -0
  43. package/dist/services/CmcdAdReporter.d.ts +81 -0
  44. package/dist/services/CmcdAdReporter.js +1 -0
  45. package/dist/services/GamPodAdTracker.d.ts +65 -0
  46. package/dist/services/GamPodAdTracker.js +1 -0
  47. package/dist/services/GamPodUrlBuilder.d.ts +30 -0
  48. package/dist/services/GamPodUrlBuilder.js +1 -0
  49. package/dist/services/GamStreamManager.d.ts +67 -0
  50. package/dist/services/GamStreamManager.js +1 -0
  51. package/dist/services/LensReporter.d.ts +30 -0
  52. package/dist/services/LensReporter.js +1 -0
  53. package/dist/services/ManifestService.d.ts +91 -0
  54. package/dist/services/ManifestService.js +1 -0
  55. package/dist/services/MetadataCueTracker.d.ts +44 -0
  56. package/dist/services/MetadataCueTracker.js +1 -0
  57. package/dist/services/PauseAdController.d.ts +108 -0
  58. package/dist/services/PauseAdController.js +1 -0
  59. package/dist/services/RewindRearm.d.ts +109 -0
  60. package/dist/services/RewindRearm.js +1 -0
  61. package/dist/services/SsaiController.d.ts +59 -0
  62. package/dist/services/SsaiController.js +1 -0
  63. package/dist/services/StitcherUrlBuilder.d.ts +34 -0
  64. package/dist/services/StitcherUrlBuilder.js +1 -0
  65. package/dist/services/VastAdManager.d.ts +89 -0
  66. package/dist/services/VastAdManager.js +1 -0
  67. package/dist/services/adPlayer/AdPlayerEvents.d.ts +39 -0
  68. package/dist/services/adPlayer/AdPlayerEvents.js +1 -0
  69. package/dist/services/adPlayer/AdPlayerState.d.ts +98 -0
  70. package/dist/services/adPlayer/AdPlayerState.js +1 -0
  71. package/dist/services/adPlayer/AdPreloader.d.ts +54 -0
  72. package/dist/services/adPlayer/AdPreloader.js +1 -0
  73. package/dist/services/adPlayer/AdStage.d.ts +57 -0
  74. package/dist/services/adPlayer/AdStage.js +1 -0
  75. package/dist/services/adPlayer/AssetParameterResolver.d.ts +44 -0
  76. package/dist/services/adPlayer/AssetParameterResolver.js +1 -0
  77. package/dist/services/adPlayer/AssetPlayback.d.ts +71 -0
  78. package/dist/services/adPlayer/AssetPlayback.js +1 -0
  79. package/dist/services/adPlayer/BreakSequenceDriver.d.ts +46 -0
  80. package/dist/services/adPlayer/BreakSequenceDriver.js +1 -0
  81. package/dist/services/adPlayer/ContentResumeCoordinator.d.ts +44 -0
  82. package/dist/services/adPlayer/ContentResumeCoordinator.js +1 -0
  83. package/dist/services/adPlayer/ContinueContentPlayout.d.ts +26 -0
  84. package/dist/services/adPlayer/ContinueContentPlayout.js +1 -0
  85. package/dist/services/adPlayer/GamPodBridge.d.ts +66 -0
  86. package/dist/services/adPlayer/GamPodBridge.js +1 -0
  87. package/dist/services/adPlayer/PauseAdPresenter.d.ts +60 -0
  88. package/dist/services/adPlayer/PauseAdPresenter.js +1 -0
  89. package/dist/services/adPlayer/PresentationModeTracker.d.ts +66 -0
  90. package/dist/services/adPlayer/PresentationModeTracker.js +1 -0
  91. package/dist/services/adPlayer/SharedElementBreakPlayer.d.ts +54 -0
  92. package/dist/services/adPlayer/SharedElementBreakPlayer.js +1 -0
  93. package/dist/services/adPlayer/VariantSelector.d.ts +38 -0
  94. package/dist/services/adPlayer/VariantSelector.js +1 -0
  95. package/dist/services/adPlayer/connectPauseAd.d.ts +10 -0
  96. package/dist/services/adPlayer/connectPauseAd.js +1 -0
  97. package/dist/services/adPlayer/liveEdge.d.ts +6 -0
  98. package/dist/services/adPlayer/liveEdge.js +1 -0
  99. package/dist/services/assetParameterMacroTable.d.ts +9 -0
  100. package/dist/services/assetParameterMacroTable.js +1 -0
  101. package/dist/services/assetParameterMacros.d.ts +69 -0
  102. package/dist/services/assetParameterMacros.js +1 -0
  103. package/dist/services/breakTiming.d.ts +60 -0
  104. package/dist/services/breakTiming.js +1 -0
  105. package/dist/services/channelSwitch.d.ts +32 -0
  106. package/dist/services/channelSwitch.js +1 -0
  107. package/dist/services/detectDeviceType.d.ts +15 -0
  108. package/dist/services/detectDeviceType.js +1 -0
  109. package/dist/services/detectInsertionMode.d.ts +38 -0
  110. package/dist/services/detectInsertionMode.js +1 -0
  111. package/dist/services/detectPreloadMode.d.ts +13 -0
  112. package/dist/services/detectPreloadMode.js +1 -0
  113. package/dist/services/ed25519.d.ts +19 -0
  114. package/dist/services/ed25519.js +1 -0
  115. package/dist/services/fetchWithTimeout.d.ts +35 -0
  116. package/dist/services/fetchWithTimeout.js +1 -0
  117. package/dist/services/lensBackend.d.ts +16 -0
  118. package/dist/services/lensBackend.js +1 -0
  119. package/dist/services/lensBackendDevelopment.d.ts +1 -0
  120. package/dist/services/lensBackendDevelopment.js +1 -0
  121. package/dist/services/lensBackendProduction.d.ts +9 -0
  122. package/dist/services/lensBackendProduction.js +1 -0
  123. package/dist/services/manifestSignature.d.ts +43 -0
  124. package/dist/services/manifestSignature.js +1 -0
  125. package/dist/services/manifestTrustedKeys.d.ts +9 -0
  126. package/dist/services/manifestTrustedKeys.js +1 -0
  127. package/dist/services/parseBreakManifest.d.ts +15 -0
  128. package/dist/services/parseBreakManifest.js +1 -0
  129. package/dist/services/parseVastCompanion.d.ts +31 -0
  130. package/dist/services/parseVastCompanion.js +1 -0
  131. package/dist/services/parseVastLinear.d.ts +36 -0
  132. package/dist/services/parseVastLinear.js +1 -0
  133. package/dist/services/pictureInPicture.d.ts +28 -0
  134. package/dist/services/pictureInPicture.js +1 -0
  135. package/dist/services/resolveAssetParameters.d.ts +6 -0
  136. package/dist/services/resolveAssetParameters.js +1 -0
  137. package/dist/services/resolveDeliveryMode.d.ts +54 -0
  138. package/dist/services/resolveDeliveryMode.js +1 -0
  139. package/dist/services/resolveGamVendorConfiguration.d.ts +55 -0
  140. package/dist/services/resolveGamVendorConfiguration.js +1 -0
  141. package/dist/services/resolvePauseResumePoint.d.ts +32 -0
  142. package/dist/services/resolvePauseResumePoint.js +1 -0
  143. package/dist/services/resolvePollingDecision.d.ts +24 -0
  144. package/dist/services/resolvePollingDecision.js +1 -0
  145. package/dist/services/resolveResumePoint.d.ts +38 -0
  146. package/dist/services/resolveResumePoint.js +1 -0
  147. package/dist/services/resolveTargetedUri.d.ts +22 -0
  148. package/dist/services/resolveTargetedUri.js +1 -0
  149. package/dist/services/resolveVastAdmission.d.ts +34 -0
  150. package/dist/services/resolveVastAdmission.js +1 -0
  151. package/dist/services/selectVariant.d.ts +47 -0
  152. package/dist/services/selectVariant.js +1 -0
  153. package/dist/services/urlOrigin.d.ts +23 -0
  154. package/dist/services/urlOrigin.js +1 -0
  155. package/dist/session/AdBreakStatusTracker.d.ts +49 -0
  156. package/dist/session/AdBreakStatusTracker.js +1 -0
  157. package/dist/session/BreakLifecycle.d.ts +62 -0
  158. package/dist/session/BreakLifecycle.js +1 -0
  159. package/dist/session/SessionStarter.d.ts +98 -0
  160. package/dist/session/SessionStarter.js +1 -0
  161. package/dist/session/SessionState.d.ts +37 -0
  162. package/dist/session/SessionState.js +1 -0
  163. package/dist/types/BreakManifest.d.ts +335 -0
  164. package/dist/types/BreakManifest.js +1 -0
  165. package/dist/types/Events.d.ts +245 -0
  166. package/dist/types/Events.js +1 -0
  167. package/dist/types/OptiViewAdsConfig.d.ts +425 -0
  168. package/dist/types/OptiViewAdsConfig.js +1 -0
  169. package/dist/types/VendorAdError.d.ts +12 -0
  170. package/dist/types/VendorAdError.js +1 -0
  171. package/dist/vendor/lens-sdk/THIRD-PARTY-NOTICES.txt +266 -0
  172. package/dist/vendor/lens-sdk/compat.d.ts +9 -0
  173. package/dist/vendor/lens-sdk/encoding-cmcd.d.ts +9 -0
  174. package/dist/vendor/lens-sdk/encoding-json.d.ts +9 -0
  175. package/dist/vendor/lens-sdk/encoding.d.ts +42 -0
  176. package/dist/vendor/lens-sdk/environment.d.ts +35 -0
  177. package/dist/vendor/lens-sdk/index.d.ts +3 -0
  178. package/dist/vendor/lens-sdk/index.js +1 -0
  179. package/dist/vendor/lens-sdk/legacy.d.ts +12 -0
  180. package/dist/vendor/lens-sdk/lens-core-Q5lbQGMC.js +1 -0
  181. package/dist/vendor/lens-sdk/lens-global.d.ts +23 -0
  182. package/dist/vendor/lens-sdk/lens.d.ts +21 -0
  183. package/dist/vendor/lens-sdk/transport.d.ts +46 -0
  184. package/dist/vendor/lens-sdk/types.d.ts +218 -0
  185. package/dist/vendor/lens-sdk/user-id.d.ts +5 -0
  186. package/dist/vendor/lens-sdk/validation.d.ts +30 -0
  187. package/package.json +57 -0
@@ -0,0 +1,495 @@
1
+ import { PlayerAdapter } from '../interfaces/PlayerAdapter';
2
+ import { Asset, Break, BreakFormat, Timebase } from '../types/BreakManifest';
3
+ import { AdInsertionType, CreateAdAdapter, DoubleBoxAudio, GamConfig } from '../types/OptiViewAdsConfig';
4
+ import { AssetParameterMacros } from './assetParameterMacros';
5
+ import { ResolvedPreloadMode } from './detectPreloadMode';
6
+ import { ResolvedInsertionMode } from './detectInsertionMode';
7
+ import type { GamSessionIdentity } from './resolveGamVendorConfiguration';
8
+ import { type NoPlayableAssetReason } from './AdBreakSequencer';
9
+ import type { PauseAdResolution } from './PauseAdController';
10
+ import { type Clock } from './BreakScheduler';
11
+ import { PauseAdPresenter } from './adPlayer/PauseAdPresenter';
12
+ /** Creative identity IMA reports for an ad of a GAM pod; absent for other asset kinds. */
13
+ export interface AdCreativeIdentity {
14
+ adId?: string | undefined;
15
+ creativeId?: string | undefined;
16
+ /** 1-based position within the pod (IMA `getAdPodInfo().getAdPosition()` / VAST `sequence`); absent when unreported. */
17
+ podPosition?: number | undefined;
18
+ }
19
+ export interface AdPlayerCallbacks {
20
+ onAdStart: (breakInfo: Break, asset: Asset, index: number, total: number, identity?: AdCreativeIdentity) => void;
21
+ onAdEnd: (breakInfo: Break, asset: Asset, index: number, total: number, identity?: AdCreativeIdentity) => void;
22
+ /** `asset` is undefined for a break-level error (no playable variant, the break never began). */
23
+ onAdError: (breakInfo: Break, asset: Asset | undefined, error: Error) => void;
24
+ onAdTimeUpdate: (breakInfo: Break, asset: Asset, currentTime: number, duration: number) => void;
25
+ onAdWaiting: (breakInfo: Break, asset: Asset) => void;
26
+ onAdPlaying: (breakInfo: Break, asset: Asset) => void;
27
+ onBreakEnd: (breakInfo: Break) => void;
28
+ /**
29
+ * A content-covering break ended before its content pause landed, so no player transition
30
+ * announces the resume. Only the deferred-pause renderers (Kotlin/Swift) fire this.
31
+ */
32
+ onBreakEndedWithoutContentPause?: (breakInfo: Break) => void;
33
+ /** Ad overlay became visible; gates `adbreakbegin` so the AD badge never precedes the first ad frame. */
34
+ onBreakVisible?: (breakInfo: Break) => void;
35
+ /** The current break soft-ended into a chained successor (overlay held, no content resume). */
36
+ onChainedBreakBegin?: (next: Break) => void;
37
+ /** A chained successor resolved but has nothing to play; the SDK must retire it (completeBreak). */
38
+ onChainedBreakSkipped?: (next: Break) => void;
39
+ /**
40
+ * Fired just before the runtime's own post-break resume-seek, so the scheduler does not read
41
+ * the backward step as a DVR seek-back and re-arm the break.
42
+ */
43
+ onContentResumeSeek?: (targetSeconds: number, breakEndSeconds: number) => void;
44
+ /**
45
+ * Brackets a content RELOAD (shared-element break end), so the playhead passing through the
46
+ * start of the freshly loaded stream is not read as a seek back before the break.
47
+ */
48
+ onContentReloading?: (active: boolean) => void;
49
+ }
50
+ export interface PlayBreakOptions {
51
+ /** Seconds to present the break for (tune-in breaks: the remaining time); defaults to `break.duration`. */
52
+ effectiveDurationSec?: number;
53
+ /** Defer the overlay and `onBreakVisible` until the first ad frame renders (held delay:0 fullscreen pre-rolls). */
54
+ firstFrameGate?: boolean;
55
+ }
56
+ /**
57
+ * IMA quartile callbacks. `adIndex`/`totalAds` attribute the milestone to one ad of a
58
+ * multi-ad GAM pod; omitted when there is no per-ad breakdown.
59
+ */
60
+ export interface GamEventCallbacks {
61
+ onAdFirstQuartile?: (breakInfo: Break, asset: Asset, adIndex?: number, totalAds?: number) => void;
62
+ onAdMidpoint?: (breakInfo: Break, asset: Asset, adIndex?: number, totalAds?: number) => void;
63
+ onAdThirdQuartile?: (breakInfo: Break, asset: Asset, adIndex?: number, totalAds?: number) => void;
64
+ }
65
+ export declare class AdPlayerController {
66
+ private static readonly AD_START_BUDGET_MS;
67
+ private static readonly GAM_POD_AD_START_BUDGET_MS;
68
+ private static readonly MIN_AD_START_BUDGET_MS;
69
+ private contentPlayer;
70
+ private container;
71
+ private playerContainer;
72
+ private playerContainerCreatedBySDK;
73
+ private createAdAdapter;
74
+ private adMediaContainer;
75
+ private adPlayer;
76
+ private adContainer;
77
+ private companionElement;
78
+ private staticQuartilesFired;
79
+ private sequencer;
80
+ private pendingAdError;
81
+ private get contentPaused();
82
+ private set contentPaused(value);
83
+ /** Wall-clock ms when a wallclock-timebase break pinned content; 0 when N/A. */
84
+ private preRollHoldActive;
85
+ private preRollHoldHandler;
86
+ private breakContentGateHandler;
87
+ private get firstFrameGateActive();
88
+ private set firstFrameGateActive(value);
89
+ private get firstFrameGateShown();
90
+ private set firstFrameGateShown(value);
91
+ private get firstFrameRejector();
92
+ private set firstFrameRejector(value);
93
+ private readonly state;
94
+ readonly pauseAdPresenter: PauseAdPresenter;
95
+ private readonly assetParameters;
96
+ private readonly gamPodBridge;
97
+ private readonly adStage;
98
+ private readonly preloader;
99
+ private readonly assetPlayback;
100
+ private readonly breakSequenceDriver;
101
+ private readonly variantSelector;
102
+ private readonly adPlayerEvents;
103
+ private get gamEventCallbacks();
104
+ /** Grace before the live resume releases the scheduler's reload guard — see endBreak(). */
105
+ private readonly RESUME_GUARD_RELEASE_GRACE_MS;
106
+ /**
107
+ * The panel frees the displaced decoder asynchronously; resuming in the same task
108
+ * intermittently fails with MEDIA_ERR_DECODE on Tizen — see endBreak().
109
+ */
110
+ private readonly SINGLE_DECODER_RESUME_DELAY_MS;
111
+ /** Post-restore progress check — see armSharedRestoreWatchdog(). Mirrors the iOS runtime. */
112
+ private debug;
113
+ /**
114
+ * Early-return state (manifest spec "Break removal"): suppresses the chained hand-off and
115
+ * overrides the resume point to `break.start + offset`, even in `replacement` mode.
116
+ */
117
+ private abortingBreak;
118
+ private overlayImageEl;
119
+ private imageAssetTimer;
120
+ private get preloadedBreakId();
121
+ private set preloadedBreakId(value);
122
+ private chainResolver;
123
+ private transitionPhaseReporter;
124
+ private chaining;
125
+ private get vastAdManager();
126
+ private set vastAdManager(value);
127
+ /** Runtime pod position IMA reported for the VAST ad whose `adbegin` is about to be emitted. */
128
+ private vastPodPosition;
129
+ private diagnoseHandler;
130
+ /**
131
+ * One closure releases both the `seeked` listener and its timeout; a leaked timer of
132
+ * exactly this shape held jest and its container open.
133
+ */
134
+ /**
135
+ * GAM identity the IMA/DAI session was opened under. A pod URL built from a different
136
+ * identity is rejected by Google (HTTP 410), so {@link buildGamUrl} checks against it.
137
+ */
138
+ private playerContainerOriginalStyle;
139
+ private companionRemoveTimer;
140
+ private adFadeTimer;
141
+ private readonly presentationModes;
142
+ private readonly sharedElementPlayer;
143
+ private readonly resumeCoordinator;
144
+ private syncing;
145
+ private contentVolumeHandler;
146
+ private adVolumeChangeHandler;
147
+ private volumeChangeCallback;
148
+ private stage;
149
+ private resizeObserver;
150
+ private contentVideoElement;
151
+ private contentVideoGeometryHandler;
152
+ private contentVideoMutationObserver;
153
+ private preloadMode;
154
+ private insertionMode;
155
+ /**
156
+ * Manifest-spec platform-capability fallback: on handheld/tablet web a `double` break renders
157
+ * as a single fullscreen ad, while the reported format stays `double`.
158
+ */
159
+ private readonly singleSurfaceDevice;
160
+ /** Declared format of the selected variant, latched at break start (selection never re-runs mid-break). */
161
+ private currentSelectedFormat;
162
+ private get currentBreak();
163
+ private set currentBreak(value);
164
+ private get currentAsset();
165
+ private set currentAsset(value);
166
+ private get callbacks();
167
+ private set callbacks(value);
168
+ private get isPlaying();
169
+ private set isPlaying(value);
170
+ private get effectiveBreakDurationSec();
171
+ private set effectiveBreakDurationSec(value);
172
+ private get adBreakCutSafetyMarginSec();
173
+ private set adBreakCutSafetyMarginSec(value);
174
+ private get durationTimer();
175
+ private set durationTimer(value);
176
+ private get adInsertionType();
177
+ private set adInsertionType(value);
178
+ private get breakTimebase();
179
+ private set breakTimebase(value);
180
+ /**
181
+ * Anchor the resume offset is added to. Anchoring here rather than on `Break.start` keeps the
182
+ * rule timebase-free: on wallclock, `start` is an ISO timestamp.
183
+ */
184
+ private readonly clock;
185
+ /**
186
+ * The SDK's own ad player bound to the content element for a shared-element break. Leaving
187
+ * the swap to the content engine loses the Safari PiP window (Shaka's `load()` detaches the
188
+ * element); replacing the source ourselves keeps it. Null when `createAdAdapter` ignores the
189
+ * element argument, in which case the `contentPlayer.load()` path still runs.
190
+ */
191
+ /** Whichever adapter carries the running shared-element ad — the SDK's, or the content's. */
192
+ /**
193
+ * Bounds how long a shared-element ad may sit at zero frames after `play()` resolved;
194
+ * without it a never-started ad produced no `adbegin`, error or diagnostic.
195
+ */
196
+ /**
197
+ * Set when the content element is claimed for an ad. The ad's listeners are armed only after
198
+ * the media swap resolves, so this covers the window in which a PiP entry would otherwise
199
+ * load the same creative onto the same element twice.
200
+ */
201
+ /** Seconds behind the live edge when the ad took the element; null for VOD. */
202
+ /**
203
+ * THEOplayer replaces its own `<video>` on a source change; resolving the element fresh at
204
+ * teardown would unbind from the new node and leave listeners on the dead one.
205
+ */
206
+ /** True while the PiP window has been moved to the ad element by this controller. */
207
+ /**
208
+ * Set at break start or by a mid-break switch, cleared per break. Leaving PiP mid-break does
209
+ * not undo it: re-boxing a rolling creative would re-fetch a skipped companion and un-pause content.
210
+ */
211
+ private doubleBoxAudio;
212
+ private audioFocus;
213
+ constructor(contentPlayer: PlayerAdapter, container: HTMLElement, playerContainer: HTMLElement | undefined, createAdAdapter: CreateAdAdapter, debug?: boolean, gamConfig?: GamConfig, preloadMode?: ResolvedPreloadMode, insertionMode?: ResolvedInsertionMode, adBreakCutSafetyMarginSec?: number, doubleBoxAudio?: DoubleBoxAudio, singleSurfaceDevice?: boolean,
214
+ /** Injected so drift correction is deterministic under fake timers; reuses the scheduler's `Clock`. */
215
+ clock?: Clock);
216
+ setGamEventCallbacks(callbacks: GamEventCallbacks): void;
217
+ setDiagnoseHandler(fn: (code: string, message: string, context?: Record<string, unknown>) => void): void;
218
+ private diagnose;
219
+ /**
220
+ * Pause content while an immediate (delay:0) pre-roll is pending and re-pause on any `playing`
221
+ * until {@link releaseContentHold}. Only for formats that fully cover content. Idempotent.
222
+ */
223
+ holdContentForPreRoll(breakInfo: Break): void;
224
+ /** Detach the pre-roll re-pause listener; the break then owns the content pause/resume. Idempotent. */
225
+ releaseContentHold(): void;
226
+ /**
227
+ * Re-pause content on any `playing` while `contentPaused`, so a late app `play()` or a
228
+ * buffer auto-resume cannot leak content frames behind the overlay. Idempotent.
229
+ */
230
+ private gateContentForBreak;
231
+ private clearContentGate;
232
+ /** `null` disables chaining: breaks then always hard-end regardless of how close the next one is. */
233
+ setChainResolver(resolver: ((currentBreakId: string) => Break | null) | null): void;
234
+ /** Only wired by the SDK in debug mode, so production reports keep their shape. */
235
+ setTransitionPhaseReporter(reporter: ((name: string) => void) | null): void;
236
+ /** No-op when no reporter is wired or no transition is in flight. */
237
+ private reportPhase;
238
+ /**
239
+ * `insertionType` is `undefined` when the integrator did not set one; do not substitute a
240
+ * default, or the manifest can never drive the resume point.
241
+ */
242
+ setBreakResumePolicy(insertionType: AdInsertionType | undefined, timebase: Timebase, continueContentDuringBreak?: boolean): void;
243
+ /** One-time setup: creates the ad <video>, calls createAdAdapter and mounts the overlay container. */
244
+ initialize(): void;
245
+ /**
246
+ * Creates a fresh IMA session; call once the break manifest has been fetched (the identity
247
+ * comes from its `vendorConfiguration`). The manifest layer is per asset and applied in {@link buildGamUrl}.
248
+ */
249
+ startGamSession(identity: GamSessionIdentity, assetParameters?: Record<string, string>): Promise<void>;
250
+ endGamSession(): void;
251
+ /**
252
+ * Record the session layer of the asset parameters (`SessionConfig.assetParameters`) for the
253
+ * VAST path, which needs no vendor session to consume it.
254
+ */
255
+ setSessionAssetParameters(params: Record<string, string> | undefined): void;
256
+ setManifestAssetParameters(params: Record<string, string> | undefined): void;
257
+ /**
258
+ * Replace the live-update layer of the asset parameters for future breaks: VAST tag URLs
259
+ * re-resolve the layers per asset, and an active IMA session gets the new map pushed right
260
+ * away. Stored as well as pushed: each later asset re-resolves the three layers, so a
261
+ * mid-break update applies from the next asset on.
262
+ */
263
+ updateAssetParameters(params: Record<string, string>): void;
264
+ /** The live-update layer last set by {@link updateAssetParameters}; `endGamSession()` clears it. */
265
+ get updatedAssetParameters(): Record<string, string> | undefined;
266
+ /** Record the session's customer macros (`SessionConfig.assetParameterMacros`). */
267
+ setSessionAssetParameterMacros(macros: AssetParameterMacros | undefined): void;
268
+ private buildVastTagUrl;
269
+ private pushAssetParameters;
270
+ private setupOverlay;
271
+ /** Always creates a fresh IMA session. */
272
+ private isGamPodAsset;
273
+ private isExpandingPodAsset;
274
+ private beginGamPodTracking;
275
+ private fallBackToPodLevelReporting;
276
+ private resetGamPodTracking;
277
+ private emitGamPodSteps;
278
+ /**
279
+ * True unless a host opted out with `gam: { enabled: false }`. Not gated on a GamConfig: the
280
+ * runtime links IMA unconditionally, and requiring one made React Native hosts skip GAM silently.
281
+ */
282
+ isGamEnabled(): boolean;
283
+ isGamReady(): boolean;
284
+ /** Used by the SDK to decide whether `adbreakbegin` can be first-frame gated. */
285
+ isOverlayInsertion(): boolean;
286
+ /**
287
+ * Used by both insertion paths; on the shared-element path the ad plays through the content
288
+ * element, and `adbreakstatus.breakRemainingSec` is driven by this same callback.
289
+ */
290
+ /** A still image has no media timeline, so it contributes its declared duration instead. */
291
+ private settleAssetProgress;
292
+ private reportAdProgress;
293
+ private setupEventListeners;
294
+ preload(breakInfo: Break): Promise<void>;
295
+ private renderLshapeContentBackdrop;
296
+ /**
297
+ * `adaptive` (iPhone iOS 17.1+/MMS) maps to `shared-element` while the content video is in
298
+ * OS-native fullscreen (DOM overlays cannot render there) and to `overlay` otherwise.
299
+ */
300
+ /**
301
+ * Public because the mechanism changes what an observer sees: with `shared-element` the ad
302
+ * is the content element, so content position keeps advancing and the PiP window stays `content`.
303
+ */
304
+ currentInsertionMode(): 'overlay' | 'shared-element';
305
+ private effectiveInsertionMode;
306
+ private isContentPictureInPicture;
307
+ /**
308
+ * THEOplayer replaces its media element on a source change, which the SDK causes on every
309
+ * shared-element break; listeners left on the old node never see PiP transitions again.
310
+ * PiP state is re-read from the new element rather than reset.
311
+ */
312
+ private rebindContentElementIfSwapped;
313
+ private teardownFullscreenTracking;
314
+ /** Remove the listeners registered by setupPictureInPictureTracking(). */
315
+ private teardownPictureInPictureTracking;
316
+ /** Public answer behind `OptiViewAds.getPresentationState()`, so integrators never infer it from the DOM. */
317
+ isPictureInPicture(): boolean;
318
+ /**
319
+ * Distinct from {@link isShowingAd}, which is about the media: only this tells a harness the
320
+ * viewer is looking at content while the ad plays (Safari refuses the hand-over silently).
321
+ */
322
+ pictureInPictureOwner(): 'content' | 'ad' | null;
323
+ /**
324
+ * Differs from {@link isAdPlaying} for an `lshape_content` break in picture-in-picture: active,
325
+ * yet showing only the main content. Mirrors the Kotlin `AdRenderer.isShowingAd`.
326
+ */
327
+ isShowingAd(): boolean;
328
+ /** Latched at break start: a PiP entry after start must not flip which variant is reasoned about. */
329
+ private currentDeclaredFormat;
330
+ playBreak(breakInfo: Break, callbacks: AdPlayerCallbacks, options?: PlayBreakOptions): Promise<void>;
331
+ /** Read from the element's seekable range, the one place MSE and native playback agree on the edge. */
332
+ /**
333
+ * Latest position the engine will hold on live content, or null when unknown and on VOD.
334
+ * Seeking past the engine's minimum live offset is quietly pulled back, so the resume target
335
+ * is clamped to it. Liveness is `!Number.isFinite(duration)` of the content, not the break's
336
+ * timebase (ID3/Anvato breaks are PTS). `null` from the adapter means no clamp: a guessed
337
+ * holdback would be wrong on any stream whose segments are not 6s.
338
+ */
339
+ /** Read from the element's seekable range, the same source {@link liveEdgeDistanceSec} trusts. */
340
+ /**
341
+ * `Number.isFinite` is not enough: MAX_SAFE_INTEGER passes it. Anything a day beyond the
342
+ * playhead is a sentinel, not a DVR window.
343
+ */
344
+ /**
345
+ * Move the paused content player onto its resume point while the ad plays, as soon as the
346
+ * live window reaches it. A single seek at `adbreakend` targets a position that may not
347
+ * exist yet on live and gets refused; THEOads does the same
348
+ * (`PlayerController.seekContentToResumePoint`). No-op on VOD or once positioned.
349
+ */
350
+ /**
351
+ * Let content play (muted, behind the ad) for the last stretch so it arrives at its resume
352
+ * point instead of being seeked there: a paused player starves its playlist refresh, a
353
+ * playing one pulls segments aggressively. Started only when the remaining ad time covers
354
+ * the gap; overshoot is bounded by one ad tick. Live only.
355
+ */
356
+ /**
357
+ * Idempotent. `keepPlaying` at break end avoids the decoder's start-up (~450ms) of a pause
358
+ * and play() on the right frame; on abort/teardown content must stop.
359
+ */
360
+ /** True while content is playing behind the ad, so the resume can hand over without a stop. */
361
+ private get resumeHandoverInMotion();
362
+ /**
363
+ * Computed from the declared length because `adSecondsPlayedThisBreak` is still growing
364
+ * mid-break (THEOads pre-seeks to a `plannedResumeTime` too). {@link applyResumeSeek}
365
+ * corrects at break end if the two differ by more than a frame.
366
+ */
367
+ /** Attached to both the pre-positioned and the clamped path, since which one fires is the outcome to explain. */
368
+ /** Release an armed resume-landing probe, if any. Safe to call repeatedly. */
369
+ /**
370
+ * Report where the resume-seek landed, as distinct from where it was aimed. Report-only.
371
+ * The listener is attached before the seek and reads `currentTime` in the handler, because
372
+ * playback resumes right after. Timeout is a normal outcome (`landed: null`): a seek to the
373
+ * current position fires no `seeked` on several engines.
374
+ */
375
+ /** Gives up rather than hanging: a missed seek leaves the viewer at the live edge. */
376
+ private reapplyAdContainerLayout;
377
+ /**
378
+ * Entering PiP while an ad is already on screen hands the window straight to the ad;
379
+ * otherwise the window shows the paused content element while the ad plays on the page.
380
+ * Fire-and-forget (runs from a DOM event handler); a refused transfer is diagnosed inside.
381
+ */
382
+ private adoptPictureInPictureMidBreak;
383
+ /** Only when we took it: a viewer who opened PiP on the ad or closed the window must not have one forced back open. */
384
+ private restorePictureInPictureToContent;
385
+ private continueContentDuringBreakReason;
386
+ private shouldPauseContent;
387
+ private selectionInputs;
388
+ /**
389
+ * The SDK's pre-`adbreakbegin` gate: a non-null reason means no adbreakbegin/adbreakend,
390
+ * aderror + DA-BREAK-NO-PLAYABLE-ASSET instead, and content keeps playing.
391
+ */
392
+ breakNothingToPlayReason(breakInfo: Break): NoPlayableAssetReason | null;
393
+ /**
394
+ * Raw `format` strings of variants skipped as unrecognised; `''` means absent. Read at the
395
+ * break-start gates only, because selection runs several times per break.
396
+ */
397
+ unknownVariantFormatsOf(breakInfo: Break): string[];
398
+ /** Called from the break-start gates; a break with nothing unknown emits nothing. */
399
+ diagnoseUnknownVariantFormats(breakInfo: Break): void;
400
+ /** What the public events report as "declared" before any PiP mapping. */
401
+ declaredFormatOf(breakInfo: Break): BreakFormat | undefined;
402
+ private getVariant;
403
+ private applyLayout;
404
+ /**
405
+ * For double/lshape_ad/lshape_content, playerContainer keeps its break-time z-index (101)
406
+ * during the transition so it stays above the still-fading adContainer (z:100) and companion
407
+ * (z:99); otherwise the backdrop cuts to black instead of content growing back.
408
+ */
409
+ private restoreLayout;
410
+ /**
411
+ * Selection-aware: without the inputs, a device-targeted variant's assets would read as empty
412
+ * on exactly the device it targets.
413
+ */
414
+ private getAssets;
415
+ private playAsset;
416
+ private clearOverlayImage;
417
+ showPauseImage(resolution: PauseAdResolution): Promise<void>;
418
+ /** A video creative is stopped immediately so it does not keep playing under the fade. */
419
+ hidePauseImage(): void;
420
+ private drive;
421
+ private emitStep;
422
+ private resolveAssetUri;
423
+ /** Null (with a warning) if GAM is not configured. */
424
+ private buildGamUrl;
425
+ private resolveUri;
426
+ private adPlayerStreamRemainingSec;
427
+ private onAdEnded;
428
+ private toAdError;
429
+ private onAdError;
430
+ private endBreak;
431
+ /** Exposed so `clickAd()` can name the creative the viewer actually clicked. */
432
+ currentAdAsset(): Asset | null;
433
+ /**
434
+ * Same path as the break-cut timer: the sequencer's `break-elapsed` emits the in-flight ad's
435
+ * `adend` before `adbreakend`, so a skipped break is indistinguishable in the event stream
436
+ * (e2e G3). Gating is the caller's job: `OptiViewAds.skipAd()` owns `controls.skipOffset`.
437
+ */
438
+ skipBreak(): void;
439
+ /**
440
+ * The manifest spec's "early return": same sequencer-driven teardown as {@link skipBreak}, but
441
+ * content resumes at `break.start + resumeOffsetSec` (forcing the seek even in `replacement`
442
+ * mode, since the rest of the replaced window no longer exists) and chaining is suppressed
443
+ * (the successor is anchored to the removed break's scheduled end). Live needs no override:
444
+ * `restoreLiveLatency` gives back exactly the elapsed wall time.
445
+ */
446
+ abortBreak(resumeOffsetSec: number): void;
447
+ /**
448
+ * Pausing the ad media is what stops its audio — removing the overlay from the DOM does not
449
+ * reliably stop a playing element. Unlike {@link endBreak} it does not resume content: the
450
+ * caller owns the content lifecycle once the session is ending. No-op when idle.
451
+ */
452
+ stopActiveBreak(): void;
453
+ private resolveChainedSuccessor;
454
+ private advanceToChainedBreak;
455
+ /**
456
+ * Warms the HTTP cache (and a detached prefetch if the adapter supports it) without attaching
457
+ * a second MediaSource — safe on single-decoder Smart TVs. GAM successors are skipped: their
458
+ * pod URLs carry per-break targeting that must be requested fresh.
459
+ */
460
+ private preloadChainedSuccessor;
461
+ private revealFirstFrame;
462
+ /**
463
+ * Resolves `true` on success, `false` past the budget (then `aderror` was already raised and
464
+ * the caller must stop); a rejecting load is rethrown into `playAsset`'s catch. Needed because
465
+ * a host that never answers leaves `load()` pending, so `waitForFirstFrame()` is never armed.
466
+ * `onAdError` is called rather than thrown: `playAsset`'s catch swallows errors while
467
+ * `firstFrameGateActive && firstFrameResolver === null`, which is the default before the wait is armed.
468
+ */
469
+ private armAdStartBudget;
470
+ private remainingAdStartBudgetMs;
471
+ private loadWithinBudget;
472
+ /** Resolves on the first `playing` event, rejects on error/timeout. */
473
+ private waitForFirstFrame;
474
+ /** Called when the break ends before the first frame arrives. */
475
+ private clearFirstFrame;
476
+ private show;
477
+ private hide;
478
+ isAdPlaying(): boolean;
479
+ /**
480
+ * Reads/writes the effective audio owner — the ad player during a break, content otherwise.
481
+ * The `volumechange` sync mirrors onto the other side; a CSAI ad is bridged via
482
+ * {@link VastAdManager.setMuted} (IMA manages its own audio path). With an active
483
+ * {@link audioFocus} only the focused side is targeted.
484
+ */
485
+ get muted(): boolean;
486
+ set muted(value: boolean);
487
+ /** 0-1. See {@link muted} for which player is the effective target. */
488
+ get volume(): number;
489
+ set volume(value: number);
490
+ /** Invoked with the current {@link muted}/{@link volume} whenever either changes. Pass `null` to detach. */
491
+ setVolumeChangeCallback(callback: ((muted: boolean, volume: number) => void) | null): void;
492
+ private notifyVolumeChange;
493
+ destroy(): void;
494
+ private log;
495
+ }
@@ -0,0 +1 @@
1
+ import{BreakFormat as e,Timebase as t,isPostRollBreak as r}from"../types/BreakManifest";import{DEFAULT_AD_BREAK_CUT_SAFETY_MARGIN_SEC as a,DEFAULT_DOUBLE_BOX_AUDIO as i}from"../types/OptiViewAdsConfig";import{pipOverridesFormat as s,pipSuppressesBackdrop as n}from"./pictureInPicture";import{AdBreakSequencer as o,assetsOfVariant as l,resolveBreakFormat as d}from"./AdBreakSequencer";import{selectVariantDetailed as h}from"./selectVariant";import{debugLog as u}from"../diagnostics/debugLog";import{systemClock as c}from"./BreakScheduler";import{createAdPlayerState as m}from"./adPlayer/AdPlayerState";import{PauseAdPresenter as g}from"./adPlayer/PauseAdPresenter";import{AssetParameterResolver as P}from"./adPlayer/AssetParameterResolver";import{GamPodBridge as y}from"./adPlayer/GamPodBridge";import{AdStage as p}from"./adPlayer/AdStage";import{AdPreloader as A}from"./adPlayer/AdPreloader";import{PresentationModeTracker as C}from"./adPlayer/PresentationModeTracker";import{SharedElementBreakPlayer as v}from"./adPlayer/SharedElementBreakPlayer";import{ContentResumeCoordinator as k}from"./adPlayer/ContentResumeCoordinator";import{AssetPlayback as f}from"./adPlayer/AssetPlayback";import{BreakSequenceDriver as S}from"./adPlayer/BreakSequenceDriver";import{VariantSelector as B}from"./adPlayer/VariantSelector";import{AdPlayerEvents as E}from"./adPlayer/AdPlayerEvents";export class AdPlayerController{get contentPaused(){return this.state.contentPaused}set contentPaused(e){this.state.contentPaused=e}get firstFrameGateActive(){return this.state.firstFrameGateActive}set firstFrameGateActive(e){this.state.firstFrameGateActive=e}get firstFrameGateShown(){return this.state.firstFrameGateShown}set firstFrameGateShown(e){this.state.firstFrameGateShown=e}get firstFrameRejector(){return this.state.firstFrameRejector}set firstFrameRejector(e){this.state.firstFrameRejector=e}get gamEventCallbacks(){return this.gamPodBridge.eventCallbacks}get preloadedBreakId(){return this.state.preloadedBreakId}set preloadedBreakId(e){this.state.preloadedBreakId=e}get vastAdManager(){return this.state.vastAdManager}set vastAdManager(e){this.state.vastAdManager=e}get currentBreak(){return this.state.currentBreak}set currentBreak(e){this.state.currentBreak=e}get currentAsset(){return this.state.currentAsset}set currentAsset(e){this.state.currentAsset=e}get callbacks(){return this.state.callbacks}set callbacks(e){this.state.callbacks=e}get isPlaying(){return this.state.isPlaying}set isPlaying(e){this.state.isPlaying=e}get effectiveBreakDurationSec(){return this.state.effectiveBreakDurationSec}set effectiveBreakDurationSec(e){this.state.effectiveBreakDurationSec=e}get adBreakCutSafetyMarginSec(){return this.state.adBreakCutSafetyMarginSec}set adBreakCutSafetyMarginSec(e){this.state.adBreakCutSafetyMarginSec=e}get durationTimer(){return this.state.durationTimer}set durationTimer(e){this.state.durationTimer=e}get adInsertionType(){return this.state.adInsertionType}set adInsertionType(e){this.state.adInsertionType=e}get breakTimebase(){return this.state.breakTimebase}set breakTimebase(e){this.state.breakTimebase=e}constructor(e,t,r,s,n=!1,o,l="parallel",d="overlay",h=a,u=i,b=!1,T=c){this.playerContainerCreatedBySDK=!1,this.adMediaContainer=null,this.adPlayer=null,this.adContainer=null,this.companionElement=null,this.staticQuartilesFired=new Set,this.sequencer=null,this.pendingAdError=null,this.preRollHoldActive=!1,this.preRollHoldHandler=null,this.breakContentGateHandler=null,this.RESUME_GUARD_RELEASE_GRACE_MS=2e3,this.SINGLE_DECODER_RESUME_DELAY_MS=300,this.abortingBreak=!1,this.overlayImageEl=null,this.imageAssetTimer=null,this.chainResolver=null,this.transitionPhaseReporter=null,this.chaining=!1,this.diagnoseHandler=null,this.playerContainerOriginalStyle="",this.companionRemoveTimer=null,this.adFadeTimer=null,this.syncing=!1,this.contentVolumeHandler=null,this.adVolumeChangeHandler=null,this.volumeChangeCallback=null,this.stage=null,this.resizeObserver=null,this.contentVideoElement=null,this.contentVideoGeometryHandler=null,this.contentVideoMutationObserver=null,this.singleSurfaceDevice=!1,this.currentSelectedFormat=void 0,this.audioFocus=null,this.state=m(),this.state.playerContainer=r??null,this.clock=T,this.singleSurfaceDevice=b,this.contentPlayer=e,this.adBreakCutSafetyMarginSec=h,this.doubleBoxAudio=u,this.container=t,r&&(this.playerContainer=r),this.createAdAdapter=s,this.debug=n,this.state.gamConfig=o,this.preloadMode=l,this.insertionMode=d,this.pauseAdPresenter=new g({contentPlayer:this.contentPlayer,getStage:()=>this.stage,resolveUri:e=>this.resolveUri(e),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.assetParameters=new P(this.state,{contentPlayer:this.contentPlayer,container:this.container,getGamStreamManager:()=>this.state.gamStreamManager,getCurrentBreak:()=>this.currentBreak,getEffectiveBreakDuration:()=>this.effectiveBreakDurationSec,diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.gamPodBridge=new y(this.state,{contentPlayer:this.contentPlayer,debug:this.debug,getAdPlayer:()=>this.adPlayer,getAdContainer:()=>this.adContainer,isSharedElement:()=>"shared-element"===this.effectiveInsertionMode(),getCurrentBreak:()=>this.currentBreak,getCurrentAsset:()=>this.currentAsset,getEffectiveBreakDuration:()=>this.effectiveBreakDurationSec,getAdPlayerStreamRemainingSec:()=>this.adPlayerStreamRemainingSec(),emitStep:e=>this.emitStep(e),emitAdStart:(e,t,r,a,i)=>this.callbacks?.onAdStart(e,t,r,a,i),emitAdEnd:(e,t,r,a,i)=>this.callbacks?.onAdEnd(e,t,r,a,i),onAdEnded:()=>this.onAdEnded(),pushAssetParameters:(e,t)=>this.pushAssetParameters(e,t),resolveSessionAdTagParameters:()=>this.assetParameters.resolveSessionAdTagParameters(),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.adStage=new p({contentPlayer:this.contentPlayer,container:this.container,getPlayerContainer:()=>this.playerContainer,setPlayerContainer:e=>{this.playerContainer=e},setPlayerContainerOriginalStyle:e=>{this.playerContainerOriginalStyle=e},onPlayerContainerCreated:()=>{this.playerContainerCreatedBySDK=!0},getStage:()=>this.stage,setStage:e=>{this.stage=e},getContentVideo:()=>this.contentVideoElement,setContentVideo:e=>{this.contentVideoElement=e},getAdContainer:()=>this.adContainer,setAdContainer:e=>{this.adContainer=e},getAdMediaContainer:()=>this.adMediaContainer,setAdMediaContainer:e=>{this.adMediaContainer=e},setAdPlayer:e=>{this.adPlayer=e},createAdAdapter:e=>this.createAdAdapter(e),setupEventListeners:()=>this.setupEventListeners(),resizeVast:()=>this.vastAdManager?.resize(),getVariant:e=>this.getVariant(e),getCurrentBreak:()=>this.currentBreak,resolveUri:e=>this.resolveUri(e),getCompanion:()=>this.companionElement,setCompanion:e=>{this.companionElement=e},getOverlayImage:()=>this.overlayImageEl,setOverlayImage:e=>{this.overlayImageEl=e},getImageAssetTimer:()=>this.imageAssetTimer,setImageAssetTimer:e=>{this.imageAssetTimer=e},isChaining:()=>this.chaining,log:(...e)=>this.log(...e)}),this.preloader=new A({state:this.state,clock:this.clock,adStartBudgetMs:AdPlayerController.AD_START_BUDGET_MS,gamPodAdStartBudgetMs:AdPlayerController.GAM_POD_AD_START_BUDGET_MS,minAdStartBudgetMs:AdPlayerController.MIN_AD_START_BUDGET_MS,debug:this.debug,isPlaying:()=>this.isPlaying,preloadMode:this.preloadMode,effectiveInsertionMode:()=>this.effectiveInsertionMode(),getVariant:e=>this.getVariant(e),getAssets:e=>this.getAssets(e),resolveUri:e=>this.resolveUri(e),resolveAssetUri:(e,t)=>this.resolveAssetUri(e,t),getCompanionVariant:e=>this.getVariant(e),getAdPlayer:()=>this.adPlayer,getAdContainer:()=>this.adContainer,buildVastTagUrl:(e,t)=>this.buildVastTagUrl(e,t),resolveChainedSuccessor:e=>this.resolveChainedSuccessor(e),show:()=>this.show(),reapplyAdContainerLayout:e=>this.reapplyAdContainerLayout(e),getCurrentBreak:()=>this.currentBreak,onBreakVisible:e=>this.callbacks?.onBreakVisible?.(e),onAdError:e=>this.onAdError(e),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.presentationModes=new C(this.state,{contentPlayer:this.contentPlayer,getAdPlayer:()=>this.adPlayer,insertionMode:this.insertionMode,getCurrentBreak:()=>this.currentBreak,getCurrentFormat:()=>this.currentSelectedFormat,isSharedElementActive:()=>this.state.sharedAdClaimActive,getVariant:e=>this.getVariant(e),isAdPlaying:()=>this.isAdPlaying(),hasCurrentAsset:()=>null!==this.currentAsset,contentSourceIsReloadable:()=>null!==this.sharedElementPlayer.restorableContentSource(),adoptPictureInPictureMidBreak:()=>this.adoptPictureInPictureMidBreak(),restoreLayout:e=>this.restoreLayout(e),applyLayout:e=>this.applyLayout(e),show:()=>this.show(),playAdThroughContentElement:()=>this.sharedElementPlayer.playAdThroughContentElement(),getContentPositionAtBreakStart:()=>this.state.contentPositionAtBreakStart,setContentPositionAtBreakStart:e=>{this.state.contentPositionAtBreakStart=e},gateContentForBreak:()=>this.gateContentForBreak(),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.resumeCoordinator=new k(this.state,{contentPlayer:this.contentPlayer,clock:this.clock,getInsertionMode:()=>this.effectiveInsertionMode(),gateContentForBreak:()=>this.gateContentForBreak(),clearContentGate:e=>this.clearContentGate(e),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.sharedElementPlayer=new v(this.state,{contentPlayer:this.contentPlayer,getAdPlayer:()=>this.adPlayer,resolveAssetUri:(e,t)=>this.resolveAssetUri(e,t),liveEdgeDistanceSec:()=>this.resumeCoordinator.liveEdgeDistanceSec(),rebindContentElementIfSwapped:()=>this.rebindContentElementIfSwapped(),createAdAdapter:(e,t)=>this.createAdAdapter(e,t),reportAdProgress:e=>this.reportAdProgress(e),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e),clearContentGate:()=>this.clearContentGate(),hide:()=>this.hide(),waitForLiveEdge:()=>this.resumeCoordinator.waitForLiveEdge(),getVariant:e=>this.getVariant(e),getAssets:e=>this.getAssets(e)}),this.variantSelector=new B(this.state,{getEffectiveInsertionMode:()=>this.effectiveInsertionMode(),singleSurfaceDevice:this.singleSurfaceDevice,preloadMode:this.preloadMode,getIsContentPictureInPicture:()=>this.isContentPictureInPicture(),getIsGamReady:()=>this.isGamReady(),getSupportsParallelBuffering:()=>this.contentPlayer.supportsParallelBuffering,diagnose:(e,t,r)=>this.diagnose(e,t,r)}),this.assetPlayback=new f(this.state,{getAdPlayer:()=>this.adPlayer,getAdContainer:()=>this.adContainer,getAdMediaContainer:()=>this.adMediaContainer,clearStaticQuartiles:()=>this.staticQuartilesFired.clear(),getVariant:e=>this.getVariant(e),getGamEventCallbacks:()=>this.gamEventCallbacks,getSequencer:()=>this.sequencer,debug:this.debug,resolveUri:e=>this.resolveUri(e),buildGamUrl:(e,t)=>this.buildGamUrl(e,t),buildVastTagUrl:(e,t)=>this.buildVastTagUrl(e,t),onAdError:e=>this.onAdError(e),onAdEnded:()=>this.onAdEnded(),drive:e=>this.drive(e),clearOverlayImage:()=>this.clearOverlayImage(),revealFirstFrame:()=>this.preloader.revealFirstFrame(),transferPictureInPictureToAd:()=>this.presentationModes.transferPictureInPictureToAd(),isGamPodAsset:e=>this.isGamPodAsset(e),beginGamPodTracking:e=>this.beginGamPodTracking(e),recordAdProgress:e=>this.adPlayerEvents.recordAdProgress(e),reportPhase:e=>this.reportPhase(e),armAdStartBudget:e=>this.armAdStartBudget(e),remainingAdStartBudgetMs:()=>this.remainingAdStartBudgetMs(),loadWithinBudget:e=>this.loadWithinBudget(e),waitForFirstFrame:()=>this.waitForFirstFrame(),getOverlayImage:()=>this.overlayImageEl,setOverlayImage:e=>{this.overlayImageEl=e},getImageAssetTimer:()=>this.imageAssetTimer,setImageAssetTimer:e=>{this.imageAssetTimer=e},getVastPodPosition:()=>this.vastPodPosition,setVastPodPosition:e=>{this.vastPodPosition=e},diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.breakSequenceDriver=new S(this.state,{getChainResolver:()=>this.chainResolver,getEffectiveInsertionMode:()=>this.effectiveInsertionMode(),getVastPodPosition:()=>this.vastPodPosition,setVastPodPosition:e=>{this.vastPodPosition=e},getPendingAdError:()=>this.pendingAdError,setPendingAdError:e=>{this.pendingAdError=e},getChaining:()=>this.chaining,setChaining:e=>{this.chaining=e},isExpandingPodAsset:e=>this.isExpandingPodAsset(e),fallBackToPodLevelReporting:()=>this.fallBackToPodLevelReporting(),resetGamPodTracking:()=>this.resetGamPodTracking(),emitGamPodSteps:e=>this.gamPodBridge.emitGamPodSteps(e),playAsset:(e,t,r)=>this.playAsset(e,t,r),endBreak:()=>this.endBreak(),playBreak:(e,t,r)=>this.playBreak(e,t,r),diagnose:(e,t,r)=>this.diagnose(e,t,r),log:(...e)=>this.log(...e)}),this.adPlayerEvents=new E(this.state,{getAdPlayer:()=>this.adPlayer,getContentPlayer:()=>this.contentPlayer,getGamEventCallbacks:()=>this.gamEventCallbacks,getSequencer:()=>this.sequencer,getAudioFocus:()=>this.audioFocus,getSyncing:()=>this.syncing,setSyncing:e=>{this.syncing=e},setAdVolumeChangeHandler:e=>{this.adVolumeChangeHandler=e},setContentVolumeHandler:e=>{this.contentVolumeHandler=e},notifyVolumeChange:()=>this.notifyVolumeChange(),onAdEnded:()=>this.onAdEnded(),processTimedMetadata:e=>this.gamPodBridge.processTimedMetadata(e),toAdError:e=>this.toAdError(e),revealFirstFrame:()=>this.revealFirstFrame(),clearFirstFrameResolver:()=>this.preloader.clearFirstFrameResolver(),drive:e=>this.drive(e),setPendingAdError:e=>{this.pendingAdError=e},log:(...e)=>this.log(...e),maybePrepositionContentForResume:()=>this.resumeCoordinator.maybePrepositionContentForResume(),maybeCatchUpContentForResume:e=>this.resumeCoordinator.maybeCatchUpContentForResume(e),getStaticQuartilesFired:()=>this.staticQuartilesFired})}setGamEventCallbacks(e){this.gamPodBridge.setEventCallbacks(e)}setDiagnoseHandler(e){this.diagnoseHandler=e}diagnose(e,t,r){this.diagnoseHandler?.(e,t,r)}holdContentForPreRoll(e){if(this.preRollHoldActive)return;const t=this.getVariant(e);t&&this.shouldPauseContent(t.format)&&(this.preRollHoldActive=!0,this.contentPlayer.pause(),this.preRollHoldHandler=()=>{this.preRollHoldActive&&this.contentPlayer.pause()},this.contentPlayer.on("playing",this.preRollHoldHandler),this.diagnose("DA-PREROLL-CONTENT-HELD","Content held at session start until the pending pre-roll begins.",{breakId:e.id}))}releaseContentHold(){this.preRollHoldActive&&(this.preRollHoldActive=!1,this.preRollHoldHandler&&(this.contentPlayer.off("playing",this.preRollHoldHandler),this.preRollHoldHandler=null))}gateContentForBreak(){this.contentPlayer.pause(),this.breakContentGateHandler||(this.breakContentGateHandler=()=>{this.contentPaused&&!this.state.resumeCatchupActive&&this.contentPlayer.pause()},this.contentPlayer.on("playing",this.breakContentGateHandler))}clearContentGate(e=!1){this.resumeCoordinator.endResumeCatchup(e),this.breakContentGateHandler&&(this.contentPlayer.off("playing",this.breakContentGateHandler),this.breakContentGateHandler=null)}setChainResolver(e){this.chainResolver=e}setTransitionPhaseReporter(e){this.transitionPhaseReporter=e}reportPhase(e){this.transitionPhaseReporter?.(e)}setBreakResumePolicy(e,t,r=!1){this.adInsertionType=e,this.breakTimebase=t,this.state.continueContentDuringBreak=r,this.state.continueRefusalReported=!1}initialize(){this.adContainer||(this.setupOverlay(),this.presentationModes.setupPictureInPictureTracking(),"adaptive"===this.insertionMode&&this.presentationModes.setupFullscreenTracking())}async startGamSession(e,t){await this.gamPodBridge.startGamSession(e,t)}endGamSession(){this.gamPodBridge.endGamSession()}setSessionAssetParameters(e){this.assetParameters.setSessionAssetParameters(e)}setManifestAssetParameters(e){this.assetParameters.setManifestAssetParameters(e)}updateAssetParameters(e){this.assetParameters.updateAssetParameters(e)}get updatedAssetParameters(){return this.state.updatedAssetParameters}setSessionAssetParameterMacros(e){this.assetParameters.setSessionAssetParameterMacros(e)}buildVastTagUrl(e,t){return this.assetParameters.buildVastTagUrl(e,t)}pushAssetParameters(e,t){this.assetParameters.pushAssetParameters(e,t)}setupOverlay(){this.adStage.setupOverlay()}isGamPodAsset(e){return this.gamPodBridge.isGamPodAsset(e)}isExpandingPodAsset(e){return this.gamPodBridge.isExpandingPodAsset(e)}beginGamPodTracking(e){this.gamPodBridge.beginGamPodTracking(e)}fallBackToPodLevelReporting(){this.gamPodBridge.fallBackToPodLevelReporting()}resetGamPodTracking(){this.gamPodBridge.resetGamPodTracking()}emitGamPodSteps(e){this.gamPodBridge.emitGamPodSteps(e)}isGamEnabled(){return this.gamPodBridge.isGamEnabled()}isGamReady(){return this.gamPodBridge.isGamReady()}isOverlayInsertion(){return"overlay"===this.effectiveInsertionMode()}settleAssetProgress(){this.adPlayerEvents.settleAssetProgress()}reportAdProgress(e){this.adPlayerEvents.reportAdProgress(e)}setupEventListeners(){this.adPlayerEvents.setupEventListeners()}async preload(e){return this.preloader.preload(e)}renderLshapeContentBackdrop(e){this.adStage.renderLshapeContentBackdrop(e)}currentInsertionMode(){return this.presentationModes.currentInsertionMode()}effectiveInsertionMode(){return this.presentationModes.effectiveInsertionMode()}isContentPictureInPicture(){return this.presentationModes.isPictureInPicture()}rebindContentElementIfSwapped(){this.presentationModes.rebindContentElementIfSwapped()}teardownFullscreenTracking(){this.presentationModes.teardownFullscreenTracking()}teardownPictureInPictureTracking(){this.presentationModes.teardownPictureInPictureTracking()}isPictureInPicture(){return this.presentationModes.isPictureInPicture()}pictureInPictureOwner(){return this.presentationModes.pictureInPictureOwner()}isShowingAd(){if(!this.isAdPlaying())return!1;const e=this.currentDeclaredFormat();return!n(e,this.isContentPictureInPicture())}currentDeclaredFormat(){return this.currentSelectedFormat??(this.currentBreak?d(this.currentBreak):void 0)}async playBreak(t,a,i){this.releaseContentHold(),this.rebindContentElementIfSwapped(),this.sharedElementPlayer.clearSharedRestoreWatchdog();const n=i?.effectiveDurationSec??null;this.effectiveBreakDurationSec=null!==n&&n>0?n:null;const l=this.effectiveBreakDurationSec??t.duration;if("shared-element"===this.effectiveInsertionMode())return void await this.sharedElementPlayer.playSharedElementBreak(t,a);if(!this.adPlayer)return void this.log("playBreak called before initialize()");const d=this.getVariant(t);if(!d)return void this.log("No valid variant found for break:",t.id);this.currentBreak=t,this.callbacks=a,this.isPlaying=!0,this.firstFrameGateActive=i?.firstFrameGate??!1,this.firstFrameGateShown=!1;const h=this.continueContentDuringBreakReason(d.format),u=r(t),c=this.shouldPauseContent(d.format)&&"ok"===h&&!u;c||u||this.state.continueRefusalReported||!this.shouldPauseContent(d.format)||(this.state.continueRefusalReported=!0,this.diagnose("DA-CONTINUE-PLAYOUT-REFUSED",`Content will be paused for breaks this session: ${h}`,{reason:h,format:d.format})),this.audioFocus=d.format===e.DOUBLE?this.doubleBoxAudio:c?"ad":null,this.adPlayer&&("content"===this.audioFocus?(this.adPlayer.muted=!0,this.adPlayer.volume=0):(this.adPlayer.muted=this.contentPlayer.muted,this.adPlayer.volume=this.contentPlayer.volume,"ad"===this.audioFocus&&(this.contentPlayer.muted=!0)));const m=this.declaredFormatOf(t);if(this.currentSelectedFormat=m,this.state.pipAdoptedForBreak=s(m,this.isContentPictureInPicture()),this.state.pipAdoptedForBreak&&this.diagnose("DA-PIP-FORMAT-OVERRIDE",`Picture-in-picture: ${m} break plays as single`,{declared:m,effective:e.SINGLE,reason:"picture-in-picture",midBreak:!1}),this.shouldPauseContent(d.format)?(this.state.contentPositionAtBreakStart=this.contentPlayer.currentTime,this.resumeCoordinator.resetBreakResumeState(),c?(this.contentPaused=!1,this.resumeCoordinator.beginContinueContentPlayout()):(this.contentPaused=!0,this.gateContentForBreak())):this.contentPaused=!1,this.applyLayout(d),d.format===e.LSHAPE_CONTENT)return this.renderLshapeContentBackdrop(d),void(l&&l>0?(this.log("Starting duration timer:",l,"seconds"),this.durationTimer=setTimeout(()=>{this.log("Duration timer expired, ending break"),this.endBreak()},1e3*l)):this.endBreak());this.firstFrameGateActive||(this.show(),this.reapplyAdContainerLayout(d));if(0===this.getAssets(t).length)return this.log("No assets in break, ending immediately"),void this.endBreak();{const e=Math.max(0,l||0)+this.adBreakCutSafetyMarginSec;this.log("Starting break-cut timer:",e,"seconds"),this.durationTimer=setTimeout(()=>{this.log("Break-cut timer expired, ending break"),this.firstFrameRejector?this.onAdError(new Error("Break cut before first frame rendered")):this.sequencer&&this.currentBreak&&this.isPlaying?this.drive(this.sequencer.onOutcome({kind:"break-elapsed"})):this.endBreak()},1e3*e)}this.sequencer=new o("overlay",()=>null,this.selectionInputs()),await this.drive(this.sequencer.beginBreak(t)),this.preloadChainedSuccessor(t.id)}get resumeHandoverInMotion(){return this.state.resumeCatchupActive}reapplyAdContainerLayout(e){this.adStage.reapplyAdContainerLayout(e)}adoptPictureInPictureMidBreak(){this.presentationModes.adoptPictureInPictureMidBreak()}async restorePictureInPictureToContent(){await this.presentationModes.restorePictureInPictureToContent()}continueContentDuringBreakReason(e){return this.variantSelector.continueContentDuringBreakReason(e)}shouldPauseContent(t){return t===e.SINGLE||t===e.LSHAPE_AD}selectionInputs(){return this.variantSelector.selectionInputs()}breakNothingToPlayReason(e){return this.variantSelector.breakNothingToPlayReason(e)}unknownVariantFormatsOf(e){return this.variantSelector.unknownVariantFormatsOf(e)}diagnoseUnknownVariantFormats(e){this.variantSelector.diagnoseUnknownVariantFormats(e)}declaredFormatOf(e){const{selected:t,deviceQualified:r}=h(e,this.selectionInputs());return(t??r)?.format??d(e)}getVariant(e){return this.variantSelector.getVariant(e)}applyLayout(e){this.adStage.applyLayout(e)}restoreLayout(e){this.adStage.restoreLayout(e)}getAssets(e){return l(this.getVariant(e))}async playAsset(e,t,r){return this.assetPlayback.playAsset(e,t,r)}clearOverlayImage(){this.adStage.clearOverlayImage()}async showPauseImage(e){return this.pauseAdPresenter.showPauseImage(e)}hidePauseImage(){this.pauseAdPresenter.hidePauseImage()}async drive(e){return this.breakSequenceDriver.drive(e)}emitStep(e){this.breakSequenceDriver.emitStep(e)}async resolveAssetUri(e,t){return this.assetPlayback.resolveAssetUri(e,t)}async buildGamUrl(e,t){return this.gamPodBridge.buildGamUrl(e,t)}resolveUri(e){return this.assetParameters.resolveUri(e)}adPlayerStreamRemainingSec(){return this.assetPlayback.adPlayerStreamRemainingSec()}onAdEnded(){this.currentBreak&&this.isPlaying&&this.sequencer&&(this.settleAssetProgress(),this.drive(this.sequencer.onOutcome({kind:"asset-ended"})))}toAdError(e){return this.assetPlayback.toAdError(e)}onAdError(e){this.adPlayerEvents.onAdError(e)}endBreak(){if(!this.currentBreak)return;this.log("Break ended:",this.currentBreak.id),this.durationTimer&&(clearTimeout(this.durationTimer),this.durationTimer=null),this.state.gamPodTracker&&this.emitGamPodSteps(this.state.gamPodTracker.finish()),this.resetGamPodTracking(),this.pushAssetParameters(void 0);const e=this.currentBreak,a=this.getVariant(e)?.format;let i=this.abortingBreak?null:this.resolveChainedSuccessor(e.id);if(i){const e=this.breakNothingToPlayReason(i);this.diagnoseUnknownVariantFormats(i),e&&(this.diagnose("DA-BREAK-NO-PLAYABLE-ASSET",`chained break ${i.id} has no playable variant (${e}); it will not begin.`,{breakId:i.id,reason:e}),this.callbacks?.onAdError(i,void 0,new Error(`Break ${i.id} has no playable variant (${e})`)),this.callbacks?.onChainedBreakSkipped?.(i),i=null)}if(i)this.advanceToChainedBreak(e,i);else{if(this.currentSelectedFormat=void 0,this.resumeCoordinator.endContinueContentPlayout(),this.restorePictureInPictureToContent(),this.isPlaying=!1,this.currentBreak=null,this.effectiveBreakDurationSec=null,this.preloadedBreakId=null,this.preloader.clearWarmedBreaks(),this.firstFrameGateActive=!1,this.firstFrameGateShown=!1,this.clearFirstFrame("Break ended before first frame"),"ad"===this.audioFocus&&this.adPlayer?(this.contentPlayer.muted=this.adPlayer.muted,this.contentPlayer.volume=this.adPlayer.volume):"content"===this.audioFocus&&this.adPlayer&&(this.adPlayer.muted=this.contentPlayer.muted,this.adPlayer.volume=this.contentPlayer.volume),this.audioFocus=null,this.clearOverlayImage(),this.vastAdManager?.reset(),this.hide(),this.restoreLayout(a),this.adPlayer?.pause(),this.state.sharedAdClaimActive)return this.sharedElementPlayer.detachSharedAdListeners(),this.sharedElementPlayer.restoreSharedElementContent(e),this.abortingBreak=!1,this.state.earlyReturnResumeOffsetSec=null,void this.callbacks?.onBreakEnd(e);if("single-decoder"===this.preloadMode&&this.adPlayer?.unload?.(),this.contentPaused&&r(e))this.contentPaused=!1,this.clearContentGate();else if(this.contentPaused){this.contentPaused=!1,this.clearContentGate(this.resumeHandoverInMotion);const r=this.state.earlyReturnResumeOffsetSec,a=this.breakTimebase===t.WALLCLOCK,i=()=>{a&&this.callbacks?.onContentReloading?.(!0),this.resumeCoordinator.applyResumeSeek(e,r),this.contentPlayer.play().catch(e=>{this.log("Content resume failed:",e)}).finally(()=>{a&&setTimeout(()=>this.callbacks?.onContentReloading?.(!1),this.RESUME_GUARD_RELEASE_GRACE_MS)})};"single-decoder"===this.preloadMode?setTimeout(i,this.SINGLE_DECODER_RESUME_DELAY_MS):i()}this.abortingBreak=!1,this.state.earlyReturnResumeOffsetSec=null,this.callbacks?.onBreakEnd(e)}}currentAdAsset(){return this.isPlaying?this.currentAsset:null}skipBreak(){this.isPlaying&&(this.log("Skipping break:",this.currentBreak?.id),this.durationTimer&&(clearTimeout(this.durationTimer),this.durationTimer=null),this.sequencer&&this.currentBreak?this.drive(this.sequencer.onOutcome({kind:"break-elapsed"})):this.endBreak())}abortBreak(e){this.isPlaying&&(this.log("Early return — break removed from manifest:",this.currentBreak?.id),this.state.earlyReturnResumeOffsetSec=Math.max(0,e),this.abortingBreak=!0,this.durationTimer&&(clearTimeout(this.durationTimer),this.durationTimer=null),this.sequencer&&this.currentBreak?this.drive(this.sequencer.onOutcome({kind:"break-elapsed"})):this.endBreak())}stopActiveBreak(){this.isPlaying&&(this.log("Aborting active break on session end:",this.currentBreak?.id),this.durationTimer&&(clearTimeout(this.durationTimer),this.durationTimer=null),this.sharedElementPlayer.detachSharedAdListeners(),this.sharedElementPlayer.releaseContentElementAdPlayer(),this.adPlayer?.pause(),this.clearOverlayImage(),this.vastAdManager?.reset(),this.hide(),this.restoreLayout(this.currentBreak?this.getVariant(this.currentBreak)?.format??void 0:void 0),this.isPlaying=!1,this.currentBreak=null,this.currentAsset=null,this.contentPaused=!1,this.clearContentGate(),this.resumeCoordinator.endContinueContentPlayout(),this.effectiveBreakDurationSec=null,this.firstFrameGateActive=!1,this.firstFrameGateShown=!1,this.clearFirstFrame("Break aborted before first frame"),this.audioFocus=null)}resolveChainedSuccessor(e){return this.breakSequenceDriver.resolveChainedSuccessor(e)}advanceToChainedBreak(e,t){this.breakSequenceDriver.advanceToChainedBreak(e,t)}preloadChainedSuccessor(e){this.preloader.preloadChainedSuccessor(e)}revealFirstFrame(){this.assetPlayback.revealFirstFrame()}armAdStartBudget(e){this.preloader.armAdStartBudget(e)}remainingAdStartBudgetMs(){return this.preloader.remainingAdStartBudgetMs()}loadWithinBudget(e){return this.preloader.loadWithinBudget(e)}async waitForFirstFrame(){return this.preloader.waitForFirstFrame()}clearFirstFrame(e="Break ended before first frame"){this.preloader.clearFirstFrame(e)}show(){this.adStage.show()}hide(){this.adStage.hide()}isAdPlaying(){return this.isPlaying}get muted(){return"content"===this.audioFocus?this.contentPlayer.muted:"ad"===this.audioFocus?this.adPlayer?this.adPlayer.muted:this.contentPlayer.muted:this.isPlaying&&this.adPlayer?this.adPlayer.muted:this.contentPlayer.muted}set muted(e){if("content"===this.audioFocus)this.contentPlayer.muted=e;else if("ad"===this.audioFocus)this.adPlayer&&(this.adPlayer.muted=e);else{(this.isPlaying&&this.adPlayer?this.adPlayer:this.contentPlayer).muted=e}this.vastAdManager?.setMuted(e),this.notifyVolumeChange()}get volume(){return"content"===this.audioFocus?this.contentPlayer.volume:"ad"===this.audioFocus?this.adPlayer?this.adPlayer.volume:this.contentPlayer.volume:this.isPlaying&&this.adPlayer?this.adPlayer.volume:this.contentPlayer.volume}set volume(e){if("content"===this.audioFocus)this.contentPlayer.volume=e;else if("ad"===this.audioFocus)this.adPlayer&&(this.adPlayer.volume=e);else{(this.isPlaying&&this.adPlayer?this.adPlayer:this.contentPlayer).volume=e}this.vastAdManager?.setVolume(e),this.notifyVolumeChange()}setVolumeChangeCallback(e){this.volumeChangeCallback=e}notifyVolumeChange(){this.volumeChangeCallback?.(this.muted,this.volume)}destroy(){if(this.adStage.destroy(),this.resumeCoordinator.cancelResumeLandedProbe(),this.resumeCoordinator.endResumeCatchup(),this.resumeCoordinator.endContinueContentPlayout(),this.state.resumePrepositionSettle&&(clearTimeout(this.state.resumePrepositionSettle),this.state.resumePrepositionSettle=null),this.sharedElementPlayer.clearSharedRestoreWatchdog(),this.releaseContentHold(),this.clearContentGate(),this.clearFirstFrame("Controller destroyed before first frame"),this.firstFrameGateActive=!1,this.firstFrameGateShown=!1,this.resetGamPodTracking(),this.durationTimer&&(clearTimeout(this.durationTimer),this.durationTimer=null),this.companionRemoveTimer&&(clearTimeout(this.companionRemoveTimer),this.companionRemoveTimer=null),this.adFadeTimer&&(clearTimeout(this.adFadeTimer),this.adFadeTimer=null),this.adPlayer?.pause(),this.clearOverlayImage(),this.pauseAdPresenter.destroy(),this.contentVolumeHandler&&(this.contentPlayer.off("volumechange",this.contentVolumeHandler),this.contentVolumeHandler=null),this.sharedElementPlayer.detachSharedAdListeners(),this.sharedElementPlayer.releaseContentElementAdPlayer(),this.state.pipTransferredToAd=!1,this.teardownFullscreenTracking(),this.teardownPictureInPictureTracking(),this.adVolumeChangeHandler&&this.adPlayer&&this.adPlayer.off("volumechange",this.adVolumeChangeHandler),this.adVolumeChangeHandler=null,this.hide(),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.contentVideoMutationObserver?.disconnect(),this.contentVideoMutationObserver=null,this.contentVideoElement&&this.contentVideoGeometryHandler&&(this.contentVideoElement.removeEventListener("loadedmetadata",this.contentVideoGeometryHandler),this.contentVideoElement.removeEventListener("resize",this.contentVideoGeometryHandler)),this.contentVideoElement=null,this.contentVideoGeometryHandler=null,this.playerContainerCreatedBySDK)for(;this.playerContainer.firstChild;)this.container.appendChild(this.playerContainer.firstChild);else this.container.appendChild(this.playerContainer),this.playerContainer.style.cssText=this.playerContainerOriginalStyle;this.companionElement&&this.companionElement.parentElement&&(this.companionElement.parentElement.removeChild(this.companionElement),this.companionElement=null),this.isPlaying=!1,this.currentBreak=null,this.adContainer&&this.adContainer.parentElement&&this.adContainer.parentElement.removeChild(this.adContainer),this.stage&&this.stage.parentElement&&this.stage.parentElement.removeChild(this.stage),this.stage=null,this.adContainer=null,this.adMediaContainer=null;try{this.adPlayer?.destroy()}catch(e){this.log("Ad player adapter destroy failed (ignored):",e)}this.adPlayer=null,this.callbacks=null,this.gamPodBridge.destroy(),this.vastAdManager?.destroy(),this.vastAdManager=null,this.log("Ad player destroyed")}log(...e){this.debug&&u("[OptiViewAds:AdPlayerController]",...e)}}AdPlayerController.AD_START_BUDGET_MS=5e3,AdPlayerController.GAM_POD_AD_START_BUDGET_MS=1e4,AdPlayerController.MIN_AD_START_BUDGET_MS=3e3;