{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/pal.ts","../../src/utils/mqttConfig.ts","../../src/utils/mqttClient.ts","../../src/utils/vastEnvironmentSignals.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts","../../src/utils/vastMacros.ts","../../src/utils/browserCompat.ts","../../src/player/Scte35Parser.ts","../../src/player/Scte35CueManager.ts","../../src/player/AdConfigManager.ts","../../src/player/AdTimingService.ts","../../src/player/AdPreloadPool.ts","../../src/player/PlaceholderLayer.ts","../../src/player/HlsEngine.ts","../../src/player/PlayerControls.ts","../../src/player/AdBreakOrchestrator.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","from","__copyProps","to","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","exports","import_react","require","import_hls","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","podAds","podIndex","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","emit","event","payload","set","fn","Array","error","console","warn","img","src","autoLevel","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","url","trackingUrl","includes","Image","log","getMainStreamQuality","levels","currentLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","scope","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","keys","source","concat","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","parseAdElement","fetch","fetchVastXml","vastTagUrl","response","mode","credentials","headers","referrerPolicy","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","substring","mergeTrackingUrls","fetchAndParsePod","adElements","ads","resolved","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","progress","currentTime","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","isPlaying","dataset","setAdPlayingFlag","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","play","catch","ERROR","_event","data","fatal","canPlayType","load","total","display","pointerEvents","continueLiveStreamDuringAds","paused","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","preloaded","Promise","reject","has","delete","resolve","contentVolume","stop","previousMutedState","visibility","opacity","timeoutId","clearTimeout","remove","removeChild","clear","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","getPodAdCount","getPodTotalDurationMs","reduce","PAL_SDK_URL","_nonceLoader","_palLoadPromise","loadPalSdk","window","goog","pal","existing","timeout","setTimeout","script","async","setAttribute","onload","onerror","head","consentSettings","ConsentSettings","allowStorage","NonceLoader","createPalNonceManager","currentNonce","currentNonceManager","generateNonce","loader","request","manager","getOrCreateNonceLoader","NonceRequest","adWillAutoPlay","adWillPlayMuted","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","loadNonceManager","getNonce","getCurrentNonce","injectNonce","URL","searchParams","base","replace","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdClick","sendAdTouch","reset","DEFAULT_MQTT_CONFIG","enabled","brokerAddress","brokerPort","wsPort","username","password","topicPrefix","qos","mqttConfig","isMQTTEnabled","buildMQTTBrokerUrl","brokerUrl","buildPlayerTopic","channel","import_mqtt","LOG","client","status","initMQTTClient","clientId","slice","reconnectPeriod","connectTimeout","queueQoSZero","keepalive","clean","err","info","message","ensureMQTTClient","publishMQTT","topic","publish","JSON","stringify","AIRY_TIZEN_APP_ID","PLAYER_ID_STORAGE_KEY","LG_TEST_APP_ID","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_ROKU_APP_ID","AIRY_APP_NAME","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","LG_TEST_APP_NAME","LG_TEST_CONTENT_URL","getLgTestDeviceId","_lgTestDeviceId","createUuid","isLgWebOS","navigator","getDefaultAppId","test","userAgent","ua","DEVICE_ID_STORAGE_KEYS","ANDROID_ID_TYPES","bridgeSignals","readNativeBridgeSignals","platformDevice","readPlatformNativeDeviceId","isCtv","deviceId","readStoredDeviceId","lg","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","platformLat","readStoredLimitAdTracking","contentUrl","getOrCreateCtvSessionId","deviceTypeHint","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","readPersistentId","writePersistentId","readCookie","localStorage","setItem","writeCookie","PERSISTENT_ID_COOKIE_MAX_AGE","prefix","parts","cookie","part","entry","decodeURIComponent","bytes","crypto","randomUUID","getRandomValues","seed","i","floor","performanceNow","hex","padStart","performance","adinfo","webapis","tifa","getTIFA","lat","isLATEnabled","webOSDev","lgudid","LGUDID","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","t","candidates","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","AiryTV","Android","webOS","tizen","amazon","filter","Boolean","readBridgeValue","appId","appName","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","cachedBrowserId","buildAnalyticsContext","config","context","debugAdTiming","isLiveStream","inputStreamType","getClientInfo","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","hostname","origin","path","pathname","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","sha256Hex","input","encodedData","utf8","buffer","hashBuffer","hash","char","fallbackHash","timestamp","subtle","digest","Uint8Array","TextEncoder","encode","unescape","charCodeAt","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","getBrowserID","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","URLSearchParamsPolyfill","polyfillURLSearchParams","URLSearchParams","init","parseQueryString","params","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","values","getAll","String","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","polyfillStringIncludes","initializePolyfills","UNEXPANDED_MACRO_PATTERN","indexOf","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","pattern","getValue","ctx","correlator","trimmed","generateCorrelator","buf","Uint32Array","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","trimStart","raw","normalizeVastTagUrl","anValue","orphanFragments","reconstructed","trimEnd","_match","val","applyVastMacros","expandedUrl","expandInlineMacroPlaceholders","replaceCorrelatorFallback","streamCorrelator","pod","optimizedPodMode","podMaxAds","podMinDurationMs","podMaxDurationMs","round","adPosition","requestUrl","pageUrl","existingUrl","consent","gdpr","gdprConsent","uspApi","correlatorRegex","timeoutMs","usPrivacy","staleKeys","fetchConsentSignals","signals","tasks","tcfApi","__tcfapi","tcData","success","settled","eventStatus","gdprApplies","tcString","listenerId","__uspapi","uspString","getChromeVersion","getPlatform","userAgentData","detectBrowser","version","majorVersion","supportsModernJS","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","getWebKitVersion","isLegacyTV","getBrowserConfigOverrides","browser","overrides","allowNativeHls","logBrowserInfo","debug","parseCueOutDuration","num","parseFloat","dStr","d","parseCueOutCont","res","elapsedMatch","durationMatch","elapsed","slashMatch","parseAttributeList","attrs","regex","exec","rawVal","toNumber","n","isManifestBasedMarker","marker","id3","splice_command_type","decodeId3ValueToText","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteOut","hasScteIn","klass","bin","parseScte35Binary","normalizeFragmentPayload","ArrayBuffer","isView","view","byteOffset","byteLength","detectTsPacketFormat","packetSizes","packetSize","tsPayloadOffset","offset","matchedPackets","packetStart","getPsiSectionStart","payloadUnitStart","pointerField","sectionStart","getPsiSectionLength","parsePatSection","pmtPids","sectionLength","sectionEnd","programNumber","pid","descriptorsIdentifyScte35","end","descriptorStart","descriptorEnd","registration","parsePmtSection","tsScte35Pids","programInfoLength","streamType","elementaryPid","esInfoLength","hasProcessedTsScte35Section","section","processedSections","checksum","size","firstKey","next","markers","appendScte35Bytes","assemblers","assembler","expectedLength","addScte35SectionMarker","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","secondByte","thirdByte","fourthByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","BitReader","bytePos","bitPos","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","readBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","descriptorLoopLength","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","parseScte35SegmentationDescriptors","descriptorOffset","descriptorTag","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","cancel","outOfNetwork","programSpliceFlag","durationFlag","spliceImmediateFlag","componentPtsSeconds","expectedDescriptorOffset","splice_event_id","segmentation_event_id","Scte35CueManager","callbacks","pendingScte35Cues","processedTsScte35Sections","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","scheduledScte35BreakKeyValue","createScte35CueContext","readiness","sn","fragmentSn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","onEarlyStartCue","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","hasRecentlyHandledScte35Cue","markScte35CueHandled","onPlaybackCue","matchingCues","entries","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","isStrongScte35CueKey","recentKey","recentScte35CueKeys","recentScte35CueLimit","viewCorrelator","AdConfigManager","vmapBreaks","consentSignals","podCounter","podAssignedByPrefetch","adRequestPositionInBreak","isVmapEnabled","fetchAdConfiguration","fetchAndParseVmap","vmapUrl","vastMode","vastEndpoint","apiVastTagUrl","apiUrl","json","imaPayload","ima","decodedPayload","numberAds","vast","cue_tones","number_ads","apiNumberAds","vmapXml","parseVmapToBreaks","consumedVmapBreakIds","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","aStart","bStart","timeOffset","hms","hh","mm","ss","ms","hours","minutes","seconds","millis","percent","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","generateVastUrlsWithCorrelators","count","adPlayer","palNonce","envSignals","resolveVastEnvironmentSignals","ctvAdRequest","urlWithMacros","autoplay","adTest","finalUrl","resolvePodParams","breakDurationMs","maxDurationMs","maxAds","defaultPodMaxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","heartbeatInterval","setInterval","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","adStopTimerId","nowWallClockMs","endWallClockMs","initializeTracking","sendHeartbeatIfNeeded","lastHeartbeatTime","destroyTracking","clearInterval","AdTimingService","adRequestWatchdogToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ensureAdStoppedByTimer","onAdStopTimerFired","scheduleAdStartIn","delayMs","cueKey","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","scteAdBreakEndWallClockMs","currentAdBreakStartWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adController","fits","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","ensureLoadedAdFitsBudget","rejectLoadedAdForDuration","markAdStarted","notePodAdStarted","totalAdsInBreak","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","cleanupTemporaryFailures","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","isGamInCooldown","recordGamNoFill","exponent","backoff","pow","resetGamNoFillCounter","logAdState","adFailsafeTimerId","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","adFailsafeTimeoutMs","adRequestWatchdogId","clearAdRequestWatchdog","startAdFailsafeTimer","failsafeMs","adFailsafeToken","videoPaused","onFailsafeTimeout","poolActive","loopRunning","initialUrls","clearAdFailsafeTimer","extra","showAds","resetForBreakEnd","AdPreloadPool","deps","pool","maxPoolSize","active","isLoopRunning","startPreloadPool","baseVastUrl","startLoopImmediately","preloadPoolLoop","preloadAdIntoPool","vastUrl","timing","epoch","loadPromise","some","hasAdError","adErrorPayload","errorListenerCleanup","preloadAd","errorListener","isNoFill","poolEntry","loadedDuration","lateErrorListener","shouldContinueLiveStreamDuringAds","createAdPlayer","code","vastErrorCode","loadedAt","isReady","findIndex","splice","newUrls","newUrl","getPendingAdBreak","getPreloadedAd","PlaceholderLayer","ensureContainer","transition","show","wasHidden","offsetHeight","requestAnimationFrame","hide","HlsEngine","cueManager","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","setupNativeHls","canNative","adBehavior","isLive","setupHls","hls","import_hls2","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","fragmentsToScan","fragments","LEVEL_LOADED","_evt","hasPendingAdBreak","tagList","isArray","idx","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","onFatalDestroy","payloadData","getLiveSyncPosition","liveSyncPosition","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","requestFullscreen","isMuted","setMuted","setVolume","clampedVolume","getVolume","isFullscreen","clientWidth","clientHeight","AdBreakOrchestrator","host","preloadPool","adConfig","placeholder","isShowingPlaceholder","adDetectSentForCurrentBreak","continuousFetchingActive","adRequestQueue","adPodQueue","maxPlaceholderDurationMs","pendingAdBreak","analyticsContext","optimizedPodsEnabled","optimizedPods","attachImaEventListeners","getAdPlayer","adIndex","remaining","queuedUrls","tryNextAvailableAdWithRateLimit","handleAdPodComplete","errorPayload","errorMessage","errorCode","cause","innerError","causeMessage","recreateAdController","shouldShowPlaceholder","adBreakDurationMs","_marker","scheduled","currentMuted","currentVolume","startOptimizedPod","podPlayed","usePreloadedAd","firstAdUrl","preloadedController","vastUrls","clearPendingAdBreak","firstAdUrlArray","generateVastUrls","startContinuousFetching","preservedMuted","preservedVolume","setAdPlayer","adVolume","fallbackPreloaded","swapToPreloadedAdPlayer","ap","fallbackError","requestToken","podCount","podUrl","continuousFetchLoopRunning","continuousFetchLoop","maxQueueSize","newAdUrl","queuedUrlsPreview","generationDelay","stopContinuousFetching","backoffMultiplier","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","tryNextAvailableAd","retryCount","nextAdUrl","maxRetries","playSingleAd"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n  // If the importer is in node compatibility mode or this is not an ESM\n  // file that has been converted to a CommonJS file using a Babel-\n  // compatible transform (i.e. \"__esModule\" has not been set), then set\n  // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n  isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n  mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n  StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(contentVideo, options) {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = /* @__PURE__ */ new Map();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n  let adVideoElement;\n  let adHls;\n  let adContainerEl;\n  let currentAd;\n  let podAds = [];\n  let podIndex = 0;\n  let sessionId;\n  const preloadedAds = /* @__PURE__ */ new Map();\n  const preloadingAds = /* @__PURE__ */ new Map();\n  let destroyed = false;\n  let pendingTimeouts = [];\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false\n  };\n  function emit(event, payload) {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n  function generateSessionId() {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n  function fireTrackingPixels(urls) {\n    if (!urls || urls.length === 0) return;\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n        }\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n        }\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n  function getMainStreamQuality() {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level2 = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level2.width || 1920,\n          height: level2.height || 1080,\n          bitrate: level2.bitrate || 5e6\n        };\n      }\n      return null;\n    }\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5e6\n    };\n  }\n  function selectBestMediaFile(mediaFiles) {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n      const fileBitrate = (file.bitrate || 5e3) * 1e3;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n      const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n    scoredFiles.sort((a, b) => a.score - b.score);\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff\n    });\n    return bestMatch.file;\n  }\n  function isHlsMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n  }\n  function isProgressiveMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n  }\n  function createEmptyTrackingUrls() {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: []\n    };\n  }\n  function extractTrackingUrls(scope) {\n    const trackingUrls = createEmptyTrackingUrls();\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n    return trackingUrls;\n  }\n  function mergeTrackingUrls(target, source) {\n    Object.keys(target).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n  function parseVastXml(xmlString) {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: void 0\n        };\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  function parseAdElement(adElement) {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = adElement.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        if (!url) return;\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n        };\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  async function fetchVastXml(vastTagUrl) {\n    const response = await fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: \"include\",\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\"\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\"\n    });\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n  async function fetchAndParseVastAd(vastTagUrl, depth = 0, accumulatedTracking = createEmptyTrackingUrls()) {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2e3)\n    );\n    const parsed = parseVastXml(vastXml);\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n  async function fetchAndParsePod(vastTagUrl) {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n    const ads = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n  function createAdVideoElement() {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n    video.volume = 1;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n    return video;\n  }\n  function setupAdEventListeners() {\n    if (!adVideoElement || !currentAd) return;\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n      const progress = adVideoElement.currentTime / currentAd.duration;\n      if (progress >= 0.25 && !trackingFired.firstQuartile) {\n        trackingFired.firstQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n      }\n      if (progress >= 0.5 && !trackingFired.midpoint) {\n        trackingFired.midpoint = true;\n        fireTrackingPixels(currentAd.trackingUrls.midpoint);\n      }\n      if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n        trackingFired.thirdQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n      }\n    });\n    adVideoElement.addEventListener(\"playing\", () => {\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdComplete();\n    });\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdError();\n    });\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n  function setAdPlayingFlag(isPlaying) {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n  function resetQuartileTracking(preserveImpression) {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false\n    };\n  }\n  function loadCurrentAdMedia() {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n    if (isHlsAd && import_hls.default.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n      adHls = new import_hls.default({\n        enableWorker: true,\n        lowLatencyMode: false\n      });\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n      adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n      adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (isHlsAd && adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n  function advanceToNextPodAd() {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n  function handleAdComplete() {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {\n        });\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n    emit(\"content_resume\");\n  }\n  function handleAdError() {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    emit(\"ad_error\");\n  }\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n    async requestAds(vastTagUrl) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n      try {\n        sessionId = generateSessionId();\n        let ads = [];\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n        resetQuartileTracking(true);\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n        emit(\"content_pause\");\n        loadCurrentAdMedia();\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {\n          });\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {\n          });\n        }\n      }\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n      }\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n    },\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      for (const timeoutId of pendingTimeouts) {\n        clearTimeout(timeoutId);\n      }\n      pendingTimeouts = [];\n      adPlaying = false;\n      setAdPlayingFlag(false);\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n        adVideoElement.remove();\n        adVideoElement = void 0;\n      }\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n      adContainerEl = void 0;\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n    isAdPlaying() {\n      return adPlaying;\n    },\n    resize(width, height) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n    on(event, listener) {\n      if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n      listeners.get(event).add(listener);\n    },\n    off(event, listener) {\n      listeners.get(event)?.delete(listener);\n    },\n    updateOriginalMutedState(muted, volume) {\n      const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n    setAdVolume(volume) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n    getAdVolume() {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1e3 : 0),\n        0\n      );\n    }\n  };\n}\n\n// src/sdk/pal.ts\nvar PAL_SDK_URL = \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\nvar _nonceLoader;\nvar _palLoadPromise;\nfunction loadPalSdk() {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n  if (_palLoadPromise) return _palLoadPromise;\n  _palLoadPromise = new Promise((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    );\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        1e4\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n  return _palLoadPromise;\n}\nfunction getOrCreateNonceLoader() {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\nfunction createPalNonceManager() {\n  let currentNonce = \"\";\n  let currentNonceManager;\n  return {\n    async generateNonce(options = {}) {\n      try {\n        await loadPalSdk();\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume = options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url = options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce();\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = void 0;\n        return \"\";\n      }\n    },\n    getCurrentNonce() {\n      return currentNonce;\n    },\n    injectNonce(vastTagUrl) {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl.replace(/([?&])paln=[^&]*/g, \"\").replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n    sendPlaybackStart() {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {\n      }\n    },\n    sendPlaybackEnd() {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {\n      }\n    },\n    sendAdClick() {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {\n      }\n    },\n    sendAdTouch(event) {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {\n      }\n    },\n    reset() {\n      currentNonce = \"\";\n      currentNonceManager = void 0;\n    }\n  };\n}\n\n// src/utils/mqttConfig.ts\nvar DEFAULT_MQTT_CONFIG = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1\n};\nvar mqttConfig = { ...DEFAULT_MQTT_CONFIG };\nfunction isMQTTEnabled() {\n  return mqttConfig.enabled;\n}\nfunction buildMQTTBrokerUrl() {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\nfunction buildPlayerTopic(licenseKey, channel) {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n\n// src/utils/mqttClient.ts\nvar import_mqtt = __toESM(require(\"mqtt\"), 1);\nvar LOG = \"[StormcloudVideoPlayer][MQTT]\";\nvar client = null;\nvar status = \"disconnected\";\nfunction initMQTTClient() {\n  if (client || !isMQTTEnabled()) return;\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n  try {\n    client = import_mqtt.default.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5e3,\n      connectTimeout: 1e4,\n      queueQoSZero: false\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting\\u2026`);\n  });\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\nfunction ensureMQTTClient() {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\nfunction publishMQTT(topic, payload) {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n  ensureMQTTClient();\n  if (!client) {\n    return false;\n  }\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\n// src/utils/vastEnvironmentSignals.ts\nvar AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nvar AIRY_WEBOS_APP_ID = \"com.freeairytv.webos\";\nvar AIRY_TIZEN_APP_ID = \"com.freeairytv.samsung\";\nvar AIRY_ROKU_APP_ID = \"com.freeairytv.roku\";\nvar AIRY_APP_NAME = \"AiryTV Movies & TV\";\nvar AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nvar CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nvar PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\nvar LG_TEST_APP_ID = \"com.hulu.plus\";\nvar LG_TEST_APP_NAME = \"Hulu\";\nvar LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\nvar _lgTestDeviceId;\nfunction getLgTestDeviceId() {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\nfunction isLgWebOS() {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\nfunction getDefaultAppId() {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\nvar DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\"\n];\nvar ANDROID_ID_TYPES = /* @__PURE__ */ new Set([\"aaid\", \"adid\"]);\nfunction resolveVastEnvironmentSignals(isCtv) {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);\n  const deviceIdType = bridgeSignals.deviceIdType || readStoredString(\"deviceIdType\") || readStoredString(\"idtype\") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? \"lgudid\" : void 0);\n  const platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;\n  const limitAdTracking = deviceId != null ? platformLat ?? readStoredLimitAdTracking() ?? false : void 0;\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl: bridgeSignals.contentUrl || readStoredString(\"contentUrl\") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId: bridgeSignals.appId || readStoredString(\"appId\") || readStoredString(\"msid\") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName: bridgeSignals.appName || readStoredString(\"appName\") || readStoredString(\"an\") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...deviceId ? { deviceId } : {},\n      ...deviceIdType ? { deviceIdType } : {},\n      ...limitAdTracking != null ? { limitAdTracking } : {},\n      deviceTypeHint: 5\n    };\n  }\n  return {\n    isCtv: false,\n    ...deviceId ? { deviceId } : {},\n    ...deviceIdType ? { deviceIdType } : {},\n    ...limitAdTracking != null ? { limitAdTracking } : {}\n  };\n}\nfunction inferDeviceIdType() {\n  if (typeof navigator === \"undefined\") {\n    return void 0;\n  }\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return void 0;\n}\nfunction isEquivalentDeviceIdType(tagType, runtimeType) {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\nfunction resolveNativeDeviceId() {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return void 0;\n  }\n  return deviceId;\n}\nfunction getOrCreateStoredUuid(storageKey) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\nfunction readPersistentId(storageKey) {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\nfunction writePersistentId(storageKey, value) {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {\n  }\n  writeCookie(storageKey, value);\n}\nvar PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5;\nfunction readCookie(name) {\n  if (typeof document === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || void 0;\n      }\n    }\n  } catch {\n  }\n  return void 0;\n}\nfunction writeCookie(name, value) {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n  try {\n    document.cookie = encodeURIComponent(name) + \"=\" + encodeURIComponent(value) + \";path=/;max-age=\" + PERSISTENT_ID_COOKIE_MAX_AGE + \";SameSite=Lax\";\n  } catch {\n  }\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = seed * 1103515245 + 12345 & 2147483647;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 255;\n    }\n  }\n  bytes[6] = (bytes[6] ?? 0) & 15 | 64;\n  bytes[8] = (bytes[8] ?? 0) & 63 | 128;\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n  return hex.slice(0, 8) + \"-\" + hex.slice(8, 12) + \"-\" + hex.slice(12, 16) + \"-\" + hex.slice(16, 20) + \"-\" + hex.slice(20, 32);\n}\nfunction performanceNow() {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {\n  }\n  return 0;\n}\nfunction readPlatformNativeDeviceId() {\n  if (typeof window === \"undefined\") return {};\n  try {\n    const adinfo = window.webapis?.adinfo;\n    if (adinfo) {\n      const tifa = typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat = typeof adinfo.isLATEnabled === \"function\" ? adinfo.isLATEnabled() : void 0;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}\n        };\n      }\n    }\n  } catch {\n  }\n  try {\n    const webOSDev = window.webOSDev;\n    if (webOSDev) {\n      const lgudid = typeof webOSDev.LGUDID === \"function\" ? webOSDev.LGUDID() : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {\n  }\n  try {\n    const roku = window.Roku;\n    if (roku) {\n      const rida = typeof roku.getPublisherUniqueId === \"function\" ? roku.getPublisherUniqueId() : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {\n  }\n  return {};\n}\nvar ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\"\n]);\nfunction isMacroPlaceholder(value) {\n  const t = value.trim();\n  return !t || /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\nfunction isZeroedAdId(value) {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\nfunction readNativeBridgeSignals() {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n  const candidates = [\n    window.__STORMCLOUD_CTV_AD_INFO__,\n    window.__STORMCLOUD_CTV__,\n    window.stormcloudCtv,\n    window.AiryTV,\n    window.Android,\n    window.webOS,\n    window.tizen,\n    window.amazon\n  ].filter(Boolean);\n  for (const source of candidates) {\n    const contentUrl = readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) || void 0;\n    const appId = readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) || void 0;\n    const appName = readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || void 0;\n    const deviceId = readBridgeValue(source, [\n      \"rdid\",\n      \"ifa\",\n      \"advertisingId\",\n      \"adId\",\n      \"deviceId\",\n      \"lgudid\",\n      \"LGUDID\",\n      \"tifa\",\n      \"rida\",\n      \"afai\",\n      \"aaid\"\n    ]) || void 0;\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n    const deviceIdType = readBridgeValue(source, [\n      \"idtype\",\n      \"deviceIdType\",\n      \"advertisingIdType\",\n      \"idType\"\n    ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\"\n    ]);\n    return {\n      ...contentUrl ? { contentUrl } : {},\n      ...appId ? { appId } : {},\n      ...appName ? { appName } : {},\n      ...deviceId ? { deviceId } : {},\n      ...deviceId && deviceIdType ? { deviceIdType } : {},\n      ...deviceId && limitAdTracking != null ? { limitAdTracking } : {}\n    };\n  }\n  return {};\n}\nfunction readBridgeValue(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readBridgeBoolean(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readStoredDeviceId() {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return void 0;\n}\nfunction readStoredString(key) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || void 0;\n  } catch {\n    return void 0;\n  }\n}\nfunction readStoredLimitAdTracking() {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") || readStoredString(\"limitedAdTracking\") || readStoredString(\"is_lat\")\n  );\n}\nfunction normalizeBoolean(value) {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return void 0;\n}\n\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction buildAnalyticsContext(config) {\n  const context = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== void 0) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\nfunction getClientInfo() {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = navigator.deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: screen?.orientation?.type || \"\",\n    pixelDepth: screen?.pixelDepth\n  };\n  let deviceType = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n    if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n  isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState\n  };\n}\nasync function sha256Hex(input) {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n      let encodedData;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\nfunction resolvePlayerIdentitySeed(clientInfo) {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\nasync function getBrowserID(clientInfo) {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\nfunction canPublish(licenseKey) {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\nasync function buildPlayerMetricEvent(context = {}, flags = {}) {\n  const clientInfo = getClientInfo();\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n  const playerId = await getBrowserID(clientInfo);\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n  const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...context.inputStreamType ? { input_stream_type: context.inputStreamType } : {}\n  };\n}\nfunction publishTracking(licenseKey, channel, body) {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false\n    });\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp\n    });\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp\n        }\n      ]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n  if (typeof URLSearchParams !== \"undefined\") {\n    return;\n  }\n  class URLSearchParamsPolyfill {\n    constructor(init) {\n      this.params = /* @__PURE__ */ new Map();\n      if (typeof init === \"string\") {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n    parseQueryString(query) {\n      const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n      if (!cleanQuery) return;\n      cleanQuery.split(\"&\").forEach((param) => {\n        const [key, value] = param.split(\"=\");\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n    safeDecodeURIComponent(str) {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, \" \"));\n      } catch (e) {\n        return str;\n      }\n    }\n    append(name, value) {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n    delete(name) {\n      this.params.delete(name);\n    }\n    get(name) {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n    }\n    getAll(name) {\n      return this.params.get(name) || [];\n    }\n    has(name) {\n      return this.params.has(name);\n    }\n    set(name, value) {\n      this.params.set(name, [String(value)]);\n    }\n    forEach(callback) {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n    toString() {\n      const parts = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join(\"&\");\n    }\n  }\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n  if (typeof TextEncoder !== \"undefined\") {\n    return;\n  }\n  class TextEncoderPolyfill {\n    constructor() {\n      this.encoding = \"utf-8\";\n    }\n    encode(str) {\n      const utf8 = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 128) {\n          utf8.push(charcode);\n        } else if (charcode < 2048) {\n          utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n        } else if (charcode < 55296 || charcode >= 57344) {\n          utf8.push(\n            224 | charcode >> 12,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        } else {\n          i++;\n          charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n          utf8.push(\n            240 | charcode >> 18,\n            128 | charcode >> 12 & 63,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n  window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n  if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n    Promise.prototype.finally = function(callback) {\n      const constructor = this.constructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) => constructor.resolve(callback()).then(() => {\n          throw reason;\n        })\n      );\n    };\n  }\n}\nfunction polyfillObjectAssign() {\n  if (typeof Object.assign !== \"function\") {\n    Object.assign = function(target, ...sources) {\n      if (target == null) {\n        throw new TypeError(\"Cannot convert undefined or null to object\");\n      }\n      const to = Object(target);\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to;\n    };\n  }\n}\nfunction polyfillArrayFrom() {\n  if (!Array.from) {\n    Array.from = function(arrayLike, mapFn, thisArg) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError(\"Array.from requires an array-like object\");\n      }\n      const len = items.length >>> 0;\n      const result = new Array(len);\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n      return result;\n    };\n  }\n}\nfunction polyfillStringStartsWith() {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function(search, pos) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\nfunction polyfillStringEndsWith() {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function(search, length) {\n      if (length === void 0 || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\nfunction polyfillStringIncludes() {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function(search, start) {\n      if (typeof start !== \"number\") {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\nfunction initializePolyfills() {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n// src/utils/vastMacros.ts\nvar UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nvar INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nvar EXAMPLE_COM_URL = /example\\.com/i;\nvar CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\"\n];\nvar INLINE_DEVICE_MACRO_REPLACEMENTS = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator }\n];\nfunction isMacroPlaceholder2(value) {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\nfunction generateCorrelator() {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 2097152 + ((buf[1] ?? 0) & 2097151);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\nfunction expandInlineMacroPlaceholders(baseUrl, ctx) {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\nfunction applyDeviceIdentityParams(params, ctx) {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue = ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0;\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder2(tagLat) ? \"0\" : tagLat));\n    return;\n  }\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));\n  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n  if (tagRdidValid) {\n    if (isMacroPlaceholder2(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder2(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\nfunction removeBrokenAppNameOrphans(params, appName) {\n  const toDelete = [];\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\nfunction normalizeVastTagUrl(raw) {\n  if (!raw) return raw;\n  try {\n    const url = new URL(raw);\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments].filter(Boolean).join(\" & \");\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\nfunction applyVastMacros(baseUrl, ctx) {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n  const params = url.searchParams;\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n  const optimizedPodMode = ctx.podMaxAds != null || ctx.podMinDurationMs != null || ctx.podMaxDurationMs != null;\n  if (optimizedPodMode) {\n    params.delete(\"ppos\");\n    params.delete(\"lip\");\n    if (ctx.podMinDurationMs != null) {\n      params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n    }\n    if (ctx.podMaxDurationMs != null) {\n      params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n    }\n    if (ctx.podMaxAds != null) {\n      params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n    }\n  } else if (ctx.adPosition != null) {\n    params.set(\"ppos\", String(ctx.adPosition));\n  }\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n  applyDeviceIdentityParams(params, ctx);\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n  const staleKeys = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder2(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n  removeBrokenAppNameOrphans(params, ctx.appName);\n  return url.toString();\n}\nfunction replaceCorrelatorFallback(baseUrl, correlator) {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\nfunction fetchConsentSignals(timeoutMs = 1500) {\n  const signals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n  const tasks = [];\n  const tcfApi = window.__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData, success) => {\n            if (settled) return;\n            if (success && tcData && (tcData.eventStatus === \"tcloaded\" || tcData.eventStatus === \"useractioncomplete\")) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {\n                }, tcData.listenerId);\n              } catch {\n              }\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n  const uspApi = window.__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data, success) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n  return Promise.all(tasks).then(() => signals);\n}\n\n// src/utils/browserCompat.ts\nfunction getChromeVersion(ua) {\n  const match = ua.match(/Chrome\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getWebKitVersion(ua) {\n  const match = ua.match(/AppleWebKit\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\nfunction getPlatform() {\n  if (\"userAgentData\" in navigator && navigator.userAgentData?.platform) {\n    return navigator.userAgentData.platform;\n  }\n  const ua = navigator.userAgent;\n  if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n    return /iPhone|iPad|iPod/i.test(ua) ? \"iPhone\" : \"MacIntel\";\n  }\n  if (/Win/i.test(ua)) {\n    return \"Win32\";\n  }\n  if (/Linux/i.test(ua)) {\n    return /Android/i.test(ua) ? \"Linux armv8l\" : \"Linux x86_64\";\n  }\n  if (/CrOS/i.test(ua)) {\n    return \"CrOS\";\n  }\n  return navigator.platform || \"Unknown\";\n}\nfunction detectBrowser() {\n  const ua = navigator.userAgent;\n  const platform = getPlatform();\n  let name = \"Unknown\";\n  let version = \"0\";\n  let majorVersion = 0;\n  let isSmartTV = false;\n  let isLegacyTV = false;\n  let supportsModernJS = true;\n  let webOSVersion;\n  let tizenVersion;\n  let chromeVersionNum;\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = \"LG WebOS\";\n    isSmartTV = true;\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = \"6.0\";\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = \"5.0\";\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = \"4.0\";\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = \"3.0\";\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = \"2.0\";\n        majorVersion = 2;\n      }\n    } else {\n      version = \"Unknown\";\n      webOSVersion = void 0;\n    }\n    isLegacyTV = webOSVersion !== void 0 && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = \"Samsung Tizen\";\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : \"Unknown\";\n    if (version !== \"Unknown\") {\n      const parts = version.split(\".\");\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n    isLegacyTV = tizenVersion !== void 0 && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = \"Smart TV\";\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else if (/NetCast/i.test(ua)) {\n    name = \"LG NetCast\";\n    isSmartTV = true;\n    isLegacyTV = true;\n  } else if (/BRAVIA/i.test(ua)) {\n    name = \"Sony BRAVIA\";\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = \"Chrome\";\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\n    }\n  }\n  if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n    supportsModernJS = false;\n  }\n  if (typeof URLSearchParams === \"undefined\") {\n    supportsModernJS = false;\n  }\n  return {\n    name,\n    version,\n    majorVersion,\n    isSmartTV,\n    isLegacyTV,\n    platform,\n    supportsModernJS,\n    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum\n  };\n}\nfunction getBrowserConfigOverrides() {\n  const browser = detectBrowser();\n  const overrides = {};\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n  }\n  return overrides;\n}\nfunction logBrowserInfo(debug = false) {\n  if (!debug) return;\n  const browser = detectBrowser();\n  console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n    ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n    ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n    userAgent: navigator.userAgent\n  });\n}\n\n// src/player/Scte35Parser.ts\nfunction parseCueOutDuration(value) {\n  const num = parseFloat(value.trim());\n  if (!Number.isNaN(num)) return num;\n  const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (match && match[1] != null) {\n    const dStr = match[1];\n    const d = parseFloat(dStr);\n    return Number.isNaN(d) ? void 0 : d;\n  }\n  return void 0;\n}\nfunction parseCueOutCont(value) {\n  const res = {};\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return void 0;\n}\nfunction parseAttributeList(value) {\n  const attrs = {};\n  const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n  let match;\n  while ((match = regex.exec(value)) !== null) {\n    const key = match[1] ?? \"\";\n    let rawVal = match[3] ?? match[4] ?? \"\";\n    if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n      rawVal = rawVal.slice(1, -1);\n    }\n    if (key) {\n      attrs[key] = rawVal;\n    }\n  }\n  return attrs;\n}\nfunction toNumber(val) {\n  if (val == null) return void 0;\n  const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n  return Number.isNaN(n) ? void 0 : n;\n}\nfunction isManifestBasedMarker(marker) {\n  const raw = marker.raw;\n  if (!raw) return false;\n  if (raw.tag) {\n    const tag = String(raw.tag);\n    return tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-CUE-IN\") || tag.includes(\"EXT-X-DATERANGE\");\n  }\n  if (raw.id3) return false;\n  if (raw.splice_command_type) return false;\n  return false;\n}\nfunction decodeId3ValueToText(value) {\n  try {\n    if (typeof value === \"string\") return value;\n    const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n    const text = decoder.decode(value);\n    if (text && /[\\x20-\\x7E]/.test(text)) return text;\n    let out = \"\";\n    for (let i = 0; i < value.length; i++)\n      out += String.fromCharCode(value[i]);\n    return out;\n  } catch {\n    return void 0;\n  }\n}\nfunction getFragmentStartSeconds(frag) {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return void 0;\n}\nfunction parseScte35FromId3(tag) {\n  const text = decodeId3ValueToText(tag.value);\n  if (!text) return void 0;\n  const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n  if (cueOutMatch) {\n    const arg = (cueOutMatch[1] ?? \"\").trim();\n    const dur = parseCueOutDuration(arg);\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...dur !== void 0 ? { durationSeconds: dur } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n  if (cueOutContMatch) {\n    const arg = (cueOutContMatch[1] ?? \"\").trim();\n    const cont = parseCueOutCont(arg);\n    const marker = {\n      type: \"progress\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n  if (cueInMatch) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n  if (daterangeMatch) {\n    const attrs = parseAttributeList(daterangeMatch[1] ?? \"\");\n    const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n    const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n    const klass = String(attrs[\"CLASS\"] ?? \"\");\n    const duration = toNumber(attrs[\"DURATION\"]);\n    if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n      const marker = {\n        type: \"start\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        ...duration !== void 0 ? { durationSeconds: duration } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n    if (hasScteIn) {\n      const marker = {\n        type: \"end\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n  }\n  if (/SCTE35-OUT/i.test(text)) {\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (/SCTE35-IN/i.test(text)) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (tag.value instanceof Uint8Array) {\n    const bin = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n  return void 0;\n}\nfunction normalizeFragmentPayload(payload) {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return void 0;\n}\nfunction detectTsPacketFormat(data) {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (let packetStart = offset; packetStart + tsPayloadOffset < data.length && matchedPackets < 5; packetStart += packetSize) {\n        if (data[packetStart + tsPayloadOffset] !== 71) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return void 0;\n}\nfunction getPsiSectionStart(payload, payloadUnitStart) {\n  if (!payloadUnitStart) {\n    return void 0;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return void 0;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : void 0;\n}\nfunction getPsiSectionLength(data, offset) {\n  return ((data[offset + 1] ?? 0) & 15) << 8 | (data[offset + 2] ?? 0);\n}\nfunction parsePatSection(payload, payloadUnitStart, pmtPids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber = (payload[offset] ?? 0) << 8 | (payload[offset + 1] ?? 0);\n    const pid = ((payload[offset + 2] ?? 0) & 31) << 8 | (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\nfunction descriptorsIdentifyScte35(data, start, end) {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n    const registration = length >= 4 ? String.fromCharCode(\n      data[descriptorStart] ?? 0,\n      data[descriptorStart + 1] ?? 0,\n      data[descriptorStart + 2] ?? 0,\n      data[descriptorStart + 3] ?? 0\n    ) : \"\";\n    if (tag === 138 || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n    offset = descriptorEnd;\n  }\n  return false;\n}\nfunction parsePmtSection(payload, payloadUnitStart, tsScte35Pids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 2) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength = ((payload[sectionStart + 10] ?? 0) & 15) << 8 | (payload[sectionStart + 11] ?? 0);\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid = ((payload[offset + 1] ?? 0) & 31) << 8 | (payload[offset + 2] ?? 0);\n    const esInfoLength = ((payload[offset + 3] ?? 0) & 15) << 8 | (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n    if (streamType === 134 || streamType === 6 && descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd)) {\n      tsScte35Pids.add(elementaryPid);\n    }\n    offset = descriptorStart + esInfoLength;\n  }\n}\nfunction hasProcessedTsScte35Section(section, processedSections) {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = checksum * 31 + (section[i] ?? 0) >>> 0;\n  }\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\nfunction addScte35SectionMarker(section, markers, processedSections) {\n  if (section[0] !== 252 || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n  marker.raw = {\n    ...typeof marker.raw === \"object\" && marker.raw ? marker.raw : {},\n    source: \"ts-packet\"\n  };\n  markers.push(marker);\n}\nfunction appendScte35Bytes(pid, bytes, assemblers, markers, processedSections) {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\nfunction collectScte35SectionsFromPayload(pid, payload, payloadUnitStart, assemblers, markers, processedSections) {\n  if (payload.length === 0) {\n    return;\n  }\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 255) {\n      return;\n    }\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength\n      });\n      return;\n    }\n  }\n}\nfunction parseScte35FromTsPackets(data, tsScte35Pids, pmtPids, processedSections) {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n  const markers = [];\n  const sectionAssemblers = /* @__PURE__ */ new Map();\n  for (let packetStart = packetInfo.offset; packetStart + packetInfo.packetSize <= data.length; packetStart += packetInfo.packetSize) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 71) {\n      continue;\n    }\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (secondByte == null || thirdByte == null || fourthByte == null || (secondByte & 128) !== 0) {\n      continue;\n    }\n    const payloadUnitStart = (secondByte & 64) !== 0;\n    const pid = (secondByte & 31) << 8 | thirdByte;\n    const adaptationFieldControl = fourthByte >> 4 & 3;\n    const hasPayload = adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n  return markers;\n}\nvar BitReader = class {\n  constructor(buf) {\n    this.buf = buf;\n    this.bytePos = 0;\n    this.bitPos = 0;\n  }\n  readBits(numBits) {\n    let result = 0;\n    while (numBits > 0) {\n      if (this.bytePos >= this.buf.length) return result;\n      const remainingInByte = 8 - this.bitPos;\n      const toRead = Math.min(numBits, remainingInByte);\n      const currentByte = this.buf[this.bytePos];\n      const shift = remainingInByte - toRead;\n      const mask = (1 << toRead) - 1 & 255;\n      const bits = currentByte >> shift & mask;\n      result = result << toRead | bits;\n      this.bitPos += toRead;\n      if (this.bitPos >= 8) {\n        this.bitPos = 0;\n        this.bytePos += 1;\n      }\n      numBits -= toRead;\n    }\n    return result >>> 0;\n  }\n  skipBits(n) {\n    this.readBits(n);\n  }\n  get bytePosition() {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n};\nfunction readSpliceTime(r, ptsAdjustmentTicks) {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return void 0;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks = (high * 4294967296 + low + ptsAdjustmentTicks) % 8589934592;\n  return ptsTicks / 9e4;\n}\nfunction markerTypeFromSegmentationTypeId(segmentationTypeId) {\n  switch (segmentationTypeId) {\n    case 16:\n    case 34:\n    case 48:\n    case 50:\n    case 52:\n    case 54:\n      return \"start\";\n    case 17:\n    case 35:\n    case 49:\n    case 51:\n    case 53:\n    case 55:\n      return \"end\";\n    default:\n      return void 0;\n  }\n}\nfunction parseScte35SegmentationDescriptor(descriptor) {\n  if (descriptor.length < 11) {\n    return void 0;\n  }\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return void 0;\n  }\n  const segmentationEventId = (descriptor[4] ?? 0) * 16777216 + ((descriptor[5] ?? 0) << 16) + ((descriptor[6] ?? 0) << 8) + (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 128) !== 0;\n  if (cancelIndicator) {\n    return void 0;\n  }\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 128) !== 0;\n  const segmentationDurationFlag = (flags & 64) !== 0;\n  let offset = 10;\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return void 0;\n    }\n  }\n  let durationSeconds = void 0;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return void 0;\n    }\n    const durationTicks = (descriptor[offset] ?? 0) * 4294967296 + (descriptor[offset + 1] ?? 0) * 16777216 + ((descriptor[offset + 2] ?? 0) << 16) + ((descriptor[offset + 3] ?? 0) << 8) + (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 9e4;\n    offset += 5;\n  }\n  if (offset + 2 > descriptor.length) {\n    return void 0;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return void 0;\n  }\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return void 0;\n  }\n  return {\n    type: markerType,\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    segmentationEventId\n  };\n}\nfunction parseScte35SegmentationDescriptors(data, offset) {\n  if (offset + 2 > data.length) {\n    return void 0;\n  }\n  const descriptorLoopLength = (data[offset] ?? 0) << 8 | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return void 0;\n    }\n    if (descriptorTag === 2) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n    descriptorOffset = descriptorDataEnd;\n  }\n  return void 0;\n}\nfunction parseScte35Binary(data) {\n  const r = new BitReader(data);\n  const tableId = r.readBits(8);\n  if (tableId !== 252) return void 0;\n  r.readBits(1);\n  r.readBits(1);\n  r.readBits(2);\n  const sectionLength = r.readBits(12);\n  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return void 0;\n  }\n  r.readBits(8);\n  r.readBits(1);\n  r.readBits(6);\n  const ptsAdjHigh = r.readBits(1);\n  const ptsAdjLow = r.readBits(32);\n  const ptsAdjustmentTicks = ptsAdjHigh * 4294967296 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n  let markerType;\n  let durationSeconds = void 0;\n  let ptsSeconds = void 0;\n  let spliceEventId = void 0;\n  const commandBodyStart = r.bytePosition;\n  if (spliceCommandType === 5) {\n    spliceEventId = r.readBits(32);\n    const cancel = r.readBits(1) === 1;\n    r.readBits(7);\n    if (cancel) return void 0;\n    const outOfNetwork = r.readBits(1) === 1;\n    const programSpliceFlag = r.readBits(1) === 1;\n    const durationFlag = r.readBits(1) === 1;\n    const spliceImmediateFlag = r.readBits(1) === 1;\n    r.readBits(4);\n    markerType = outOfNetwork ? \"start\" : \"end\";\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n    } else if (!programSpliceFlag) {\n      const componentCount = r.readBits(8);\n      for (let i = 0; i < componentCount; i++) {\n        r.readBits(8);\n        if (!spliceImmediateFlag) {\n          const componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === void 0) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n    if (durationFlag) {\n      r.readBits(6);\n      r.readBits(1);\n      const high = r.readBits(1);\n      const low = r.readBits(32);\n      const durationTicks = high * 4294967296 + low;\n      durationSeconds = durationTicks / 9e4;\n    }\n    r.readBits(16);\n    r.readBits(8);\n    r.readBits(8);\n  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return void 0;\n  }\n  const expectedDescriptorOffset = spliceCommandLength === 4095 ? r.bytePosition : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === void 0) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n  if (!markerType) {\n    return void 0;\n  }\n  const marker = {\n    type: markerType,\n    ...ptsSeconds !== void 0 ? { ptsSeconds } : {},\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...spliceEventId !== void 0 ? { splice_event_id: spliceEventId } : {},\n      ...descriptorMarker?.segmentationEventId !== void 0 ? { segmentation_event_id: descriptorMarker.segmentationEventId } : {}\n    }\n  };\n  return marker;\n}\n\n// src/player/Scte35CueManager.ts\nvar Scte35CueManager = class {\n  constructor(debug, callbacks) {\n    this.pendingScte35Cues = /* @__PURE__ */ new Map();\n    this.recentScte35CueKeys = /* @__PURE__ */ new Map();\n    this.recentScte35CueLimit = 200;\n    this.tsScte35Pids = /* @__PURE__ */ new Set();\n    this.pmtPids = /* @__PURE__ */ new Set();\n    this.processedTsScte35Sections = /* @__PURE__ */ new Set();\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n  get pendingScte35CueKey() {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value) {\n    this.pendingScte35CueKeyValue = value;\n  }\n  get activeScte35BreakKey() {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value) {\n    this.activeScte35BreakKeyValue = value;\n  }\n  get scheduledScte35BreakKey() {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n  createScte35CueContext(source, readiness, frag) {\n    const context = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== void 0) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n  onScte35Cue(marker, context) {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source\n        });\n      }\n      return;\n    }\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source\n        });\n      }\n      return;\n    }\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n  activatePendingScte35CuesForFragment(frag) {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : void 0;\n    if (fragmentSn === void 0) {\n      return;\n    }\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context = {\n        source: cue.source,\n        readiness: \"playback\"\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec = cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n  createScte35Cue(marker, context) {\n    const cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context)\n    };\n    if (context.fragmentSn !== void 0) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== void 0) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n  getScte35CueKey(marker, context) {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n    const scteValue = this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) || this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n    if (context.fragmentSn !== void 0) {\n      return `fragment:${context.fragmentSn}`;\n    }\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1e3)}`;\n  }\n  getPendingScte35CueKey(cue) {\n    return `${cue.marker.type}:${cue.key}:${cue.fragmentSn !== void 0 ? cue.fragmentSn : \"unknown\"}`;\n  }\n  getScte35MarkerRaw(marker) {\n    return typeof marker.raw === \"object\" && marker.raw !== null ? marker.raw : {};\n  }\n  toIdentityString(value) {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return void 0;\n  }\n  isStrongScte35CueKey(key) {\n    return !!(key && (key.startsWith(\"splice:\") || key.startsWith(\"segmentation:\") || key.startsWith(\"daterange:\") || key.startsWith(\"daterange-scte:\")));\n  }\n  hasRecentlyHandledScte35Cue(cue) {\n    if (this.activeScte35BreakKeyValue === cue.key || this.scheduledScte35BreakKeyValue === cue.key) {\n      return true;\n    }\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n  markScte35CueHandled(cue) {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n  trimRecentScte35CueMaps() {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n  shouldAcceptScte35EndCue(cue) {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n    if (this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) && this.isStrongScte35CueKey(cue.key) && this.activeScte35BreakKeyValue !== cue.key) {\n      return false;\n    }\n    return true;\n  }\n};\n\n// src/player/AdConfigManager.ts\nvar AdConfigManager = class {\n  constructor(config, video) {\n    this.vmapBreaks = [];\n    this.consumedVmapBreakIds = /* @__PURE__ */ new Set();\n    this.streamCorrelator = generateCorrelator();\n    this.viewCorrelator = generateCorrelator();\n    this.consentSignals = {};\n    this.podCounter = 0;\n    this.podAssignedByPrefetch = false;\n    this.adRequestPositionInBreak = 0;\n    this.lastHeartbeatTime = 0;\n    this.defaultPodMaxAds = 6;\n    this.config = config;\n    this.video = video;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  isVmapEnabled() {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n  async fetchAdConfiguration() {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n    const vastMode = this.config.vastMode || \"default\";\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n          );\n        }\n        return;\n      }\n      const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n      this.apiVastTagUrl = vastEndpoint;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n          vastEndpoint\n        );\n      }\n      return;\n    }\n    if (this.config.vastTagUrl) {\n      this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n      return;\n    }\n    const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n        apiUrl\n      );\n    }\n    const headers = {};\n    if (this.config.licenseKey) {\n      headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n    }\n    const response = await fetch(apiUrl, { headers });\n    if (!response.ok) {\n      if (this.debug) {\n        console.warn(\n          `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n        );\n      }\n      return;\n    }\n    const data = await response.json();\n    const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n    if (imaPayload) {\n      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n        );\n      }\n    }\n    const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n    if (numberAds != null && numberAds > 0) {\n      this.apiNumberAds = numberAds;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n  async fetchAndParseVmap(vmapUrl) {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n  parseVmapToBreaks(vmapXml) {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed = [];\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode = node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") ?? void 0;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n      const breakId = node.getAttribute(\"breakId\") || `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl\n      });\n    });\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n    return parsed;\n  }\n  parseVmapTimeOffsetToMs(timeOffset) {\n    if (!timeOffset) {\n      return void 0;\n    }\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n    if (normalized === \"end\") {\n      return -1;\n    }\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return (hours * 3600 + minutes * 60 + seconds) * 1e3 + millis;\n    }\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3 * ratio);\n      }\n      return void 0;\n    }\n    return void 0;\n  }\n  getAdBreakKey(adBreak) {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n  resolveBreakStartMs(adBreak) {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1e3);\n      }\n    }\n    return void 0;\n  }\n  findCurrentOrNextBreak(nowMs) {\n    const schedule = this.vmapBreaks;\n    let candidate;\n    const tol = this.config.driftToleranceMs ?? 1e3;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (breakStartMs <= nowMs + tol && (candidate == null || breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n  findBreakForTime(nowMs) {\n    const schedule = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return void 0;\n  }\n  selectVastTagsForBreak(b) {\n    if (!b || !b.vastTagUrl) return void 0;\n    if (b.vastTagUrl.includes(\",\")) {\n      return b.vastTagUrl.split(\",\").map((s) => s.trim()).filter((s) => s.length > 0);\n    }\n    return [b.vastTagUrl];\n  }\n  beginNewAdPod() {\n    this.podCounter++;\n    this.adRequestPositionInBreak = 0;\n  }\n  generateVastUrlsWithCorrelators(baseUrl, count, adPlayer, palNonce, inAdBreak) {\n    const urls = [];\n    for (let i = 0; i < count; i++) {\n      this.adRequestPositionInBreak++;\n      const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n      const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n      const urlWithMacros = applyVastMacros(baseUrl, {\n        correlator: this.viewCorrelator,\n        streamCorrelator: this.streamCorrelator,\n        pod: this.podCounter > 0 ? this.podCounter : void 0,\n        adPosition: this.adRequestPositionInBreak,\n        isCtv: envSignals.isCtv,\n        contentUrl: envSignals.contentUrl,\n        pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? window.location.href : void 0,\n        adWillPlayMuted,\n        adWillAutoPlay: !!this.config.autoplay,\n        appId: envSignals.appId,\n        appName: envSignals.appName,\n        sessionId: envSignals.sessionId,\n        deviceId: envSignals.deviceId,\n        deviceIdType: envSignals.deviceIdType,\n        limitAdTracking: envSignals.limitAdTracking,\n        deviceTypeHint: envSignals.deviceTypeHint,\n        adTest: this.config.adTest,\n        consent: this.consentSignals\n      });\n      const finalUrl = palNonce.injectNonce(urlWithMacros);\n      console.log(\n        `[StormcloudVideoPlayer] Resolved ad request URL (pod=${this.podCounter}, pos=${this.adRequestPositionInBreak}):`,\n        finalUrl\n      );\n      urls.push(finalUrl);\n    }\n    return urls;\n  }\n  resolvePodParams(breakDurationMs) {\n    const maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs;\n    const maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;\n    const minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n  generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {\n    const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : void 0,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? window.location.href : void 0,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals\n    });\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n  // --- Tracking ---\n  initializeTracking() {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config)).then(() => {\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    }).catch((error) => {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n          error\n        );\n      }\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    });\n  }\n  sendHeartbeatIfNeeded() {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n  destroyTracking() {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = void 0;\n    }\n  }\n};\n\n// src/player/AdTimingService.ts\nvar AdTimingService = class {\n  constructor(config, video, callbacks) {\n    this.adRequestWatchdogToken = null;\n    this.adFailsafeToken = null;\n    this.ptsDriftEmaMs = 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.adBreakEpoch = 0;\n    this.adRequestTokenCounter = 0;\n    this.activeAdRequestToken = null;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.totalAdRequestsInBreak = 0;\n    this.maxTotalAdRequestsPerBreak = 10;\n    this.lastAdRequestTime = 0;\n    this.consecutiveFailures = 0;\n    this.maxConsecutiveFailures = 5;\n    this.minAdRequestIntervalMs = 3e3;\n    this.backoffBaseMs = 1e3;\n    this.maxBackoffMs = 15e3;\n    this.defaultMinRemainingMsToStartAd = 4e3;\n    this.failedVastUrls = /* @__PURE__ */ new Set();\n    this.temporaryFailureUrls = /* @__PURE__ */ new Map();\n    this.temporaryFailureCooldownMs = 3e4;\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillThreshold = 3;\n    this.globalNoFillCooldownUntil = 0;\n    this.globalNoFillBackoffBaseMs = 5e3;\n    this.globalNoFillBackoffMaxMs = 6e4;\n    this.globalLastGamRequestTime = 0;\n    this.globalMinGamIntervalMs = 3e3;\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  // --- Ad stop timer ---\n  scheduleAdStopCountdown(remainingMs) {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms);\n  }\n  clearAdStopTimer() {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = void 0;\n    }\n  }\n  ensureAdStoppedByTimer() {\n    this.adStopTimerId = void 0;\n    this.callbacks.onAdStopTimerFired();\n  }\n  // --- Ad start timer ---\n  scheduleAdStartIn(delayMs, marker = { type: \"start\" }, cueKey) {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms);\n  }\n  clearAdStartTimer() {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = void 0;\n    }\n  }\n  // --- PTS drift ---\n  updatePtsDrift(ptsSecondsSample) {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n  resolveScteBreakStartWallClockMs(marker) {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n    const nowMs = this.video.currentTime * 1e3;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n  // --- Duration boundary ---\n  setAdBreakDurationBoundary(durationMs) {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {\n      this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = void 0;\n    }\n  }\n  scheduleAdStopAtBreakBoundary() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n  // --- Duration budget ---\n  getWallClockRemainingAdMs() {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n  getAdBreakEndWallClockMs() {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) {\n      return void 0;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n  getDurationBudgetRemainingMs() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n  getLoadedAdDurationMs(adController) {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1e3);\n  }\n  adFitsRemainingBudget(durationMs) {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n  logAdDurationDecision(accepted, durationMs, adController) {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms \\u2014 requesting another ad`\n      );\n    }\n  }\n  recordPlayedAdDuration(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms \\u2014 total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n  ensureLoadedAdFitsBudget(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n  rejectLoadedAdForDuration(adController) {\n    try {\n      adController.destroy();\n    } catch {\n    }\n  }\n  markAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n  notePodAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n  getRemainingAdMs() {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n  getMinRemainingMsToStartAd() {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n  hasTimeToStartAnotherAd() {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return this.getWallClockRemainingAdMs() > minRemaining && this.getDurationBudgetRemainingMs() > minRemaining;\n  }\n  // --- Circuit breaker ---\n  isTemporaryAdError(error) {\n    const message = error?.message?.toLowerCase() || \"\";\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n  isUrlInCooldown(vastTagUrl) {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n    return true;\n  }\n  cleanupTemporaryFailures() {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n  isGamInCooldown() {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n  recordGamNoFill() {\n    this.globalConsecutiveNoFills++;\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n  resetGamNoFillCounter() {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n  async enforceGlobalRateLimit() {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n  // --- Watchdog ---\n  startAdRequestWatchdog(token) {\n    this.clearAdRequestWatchdog();\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n      this.adRequestWatchdogId = void 0;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs);\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n  clearAdRequestWatchdog() {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = void 0;\n    }\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n  // --- Failsafe ---\n  startAdFailsafeTimer(token) {\n    this.clearAdFailsafeTimer();\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adFailsafeToken = token;\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n      this.adFailsafeTimerId = void 0;\n      this.adFailsafeToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused\n      });\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs);\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n  clearAdFailsafeTimer() {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = void 0;\n    }\n    this.adFailsafeToken = null;\n  }\n  logAdState(event, extra = {}, adPlayer, inAdBreak, showAds) {\n    if (!this.debug) {\n      return;\n    }\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra\n    });\n  }\n  // --- Reset for ad break end ---\n  resetForBreakEnd() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = void 0;\n    this.currentAdBreakStartWallClockMs = void 0;\n    this.scteAdBreakEndWallClockMs = void 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n  destroy() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n};\n\n// src/player/AdPreloadPool.ts\nvar AdPreloadPool = class {\n  constructor(deps) {\n    this.pool = [];\n    this.maxPoolSize = 2;\n    this.poolActive = false;\n    this.loopRunning = false;\n    this.deps = deps;\n  }\n  get active() {\n    return this.poolActive;\n  }\n  set active(value) {\n    this.poolActive = value;\n  }\n  get isLoopRunning() {\n    return this.loopRunning;\n  }\n  startPreloadPool(baseVastUrl, initialUrls, startLoopImmediately = true) {\n    if (this.poolActive) {\n      if (this.deps.debug) {\n        console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n      }\n      return;\n    }\n    this.poolActive = true;\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Starting preload pool EARLY (target size: ${this.maxPoolSize})`);\n      console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n    }\n    for (const url of initialUrls) {\n      if (this.pool.length < this.maxPoolSize) {\n        this.preloadAdIntoPool(url);\n      }\n    }\n    if (startLoopImmediately) {\n      this.preloadPoolLoop(baseVastUrl);\n    } else if (this.deps.debug) {\n      console.log(\n        \"[PRELOAD-POOL] Pre-break mode: preloaded once, waiting for SCTE start to continue fetching\"\n      );\n    }\n  }\n  async preloadAdIntoPool(vastUrl) {\n    const timing = this.deps.timing;\n    if (timing.isGamInCooldown()) {\n      if (this.deps.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping preload\");\n      }\n      return;\n    }\n    if (this.pool.some((entry) => entry.vastUrl === vastUrl) || timing.failedVastUrls.has(vastUrl) || timing.isUrlInCooldown(vastUrl)) {\n      return;\n    }\n    if (this.pool.length >= this.maxPoolSize) {\n      return;\n    }\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Preloading ad into pool: ${vastUrl}`);\n    }\n    const epoch = timing.adBreakEpoch;\n    const loadPromise = (async () => {\n      let hasAdError = false;\n      let adErrorPayload = null;\n      let errorListenerCleanup = null;\n      try {\n        const continueLiveStreamDuringAds = this.deps.shouldContinueLiveStreamDuringAds();\n        const preloadAd = this.deps.createAdPlayer(continueLiveStreamDuringAds);\n        preloadAd.initialize();\n        const errorListener = (payload) => {\n          hasAdError = true;\n          adErrorPayload = payload;\n        };\n        preloadAd.on(\"ad_error\", errorListener);\n        errorListenerCleanup = () => preloadAd.off(\"ad_error\", errorListener);\n        await timing.enforceGlobalRateLimit();\n        await preloadAd.requestAds(vastUrl);\n        preloadAd.pause();\n        await new Promise((resolve) => setTimeout(resolve, 1500));\n        preloadAd.pause();\n        if (hasAdError) {\n          const isNoFill = adErrorPayload?.isNoFill || adErrorPayload?.code === 303 || adErrorPayload?.vastErrorCode === 303;\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          preloadAd.destroy();\n          timing.recordGamNoFill();\n          if (isNoFill) {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload returned no-fill: ${vastUrl}`);\n            }\n            timing.temporaryFailureUrls.set(vastUrl, Date.now());\n          } else {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n            }\n            if (adErrorPayload && !timing.isTemporaryAdError(adErrorPayload)) {\n              timing.failedVastUrls.add(vastUrl);\n            } else {\n              timing.temporaryFailureUrls.set(vastUrl, Date.now());\n            }\n          }\n          return;\n        }\n        if (!this.poolActive || epoch !== timing.adBreakEpoch) {\n          if (this.deps.debug) {\n            console.log(\n              \"[PRELOAD-POOL] Discarding preloaded ad - break ended during fetch\"\n            );\n          }\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          try {\n            preloadAd.destroy();\n          } catch {\n          }\n          return;\n        }\n        const poolEntry = {\n          vastUrl,\n          adController: preloadAd,\n          loadedAt: Date.now(),\n          isReady: true,\n          loadPromise: Promise.resolve()\n        };\n        const loadedDuration = preloadAd.getLoadedAdDuration?.();\n        if (loadedDuration != null && loadedDuration > 0) {\n          poolEntry.durationSeconds = loadedDuration;\n        }\n        const lateErrorListener = (payload) => {\n          const index = this.pool.findIndex((entry) => entry.vastUrl === vastUrl);\n          if (index >= 0) {\n            this.pool.splice(index, 1);\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Late error detected, removed from pool: ${vastUrl}`, payload);\n            }\n            try {\n              preloadAd.destroy();\n            } catch {\n            }\n          }\n        };\n        preloadAd.on(\"ad_error\", lateErrorListener);\n        this.pool.push(poolEntry);\n        if (this.deps.debug) {\n          console.log(`[PRELOAD-POOL] Ad preloaded (no errors detected within timeout) (pool size: ${this.pool.length}/${this.maxPoolSize}, duration=${poolEntry.durationSeconds ?? \"?\"}s)`);\n        }\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n      } catch (error) {\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n        timing.recordGamNoFill();\n        if (this.deps.debug) {\n          console.warn(`[PRELOAD-POOL] Failed to preload ad: ${vastUrl}`, error);\n        }\n        if (error instanceof Error && !timing.isTemporaryAdError(error)) {\n          timing.failedVastUrls.add(vastUrl);\n        } else if (error instanceof Error && timing.isTemporaryAdError(error)) {\n          timing.temporaryFailureUrls.set(vastUrl, Date.now());\n        }\n      }\n    })();\n    loadPromise.catch(() => {\n    });\n  }\n  async preloadPoolLoop(baseVastUrl) {\n    if (this.loopRunning) {\n      return;\n    }\n    this.loopRunning = true;\n    const epoch = this.deps.timing.adBreakEpoch;\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Starting continuous preload loop\");\n    }\n    while (this.poolActive && epoch === this.deps.timing.adBreakEpoch) {\n      if (this.deps.timing.isGamInCooldown()) {\n        if (this.deps.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop\");\n        }\n        break;\n      }\n      if (!this.deps.isInAdBreak() && this.pool.length >= this.maxPoolSize) {\n        await new Promise((resolve) => setTimeout(resolve, 2e3));\n        continue;\n      }\n      if (!this.deps.isInAdBreak() && this.deps.getPendingAdBreak() === null) {\n        if (this.deps.debug) {\n          console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n        }\n        break;\n      }\n      while (this.pool.length < this.maxPoolSize) {\n        if (!this.poolActive || epoch !== this.deps.timing.adBreakEpoch || this.deps.timing.isGamInCooldown()) {\n          break;\n        }\n        if (this.deps.isInAdBreak() && !this.deps.timing.hasTimeToStartAnotherAd()) {\n          if (this.deps.debug) {\n            console.log(\"[PRELOAD-POOL] Not enough ad break time left, stopping preload\");\n          }\n          break;\n        }\n        const newUrls = this.deps.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n        const newUrl = newUrls[0];\n        if (newUrl && !this.deps.timing.failedVastUrls.has(newUrl) && !this.deps.timing.isUrlInCooldown(newUrl)) {\n          await this.preloadAdIntoPool(newUrl);\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1e3));\n      }\n      await new Promise((resolve) => setTimeout(resolve, 2e3));\n    }\n    this.loopRunning = false;\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload loop ended\");\n    }\n  }\n  getPreloadedAd() {\n    if (this.pool.length === 0) {\n      return null;\n    }\n    const entry = this.pool.shift();\n    if (!entry || !entry.isReady) {\n      return null;\n    }\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Using preloaded ad from pool (${this.pool.length} remaining)`);\n    }\n    return {\n      vastUrl: entry.vastUrl,\n      adController: entry.adController\n    };\n  }\n  stop() {\n    this.poolActive = false;\n    this.loopRunning = false;\n    for (const entry of this.pool) {\n      try {\n        entry.adController.destroy();\n      } catch (error) {\n        if (this.deps.debug) {\n          console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n        }\n      }\n    }\n    this.pool = [];\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload pool stopped and cleaned up\");\n    }\n  }\n};\n\n// src/player/PlaceholderLayer.ts\nvar PlaceholderLayer = class {\n  constructor(video, debug) {\n    this.video = video;\n    this.debug = debug;\n  }\n  ensureContainer() {\n    if (this.container) {\n      return;\n    }\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n  show() {\n    this.ensureContainer();\n    if (!this.container) {\n      return;\n    }\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n  hide() {\n    if (!this.container) {\n      return;\n    }\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n  destroy() {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = void 0;\n    }\n  }\n};\n\n// src/player/HlsEngine.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\nvar HlsEngine = class {\n  constructor(config, video, cueManager, timing, callbacks) {\n    this.isLiveStream = false;\n    this.nativeHlsMode = false;\n    this.videoSrcProtection = null;\n    this.bufferedSegmentsCount = 0;\n    this.shouldAutoplayAfterBuffering = false;\n    this.hasInitialBufferCompleted = false;\n    this.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  shouldUseNativeHls(getStreamType) {\n    const streamType = getStreamType();\n    if (streamType === \"other\") {\n      return true;\n    }\n    const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n    return !!(this.config.allowNativeHls && canNative);\n  }\n  async setupNativeHls() {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n    if (this.debug) {\n      const adBehavior = this.isLiveStream ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior\n        }\n      );\n    }\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {\n      });\n    }\n  }\n  setupHls() {\n    this.hls = new import_hls2.default({\n      enableWorker: true,\n      backBufferLength: 30,\n      liveDurationInfinity: true,\n      lowLatencyMode: !!this.config.lowLatencyMode,\n      maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1,\n      ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {},\n      maxBufferLength: 30,\n      maxMaxBufferLength: 600,\n      maxBufferSize: 60 * 1e3 * 1e3,\n      maxBufferHole: 0.5,\n      highBufferWatchdogPeriod: 2,\n      nudgeOffset: 0.1,\n      nudgeMaxRetry: 3,\n      startPosition: -1\n    });\n    this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {\n      this.hls?.loadSource(this.config.src);\n    });\n    this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, _data) => {\n      this.isLiveStream = this.config.isLiveStream ?? (this.hls?.levels?.some(\n        (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n      ) ?? false);\n      await this.callbacks.onManifestParsed(this.isLiveStream);\n      this.bufferedSegmentsCount = 0;\n      this.hasInitialBufferCompleted = false;\n      this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {\n          });\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.LEVEL_LOADED, (_evt, data) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList = frag?.tagList;\n        if (!Array.isArray(tagList)) continue;\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n          if (!tag) continue;\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\") ? parseAttributeList(value) : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") || \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker = {\n                type: \"start\",\n                ...durationSeconds !== void 0 ? { durationSeconds } : {},\n                raw: { tag, value, earlyDetection: true }\n              };\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag)\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_BUFFERED, async (_evt, _data) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n        );\n      }\n      if (this.bufferedSegmentsCount >= minSegments) {\n        this.hasInitialBufferCompleted = true;\n        if (this.shouldAutoplayAfterBuffering) {\n          if (this.debug) {\n            console.log(\n              `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n            );\n          }\n          await this.video.play()?.catch((err) => {\n            if (this.debug) {\n              console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n            }\n          });\n        }\n      }\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {\n      const id3Tags = (data?.samples || []).map((s) => ({\n        key: \"ID3\",\n        value: s?.data,\n        ptsSeconds: s?.pts\n      }));\n      id3Tags.forEach((tag) => this.onId3Tag(tag));\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_LOADED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_DECRYPTED, (_evt, data) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : void 0,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n    this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {\n      const frag = data?.frag;\n      const tagList = frag?.tagList;\n      if (!Array.isArray(tagList)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        return;\n      }\n      for (const entry of tagList) {\n        let tag = \"\";\n        let value = \"\";\n        if (Array.isArray(entry)) {\n          tag = String(entry[0] ?? \"\");\n          value = String(entry[1] ?? \"\");\n        } else if (typeof entry === \"string\") {\n          const idx = entry.indexOf(\":\");\n          if (idx >= 0) {\n            tag = entry.substring(0, idx);\n            value = entry.substring(idx + 1);\n          } else {\n            tag = entry;\n            value = \"\";\n          }\n        }\n        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = parseCueOutCont(value);\n          const marker = {\n            type: \"progress\",\n            ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},\n            ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},\n            raw: { tag, value }\n          };\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker = {\n            type: \"start\",\n            ...durationSeconds !== void 0 ? { durationSeconds } : {},\n            raw: { tag, value }\n          };\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = parseAttributeList(value);\n          const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n          const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n          const klass = String(attrs[\"CLASS\"] ?? \"\");\n          const duration = toNumber(attrs[\"DURATION\"]);\n          if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n            const marker = {\n              type: \"start\",\n              ...duration !== void 0 ? { durationSeconds: duration } : {},\n              raw: { tag, value, attrs }\n            };\n            this.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag)\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\n    });\n    this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {\n      if (data?.fatal) {\n        switch (data.type) {\n          case import_hls2.default.ErrorTypes.NETWORK_ERROR:\n            this.hls?.startLoad();\n            break;\n          case import_hls2.default.ErrorTypes.MEDIA_ERROR:\n            this.hls?.recoverMediaError();\n            break;\n          default:\n            this.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n    this.hls.attachMedia(this.video);\n  }\n  onId3Tag(tag) {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\"\n      });\n    }\n  }\n  processFragmentScte35Payload(payloadData, fragmentSn, fragmentStartSeconds) {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context = {\n        source: \"ts\",\n        readiness: \"early\"\n      };\n      if (fragmentSn !== void 0) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n  getLiveSyncPosition() {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : void 0;\n  }\n  destroy() {\n    this.hls?.destroy();\n    this.hls = void 0;\n  }\n};\n\n// src/player/PlayerControls.ts\nfunction getAdAudioVolume(adPlayer) {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\nfunction toggleMute(video, adPlayer, debug) {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\nfunction toggleFullscreen(video, debug) {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container.requestFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n        }\n        reject(err);\n      });\n    } else {\n      document.exitFullscreen().then(() => {\n        if (debug) {\n          console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n        }\n        resolve();\n      }).catch((err) => {\n        if (debug) {\n          console.error(\n            \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n            err\n          );\n        }\n        reject(err);\n      });\n    }\n  });\n}\nfunction isMuted(video, adPlayer) {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\nfunction setMuted(video, adPlayer, muted, debug) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n  video.muted = muted;\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted\n      });\n    }\n    return;\n  }\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\nfunction setVolume(video, adPlayer, volume, debug) {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\nfunction getVolume(video, adPlayer) {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\nfunction isFullscreen() {\n  return !!document.fullscreenElement;\n}\nfunction resizePlayer(video, adPlayer, debug) {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n    adPlayer.resize(width, height);\n  }\n}\n\n// src/player/AdBreakOrchestrator.ts\nvar AdBreakOrchestrator = class {\n  constructor(host, timing, preloadPool, adConfig, cueManager, placeholder) {\n    this.inAdBreak = false;\n    this.showAds = false;\n    this.isShowingPlaceholder = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.adRequestQueue = [];\n    this.adPodQueue = [];\n    this.maxPlaceholderDurationMs = 5e3;\n    this.pendingAdBreak = null;\n    this.host = host;\n    this.timing = timing;\n    this.preloadPool = preloadPool;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n  get debug() {\n    return !!this.host.config.debugAdTiming;\n  }\n  get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n  get optimizedPodsEnabled() {\n    return this.host.config.optimizedPods !== false;\n  }\n  attachImaEventListeners() {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      this.timing.consecutiveFailures = 0;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload) => {\n      let errorMessage = \"Ad playback failed\";\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n      if (!this.inAdBreak) {\n        return;\n      }\n      this.timing.consecutiveFailures = 0;\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n  recreateAdController() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n  clearPendingAdBreak() {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = void 0;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = void 0;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n  async handleAdStart(_marker) {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1e3\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n    const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    if (this.timing.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n    if (this.optimizedPodsEnabled) {\n      const podPlayed = await this.startOptimizedPod(\n        baseVastUrl,\n        adBreakDurationMs,\n        currentMuted,\n        currentVolume\n      );\n      if (podPlayed) {\n        return;\n      }\n      if (this.debug) {\n        console.log(\"[POD] Optimized pod unavailable, falling back to sequential single-ad path\");\n      }\n    }\n    let firstAdUrl;\n    let usePreloadedAd = false;\n    let preloadedController;\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      firstAdUrl = preloaded.vastUrl;\n      preloadedController = preloaded.adController;\n      usePreloadedAd = true;\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: firstAdUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n      }\n    } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n      firstAdUrl = this.adRequestQueue.shift();\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n      }\n      this.clearPendingAdBreak();\n    } else {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Generating new ad URLs...\");\n      }\n      const firstAdUrlArray = this.host.generateVastUrls(baseVastUrl, 1);\n      firstAdUrl = firstAdUrlArray[0];\n      this.adRequestQueue = [];\n    }\n    if (!firstAdUrl) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] Failed to get first ad URL\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] First VAST URL:\", firstAdUrl);\n    }\n    try {\n      if (usePreloadedAd && preloadedController) {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloadedController)) {\n          this.timing.rejectLoadedAdForDuration(preloadedController);\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        const adPlayer = this.host.getAdPlayer();\n        const preservedMuted = adPlayer.getOriginalMutedState();\n        const preservedVolume = adPlayer.getOriginalVolume();\n        adPlayer.destroy();\n        this.host.video.muted = true;\n        this.host.setAdPlayer(preloadedController);\n        preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n        this.attachImaEventListeners();\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n        }\n        preloadedController.resume();\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.active = true;\n        }\n        if (!this.preloadPool.isLoopRunning) {\n          this.preloadPool.preloadPoolLoop(baseVastUrl);\n        }\n        await preloadedController.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        const adVolume = currentMuted ? 0 : currentVolume;\n        preloadedController.setAdVolume(adVolume);\n      } else {\n        const adPlayer = this.host.getAdPlayer();\n        await this.timing.enforceGlobalRateLimit();\n        this.timing.lastAdRequestTime = Date.now();\n        await adPlayer.requestAds(firstAdUrl);\n        sendAdLoadedTracking(\n          this.host.config.licenseKey,\n          { source: \"hls\", vastUrl: firstAdUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n          this.analyticsContext\n        ).catch(() => {\n        });\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad request successful, starting playback\");\n        }\n        if (!this.timing.ensureLoadedAdFitsBudget(adPlayer)) {\n          this.timing.rejectLoadedAdForDuration(adPlayer);\n          this.recreateAdController();\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n        await adPlayer.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        const adVolume = currentMuted ? 0 : currentVolume;\n        adPlayer.setAdVolume(adVolume);\n      }\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] First ad request failed:\", error);\n      }\n      if (!usePreloadedAd) {\n        const fallbackPreloaded = this.preloadPool.getPreloadedAd();\n        if (fallbackPreloaded) {\n          if (this.debug) {\n            console.log(\"[CONTINUOUS-FETCH] First ad failed, using preloaded fallback\");\n          }\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(fallbackPreloaded.adController)) {\n              this.timing.rejectLoadedAdForDuration(fallbackPreloaded.adController);\n              this.startContinuousFetching(baseVastUrl);\n              await this.tryNextAvailableAdWithRateLimit();\n              return;\n            }\n            this.swapToPreloadedAdPlayer(fallbackPreloaded.adController);\n            this.timing.consecutiveFailures = 0;\n            this.startContinuousFetching(baseVastUrl);\n            if (!this.preloadPool.active) {\n              this.preloadPool.active = true;\n              this.preloadPool.preloadPoolLoop(baseVastUrl);\n            }\n            const ap = this.host.getAdPlayer();\n            await ap.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            const adVolume = currentMuted ? 0 : currentVolume;\n            ap.setAdVolume(adVolume);\n            return;\n          } catch (fallbackError) {\n            if (this.debug) {\n              console.warn(\"[CONTINUOUS-FETCH] Preloaded fallback also failed:\", fallbackError);\n            }\n          }\n        }\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(firstAdUrl, Date.now());\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n        }\n      } else {\n        this.timing.failedVastUrls.add(firstAdUrl);\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n        }\n      }\n      this.timing.consecutiveFailures++;\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n  async startOptimizedPod(baseVastUrl, breakDurationMs, currentMuted, currentVolume) {\n    let podUrl;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n    if (!podUrl) {\n      return false;\n    }\n    this.continuousFetchingActive = false;\n    this.recreateAdController();\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n      if (this.debug) {\n        console.log(\n          podCount === 1 ? \"[POD] Response contained a single ad; playing it and enabling sequential top-up\" : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n      if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n      if (podCount === 1) {\n        this.continuousFetchingActive = true;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n      }\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n  swapToPreloadedAdPlayer(preloadedController) {\n    const adPlayer = this.host.getAdPlayer();\n    const preservedMuted = adPlayer.getOriginalMutedState();\n    const preservedVolume = adPlayer.getOriginalVolume();\n    adPlayer.destroy();\n    this.host.video.muted = true;\n    this.host.setAdPlayer(preloadedController);\n    this.attachImaEventListeners();\n    preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n    preloadedController.resume();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n  startContinuousFetching(baseVastUrl) {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n  async continuousFetchLoop(baseVastUrl) {\n    const epoch = this.timing.adBreakEpoch;\n    while (this.continuousFetchingActive && this.inAdBreak && epoch === this.timing.adBreakEpoch) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1e3));\n        continue;\n      }\n      const newAdUrl = this.host.generateVastUrls(baseVastUrl, 1)[0];\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise((resolve) => setTimeout(resolve, 500));\n        continue;\n      }\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n      this.adRequestQueue.push(newAdUrl);\n      const generationDelay = this.timing.consecutiveFailures > 0 ? Math.min(1e3 * Math.pow(2, this.timing.consecutiveFailures), 5e3) : 500;\n      await new Promise((resolve) => setTimeout(resolve, generationDelay));\n    }\n    this.continuousFetchLoopRunning = false;\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n  stopContinuousFetching() {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n    this.placeholder.hide();\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n  async tryNextAvailableAdWithRateLimit() {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const epoch = this.timing.adBreakEpoch;\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitTime));\n    }\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n    return this.tryNextAvailableAd(0);\n  }\n  async tryNextAvailableAd(retryCount = 0) {\n    if (!this.inAdBreak) {\n      return;\n    }\n    const remaining = this.timing.getRemainingAdMs();\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n    this.timing.cleanupTemporaryFailures();\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Using preloaded ad from pool`);\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: preloaded.vastUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      try {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloaded.adController)) {\n          this.timing.rejectLoadedAdForDuration(preloaded.adController);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        this.swapToPreloadedAdPlayer(preloaded.adController);\n        const ap = this.host.getAdPlayer();\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        return;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[CONTINUOUS-FETCH] Preloaded ad failed to play:\", error);\n        }\n      }\n    }\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n      if (!nextAdUrl) continue;\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = error.message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n    if (!this.isShowingPlaceholder && remaining > 1e3) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n  async playSingleAd(vastTagUrl) {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n    this.recreateAdController();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n        const preloadedFallback = this.preloadPool.getPreloadedAd();\n        if (preloadedFallback) {\n          if (this.debug) console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n              this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n              throw playError;\n            }\n            this.timing.clearAdFailsafeTimer();\n            this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n            this.timing.consecutiveFailures = 0;\n            const fbAp = this.host.getAdPlayer();\n            await fbAp.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            fbAp.setAdVolume(getAdAudioVolume(fbAp));\n            return;\n          } catch (fallbackError) {\n            if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n          }\n        }\n        if (this.timing.isTemporaryAdError(playError)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = error?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n      const preloadedFallback = this.preloadPool.getPreloadedAd();\n      if (preloadedFallback) {\n        if (this.debug) console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n        try {\n          if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n            this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n            throw error;\n          }\n          this.timing.clearAdRequestWatchdog();\n          this.timing.clearAdFailsafeTimer();\n          this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n          this.timing.consecutiveFailures = 0;\n          const fbAp = this.host.getAdPlayer();\n          await fbAp.play();\n          this.timing.markAdStarted();\n          fbAp.setAdVolume(getAdAudioVolume(fbAp));\n          return;\n        } catch (fallbackError) {\n          if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n        }\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n  async showPlaceholderAndWaitForAds() {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n    if (waitTime < 1e3) {\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n      if (!this.inAdBreak) return;\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = error.message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n  handleAdPodComplete() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n    this.timing.resetForBreakEnd();\n    this.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.clearPendingAdBreak();\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n    this.adRequestQueue = [];\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = void 0;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    this.host.getAdPlayer().stop().catch(() => {\n    });\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end \\u2014 snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s \\u2192 ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {\n        });\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {\n      });\n    }\n  }\n  handleAdFailure() {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n};\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n  constructor(config) {\n    this.attached = false;\n    this.palPlaybackStarted = false;\n    initializePolyfills();\n    const browserOverrides = getBrowserConfigOverrides();\n    this.config = { ...browserOverrides, ...config };\n    this.video = config.videoElement;\n    logBrowserInfo(config.debugAdTiming);\n    this.adPlayer = this.createAdPlayer(false);\n    this.palNonce = createPalNonceManager();\n    this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {\n      onEarlyStartCue: (marker, fragmentSn, cueKey) => {\n        this.startAdPrefetch(marker, fragmentSn, cueKey);\n      },\n      onPlaybackCue: (marker, cueKey) => {\n        this.onScte35Marker(marker, cueKey);\n      },\n      isInAdBreak: () => this.adBreak.inAdBreak\n    });\n    this.adConfig = new AdConfigManager(this.config, this.video);\n    this.timing = new AdTimingService(this.config, this.video, {\n      onAdStopTimerFired: () => this.onAdStopTimerFired(),\n      onAdStartTimerFired: (marker, cueKey) => {\n        this.startScte35AdBreak(\n          marker,\n          cueKey,\n          marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.timing.expectedAdBreakDurationMs\n        );\n      },\n      onWatchdogTimeout: () => this.adBreak.handleAdFailure(),\n      onFailsafeTimeout: () => this.adBreak.handleAdFailure()\n    });\n    this.preloadPool = new AdPreloadPool({\n      debug: !!this.config.debugAdTiming,\n      createAdPlayer: (c) => this.createAdPlayer(c),\n      shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n      timing: this.timing,\n      generateVastUrlsWithCorrelators: (base, count) => this.generateVastUrls(base, count),\n      isInAdBreak: () => this.adBreak.inAdBreak,\n      getPendingAdBreak: () => this.adBreak.pendingAdBreak\n    });\n    this.placeholder = new PlaceholderLayer(this.video, !!this.config.debugAdTiming);\n    this.hlsEngine = new HlsEngine(this.config, this.video, this.cueManager, this.timing, {\n      onManifestParsed: async (isLive) => this.onManifestParsed(isLive),\n      onScte35Cue: (marker, context) => this.cueManager.onScte35Cue(marker, context),\n      activatePendingCuesForFragment: (frag) => this.cueManager.activatePendingScte35CuesForFragment(frag),\n      onFatalDestroy: () => this.destroy(),\n      isInAdBreak: () => this.adBreak.inAdBreak,\n      hasPendingAdBreak: () => this.adBreak.pendingAdBreak !== null\n    });\n    this.adBreak = new AdBreakOrchestrator(\n      {\n        config: this.config,\n        video: this.video,\n        getAdPlayer: () => this.adPlayer,\n        setAdPlayer: (p) => {\n          this.adPlayer = p;\n        },\n        createAdPlayer: (c) => this.createAdPlayer(c),\n        shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n        getLiveSyncPosition: () => this.hlsEngine.getLiveSyncPosition(),\n        generateVastUrls: (base, count) => this.generateVastUrls(base, count),\n        generatePodVastUrl: (base, breakDurationMs) => this.generatePodVastUrl(base, breakDurationMs)\n      },\n      this.timing,\n      this.preloadPool,\n      this.adConfig,\n      this.cueManager,\n      this.placeholder\n    );\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  createAdPlayer(continueLiveStreamDuringAds) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Creating HLS ad player\");\n    }\n    return createHlsAdPlayer(this.video, {\n      continueLiveStreamDuringAds,\n      ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n      ...this.hlsEngine?.hls ? { mainHlsInstance: this.hlsEngine.hls } : {}\n    });\n  }\n  generateVastUrls(baseUrl, count) {\n    return this.adConfig.generateVastUrlsWithCorrelators(\n      baseUrl,\n      count,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  generatePodVastUrl(baseUrl, breakDurationMs) {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl,\n      podParams,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n  async load() {\n    if (!this.attached) {\n      this.attach();\n    }\n    try {\n      await this.adConfig.fetchAdConfiguration();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n          error\n        );\n      }\n    }\n    this.palNonce.generateNonce({\n      videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,\n      videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,\n      adWillAutoPlay: !!this.config.autoplay,\n      adWillPlayMuted: true,\n      playerVolume: 0,\n      continuousPlayback: this.config.lowLatencyMode ?? false\n    }).catch(() => {\n    });\n    fetchConsentSignals().then((signals) => {\n      this.adConfig.consentSignals = signals;\n    }).catch(() => {\n    });\n    this.adConfig.initializeTracking();\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n      const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Native HLS ad behavior:\", {\n          isLive: this.hlsEngine.isLiveStream,\n          continueLiveStreamDuringAds\n        });\n      }\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n    this.hlsEngine.setupHls();\n  }\n  async onManifestParsed(isLive) {\n    if (!this.adConfig.isVmapEnabled() && !isLive && this.adConfig.vmapBreaks.length === 0 && this.adConfig.apiVastTagUrl) {\n      const prerollKey = \"synthetic-vod-preroll\";\n      if (!this.adConfig.consumedVmapBreakIds.has(prerollKey)) {\n        this.adConfig.vmapBreaks = [\n          { id: prerollKey, startTimeMs: 0, vastTagUrl: this.adConfig.apiVastTagUrl }\n        ];\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Injected synthetic VOD preroll from apiVastTagUrl\"\n          );\n        }\n      }\n    }\n    if (this.debug) {\n      const adBehavior = this.shouldContinueLiveStreamDuringAds() ? \"live (main video continues muted during ads)\" : \"vod (main video pauses during ads)\";\n      console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n        isLive,\n        allowNativeHls: this.config.allowNativeHls,\n        adBehavior\n      });\n    }\n    this.adPlayer.destroy();\n    this.adPlayer = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n    this.adPlayer.initialize();\n  }\n  attach() {\n    if (this.attached) return;\n    this.attached = true;\n    this.video.autoplay = !!this.config.autoplay;\n    this.video.muted = !!this.config.muted;\n    this.adPlayer.initialize();\n    this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n    this.adBreak.attachImaEventListeners();\n    this.video.addEventListener(\"play\", () => {\n      if (!this.palPlaybackStarted && !this.adPlayer.isAdPlaying()) {\n        this.palPlaybackStarted = true;\n        this.palNonce.sendPlaybackStart();\n      }\n    });\n    this.endedHandler = () => {\n      if (this.palPlaybackStarted) {\n        this.palPlaybackStarted = false;\n        this.palNonce.sendPlaybackEnd();\n      }\n      this.onVideoEnded();\n    };\n    this.video.addEventListener(\"ended\", this.endedHandler);\n    this.video.addEventListener(\"mousedown\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.video.addEventListener(\"touchstart\", (e) => {\n      this.palNonce.sendAdTouch(e);\n    });\n    this.timeUpdateHandler = () => {\n      this.onTimeUpdate(this.video.currentTime);\n    };\n    this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n    this.emptiedHandler = () => {\n      if (this.hlsEngine.nativeHlsMode && this.hlsEngine.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n        if (this.debug) {\n          console.log(\n            \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n            this.hlsEngine.videoSrcProtection\n          );\n        }\n        const currentTime = this.video.currentTime;\n        const wasPaused = this.video.paused;\n        this.video.src = this.hlsEngine.videoSrcProtection;\n        this.video.currentTime = currentTime;\n        if (!wasPaused) {\n          this.video.play().catch(() => {\n          });\n        }\n      }\n    };\n    this.video.addEventListener(\"emptied\", this.emptiedHandler);\n  }\n  shouldContinueLiveStreamDuringAds() {\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n    return false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n  onScte35Marker(marker, cueKey) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n        type: marker.type,\n        ptsSeconds: marker.ptsSeconds,\n        durationSeconds: marker.durationSeconds,\n        currentTime: this.video.currentTime,\n        raw: marker.raw,\n        hasPendingAdBreak: !!this.adBreak.pendingAdBreak\n      });\n    }\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1e3;\n          if (this.timing.expectedAdBreakDurationMs == null || newDurationMs > this.timing.expectedAdBreakDurationMs) {\n            this.timing.setAdBreakDurationBoundary(newDurationMs);\n            this.timing.scheduleAdStopAtBreakBoundary();\n            if (this.debug) {\n              console.log(\n                `[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${newDurationMs}ms, remaining: ${this.timing.getWallClockRemainingAdMs()}ms`\n              );\n            }\n          }\n        }\n        return;\n      }\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload = {};\n        if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n        if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n        sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n        });\n      }\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n      const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.adBreak.pendingAdBreak?.marker.durationSeconds != null ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n          isManifestMarker: isManifest,\n          forceImmediate,\n          hasPts: typeof marker.ptsSeconds === \"number\",\n          hasPrefetchedAds\n        });\n      }\n      if (isManifest && forceImmediate) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n          );\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      } else if (typeof marker.ptsSeconds === \"number\") {\n        const tol = this.config.driftToleranceMs ?? 1e3;\n        const nowMs = this.video.currentTime * 1e3;\n        const estCurrentPtsMs = nowMs - this.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n            nowMs,\n            estCurrentPtsMs,\n            markerPtsMs: marker.ptsSeconds * 1e3,\n            deltaMs,\n            tolerance: tol\n          });\n        }\n        if (deltaMs > tol) {\n          if (this.debug) {\n            console.log(`[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`);\n          }\n          this.timing.expectedAdBreakDurationMs = durationMs;\n          this.cueManager.scheduledScte35BreakKey = cueKey;\n          this.timing.scheduleAdStartIn(deltaMs, marker, cueKey);\n        } else {\n          if (this.debug) {\n            console.log(\"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\");\n          }\n          this.timing.clearAdStartTimer();\n          this.startScte35AdBreak(marker, cueKey, durationMs);\n        }\n      } else {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad immediately (fallback)\");\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      }\n      return;\n    }\n    if (marker.type === \"progress\" && this.adBreak.inAdBreak) {\n      if (marker.durationSeconds != null) {\n        this.timing.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n      if (!this.adPlayer.isAdPlaying() && this.timing.activeAdRequestToken === null && this.adBreak.adRequestQueue.length > 0 && this.timing.hasTimeToStartAnotherAd()) {\n        this.adBreak.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    if (marker.type === \"end\") {\n      if (!this.video.muted) {\n        this.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n        }\n      }\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n          remaining,\n          adPlaying,\n          hasQueuedAds,\n          activeAdRequest: this.timing.activeAdRequestToken !== null\n        });\n      }\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {\n        });\n      }\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n  startScte35AdBreak(marker, cueKey, durationMs) {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n    this.adBreak.handleAdStart(marker);\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n  onAdStopTimerFired() {\n    if (!this.adBreak.inAdBreak) return;\n    const adPlaying = this.adPlayer.isAdPlaying();\n    const checkIntervalMs = Math.max(\n      250,\n      Math.floor(this.config.adBreakCheckIntervalMs ?? 1e3)\n    );\n    const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n    const maxExtensionMs = typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Ad break boundary reached (overrun=${overrunMs}ms) - hard-stopping ads and resuming stream`\n      );\n    }\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {\n      });\n    }\n    this.adBreak.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n  startAdPrefetch(marker, fragmentSn, cueKey) {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1e3);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      if (this.debug) console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n      return;\n    }\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n    const optimizedPods = this.config.optimizedPods !== false;\n    const breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;\n    const generatedUrls = optimizedPods ? [this.generatePodVastUrl(baseVastUrl, breakDurationMs)] : this.generateVastUrls(baseVastUrl, 1);\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now()\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;\n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n    });\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(\n        `[PREFETCH] Pre-generated ${generatedUrls.length} ${optimizedPods ? \"pod\" : \"VAST\"} URL(s)`\n      );\n    }\n    if (optimizedPods) {\n      if (this.debug) {\n        console.log(\"[PREFETCH] Optimized pods enabled - skipping single-ad preload pool\");\n      }\n      return;\n    }\n    this.preloadPool.startPreloadPool(baseVastUrl, generatedUrls.slice(0, 1), false);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  VMAP time-based ad breaks\n  // ───────────────────────────────────────────────────────────────\n  onTimeUpdate(currentTimeSec) {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const nowMs = currentTimeSec * 1e3;\n    const breakToPlay = this.adConfig.findBreakForTime(nowMs);\n    if (breakToPlay) {\n      void this.handleVmapAdBreak(breakToPlay, nowMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad break failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  onVideoEnded() {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const durationMs = Number.isFinite(this.video.duration) ? Math.floor(this.video.duration * 1e3) : 0;\n    const postroll = this.adConfig.vmapBreaks.find(\n      (b) => b.startTimeMs === -1 && !this.adConfig.consumedVmapBreakIds.has(this.adConfig.getAdBreakKey(b))\n    );\n    if (postroll) {\n      void this.handleVmapAdBreak(postroll, durationMs).catch((error) => {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP post-roll failed gracefully:\", error);\n        }\n      });\n    }\n  }\n  async handleVmapAdBreak(adBreak, nowMs) {\n    const key = this.adConfig.getAdBreakKey(adBreak);\n    if (this.adConfig.consumedVmapBreakIds.has(key)) return;\n    const breakStartMs = this.adConfig.resolveBreakStartMs(adBreak);\n    if (breakStartMs == null) return;\n    const durationMs = adBreak.durationMs ?? 0;\n    const endMs = breakStartMs + durationMs;\n    const inWindow = durationMs > 0 ? nowMs >= breakStartMs && nowMs < endMs : nowMs >= breakStartMs;\n    if (inWindow) {\n      this.adConfig.consumedVmapBreakIds.add(key);\n      const tags = this.adConfig.selectVastTagsForBreak(adBreak);\n      if (!tags || tags.length === 0) return;\n      const first = tags[0];\n      const rest = tags.slice(1);\n      this.adBreak.adPodQueue = rest;\n      this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n      this.adBreak.showAds = true;\n      this.adBreak.inAdBreak = true;\n      this.timing.currentAdBreakStartWallClockMs = Date.now();\n      try {\n        await this.adBreak.playSingleAd(first);\n      } catch (error) {\n        this.adBreak.adPodQueue = [];\n        this.adBreak.inAdBreak = false;\n        this.adBreak.showAds = false;\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad request failed:\", error);\n        }\n      }\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Public API\n  // ───────────────────────────────────────────────────────────────\n  getCurrentAdIndex() {\n    return this.timing.currentAdIndex;\n  }\n  getTotalAdsInBreak() {\n    return this.timing.totalAdsInBreak;\n  }\n  getAdRemainingMs() {\n    return this.timing.getRemainingAdMs();\n  }\n  isAdPlaying() {\n    return this.adBreak.inAdBreak && this.adPlayer.isAdPlaying();\n  }\n  isShowingAds() {\n    return this.adBreak.showAds;\n  }\n  getStreamType() {\n    const url = this.config.src.toLowerCase();\n    if (url.includes(\".m3u8\") || url.includes(\"/hls/\") || url.includes(\"application/vnd.apple.mpegurl\")) {\n      return \"hls\";\n    }\n    return \"other\";\n  }\n  shouldShowNativeControls() {\n    const streamType = this.getStreamType();\n    if (streamType === \"other\") {\n      return !(this.config.showCustomControls ?? false);\n    }\n    return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));\n  }\n  isLive() {\n    return this.hlsEngine.isLiveStream;\n  }\n  get videoElement() {\n    return this.video;\n  }\n  toggleMute() {\n    toggleMute(this.video, this.adPlayer, this.debug);\n  }\n  toggleFullscreen() {\n    return toggleFullscreen(this.video, this.debug);\n  }\n  isMuted() {\n    return isMuted(this.video, this.adPlayer);\n  }\n  setMuted(muted) {\n    setMuted(this.video, this.adPlayer, muted, this.debug);\n  }\n  setVolume(volume) {\n    setVolume(this.video, this.adPlayer, volume, this.debug);\n  }\n  getVolume() {\n    return getVolume(this.video, this.adPlayer);\n  }\n  isFullscreen() {\n    return isFullscreen();\n  }\n  resize() {\n    resizePlayer(this.video, this.adPlayer, this.debug);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Destroy\n  // ───────────────────────────────────────────────────────────────\n  destroy() {\n    this.adBreak.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.timing.destroy();\n    this.adBreak.clearPendingAdBreak();\n    this.placeholder.destroy();\n    if (this.timeUpdateHandler) {\n      this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n      delete this.timeUpdateHandler;\n    }\n    if (this.endedHandler) {\n      this.video.removeEventListener(\"ended\", this.endedHandler);\n      delete this.endedHandler;\n    }\n    if (this.emptiedHandler) {\n      this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n      delete this.emptiedHandler;\n    }\n    this.adConfig.destroyTracking();\n    this.hlsEngine.destroy();\n    this.adPlayer?.destroy();\n    if (this.palPlaybackStarted) {\n      this.palPlaybackStarted = false;\n      this.palNonce.sendPlaybackEnd();\n    }\n    this.palNonce.reset();\n    this.adBreak.adRequestQueue = [];\n    this.timing.consecutiveFailures = 0;\n  }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\"\n];\nvar CONTROLS_HIDE_DELAY = 3e3;\nvar DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n  (props) => {\n    const {\n      src,\n      autoplay,\n      muted,\n      lowLatencyMode,\n      allowNativeHls,\n      isLiveStream,\n      driftToleranceMs,\n      immediateManifestAds,\n      debugAdTiming,\n      showCustomControls,\n      hideLoadingIndicator,\n      onVolumeToggle,\n      onFullscreenToggle,\n      onControlClick,\n      onReady,\n      wrapperClassName,\n      wrapperStyle,\n      className,\n      style,\n      controls,\n      playsInline,\n      preload,\n      poster,\n      children,\n      licenseKey,\n      vastMode,\n      vastTagUrl,\n      isVmap,\n      vmapUrl,\n      minSegmentsBeforePlay,\n      ctvAdRequest,\n      ...restVideoAttrs\n    } = props;\n    const videoRef = (0, import_react.useRef)(null);\n    const playerRef = (0, import_react.useRef)(null);\n    const bufferingTimeoutRef = (0, import_react.useRef)(null);\n    const controlsTimerRef = (0, import_react.useRef)(null);\n    const wrapperRef = (0, import_react.useRef)(null);\n    const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n    const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n    const [isMuted2, setIsMuted] = import_react.default.useState(false);\n    const [isFullscreen2, setIsFullscreen] = import_react.default.useState(false);\n    const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n    const [currentTime, setCurrentTime] = import_react.default.useState(0);\n    const [duration, setDuration] = import_react.default.useState(0);\n    const [volume, setVolume2] = import_react.default.useState(1);\n    const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n    const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n    const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n    const [isLoading, setIsLoading] = import_react.default.useState(true);\n    const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n    const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n    const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n    const [controlsVisible, setControlsVisible] = import_react.default.useState(true);\n    const [viewportWidth, setViewportWidth] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerWidth : 1920\n    );\n    const [isPortrait, setIsPortrait] = import_react.default.useState(\n      typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n    );\n    const [playerAspectRatio, setPlayerAspectRatio] = import_react.default.useState(\n      DEFAULT_PLAYER_ASPECT_RATIO\n    );\n    const getResponsiveScale = () => {\n      if (viewportWidth < 480) return 0.7;\n      if (viewportWidth < 768) return 0.8;\n      if (viewportWidth < 1024) return 0.9;\n      return 1;\n    };\n    const responsiveScale = getResponsiveScale();\n    const resetControlsTimer = (0, import_react.useCallback)(() => {\n      if (controlsTimerRef.current) {\n        clearTimeout(controlsTimerRef.current);\n      }\n      setControlsVisible(true);\n      controlsTimerRef.current = window.setTimeout(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, CONTROLS_HIDE_DELAY);\n    }, [showVolumeSlider, showSpeedMenu]);\n    const handleWrapperMouseMove = (0, import_react.useCallback)(() => {\n      resetControlsTimer();\n    }, [resetControlsTimer]);\n    const handleWrapperMouseLeave = (0, import_react.useCallback)(() => {\n      if (!showVolumeSlider && !showSpeedMenu) {\n        setControlsVisible(false);\n      }\n    }, [showVolumeSlider, showSpeedMenu]);\n    const formatTime = (seconds) => {\n      if (!isFinite(seconds)) return \"0:00:00\";\n      const hours = Math.floor(seconds / 3600);\n      const minutes = Math.floor(seconds % 3600 / 60);\n      const remainingSeconds = Math.floor(seconds % 60);\n      return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n    };\n    const handlePlayPause = () => {\n      if (videoRef.current) {\n        if (videoRef.current.paused) {\n          const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        } else {\n          videoRef.current.pause();\n          setShowCenterPlay(true);\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleCenterPlayClick = () => {\n      if (videoRef.current && videoRef.current.paused) {\n        const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n        if (hasValidSource) {\n          videoRef.current.play()?.catch((error) => {\n            console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n          });\n          setShowCenterPlay(false);\n        } else {\n          console.warn(\n            \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n          );\n        }\n      }\n    };\n    const handleTimelineSeek = (e) => {\n      if (videoRef.current && duration > 0 && isFinite(duration)) {\n        const rect = e.currentTarget.getBoundingClientRect();\n        const clickX = e.clientX - rect.left;\n        const progress = Math.max(0, Math.min(1, clickX / rect.width));\n        const newTime = progress * duration;\n        if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n          videoRef.current.currentTime = newTime;\n        }\n      }\n      resetControlsTimer();\n    };\n    const handleVolumeChange = (newVolume) => {\n      if (playerRef.current && isFinite(newVolume)) {\n        const clampedVolume = Math.max(0, Math.min(1, newVolume));\n        playerRef.current.setVolume(clampedVolume);\n      }\n    };\n    const handlePlaybackRateChange = (rate) => {\n      if (videoRef.current && isFinite(rate) && rate > 0) {\n        videoRef.current.playbackRate = rate;\n      }\n      setShowSpeedMenu(false);\n    };\n    const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n    const isLiveUiMode = isLiveStream === true;\n    const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? !isLiveUiMode : true);\n    const criticalPropsKey = (0, import_react.useMemo)(() => {\n      return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n    }, [\n      src,\n      allowNativeHls,\n      isLiveStream,\n      licenseKey,\n      isVmap,\n      vmapUrl,\n      lowLatencyMode,\n      driftToleranceMs,\n      vastMode\n    ]);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\") return;\n      const el = videoRef.current;\n      if (!el || !src) return;\n      if (!licenseKey) {\n        setShowLicenseWarning(true);\n        setIsLoading(false);\n        console.warn(\n          \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n        );\n        return;\n      }\n      setShowLicenseWarning(false);\n      if (debugAdTiming) {\n        console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n      }\n      if (playerRef.current) {\n        try {\n          playerRef.current.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      }\n      const cfg = {\n        src,\n        videoElement: el\n      };\n      if (autoplay !== void 0) cfg.autoplay = autoplay;\n      if (muted !== void 0) cfg.muted = muted;\n      if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n      if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n      if (isLiveStream !== void 0) cfg.isLiveStream = isLiveStream;\n      if (driftToleranceMs !== void 0)\n        cfg.driftToleranceMs = driftToleranceMs;\n      if (immediateManifestAds !== void 0)\n        cfg.immediateManifestAds = immediateManifestAds;\n      if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n      if (showCustomControls !== void 0)\n        cfg.showCustomControls = showCustomControls;\n      if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n      if (onFullscreenToggle !== void 0)\n        cfg.onFullscreenToggle = onFullscreenToggle;\n      if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n      if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n      if (vastMode !== void 0) cfg.vastMode = vastMode;\n      if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;\n      if (isVmap !== void 0) cfg.isVmap = isVmap;\n      if (vmapUrl !== void 0) cfg.vmapUrl = vmapUrl;\n      if (minSegmentsBeforePlay !== void 0)\n        cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n      if (ctvAdRequest !== void 0) cfg.ctvAdRequest = ctvAdRequest;\n      const player = new StormcloudVideoPlayer(cfg);\n      playerRef.current = player;\n      player.load().then(() => {\n        const showNative = player.shouldShowNativeControls();\n        setShouldShowNativeControls(showNative);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n          );\n        }\n        onReady?.(player);\n      }).catch((error) => {\n        console.error(\n          \"StormcloudVideoPlayer: Failed to load player:\",\n          error\n        );\n        setIsLoading(false);\n        onReady?.(player);\n      });\n      return () => {\n        try {\n          player.destroy();\n        } catch {\n        }\n        playerRef.current = null;\n      };\n    }, [criticalPropsKey]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      try {\n        if (autoplay !== void 0 && playerRef.current.videoElement) {\n          playerRef.current.videoElement.autoplay = autoplay;\n        }\n        if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n          playerRef.current.setMuted(muted);\n        }\n      } catch (error) {\n        console.warn(\"Failed to update player properties:\", error);\n      }\n    }, [autoplay, muted]);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current) return;\n      const checkAdStatus = () => {\n        if (playerRef.current) {\n          const showAdsFromMethod = playerRef.current.isShowingAds();\n          const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n          const showAds = showAdsFromMethod || showAdsFromAttribute;\n          const currentIndex = playerRef.current.getCurrentAdIndex();\n          const totalAds = playerRef.current.getTotalAdsInBreak();\n          const remainingMs = playerRef.current.getAdRemainingMs();\n          const remainingSeconds = showAds ? Math.max(0, Math.ceil(remainingMs / 1e3)) : 0;\n          setAdStatus((prev) => {\n            if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds || prev.remainingSeconds !== remainingSeconds) {\n              if (showAds && !prev.showAds) {\n                setShowCenterPlay(false);\n              }\n              return { showAds, currentIndex, totalAds, remainingSeconds };\n            }\n            return prev;\n          });\n        }\n      };\n      const interval = setInterval(checkAdStatus, 50);\n      return () => clearInterval(interval);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (typeof window === \"undefined\" || !playerRef.current) return;\n      const handleResize = () => {\n        if (playerRef.current && videoRef.current) {\n          if (typeof playerRef.current.resize === \"function\") {\n            playerRef.current.resize();\n          }\n        }\n        setViewportWidth(window.innerWidth);\n        setIsPortrait(window.innerHeight > window.innerWidth);\n      };\n      window.addEventListener(\"resize\", handleResize);\n      return () => window.removeEventListener(\"resize\", handleResize);\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!playerRef.current || !videoRef.current) return;\n      const updateStates = () => {\n        if (playerRef.current && videoRef.current) {\n          setIsMuted(playerRef.current.isMuted());\n          setIsPlaying(!videoRef.current.paused);\n          const currentTimeValue = videoRef.current.currentTime;\n          setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n          const durationValue = videoRef.current.duration;\n          setDuration(isFinite(durationValue) ? durationValue : 0);\n          const volumeValue = playerRef.current.getVolume();\n          setVolume2(\n            isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n          );\n          const rateValue = videoRef.current.playbackRate;\n          setPlaybackRate(\n            isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n          );\n        }\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      const interval = setInterval(updateStates, 200);\n      const handleFullscreenChange = () => {\n        setIsFullscreen(\n          document.fullscreenElement === wrapperRef.current\n        );\n      };\n      document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n      return () => {\n        clearInterval(interval);\n        document.removeEventListener(\n          \"fullscreenchange\",\n          handleFullscreenChange\n        );\n      };\n    }, []);\n    (0, import_react.useEffect)(() => {\n      if (!videoRef.current) return;\n      const handleLoadedMetadata = () => {\n        const video2 = videoRef.current;\n        if (video2) {\n          if (video2.videoWidth > 0 && video2.videoHeight > 0) {\n            setPlayerAspectRatio(video2.videoWidth / video2.videoHeight);\n          }\n          void video2.offsetHeight;\n        }\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadedData = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadeddata, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleLoadStart = () => {\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: loadstart, readyState:\",\n            videoRef.current?.readyState\n          );\n        }\n      };\n      const handleCanPlay = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplay, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleCanPlayThrough = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n            videoRef.current?.readyState,\n            \"- clearing loading state, isLoading=false\"\n          );\n        }\n      };\n      const handleWaiting = () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n        }\n        bufferingTimeoutRef.current = window.setTimeout(() => {\n          setIsBuffering(true);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n              videoRef.current?.readyState,\n              \"- showing spinner, isBuffering=true\"\n            );\n          }\n        }, 300);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: waiting, readyState:\",\n            videoRef.current?.readyState,\n            \"- buffering delay started (300ms)\"\n          );\n        }\n      };\n      const handlePlaying = () => {\n        setIsLoading(false);\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        setIsBuffering(false);\n        setShowCenterPlay(false);\n        if (debugAdTiming) {\n          console.log(\n            \"[StormcloudUI] Video event: playing, readyState:\",\n            videoRef.current?.readyState,\n            \"- playback started, isLoading=false, isBuffering=false\"\n          );\n        }\n      };\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n      const handleEnded = () => {\n        setShowCenterPlay(true);\n      };\n      const video = videoRef.current;\n      video.addEventListener(\"loadstart\", handleLoadStart);\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.addEventListener(\"canplay\", handleCanPlay);\n      video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n      video.addEventListener(\"waiting\", handleWaiting);\n      video.addEventListener(\"playing\", handlePlaying);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      if (video.paused) {\n        setShowCenterPlay(true);\n      }\n      return () => {\n        if (bufferingTimeoutRef.current) {\n          clearTimeout(bufferingTimeoutRef.current);\n          bufferingTimeoutRef.current = null;\n        }\n        video.removeEventListener(\"loadstart\", handleLoadStart);\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n        video.removeEventListener(\"canplay\", handleCanPlay);\n        video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.removeEventListener(\"waiting\", handleWaiting);\n        video.removeEventListener(\"playing\", handlePlaying);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n      };\n    }, [debugAdTiming]);\n    (0, import_react.useEffect)(() => {\n      setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n    }, [src]);\n    (0, import_react.useEffect)(() => {\n      return () => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n      };\n    }, []);\n    const progressPercent = duration > 0 ? currentTime / duration * 100 : 0;\n    const VolumeIcon = isMuted2 || volume === 0 ? import_fa.FaVolumeMute : volume < 0.5 ? import_fa.FaVolumeDown : import_fa.FaVolumeUp;\n    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            ` }),\n      /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n        \"div\",\n        {\n          ref: wrapperRef,\n          className: `sc-wrapper ${wrapperClassName || \"\"}`,\n          onMouseMove: handleWrapperMouseMove,\n          onMouseLeave: handleWrapperMouseLeave,\n          style: {\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n            position: isFullscreen2 ? \"fixed\" : \"relative\",\n            top: isFullscreen2 ? 0 : void 0,\n            left: isFullscreen2 ? 0 : void 0,\n            overflow: \"hidden\",\n            width: isFullscreen2 ? \"100vw\" : \"100%\",\n            height: isFullscreen2 ? \"100vh\" : \"auto\",\n            minHeight: isFullscreen2 ? \"100vh\" : \"auto\",\n            aspectRatio: isFullscreen2 ? void 0 : playerAspectRatio,\n            maxWidth: isFullscreen2 ? \"100vw\" : \"100%\",\n            maxHeight: isFullscreen2 ? \"100vh\" : \"none\",\n            zIndex: isFullscreen2 ? 999999 : void 0,\n            backgroundColor: \"#000\",\n            borderRadius: isFullscreen2 ? 0 : void 0,\n            boxShadow: isFullscreen2 ? \"none\" : void 0,\n            ...wrapperStyle\n          },\n          children: [\n            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"video\",\n              {\n                ref: videoRef,\n                className,\n                style: {\n                  display: \"block\",\n                  width: \"100%\",\n                  height: \"100%\",\n                  maxWidth: \"100%\",\n                  maxHeight: isFullscreen2 ? \"100%\" : \"none\",\n                  objectFit: isFullscreen2 ? \"cover\" : \"contain\",\n                  backgroundColor: \"#000\",\n                  aspectRatio: isFullscreen2 ? \"unset\" : void 0,\n                  ...style\n                },\n                controls: shouldShowNativeControls && controls && !showCustomControls,\n                playsInline,\n                preload,\n                poster,\n                ...restVideoAttrs,\n                children\n              }\n            ),\n            (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-loading-indicator\",\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        position: \"absolute\",\n                        inset: 0,\n                        borderRadius: \"50%\",\n                        border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                        borderTopColor: \"#ff0000\",\n                        borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                        animation: \"sc-spin 0.8s linear infinite\"\n                      }\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                    \"div\",\n                    {\n                      style: {\n                        width: \"7px\",\n                        height: \"7px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff0000\",\n                        boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\"\n                      }\n                    }\n                  )\n                ]\n              }\n            ),\n            showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }, children: \"License Key Required\" }),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }, children: [\n                    \"Please provide a valid license key to use the Stormcloud Video Player.\",\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n                    \"Contact your administrator for licensing information.\"\n                  ] })\n                ]\n              }\n            ),\n            adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                style: {\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\"\n                },\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  \"div\",\n                  {\n                    style: {\n                      background: \"rgba(234, 179, 8, 0.95)\",\n                      color: \"#111\",\n                      padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                      borderRadius: \"6px\",\n                      fontSize: `${11 * responsiveScale}px`,\n                      fontWeight: 700,\n                      letterSpacing: \"0.08em\",\n                      textTransform: \"uppercase\",\n                      boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\"\n                    },\n                    children: `Ad ${Math.max(1, adStatus.currentIndex)}`\n                  }\n                )\n              }\n            ),\n            showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: handleCenterPlayClick,\n                style: {\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 15,\n                  cursor: \"pointer\",\n                  background: \"rgba(0, 0, 0, 0.55)\",\n                  backdropFilter: \"blur(8px)\",\n                  borderRadius: \"50%\",\n                  width: `${92 * responsiveScale}px`,\n                  height: `${92 * responsiveScale}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  transition: \"background 0.2s ease, transform 0.2s ease\",\n                  animation: \"sc-fade-in 0.2s ease\"\n                },\n                onMouseEnter: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.72)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                },\n                onMouseLeave: (e) => {\n                  e.currentTarget.style.background = \"rgba(0, 0, 0, 0.55)\";\n                  e.currentTarget.style.transform = \"translate(-50%, -50%) scale(1)\";\n                },\n                title: \"Play\",\n                children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                  import_fa.FaPlay,\n                  {\n                    size: Math.max(24, 32 * responsiveScale),\n                    color: \"white\",\n                    style: { marginLeft: \"4px\" }\n                  }\n                )\n              }\n            ),\n            shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n              \"div\",\n              {\n                className: \"sc-controls-bar\",\n                style: {\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\"\n                },\n                children: [\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      className: \"sc-progress-track\",\n                      style: {\n                        width: \"100%\",\n                        height: \"3px\",\n                        background: \"rgba(255, 255, 255, 0.2)\",\n                        borderRadius: \"1.5px\",\n                        marginBottom: `${8 * responsiveScale}px`,\n                        cursor: \"pointer\",\n                        position: \"relative\",\n                        transition: \"height 0.1s ease\"\n                      },\n                      onClick: handleTimelineSeek,\n                      onMouseEnter: (e) => {\n                        e.currentTarget.style.height = \"5px\";\n                      },\n                      onMouseLeave: (e) => {\n                        e.currentTarget.style.height = \"3px\";\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            style: {\n                              position: \"absolute\",\n                              top: 0,\n                              left: 0,\n                              bottom: 0,\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"1.5px\",\n                              width: `${progressPercent}%`,\n                              transition: \"width 0.15s linear\"\n                            }\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                          \"div\",\n                          {\n                            className: \"sc-progress-thumb\",\n                            style: {\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${progressPercent}%`,\n                              transform: \"translate(-50%, -50%) scale(0)\",\n                              width: \"13px\",\n                              height: \"13px\",\n                              background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                              transition: \"transform 0.1s ease, left 0.15s linear\"\n                            }\n                          }\n                        )\n                      ]\n                    }\n                  ),\n                  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                    \"div\",\n                    {\n                      style: {\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        justifyContent: \"space-between\",\n                        color: \"white\",\n                        gap: `${8 * responsiveScale}px`\n                      },\n                      children: [\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: handlePlayPause,\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isPlaying ? \"Pause\" : \"Play\",\n                                  children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPause, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, { size: Math.max(14, 18 * responsiveScale), style: { marginLeft: \"2px\" } })\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    display: \"flex\",\n                                    alignItems: \"center\",\n                                    paddingRight: `${6 * responsiveScale}px`\n                                  },\n                                  onMouseEnter: () => setShowVolumeSlider(true),\n                                  onMouseLeave: () => setShowVolumeSlider(false),\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"button\",\n                                      {\n                                        className: \"sc-ctrl-btn\",\n                                        onClick: () => {\n                                          if (playerRef.current) playerRef.current.toggleMute();\n                                          onVolumeToggle?.();\n                                          resetControlsTimer();\n                                        },\n                                        style: {\n                                          padding: `${8 * responsiveScale}px`,\n                                          borderRadius: \"50%\",\n                                          minWidth: `${36 * responsiveScale}px`,\n                                          minHeight: `${36 * responsiveScale}px`\n                                        },\n                                        title: isMuted2 ? \"Unmute\" : \"Mute\",\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                          overflow: \"hidden\",\n                                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                          display: \"flex\",\n                                          alignItems: \"center\",\n                                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\"\n                                        },\n                                        children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                          \"div\",\n                                          {\n                                            style: {\n                                              position: \"relative\",\n                                              width: `${56 * responsiveScale}px`,\n                                              height: \"3px\",\n                                              cursor: \"pointer\",\n                                              borderRadius: \"1.5px\"\n                                            },\n                                            onMouseDown: (e) => {\n                                              e.preventDefault();\n                                              const el = e.currentTarget;\n                                              const move = (ev) => {\n                                                const r2 = el.getBoundingClientRect();\n                                                handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                              };\n                                              const up = () => {\n                                                document.removeEventListener(\"mousemove\", move);\n                                                document.removeEventListener(\"mouseup\", up);\n                                              };\n                                              document.addEventListener(\"mousemove\", move);\n                                              document.addEventListener(\"mouseup\", up);\n                                              const r = el.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            onClick: (e) => {\n                                              e.stopPropagation();\n                                              const r = e.currentTarget.getBoundingClientRect();\n                                              handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                            },\n                                            children: [\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: 0,\n                                                    left: 0,\n                                                    bottom: 0,\n                                                    width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    background: \"#fff\",\n                                                    borderRadius: \"1.5px\",\n                                                    transition: \"width 0.1s ease-out\"\n                                                  }\n                                                }\n                                              ),\n                                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                                \"div\",\n                                                {\n                                                  style: {\n                                                    position: \"absolute\",\n                                                    top: \"50%\",\n                                                    left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                                    transform: \"translate(-50%, -50%)\",\n                                                    width: \"12px\",\n                                                    height: \"12px\",\n                                                    background: \"#fff\",\n                                                    borderRadius: \"50%\",\n                                                    boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                                    transition: \"left 0.1s ease-out\"\n                                                  }\n                                                }\n                                              )\n                                            ]\n                                          }\n                                        )\n                                      }\n                                    )\n                                  ]\n                                }\n                              ),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    fontSize: `${13 * responsiveScale}px`,\n                                    fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                                    color: \"rgba(255, 255, 255, 0.9)\",\n                                    display: viewportWidth < 480 ? \"none\" : \"block\",\n                                    fontVariantNumeric: \"tabular-nums\",\n                                    userSelect: \"none\",\n                                    marginLeft: `${4 * responsiveScale}px`\n                                  },\n                                  children: [\n                                    formatTime(currentTime),\n                                    \" \",\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { color: \"rgba(255,255,255,0.5)\" }, children: \"/\" }),\n                                    \" \",\n                                    formatTime(duration)\n                                  ]\n                                }\n                              )\n                            ]\n                          }\n                        ),\n                        /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                          \"div\",\n                          {\n                            style: {\n                              display: \"flex\",\n                              alignItems: \"center\",\n                              gap: `${8 * responsiveScale}px`\n                            },\n                            children: [\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }, children: [\n                                /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                  \"button\",\n                                  {\n                                    className: \"sc-ctrl-btn\",\n                                    onClick: () => {\n                                      setShowSpeedMenu(!showSpeedMenu);\n                                      resetControlsTimer();\n                                    },\n                                    style: {\n                                      padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                                      borderRadius: `${6 * responsiveScale}px`,\n                                      fontSize: `${13 * responsiveScale}px`,\n                                      fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                                      fontWeight: \"600\",\n                                      minHeight: `${32 * responsiveScale}px`\n                                    },\n                                    title: \"Playback Speed\",\n                                    children: [\n                                      playbackRate,\n                                      \"x\"\n                                    ]\n                                  }\n                                ),\n                                showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                  \"div\",\n                                  {\n                                    style: {\n                                      position: \"absolute\",\n                                      bottom: \"100%\",\n                                      right: 0,\n                                      marginBottom: \"8px\",\n                                      background: \"rgba(0, 0, 0, 0.8)\",\n                                      backdropFilter: \"blur(24px)\",\n                                      WebkitBackdropFilter: \"blur(24px)\",\n                                      borderRadius: \"10px\",\n                                      border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                                      overflow: \"hidden\",\n                                      minWidth: \"80px\",\n                                      boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                                      animation: \"sc-fade-in 0.15s ease\"\n                                    },\n                                    children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                      \"button\",\n                                      {\n                                        onClick: () => handlePlaybackRateChange(speed),\n                                        style: {\n                                          display: \"block\",\n                                          width: \"100%\",\n                                          padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                          background: playbackRate === speed ? \"rgba(255, 255, 255, 0.12)\" : \"transparent\",\n                                          border: \"none\",\n                                          color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                          cursor: \"pointer\",\n                                          fontSize: `${12 * responsiveScale}px`,\n                                          fontFamily: \"'SF Mono', monospace\",\n                                          fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                          textAlign: \"center\",\n                                          transition: \"background 0.15s ease, color 0.15s ease\"\n                                        },\n                                        onMouseEnter: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"rgba(255, 255, 255, 0.08)\";\n                                            e.target.style.color = \"#fff\";\n                                          }\n                                        },\n                                        onMouseLeave: (e) => {\n                                          if (playbackRate !== speed) {\n                                            e.target.style.background = \"transparent\";\n                                            e.target.style.color = \"rgba(255, 255, 255, 0.7)\";\n                                          }\n                                        },\n                                        children: [\n                                          speed,\n                                          \"x\"\n                                        ]\n                                      },\n                                      speed\n                                    ))\n                                  }\n                                )\n                              ] }),\n                              /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                \"button\",\n                                {\n                                  className: \"sc-ctrl-btn\",\n                                  onClick: () => {\n                                    if (onFullscreenToggle) {\n                                      onFullscreenToggle();\n                                    } else if (wrapperRef.current) {\n                                      if (!document.fullscreenElement) {\n                                        wrapperRef.current.requestFullscreen().catch(() => {\n                                        });\n                                      } else {\n                                        document.exitFullscreen().catch(() => {\n                                        });\n                                      }\n                                    }\n                                    resetControlsTimer();\n                                  },\n                                  style: {\n                                    padding: `${8 * responsiveScale}px`,\n                                    borderRadius: \"50%\",\n                                    minWidth: `${36 * responsiveScale}px`,\n                                    minHeight: `${36 * responsiveScale}px`\n                                  },\n                                  title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                                  children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                                }\n                              )\n                            ]\n                          }\n                        )\n                      ]\n                    }\n                  )\n                ]\n              }\n            ) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  style: {\n                    position: \"absolute\",\n                    top: `${10 * responsiveScale}px`,\n                    left: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: \"6px\",\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transition: \"opacity 0.35s ease\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"div\",\n                      {\n                        style: {\n                          width: \"8px\",\n                          height: \"8px\",\n                          borderRadius: \"50%\",\n                          background: \"#ff3b30\",\n                          animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                          flexShrink: 0\n                        }\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"span\",\n                      {\n                        style: {\n                          fontSize: `${12 * responsiveScale}px`,\n                          fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                          fontWeight: 700,\n                          letterSpacing: \"0.08em\",\n                          color: \"#fff\",\n                          textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                          userSelect: \"none\"\n                        },\n                        children: \"LIVE\"\n                      }\n                    )\n                  ]\n                }\n              ),\n              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                \"div\",\n                {\n                  className: \"sc-controls-bar\",\n                  style: {\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\"\n                  },\n                  children: [\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                      \"div\",\n                      {\n                        style: {\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          background: \"rgba(0, 0, 0, 0.6)\",\n                          borderRadius: `${18 * responsiveScale}px`,\n                          padding: \"2px\",\n                          paddingRight: `${8 * responsiveScale}px`\n                        },\n                        onMouseEnter: () => setShowVolumeSlider(true),\n                        onMouseLeave: () => setShowVolumeSlider(false),\n                        children: [\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"button\",\n                            {\n                              className: \"sc-ctrl-btn\",\n                              onClick: () => {\n                                if (playerRef.current) playerRef.current.toggleMute();\n                                onVolumeToggle?.();\n                                resetControlsTimer();\n                              },\n                              style: {\n                                padding: `${8 * responsiveScale}px`,\n                                borderRadius: \"50%\",\n                                minWidth: `${36 * responsiveScale}px`,\n                                minHeight: `${36 * responsiveScale}px`\n                              },\n                              title: isMuted2 ? \"Unmute\" : \"Mute\",\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, { size: Math.max(14, 18 * responsiveScale) })\n                            }\n                          ),\n                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                            \"div\",\n                            {\n                              style: {\n                                width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                                overflow: \"hidden\",\n                                transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                                display: \"flex\",\n                                alignItems: \"center\",\n                                paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                                paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\"\n                              },\n                              children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n                                \"div\",\n                                {\n                                  style: {\n                                    position: \"relative\",\n                                    width: `${56 * responsiveScale}px`,\n                                    height: \"3px\",\n                                    cursor: \"pointer\",\n                                    borderRadius: \"1.5px\"\n                                  },\n                                  onMouseDown: (e) => {\n                                    e.preventDefault();\n                                    const el = e.currentTarget;\n                                    const move = (ev) => {\n                                      const r2 = el.getBoundingClientRect();\n                                      handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));\n                                    };\n                                    const up = () => {\n                                      document.removeEventListener(\"mousemove\", move);\n                                      document.removeEventListener(\"mouseup\", up);\n                                    };\n                                    document.addEventListener(\"mousemove\", move);\n                                    document.addEventListener(\"mouseup\", up);\n                                    const r = el.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  onClick: (e) => {\n                                    e.stopPropagation();\n                                    const r = e.currentTarget.getBoundingClientRect();\n                                    handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                                  },\n                                  children: [\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" } }),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: 0,\n                                          left: 0,\n                                          bottom: 0,\n                                          width: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          background: \"#fff\",\n                                          borderRadius: \"1.5px\",\n                                          transition: \"width 0.1s ease-out\"\n                                        }\n                                      }\n                                    ),\n                                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                                      \"div\",\n                                      {\n                                        style: {\n                                          position: \"absolute\",\n                                          top: \"50%\",\n                                          left: `${(isMuted2 ? 0 : volume) * 100}%`,\n                                          transform: \"translate(-50%, -50%)\",\n                                          width: \"12px\",\n                                          height: \"12px\",\n                                          background: \"#fff\",\n                                          borderRadius: \"50%\",\n                                          boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                                          transition: \"left 0.1s ease-out\"\n                                        }\n                                      }\n                                    )\n                                  ]\n                                }\n                              )\n                            }\n                          )\n                        ]\n                      }\n                    ),\n                    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n                      \"button\",\n                      {\n                        className: \"sc-ctrl-btn\",\n                        onClick: () => {\n                          if (onFullscreenToggle) {\n                            onFullscreenToggle();\n                          } else if (wrapperRef.current) {\n                            if (!document.fullscreenElement) {\n                              wrapperRef.current.requestFullscreen().catch(() => {\n                              });\n                            } else {\n                              document.exitFullscreen().catch(() => {\n                              });\n                            }\n                          }\n                          resetControlsTimer();\n                        },\n                        style: {\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                          background: \"rgba(0, 0, 0, 0.6)\"\n                        },\n                        title: isFullscreen2 ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n                        children: isFullscreen2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, { size: Math.max(14, 18 * responsiveScale) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, { size: Math.max(14, 18 * responsiveScale) })\n                      }\n                    )\n                  ]\n                }\n              )\n            ] }),\n            onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n              \"div\",\n              {\n                onClick: onControlClick,\n                style: {\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\"\n                }\n              }\n            )\n          ]\n        }\n      )\n    ] });\n  },\n  (prevProps, nextProps) => {\n    for (const prop of CRITICAL_PROPS) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const uiProps = [\n      \"autoplay\",\n      \"muted\",\n      \"controls\",\n      \"showCustomControls\",\n      \"className\",\n      \"style\",\n      \"wrapperClassName\",\n      \"wrapperStyle\",\n      \"playsInline\",\n      \"preload\",\n      \"poster\",\n      \"children\"\n    ];\n    for (const prop of uiProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    const callbackProps = [\n      \"onReady\",\n      \"onVolumeToggle\",\n      \"onFullscreenToggle\",\n      \"onControlClick\"\n    ];\n    for (const prop of callbackProps) {\n      if (prevProps[prop] !== nextProps[prop]) {\n        return false;\n      }\n    }\n    return true;\n  }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo, useCallback } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n  FaPlay,\n  FaPause,\n  FaVolumeUp,\n  FaVolumeMute,\n  FaVolumeDown,\n  FaExpand,\n  FaCompress,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n  StormcloudVideoPlayerConfig,\n  \"videoElement\"\n> &\n  React.VideoHTMLAttributes<HTMLVideoElement> & {\n    onReady?: (player: StormcloudVideoPlayer) => void;\n    wrapperClassName?: string;\n    wrapperStyle?: React.CSSProperties;\n    licenseKey?: string;\n  };\n\nconst CRITICAL_PROPS = [\n  \"src\",\n  \"allowNativeHls\",\n  \"isLiveStream\",\n  \"licenseKey\",\n  \"isVmap\",\n  \"vmapUrl\",\n  \"lowLatencyMode\",\n  \"driftToleranceMs\",\n  \"vastMode\",\n  \"ctvAdRequest\",\n] as const;\n\nconst CONTROLS_HIDE_DELAY = 3000;\nconst DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n  React.memo(\n    (props) => {\n      const {\n        src,\n        autoplay,\n        muted,\n        lowLatencyMode,\n        allowNativeHls,\n        isLiveStream,\n        driftToleranceMs,\n        immediateManifestAds,\n        debugAdTiming,\n        showCustomControls,\n        hideLoadingIndicator,\n        onVolumeToggle,\n        onFullscreenToggle,\n        onControlClick,\n        onReady,\n        wrapperClassName,\n        wrapperStyle,\n        className,\n        style,\n        controls,\n        playsInline,\n        preload,\n        poster,\n        children,\n        licenseKey,\n        vastMode,\n        vastTagUrl,\n        isVmap,\n        vmapUrl,\n        minSegmentsBeforePlay,\n        ctvAdRequest,\n        ...restVideoAttrs\n      } = props;\n\n      const videoRef = useRef<HTMLVideoElement | null>(null);\n      const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n      const bufferingTimeoutRef = useRef<number | null>(null);\n      const controlsTimerRef = useRef<number | null>(null);\n      const wrapperRef = useRef<HTMLDivElement | null>(null);\n      const [adStatus, setAdStatus] = React.useState<{\n        showAds: boolean;\n        currentIndex: number;\n        totalAds: number;\n        remainingSeconds: number;\n      }>({ showAds: false, currentIndex: 0, totalAds: 0, remainingSeconds: 0 });\n\n      const [shouldShowNativeControls, setShouldShowNativeControls] =\n        React.useState(true);\n\n      const [isMuted, setIsMuted] = React.useState(false);\n      const [isFullscreen, setIsFullscreen] = React.useState(false);\n      const [isPlaying, setIsPlaying] = React.useState(false);\n      const [currentTime, setCurrentTime] = React.useState(0);\n      const [duration, setDuration] = React.useState(0);\n      const [volume, setVolume] = React.useState(1);\n      const [playbackRate, setPlaybackRate] = React.useState(1);\n      const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n      const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n      const [isLoading, setIsLoading] = React.useState(true);\n      const [isBuffering, setIsBuffering] = React.useState(false);\n      const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n      const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n      const [controlsVisible, setControlsVisible] = React.useState(true);\n      const [viewportWidth, setViewportWidth] = React.useState(\n        typeof window !== \"undefined\" ? window.innerWidth : 1920\n      );\n      const [isPortrait, setIsPortrait] = React.useState(\n        typeof window !== \"undefined\"\n          ? window.innerHeight > window.innerWidth\n          : false\n      );\n      const [playerAspectRatio, setPlayerAspectRatio] = React.useState(\n        DEFAULT_PLAYER_ASPECT_RATIO\n      );\n\n      const getResponsiveScale = () => {\n        if (viewportWidth < 480) return 0.7;\n        if (viewportWidth < 768) return 0.8;\n        if (viewportWidth < 1024) return 0.9;\n        return 1;\n      };\n\n      const responsiveScale = getResponsiveScale();\n\n      const resetControlsTimer = useCallback(() => {\n        if (controlsTimerRef.current) {\n          clearTimeout(controlsTimerRef.current);\n        }\n        setControlsVisible(true);\n        controlsTimerRef.current = window.setTimeout(() => {\n          if (!showVolumeSlider && !showSpeedMenu) {\n            setControlsVisible(false);\n          }\n        }, CONTROLS_HIDE_DELAY);\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const handleWrapperMouseMove = useCallback(() => {\n        resetControlsTimer();\n      }, [resetControlsTimer]);\n\n      const handleWrapperMouseLeave = useCallback(() => {\n        if (!showVolumeSlider && !showSpeedMenu) {\n          setControlsVisible(false);\n        }\n      }, [showVolumeSlider, showSpeedMenu]);\n\n      const formatTime = (seconds: number): string => {\n        if (!isFinite(seconds)) return \"0:00:00\";\n        const hours = Math.floor(seconds / 3600);\n        const minutes = Math.floor((seconds % 3600) / 60);\n        const remainingSeconds = Math.floor(seconds % 60);\n        return `${hours}:${minutes\n          .toString()\n          .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n      };\n\n      const handlePlayPause = () => {\n        if (videoRef.current) {\n          if (videoRef.current.paused) {\n            const hasValidSource =\n              videoRef.current.src ||\n              (videoRef.current.currentSrc &&\n                videoRef.current.currentSrc !== \"\") ||\n              videoRef.current.readyState >= 1;\n\n            if (hasValidSource) {\n              videoRef.current.play()?.catch((error) => {\n                console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n              });\n              setShowCenterPlay(false);\n            } else {\n              console.warn(\n                \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n              );\n            }\n          } else {\n            videoRef.current.pause();\n            setShowCenterPlay(true);\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleCenterPlayClick = () => {\n        if (videoRef.current && videoRef.current.paused) {\n          const hasValidSource =\n            videoRef.current.src ||\n            (videoRef.current.currentSrc &&\n              videoRef.current.currentSrc !== \"\") ||\n            videoRef.current.readyState >= 1;\n\n          if (hasValidSource) {\n            videoRef.current.play()?.catch((error) => {\n              console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n            });\n            setShowCenterPlay(false);\n          } else {\n            console.warn(\n              \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n            );\n          }\n        }\n      };\n\n      const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n        if (videoRef.current && duration > 0 && isFinite(duration)) {\n          const rect = e.currentTarget.getBoundingClientRect();\n          const clickX = e.clientX - rect.left;\n          const progress = Math.max(0, Math.min(1, clickX / rect.width));\n          const newTime = progress * duration;\n\n          if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n            videoRef.current.currentTime = newTime;\n          }\n        }\n        resetControlsTimer();\n      };\n\n      const handleVolumeChange = (newVolume: number) => {\n        if (playerRef.current && isFinite(newVolume)) {\n          const clampedVolume = Math.max(0, Math.min(1, newVolume));\n          playerRef.current.setVolume(clampedVolume);\n        }\n      };\n\n      const handlePlaybackRateChange = (rate: number) => {\n        if (videoRef.current && isFinite(rate) && rate > 0) {\n          videoRef.current.playbackRate = rate;\n        }\n        setShowSpeedMenu(false);\n      };\n\n      const isHlsStream =\n        src?.toLowerCase().includes(\".m3u8\") ||\n        src?.toLowerCase().includes(\"/hls/\");\n      const isLiveUiMode = isLiveStream === true;\n      const shouldShowEnhancedControls =\n        showCustomControls &&\n        (isHlsStream ? !isLiveUiMode : true);\n\n      const criticalPropsKey = useMemo(() => {\n        return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n      }, [\n        src,\n        allowNativeHls,\n        isLiveStream,\n        licenseKey,\n        isVmap,\n        vmapUrl,\n        lowLatencyMode,\n        driftToleranceMs,\n        vastMode,\n      ]);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\") return;\n        const el = videoRef.current;\n        if (!el || !src) return;\n\n        if (!licenseKey) {\n          setShowLicenseWarning(true);\n          setIsLoading(false);\n          console.warn(\n            \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n          );\n          return;\n        }\n\n        setShowLicenseWarning(false);\n\n        if (debugAdTiming) {\n          console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n        }\n\n        if (playerRef.current) {\n          try {\n            playerRef.current.destroy();\n          } catch {}\n          playerRef.current = null;\n        }\n\n        const cfg: StormcloudVideoPlayerConfig = {\n          src,\n          videoElement: el,\n        } as StormcloudVideoPlayerConfig;\n        if (autoplay !== undefined) cfg.autoplay = autoplay;\n        if (muted !== undefined) cfg.muted = muted;\n        if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n        if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n        if (isLiveStream !== undefined) cfg.isLiveStream = isLiveStream;\n        if (driftToleranceMs !== undefined)\n          cfg.driftToleranceMs = driftToleranceMs;\n        if (immediateManifestAds !== undefined)\n          cfg.immediateManifestAds = immediateManifestAds;\n        if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n        if (showCustomControls !== undefined)\n          cfg.showCustomControls = showCustomControls;\n        if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n        if (onFullscreenToggle !== undefined)\n          cfg.onFullscreenToggle = onFullscreenToggle;\n        if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n        if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n        if (vastMode !== undefined) cfg.vastMode = vastMode;\n        if (vastTagUrl !== undefined) cfg.vastTagUrl = vastTagUrl;\n        if (isVmap !== undefined) cfg.isVmap = isVmap;\n        if (vmapUrl !== undefined) cfg.vmapUrl = vmapUrl;\n        if (minSegmentsBeforePlay !== undefined)\n          cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n        if (ctvAdRequest !== undefined) cfg.ctvAdRequest = ctvAdRequest;\n\n        const player = new StormcloudVideoPlayer(cfg);\n        playerRef.current = player;\n        player\n          .load()\n          .then(() => {\n            const showNative = player.shouldShowNativeControls();\n            setShouldShowNativeControls(showNative);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n              );\n            }\n            onReady?.(player);\n          })\n          .catch((error) => {\n            console.error(\n              \"StormcloudVideoPlayer: Failed to load player:\",\n              error\n            );\n            setIsLoading(false);\n            onReady?.(player);\n          });\n\n        return () => {\n          try {\n            player.destroy();\n          } catch {}\n          playerRef.current = null;\n        };\n      }, [criticalPropsKey]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        try {\n          if (autoplay !== undefined && playerRef.current.videoElement) {\n            playerRef.current.videoElement.autoplay = autoplay;\n          }\n          if (muted !== undefined && !playerRef.current.isShowingAds()) {\n            playerRef.current.setMuted(muted);\n          }\n        } catch (error) {\n          console.warn(\"Failed to update player properties:\", error);\n        }\n      }, [autoplay, muted]);\n\n      useEffect(() => {\n        if (!playerRef.current) return;\n\n        const checkAdStatus = () => {\n          if (playerRef.current) {\n            const showAdsFromMethod = playerRef.current.isShowingAds();\n            const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n            const showAds = showAdsFromMethod || showAdsFromAttribute;\n            const currentIndex = playerRef.current.getCurrentAdIndex();\n            const totalAds = playerRef.current.getTotalAdsInBreak();\n            const remainingMs = playerRef.current.getAdRemainingMs();\n            const remainingSeconds = showAds\n              ? Math.max(0, Math.ceil(remainingMs / 1000))\n              : 0;\n\n            setAdStatus((prev) => {\n              if (\n                prev.showAds !== showAds ||\n                prev.currentIndex !== currentIndex ||\n                prev.totalAds !== totalAds ||\n                prev.remainingSeconds !== remainingSeconds\n              ) {\n                if (showAds && !prev.showAds) {\n                  setShowCenterPlay(false);\n                }\n                return { showAds, currentIndex, totalAds, remainingSeconds };\n              }\n              return prev;\n            });\n          }\n        };\n\n        const interval = setInterval(checkAdStatus, 50);\n        return () => clearInterval(interval);\n      }, []);\n\n      useEffect(() => {\n        if (typeof window === \"undefined\" || !playerRef.current) return;\n\n        const handleResize = () => {\n          if (playerRef.current && videoRef.current) {\n            if (typeof playerRef.current.resize === \"function\") {\n              playerRef.current.resize();\n            }\n          }\n          setViewportWidth(window.innerWidth);\n          setIsPortrait(window.innerHeight > window.innerWidth);\n        };\n\n        window.addEventListener(\"resize\", handleResize);\n        return () => window.removeEventListener(\"resize\", handleResize);\n      }, []);\n\n      useEffect(() => {\n        if (!playerRef.current || !videoRef.current) return;\n\n        const updateStates = () => {\n          if (playerRef.current && videoRef.current) {\n            setIsMuted(playerRef.current.isMuted());\n            setIsPlaying(!videoRef.current.paused);\n\n            const currentTimeValue = videoRef.current.currentTime;\n            setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n            const durationValue = videoRef.current.duration;\n            setDuration(isFinite(durationValue) ? durationValue : 0);\n\n            const volumeValue = playerRef.current.getVolume();\n            setVolume(\n              isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n            );\n\n            const rateValue = videoRef.current.playbackRate;\n            setPlaybackRate(\n              isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n            );\n          }\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        const interval = setInterval(updateStates, 200);\n\n        const handleFullscreenChange = () => {\n          setIsFullscreen(\n            document.fullscreenElement === wrapperRef.current\n          );\n        };\n\n        document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n        return () => {\n          clearInterval(interval);\n          document.removeEventListener(\n            \"fullscreenchange\",\n            handleFullscreenChange\n          );\n        };\n      }, []);\n\n      useEffect(() => {\n        if (!videoRef.current) return;\n\n        const handleLoadedMetadata = () => {\n          const video = videoRef.current;\n          if (video) {\n            if (video.videoWidth > 0 && video.videoHeight > 0) {\n              setPlayerAspectRatio(video.videoWidth / video.videoHeight);\n            }\n            void video.offsetHeight;\n          }\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadedData = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadeddata, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleLoadStart = () => {\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: loadstart, readyState:\",\n              videoRef.current?.readyState\n            );\n          }\n        };\n\n        const handleCanPlay = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplay, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleCanPlayThrough = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n              videoRef.current?.readyState,\n              \"- clearing loading state, isLoading=false\"\n            );\n          }\n        };\n\n        const handleWaiting = () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n          }\n\n          bufferingTimeoutRef.current = window.setTimeout(() => {\n            setIsBuffering(true);\n            if (debugAdTiming) {\n              console.log(\n                \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n                videoRef.current?.readyState,\n                \"- showing spinner, isBuffering=true\"\n              );\n            }\n          }, 300);\n\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: waiting, readyState:\",\n              videoRef.current?.readyState,\n              \"- buffering delay started (300ms)\"\n            );\n          }\n        };\n\n        const handlePlaying = () => {\n          setIsLoading(false);\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n          setIsBuffering(false);\n          setShowCenterPlay(false);\n          if (debugAdTiming) {\n            console.log(\n              \"[StormcloudUI] Video event: playing, readyState:\",\n              videoRef.current?.readyState,\n              \"- playback started, isLoading=false, isBuffering=false\"\n            );\n          }\n        };\n\n      const handlePause = () => {\n        const isAdActive = playerRef.current?.isShowingAds() || \n          videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n        \n        if (playerRef.current && !isAdActive) {\n          setShowCenterPlay(true);\n        } else {\n          setShowCenterPlay(false);\n        }\n      };\n\n        const handleEnded = () => {\n          setShowCenterPlay(true);\n        };\n\n        const video = videoRef.current;\n        video.addEventListener(\"loadstart\", handleLoadStart);\n        video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.addEventListener(\"loadeddata\", handleLoadedData);\n        video.addEventListener(\"canplay\", handleCanPlay);\n        video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n        video.addEventListener(\"waiting\", handleWaiting);\n        video.addEventListener(\"playing\", handlePlaying);\n        video.addEventListener(\"pause\", handlePause);\n        video.addEventListener(\"ended\", handleEnded);\n\n        if (video.paused) {\n          setShowCenterPlay(true);\n        }\n\n        return () => {\n          if (bufferingTimeoutRef.current) {\n            clearTimeout(bufferingTimeoutRef.current);\n            bufferingTimeoutRef.current = null;\n          }\n\n          video.removeEventListener(\"loadstart\", handleLoadStart);\n          video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n          video.removeEventListener(\"loadeddata\", handleLoadedData);\n          video.removeEventListener(\"canplay\", handleCanPlay);\n          video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n          video.removeEventListener(\"waiting\", handleWaiting);\n          video.removeEventListener(\"playing\", handlePlaying);\n          video.removeEventListener(\"pause\", handlePause);\n          video.removeEventListener(\"ended\", handleEnded);\n        };\n      }, [debugAdTiming]);\n\n      useEffect(() => {\n        setPlayerAspectRatio(DEFAULT_PLAYER_ASPECT_RATIO);\n      }, [src]);\n\n      useEffect(() => {\n        return () => {\n          if (controlsTimerRef.current) {\n            clearTimeout(controlsTimerRef.current);\n          }\n        };\n      }, []);\n\n      const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n      const VolumeIcon = isMuted || volume === 0\n        ? FaVolumeMute\n        : volume < 0.5\n          ? FaVolumeDown\n          : FaVolumeUp;\n\n      return (\n        <>\n          <style>\n            {`\n              @keyframes sc-spin {\n                from { transform: rotate(0deg); }\n                to { transform: rotate(360deg); }\n              }\n              @keyframes sc-loading-glow {\n                0%, 100% { opacity: 0.85; transform: scale(1); }\n                50% { opacity: 1; transform: scale(1.05); }\n              }\n              @keyframes sc-pulse {\n                0%, 100% { opacity: 1; }\n                50% { opacity: 0.6; }\n              }\n              @keyframes sc-fade-in {\n                from { opacity: 0; transform: translateY(8px); }\n                to { opacity: 1; transform: translateY(0); }\n              }\n              .sc-wrapper:fullscreen,\n              .sc-wrapper:has(*:fullscreen) {\n                border-radius: 0 !important;\n                box-shadow: none !important;\n                width: 100vw !important;\n                height: 100vh !important;\n                max-width: 100vw !important;\n                max-height: 100vh !important;\n                position: fixed !important;\n                top: 0 !important;\n                left: 0 !important;\n                z-index: 999999 !important;\n                background: #000 !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n              }\n              .sc-ctrl-btn {\n                background: none;\n                border: none;\n                color: #fff;\n                cursor: pointer;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                border-radius: 50%;\n                padding: 8px;\n                transition: background 0.15s ease, opacity 0.15s ease;\n                opacity: 0.9;\n              }\n              .sc-ctrl-btn:hover {\n                opacity: 1;\n                background: rgba(255, 255, 255, 0.1);\n              }\n              .sc-ctrl-btn:active {\n                opacity: 0.7;\n              }\n              .sc-controls-bar {\n                transition: opacity 0.35s ease, transform 0.35s ease;\n              }\n              .sc-progress-track:hover .sc-progress-thumb {\n                transform: translate(-50%, -50%) scale(1) !important;\n              }\n              .sc-loading-hidden .sc-loading-indicator {\n                display: none !important;\n              }\n            `}\n          </style>\n          <div\n            ref={wrapperRef}\n            className={`sc-wrapper ${wrapperClassName || \"\"}`}\n            onMouseMove={handleWrapperMouseMove}\n            onMouseLeave={handleWrapperMouseLeave}\n            style={{\n              display: \"flex\",\n              alignItems: \"center\",\n              justifyContent: \"center\",\n              position: isFullscreen ? \"fixed\" : \"relative\",\n              top: isFullscreen ? 0 : undefined,\n              left: isFullscreen ? 0 : undefined,\n              overflow: \"hidden\",\n              width: isFullscreen ? \"100vw\" : \"100%\",\n              height: isFullscreen ? \"100vh\" : \"auto\",\n              minHeight: isFullscreen ? \"100vh\" : \"auto\",\n              aspectRatio: isFullscreen ? undefined : playerAspectRatio,\n              maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n              maxHeight: isFullscreen ? \"100vh\" : \"none\",\n              zIndex: isFullscreen ? 999999 : undefined,\n              backgroundColor: \"#000\",\n              borderRadius: isFullscreen ? 0 : undefined,\n              boxShadow: isFullscreen ? \"none\" : undefined,\n              ...wrapperStyle,\n            }}\n          >\n            <video\n              ref={videoRef}\n              className={className}\n              style={{\n                display: \"block\",\n                width: \"100%\",\n                height: \"100%\",\n                maxWidth: \"100%\",\n                maxHeight: isFullscreen ? \"100%\" : \"none\",\n                objectFit: isFullscreen ? \"cover\" : \"contain\",\n                backgroundColor: \"#000\",\n                aspectRatio: isFullscreen ? \"unset\" : undefined,\n                ...style,\n              }}\n              controls={\n                shouldShowNativeControls && controls && !showCustomControls\n              }\n              playsInline={playsInline}\n              preload={preload}\n              poster={poster}\n              {...restVideoAttrs}\n            >\n              {children}\n            </video>\n\n            {(isLoading || isBuffering) && !hideLoadingIndicator && (\n              <div\n                className=\"sc-loading-indicator\"\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 20,\n                  width: `${Math.max(34, 38 * responsiveScale)}px`,\n                  height: `${Math.max(34, 38 * responsiveScale)}px`,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  animation: \"sc-loading-glow 1.4s ease-in-out infinite\",\n                  filter: \"drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55))\",\n                }}\n              >\n                <div\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    borderRadius: \"50%\",\n                    border: \"3px solid rgba(255, 255, 255, 0.25)\",\n                    borderTopColor: \"#ff0000\",\n                    borderRightColor: \"rgba(255, 255, 255, 0.85)\",\n                    animation: \"sc-spin 0.8s linear infinite\",\n                  }}\n                />\n                <div\n                  style={{\n                    width: \"7px\",\n                    height: \"7px\",\n                    borderRadius: \"50%\",\n                    background: \"#ff0000\",\n                    boxShadow: \"0 0 10px rgba(255, 0, 0, 0.65)\",\n                  }}\n                />\n              </div>\n            )}\n\n            {showLicenseWarning && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: \"50%\",\n                  left: \"50%\",\n                  transform: \"translate(-50%, -50%)\",\n                  zIndex: 25,\n                  background: \"rgba(220, 38, 38, 0.92)\",\n                  backdropFilter: \"blur(24px)\",\n                  color: \"white\",\n                  padding: \"28px 36px\",\n                  borderRadius: \"14px\",\n                  border: \"1px solid rgba(255, 255, 255, 0.15)\",\n                  boxShadow: \"0 24px 64px rgba(0, 0, 0, 0.5)\",\n                  textAlign: \"center\",\n                  maxWidth: \"400px\",\n                  margin: \"0 16px\",\n                }}\n              >\n                <div style={{ fontSize: \"18px\", fontWeight: \"700\", marginBottom: \"10px\", letterSpacing: \"-0.02em\" }}>\n                  License Key Required\n                </div>\n                <div style={{ fontSize: \"13px\", lineHeight: \"1.6\", color: \"rgba(255, 255, 255, 0.85)\" }}>\n                  Please provide a valid license key to use the Stormcloud Video\n                  Player.\n                  <br />\n                  Contact your administrator for licensing information.\n                </div>\n              </div>\n            )}\n\n            {adStatus.showAds && (\n              <div\n                style={{\n                  position: \"absolute\",\n                  top: `${12 * responsiveScale}px`,\n                  left: `${12 * responsiveScale}px`,\n                  zIndex: 50,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: \"8px\",\n                  pointerEvents: \"none\",\n                  animation: \"sc-fade-in 0.3s ease\",\n                }}\n              >\n                <div\n                  style={{\n                    background: \"rgba(234, 179, 8, 0.95)\",\n                    color: \"#111\",\n                    padding: `${4 * responsiveScale}px ${12 * responsiveScale}px`,\n                    borderRadius: \"6px\",\n                    fontSize: `${11 * responsiveScale}px`,\n                    fontWeight: 700,\n                    letterSpacing: \"0.08em\",\n                    textTransform: \"uppercase\" as const,\n                    boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.35)\",\n                  }}\n                >\n                  {`Ad ${Math.max(1, adStatus.currentIndex)}`}\n                </div>\n              </div>\n            )}\n\n            {showCenterPlay &&\n              !isLoading &&\n              !isBuffering &&\n              !showLicenseWarning &&\n              !adStatus.showAds && (\n                <div\n                  onClick={handleCenterPlayClick}\n                  style={{\n                    position: \"absolute\",\n                    top: \"50%\",\n                    left: \"50%\",\n                    transform: \"translate(-50%, -50%)\",\n                    zIndex: 15,\n                    cursor: \"pointer\",\n                    background: \"rgba(0, 0, 0, 0.55)\",\n                    backdropFilter: \"blur(8px)\",\n                    borderRadius: \"50%\",\n                    width: `${92 * responsiveScale}px`,\n                    height: `${92 * responsiveScale}px`,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"center\",\n                    transition: \"background 0.2s ease, transform 0.2s ease\",\n                    animation: \"sc-fade-in 0.2s ease\",\n                  }}\n                  onMouseEnter={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.72)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1.06)\";\n                  }}\n                  onMouseLeave={(e) => {\n                    (e.currentTarget as HTMLElement).style.background = \"rgba(0, 0, 0, 0.55)\";\n                    (e.currentTarget as HTMLElement).style.transform = \"translate(-50%, -50%) scale(1)\";\n                  }}\n                  title=\"Play\"\n                >\n                  <FaPlay\n                    size={Math.max(24, 32 * responsiveScale)}\n                    color=\"white\"\n                    style={{ marginLeft: \"4px\" }}\n                  />\n                </div>\n              )}\n\n            {shouldShowEnhancedControls && !showLicenseWarning ? (\n              <div\n                className=\"sc-controls-bar\"\n                style={{\n                  position: \"absolute\",\n                  bottom: 0,\n                  left: 0,\n                  right: 0,\n                  background: \"linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)\",\n                  padding: `${20 * responsiveScale}px ${12 * responsiveScale}px ${8 * responsiveScale}px`,\n                  zIndex: 10,\n                  opacity: controlsVisible || adStatus.showAds ? 1 : 0,\n                  transform: controlsVisible || adStatus.showAds ? \"translateY(0)\" : \"translateY(6px)\",\n                  pointerEvents: controlsVisible || adStatus.showAds ? \"auto\" : \"none\",\n                }}\n              >\n                {/* Progress Bar */}\n                <div\n                  className=\"sc-progress-track\"\n                  style={{\n                    width: \"100%\",\n                    height: \"3px\",\n                    background: \"rgba(255, 255, 255, 0.2)\",\n                    borderRadius: \"1.5px\",\n                    marginBottom: `${8 * responsiveScale}px`,\n                    cursor: \"pointer\",\n                    position: \"relative\",\n                    transition: \"height 0.1s ease\",\n                  }}\n                  onClick={handleTimelineSeek}\n                  onMouseEnter={(e) => { e.currentTarget.style.height = \"5px\"; }}\n                  onMouseLeave={(e) => { e.currentTarget.style.height = \"3px\"; }}\n                >\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: 0, left: 0, bottom: 0,\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"1.5px\",\n                      width: `${progressPercent}%`,\n                      transition: \"width 0.15s linear\",\n                    }}\n                  />\n                  <div\n                    className=\"sc-progress-thumb\"\n                    style={{\n                      position: \"absolute\",\n                      top: \"50%\",\n                      left: `${progressPercent}%`,\n                      transform: \"translate(-50%, -50%) scale(0)\",\n                      width: \"13px\",\n                      height: \"13px\",\n                      background: adStatus.showAds ? \"#f5c518\" : \"#ff0000\",\n                      borderRadius: \"50%\",\n                      boxShadow: \"0 0 4px rgba(0, 0, 0, 0.3)\",\n                      transition: \"transform 0.1s ease, left 0.15s linear\",\n                    }}\n                  />\n                </div>\n\n                {/* Controls Row */}\n                <div\n                  style={{\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"space-between\",\n                    color: \"white\",\n                    gap: `${8 * responsiveScale}px`,\n                  }}\n                >\n                  {/* Left Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Play/Pause */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={handlePlayPause}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isPlaying ? \"Pause\" : \"Play\"}\n                    >\n                      {isPlaying ? (\n                        <FaPause size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaPlay size={Math.max(14, 18 * responsiveScale)} style={{ marginLeft: \"2px\" }} />\n                      )}\n                    </button>\n\n                    {/* Volume Group - YouTube Style */}\n                    <div\n                      style={{\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingRight: `${6 * responsiveScale}px`,\n                      }}\n                      onMouseEnter={() => setShowVolumeSlider(true)}\n                      onMouseLeave={() => setShowVolumeSlider(false)}\n                    >\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => {\n                          if (playerRef.current) playerRef.current.toggleMute();\n                          onVolumeToggle?.();\n                          resetControlsTimer();\n                        }}\n                        style={{\n                          padding: `${8 * responsiveScale}px`,\n                          borderRadius: \"50%\",\n                          minWidth: `${36 * responsiveScale}px`,\n                          minHeight: `${36 * responsiveScale}px`,\n                        }}\n                        title={isMuted ? \"Unmute\" : \"Mute\"}\n                      >\n                        <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                      </button>\n                      <div\n                        style={{\n                          width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                          overflow: \"hidden\",\n                          transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                          display: \"flex\",\n                          alignItems: \"center\",\n                          paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                          paddingRight: showVolumeSlider ? `${8 * responsiveScale}px` : \"0\",\n                        }}\n                      >\n                        <div\n                          style={{\n                            position: \"relative\",\n                            width: `${56 * responsiveScale}px`,\n                            height: \"3px\",\n                            cursor: \"pointer\",\n                            borderRadius: \"1.5px\",\n                          }}\n                          onMouseDown={(e) => {\n                            e.preventDefault();\n                            const el = e.currentTarget;\n                            const move = (ev: MouseEvent) => {\n                              const r = el.getBoundingClientRect();\n                              handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                            };\n                            const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                            document.addEventListener(\"mousemove\", move);\n                            document.addEventListener(\"mouseup\", up);\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                          onClick={(e) => {\n                            e.stopPropagation();\n                            const r = e.currentTarget.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                          }}\n                        >\n                          <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: 0, left: 0, bottom: 0,\n                              width: `${(isMuted ? 0 : volume) * 100}%`,\n                              background: \"#fff\",\n                              borderRadius: \"1.5px\",\n                              transition: \"width 0.1s ease-out\",\n                            }}\n                          />\n                          <div\n                            style={{\n                              position: \"absolute\",\n                              top: \"50%\",\n                              left: `${(isMuted ? 0 : volume) * 100}%`,\n                              transform: \"translate(-50%, -50%)\",\n                              width: \"12px\",\n                              height: \"12px\",\n                              background: \"#fff\",\n                              borderRadius: \"50%\",\n                              boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                              transition: \"left 0.1s ease-out\",\n                            }}\n                          />\n                        </div>\n                      </div>\n                    </div>\n\n                    {/* Time Display */}\n                    <div\n                      style={{\n                        fontSize: `${13 * responsiveScale}px`,\n                        fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n                        color: \"rgba(255, 255, 255, 0.9)\",\n                        display: viewportWidth < 480 ? \"none\" : \"block\",\n                        fontVariantNumeric: \"tabular-nums\",\n                        userSelect: \"none\",\n                        marginLeft: `${4 * responsiveScale}px`,\n                      }}\n                    >\n                      {formatTime(currentTime)}{\" \"}\n                      <span style={{ color: \"rgba(255,255,255,0.5)\" }}>/</span>{\" \"}\n                      {formatTime(duration)}\n                    </div>\n                  </div>\n\n                  {/* Right Group */}\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: `${8 * responsiveScale}px`,\n                    }}\n                  >\n                    {/* Speed Selector */}\n                    <div style={{ position: \"relative\", display: viewportWidth < 600 ? \"none\" : \"block\" }}>\n                      <button\n                        className=\"sc-ctrl-btn\"\n                        onClick={() => { setShowSpeedMenu(!showSpeedMenu); resetControlsTimer(); }}\n                        style={{\n                          padding: `${6 * responsiveScale}px ${10 * responsiveScale}px`,\n                          borderRadius: `${6 * responsiveScale}px`,\n                          fontSize: `${13 * responsiveScale}px`,\n                          fontFamily: \"'SF Mono', 'Cascadia Code', monospace\",\n                          fontWeight: \"600\",\n                          minHeight: `${32 * responsiveScale}px`,\n                        }}\n                        title=\"Playback Speed\"\n                      >\n                        {playbackRate}x\n                      </button>\n\n                      {showSpeedMenu && (\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            bottom: \"100%\",\n                            right: 0,\n                            marginBottom: \"8px\",\n                            background: \"rgba(0, 0, 0, 0.8)\",\n                            backdropFilter: \"blur(24px)\",\n                            WebkitBackdropFilter: \"blur(24px)\",\n                            borderRadius: \"10px\",\n                            border: \"1px solid rgba(255, 255, 255, 0.1)\",\n                            overflow: \"hidden\",\n                            minWidth: \"80px\",\n                            boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5)\",\n                            animation: \"sc-fade-in 0.15s ease\",\n                          }}\n                        >\n                          {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map((speed) => (\n                            <button\n                              key={speed}\n                              onClick={() => handlePlaybackRateChange(speed)}\n                              style={{\n                                display: \"block\",\n                                width: \"100%\",\n                                padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n                                background: playbackRate === speed\n                                  ? \"rgba(255, 255, 255, 0.12)\"\n                                  : \"transparent\",\n                                border: \"none\",\n                                color: playbackRate === speed ? \"#fff\" : \"rgba(255, 255, 255, 0.7)\",\n                                cursor: \"pointer\",\n                                fontSize: `${12 * responsiveScale}px`,\n                                fontFamily: \"'SF Mono', monospace\",\n                                fontWeight: playbackRate === speed ? \"700\" : \"500\",\n                                textAlign: \"center\",\n                                transition: \"background 0.15s ease, color 0.15s ease\",\n                              }}\n                              onMouseEnter={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"rgba(255, 255, 255, 0.08)\";\n                                  (e.target as HTMLElement).style.color = \"#fff\";\n                                }\n                              }}\n                              onMouseLeave={(e) => {\n                                if (playbackRate !== speed) {\n                                  (e.target as HTMLElement).style.background = \"transparent\";\n                                  (e.target as HTMLElement).style.color = \"rgba(255, 255, 255, 0.7)\";\n                                }\n                              }}\n                            >\n                              {speed}x\n                            </button>\n                          ))}\n                        </div>\n                      )}\n                    </div>\n\n                    {/* Fullscreen */}\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (onFullscreenToggle) {\n                          onFullscreenToggle();\n                        } else if (wrapperRef.current) {\n                          if (!document.fullscreenElement) {\n                            wrapperRef.current.requestFullscreen().catch(() => {});\n                          } else {\n                            document.exitFullscreen().catch(() => {});\n                          }\n                        }\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                    >\n                      {isFullscreen ? (\n                        <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                      ) : (\n                        <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                      )}\n                    </button>\n                  </div>\n                </div>\n              </div>\n            ) : (\n              showCustomControls && !showLicenseWarning && (\n                <>\n                  <div\n                    style={{\n                      position: \"absolute\",\n                      top: `${10 * responsiveScale}px`,\n                      left: `${10 * responsiveScale}px`,\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: \"6px\",\n                      zIndex: 10,\n                      opacity: controlsVisible ? 1 : 0,\n                      transition: \"opacity 0.35s ease\",\n                    }}\n                  >\n                    <div\n                      style={{\n                        width: \"8px\",\n                        height: \"8px\",\n                        borderRadius: \"50%\",\n                        background: \"#ff3b30\",\n                        animation: \"sc-pulse 1.5s ease-in-out infinite\",\n                        flexShrink: 0,\n                      }}\n                    />\n                    <span\n                      style={{\n                        fontSize: `${12 * responsiveScale}px`,\n                        fontFamily: \"'SF Pro Display', 'Segoe UI', Arial, sans-serif\",\n                        fontWeight: 700,\n                        letterSpacing: \"0.08em\",\n                        color: \"#fff\",\n                        textShadow: \"0 1px 3px rgba(0,0,0,0.6)\",\n                        userSelect: \"none\",\n                      }}\n                    >\n                      LIVE\n                    </span>\n                  </div>\n\n                  <div\n                  className=\"sc-controls-bar\"\n                  style={{\n                    position: \"absolute\",\n                    bottom: `${10 * responsiveScale}px`,\n                    right: `${10 * responsiveScale}px`,\n                    display: \"flex\",\n                    flexDirection: isPortrait ? \"column\" : \"row\",\n                    alignItems: isPortrait ? \"flex-end\" : \"center\",\n                    gap: `${8 * responsiveScale}px`,\n                    zIndex: 10,\n                    opacity: controlsVisible ? 1 : 0,\n                    transform: controlsVisible ? \"translateY(0)\" : \"translateY(4px)\",\n                    pointerEvents: controlsVisible ? \"auto\" : \"none\",\n                  }}\n                >\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                      borderRadius: `${18 * responsiveScale}px`,\n                      padding: \"2px\",\n                      paddingRight: `${8 * responsiveScale}px`,\n                    }}\n                    onMouseEnter={() => setShowVolumeSlider(true)}\n                    onMouseLeave={() => setShowVolumeSlider(false)}\n                  >\n                    <button\n                      className=\"sc-ctrl-btn\"\n                      onClick={() => {\n                        if (playerRef.current) playerRef.current.toggleMute();\n                        onVolumeToggle?.();\n                        resetControlsTimer();\n                      }}\n                      style={{\n                        padding: `${8 * responsiveScale}px`,\n                        borderRadius: \"50%\",\n                        minWidth: `${36 * responsiveScale}px`,\n                        minHeight: `${36 * responsiveScale}px`,\n                      }}\n                      title={isMuted ? \"Unmute\" : \"Mute\"}\n                    >\n                      <VolumeIcon size={Math.max(14, 18 * responsiveScale)} />\n                    </button>\n                    <div\n                      style={{\n                        width: showVolumeSlider ? `${68 * responsiveScale}px` : \"0px\",\n                        overflow: \"hidden\",\n                        transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n                        display: \"flex\",\n                        alignItems: \"center\",\n                        paddingLeft: showVolumeSlider ? `${3 * responsiveScale}px` : \"0\",\n                        paddingRight: showVolumeSlider ? `${10 * responsiveScale}px` : \"0\",\n                      }}\n                    >\n                      <div\n                        style={{\n                          position: \"relative\",\n                          width: `${56 * responsiveScale}px`,\n                          height: \"3px\",\n                          cursor: \"pointer\",\n                          borderRadius: \"1.5px\",\n                        }}\n                        onMouseDown={(e) => {\n                          e.preventDefault();\n                          const el = e.currentTarget;\n                          const move = (ev: MouseEvent) => {\n                            const r = el.getBoundingClientRect();\n                            handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width)));\n                          };\n                          const up = () => { document.removeEventListener(\"mousemove\", move); document.removeEventListener(\"mouseup\", up); };\n                          document.addEventListener(\"mousemove\", move);\n                          document.addEventListener(\"mouseup\", up);\n                          const r = el.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                        onClick={(e) => {\n                          e.stopPropagation();\n                          const r = e.currentTarget.getBoundingClientRect();\n                          handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));\n                        }}\n                      >\n                        <div style={{ position: \"absolute\", inset: 0, background: \"rgba(255, 255, 255, 0.2)\", borderRadius: \"1.5px\" }} />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: 0, left: 0, bottom: 0,\n                            width: `${(isMuted ? 0 : volume) * 100}%`,\n                            background: \"#fff\",\n                            borderRadius: \"1.5px\",\n                            transition: \"width 0.1s ease-out\",\n                          }}\n                        />\n                        <div\n                          style={{\n                            position: \"absolute\",\n                            top: \"50%\",\n                            left: `${(isMuted ? 0 : volume) * 100}%`,\n                            transform: \"translate(-50%, -50%)\",\n                            width: \"12px\",\n                            height: \"12px\",\n                            background: \"#fff\",\n                            borderRadius: \"50%\",\n                            boxShadow: \"0 0 3px rgba(0, 0, 0, 0.3)\",\n                            transition: \"left 0.1s ease-out\",\n                          }}\n                        />\n                      </div>\n                    </div>\n                  </div>\n\n                  <button\n                    className=\"sc-ctrl-btn\"\n                    onClick={() => {\n                      if (onFullscreenToggle) {\n                        onFullscreenToggle();\n                      } else if (wrapperRef.current) {\n                        if (!document.fullscreenElement) {\n                          wrapperRef.current.requestFullscreen().catch(() => {});\n                        } else {\n                          document.exitFullscreen().catch(() => {});\n                        }\n                      }\n                      resetControlsTimer();\n                    }}\n                    style={{\n                      padding: `${8 * responsiveScale}px`,\n                      borderRadius: \"50%\",\n                      minWidth: `${36 * responsiveScale}px`,\n                      minHeight: `${36 * responsiveScale}px`,\n                      background: \"rgba(0, 0, 0, 0.6)\",\n                    }}\n                    title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n                  >\n                    {isFullscreen ? (\n                      <FaCompress size={Math.max(14, 18 * responsiveScale)} />\n                    ) : (\n                      <FaExpand size={Math.max(14, 18 * responsiveScale)} />\n                    )}\n                  </button>\n                  </div>\n                </>\n              )\n            )}\n\n            {onControlClick && (\n              <div\n                onClick={onControlClick}\n                style={{\n                  position: \"absolute\",\n                  top: 0,\n                  left: 0,\n                  right: 0,\n                  bottom: 0,\n                  zIndex: 1,\n                  cursor: \"pointer\",\n                }}\n              />\n            )}\n          </div>\n        </>\n      );\n    },\n    (prevProps, nextProps) => {\n      for (const prop of CRITICAL_PROPS) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const uiProps = [\n        \"autoplay\",\n        \"muted\",\n        \"controls\",\n        \"showCustomControls\",\n        \"className\",\n        \"style\",\n        \"wrapperClassName\",\n        \"wrapperStyle\",\n        \"playsInline\",\n        \"preload\",\n        \"poster\",\n        \"children\",\n      ] as const;\n\n      for (const prop of uiProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      const callbackProps = [\n        \"onReady\",\n        \"onVolumeToggle\",\n        \"onFullscreenToggle\",\n        \"onControlClick\",\n      ] as const;\n      for (const prop of callbackProps) {\n        if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n  );\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n  url: string;\n  type: string;\n  width: number;\n  height: number;\n  bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n  impression: string[];\n  start: string[];\n  firstQuartile: string[];\n  midpoint: string[];\n  thirdQuartile: string[];\n  complete: string[];\n  mute: string[];\n  unmute: string[];\n  pause: string[];\n  resume: string[];\n  fullscreen: string[];\n  exitFullscreen: string[];\n  skip: string[];\n  error: string[];\n}\n\ninterface VastAd {\n  id: string;\n  title: string;\n  duration: number;\n  mediaFiles: VastMediaFile[];\n  trackingUrls: VastTrackingUrls;\n  clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = new Map<string, Set<(payload?: any) => void>>();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n\n  let adVideoElement: HTMLVideoElement | undefined;\n  let adHls: Hls | undefined;\n  let adContainerEl: HTMLDivElement | undefined;\n  let currentAd: VastAd | undefined;\n  let podAds: VastAd[] = [];\n  let podIndex = 0;\n  let sessionId: string | undefined;\n  const preloadedAds = new Map<string, VastAd>();\n  const preloadingAds = new Map<string, Promise<void>>();\n  let destroyed = false;\n  let pendingTimeouts: number[] = [];\n\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false,\n  };\n\n  function emit(event: string, payload?: any): void {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n\n  function generateSessionId(): string {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  function fireTrackingPixels(urls: string[]): void {\n    if (!urls || urls.length === 0) return;\n\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }session_id=${sessionId}`;\n        }\n\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }license_key=${licenseKey}`;\n        }\n\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n\n  function getMainStreamQuality(): {\n    width: number;\n    height: number;\n    bitrate: number;\n  } | null {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level.width || 1920,\n          height: level.height || 1080,\n          bitrate: level.bitrate || 5000000,\n        };\n      }\n      return null;\n    }\n\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5000000,\n    };\n  }\n\n  function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n\n      const fileBitrate = (file.bitrate || 5000) * 1000;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n      const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n\n    scoredFiles.sort((a, b) => a.score - b.score);\n\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff,\n    });\n\n    return bestMatch.file;\n  }\n\n  function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type === \"application/x-mpegurl\" ||\n      type === \"application/vnd.apple.mpegurl\" ||\n      type.includes(\"mpegurl\") ||\n      url.includes(\".m3u8\")\n    );\n  }\n\n  function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type.startsWith(\"video/\") ||\n      url.endsWith(\".mp4\") ||\n      url.includes(\".mp4?\")\n    );\n  }\n\n  function createEmptyTrackingUrls(): VastTrackingUrls {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: [],\n    };\n  }\n\n  function extractTrackingUrls(scope: Document | Element): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event as keyof VastTrackingUrls;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n\n    return trackingUrls;\n  }\n\n  function mergeTrackingUrls(\n    target: VastTrackingUrls,\n    source: VastTrackingUrls\n  ): VastTrackingUrls {\n    (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n\n  function parseVastXml(xmlString: string): VastParseResult {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = xmlDoc\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = xmlDoc\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: undefined,\n        };\n\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr\n          ? parseInt(bitrateAttr, 10)\n          : undefined;\n        mediaFile.bitrate =\n          bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  function parseAdElement(adElement: Element): VastParseResult {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = adElement\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = adElement\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        if (!url) return;\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n        };\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  async function fetchVastXml(vastTagUrl: string): Promise<string> {\n    const response = await fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: \"include\",\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\",\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\",\n    });\n    if (!response.ok) {\n      throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n    }\n    return response.text();\n  }\n\n  async function fetchAndParseVastAd(\n    vastTagUrl: string,\n    depth = 0,\n    accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n  ): Promise<VastAd | null> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2000)\n    );\n\n    const parsed = parseVastXml(vastXml);\n\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n\n  async function fetchAndParsePod(vastTagUrl: string): Promise<VastAd[]> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n\n    const ads: VastAd[] = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n\n  function createAdVideoElement(): HTMLVideoElement {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n\n    video.volume = 1.0;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n\n    return video;\n  }\n\n  function setupAdEventListeners(): void {\n    if (!adVideoElement || !currentAd) return;\n\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n\n      const progress = adVideoElement.currentTime / currentAd.duration;\n\n      if (progress >= 0.25 && !trackingFired.firstQuartile) {\n        trackingFired.firstQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n      }\n\n      if (progress >= 0.5 && !trackingFired.midpoint) {\n        trackingFired.midpoint = true;\n        fireTrackingPixels(currentAd.trackingUrls.midpoint);\n      }\n\n      if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n        trackingFired.thirdQuartile = true;\n        fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n      }\n    });\n\n    adVideoElement.addEventListener(\"playing\", () => {\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdComplete();\n    });\n\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdError();\n    });\n\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement!.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement!.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement!.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n\n  function setAdPlayingFlag(isPlaying: boolean): void {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n\n  function resetQuartileTracking(preserveImpression: boolean): void {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false,\n    };\n  }\n\n  function loadCurrentAdMedia(): void {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n\n    if (isHlsAd && Hls.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n\n      adHls = new Hls({\n        enableWorker: true,\n        lowLatencyMode: false,\n      });\n\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n\n      adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement!.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n\n      adHls.on(Hls.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (\n      isHlsAd &&\n      adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n    ) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n\n  function advanceToNextPodAd(): boolean {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n\n  function handleAdComplete(): void {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n    \n    if (options?.continueLiveStreamDuringAds) {\n      if (contentVideo.paused) {\n        console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n        contentVideo.play().catch(() => {});\n      } else {\n        console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n      }\n    }\n\n    emit(\"content_resume\");\n  }\n\n  function handleAdError(): void {\n    console.log(\"[HlsAdPlayer] Handling ad error\");\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n\n    emit(\"ad_error\");\n  }\n\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n\n    async requestAds(vastTagUrl: string) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n\n      try {\n        sessionId = generateSessionId();\n        let ads: VastAd[] = [];\n\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n\n        resetQuartileTracking(true);\n\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n\n        emit(\"content_pause\");\n\n        loadCurrentAdMedia();\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {});\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      adPlaying = false;\n      setAdPlayingFlag(false);\n\n      const previousMutedState = contentVideo.muted;\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n      console.log(\n        `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n      );\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n\n      if (options?.continueLiveStreamDuringAds) {\n        if (contentVideo.paused) {\n          console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n          contentVideo.play().catch(() => {});\n        }\n      }\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n      }\n\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n    },\n\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      \n      for (const timeoutId of pendingTimeouts) {\n        clearTimeout(timeoutId);\n      }\n      pendingTimeouts = [];\n      \n      adPlaying = false;\n      setAdPlayingFlag(false);\n      contentVideo.muted = originalMutedState;\n      contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.pause();\n        adVideoElement.src = \"\";\n        adVideoElement.remove();\n        adVideoElement = undefined;\n      }\n\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n\n      adContainerEl = undefined;\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n\n    isAdPlaying() {\n      return adPlaying;\n    },\n\n    resize(width: number, height: number) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n\n    on(event: string, listener: (payload?: any) => void) {\n      if (!listeners.has(event)) listeners.set(event, new Set());\n      listeners.get(event)!.add(listener);\n    },\n\n    off(event: string, listener: (payload?: any) => void) {\n      listeners.get(event)?.delete(listener);\n    },\n\n    updateOriginalMutedState(muted: boolean, volume?: number) {\n      const nextVolume =\n        typeof volume === \"number\" && !Number.isNaN(volume)\n          ? Math.max(0, Math.min(1, volume))\n          : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n\n    setAdVolume(volume: number) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n\n    getAdVolume(): number {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      \n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      \n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1000 : 0),\n        0\n      );\n    },\n  };\n}\n","declare global {\n  interface Window {\n    goog?: any;\n  }\n}\n\nconst PAL_SDK_URL =\n  \"https://imasdk.googleapis.com/pal/sdkloader/pal.js\";\n\nlet _nonceLoader: any | undefined;\nlet _palLoadPromise: Promise<void> | undefined;\n\nfunction loadPalSdk(): Promise<void> {\n  if (typeof window !== \"undefined\" && window.goog?.pal) {\n    return Promise.resolve();\n  }\n\n  if (_palLoadPromise) return _palLoadPromise;\n\n  _palLoadPromise = new Promise<void>((resolve, reject) => {\n    const existing = document.querySelector(\n      'script[data-pal=\"true\"]'\n    ) as HTMLScriptElement | null;\n\n    if (existing) {\n      if (window.goog?.pal) {\n        resolve();\n        return;\n      }\n      const timeout = setTimeout(\n        () => reject(new Error(\"PAL SDK load timeout\")),\n        10000\n      );\n      existing.addEventListener(\"load\", () => {\n        clearTimeout(timeout);\n        resolve();\n      });\n      existing.addEventListener(\"error\", () => {\n        clearTimeout(timeout);\n        reject(new Error(\"PAL SDK load failed\"));\n      });\n      return;\n    }\n\n    const script = document.createElement(\"script\");\n    script.src = PAL_SDK_URL;\n    script.async = true;\n    script.setAttribute(\"data-pal\", \"true\");\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"PAL SDK load failed\"));\n    document.head.appendChild(script);\n  });\n\n  return _palLoadPromise;\n}\n\nfunction getOrCreateNonceLoader(): any {\n  if (_nonceLoader) return _nonceLoader;\n  const goog = window.goog;\n  const consentSettings = new goog.pal.ConsentSettings();\n  consentSettings.allowStorage = true;\n  _nonceLoader = new goog.pal.NonceLoader(consentSettings);\n  return _nonceLoader;\n}\n\nexport interface PalNonceOptions {\n  videoWidth?: number;\n  videoHeight?: number;\n  descriptionUrl?: string;\n  ppid?: string;\n  sessionId?: string;\n  adWillAutoPlay?: boolean;\n  adWillPlayMuted?: boolean;\n  playerVolume?: number;\n  continuousPlayback?: boolean;\n}\n\nexport interface PalNonceManager {\n  generateNonce(options?: PalNonceOptions): Promise<string>;\n\n  getCurrentNonce(): string;\n\n  injectNonce(vastTagUrl: string): string;\n\n  sendPlaybackStart(): void;\n\n  sendPlaybackEnd(): void;\n\n  sendAdClick(): void;\n\n  sendAdTouch(event: MouseEvent | TouchEvent): void;\n\n  reset(): void;\n}\n\nexport function createPalNonceManager(): PalNonceManager {\n  let currentNonce = \"\";\n  let currentNonceManager: any | undefined;\n\n  return {\n    async generateNonce(options: PalNonceOptions = {}): Promise<string> {\n      try {\n        await loadPalSdk();\n\n        const loader = getOrCreateNonceLoader();\n        const goog = window.goog;\n\n        const request = new goog.pal.NonceRequest();\n        request.adWillAutoPlay = options.adWillAutoPlay ?? true;\n        request.adWillPlayMuted = options.adWillPlayMuted ?? false;\n        request.playerVolume =\n          options.playerVolume ?? (request.adWillPlayMuted ? 0 : 1);\n        request.continuousPlayback = options.continuousPlayback ?? true;\n        request.descriptionUrl =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url =\n          options.descriptionUrl ||\n          (typeof window !== \"undefined\" ? window.location.href : \"\");\n        request.videoWidth = options.videoWidth || 640;\n        request.videoHeight = options.videoHeight || 480;\n\n        if (options.ppid) request.ppid = options.ppid;\n        if (options.sessionId) request.sessionId = options.sessionId;\n\n        const manager = await loader.loadNonceManager(request);\n        currentNonceManager = manager;\n        currentNonce = manager.getNonce() as string;\n\n        console.log(\"[PAL] Nonce generated successfully\");\n        return currentNonce;\n      } catch (error) {\n        console.warn(\"[PAL] Failed to generate nonce:\", error);\n        currentNonce = \"\";\n        currentNonceManager = undefined;\n        return \"\";\n      }\n    },\n\n    getCurrentNonce(): string {\n      return currentNonce;\n    },\n\n    injectNonce(vastTagUrl: string): string {\n      if (!currentNonce || !vastTagUrl) return vastTagUrl;\n\n      try {\n        const url = new URL(vastTagUrl);\n        url.searchParams.delete(\"paln\");\n        url.searchParams.set(\"givn\", currentNonce);\n        return url.toString();\n      } catch {\n        let base = vastTagUrl\n          .replace(/([?&])paln=[^&]*/g, \"\")\n          .replace(/[?&]$/, \"\");\n        const sep = base.includes(\"?\") ? \"&\" : \"?\";\n        return `${base}${sep}givn=${encodeURIComponent(currentNonce)}`;\n      }\n    },\n\n    sendPlaybackStart(): void {\n      try {\n        currentNonceManager?.sendPlaybackStart();\n      } catch {}\n    },\n\n    sendPlaybackEnd(): void {\n      try {\n        currentNonceManager?.sendPlaybackEnd();\n      } catch {}\n    },\n\n    sendAdClick(): void {\n      try {\n        currentNonceManager?.sendAdClick();\n      } catch {}\n    },\n\n    sendAdTouch(event: MouseEvent | TouchEvent): void {\n      try {\n        currentNonceManager?.sendAdTouch(event);\n      } catch {}\n    },\n\n    reset(): void {\n      currentNonce = \"\";\n      currentNonceManager = undefined;\n    },\n  };\n}\n","export const MQTT_CA_CERT_FILE = \"src/certs/emqxsl-ca.crt\";\n\nexport type MQTTConfig = {\n  enabled: boolean;\n  brokerAddress: string;\n  brokerPort: number;\n  wsPort: number;\n  username: string;\n  password: string;\n  topicPrefix: string;\n  qos: 0 | 1 | 2;\n  brokerUrl?: string;\n};\n\nexport const DEFAULT_MQTT_CONFIG: MQTTConfig = {\n  enabled: true,\n  brokerAddress: \"vecbae77.ala.us-east-1.emqxsl.com\",\n  brokerPort: 8883,\n  wsPort: 8084,\n  username: \"for-sonifi\",\n  password: \"sonifi-mqtt\",\n  topicPrefix: \"adstorm/players\",\n  qos: 1,\n};\n\nexport const mqttConfig: MQTTConfig = { ...DEFAULT_MQTT_CONFIG };\n\nexport function applyMQTTConfig(overrides: Partial<MQTTConfig>): void {\n  Object.assign(mqttConfig, overrides);\n}\n\nexport function isMQTTEnabled(): boolean {\n  return mqttConfig.enabled;\n}\n\nexport function buildMQTTBrokerUrl(): string {\n  if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;\n  return `wss://${mqttConfig.brokerAddress}:${mqttConfig.wsPort}/mqtt`;\n}\n\nexport function buildPlayerTopic(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\"\n): string {\n  return `${mqttConfig.topicPrefix}/${licenseKey}/${channel}`;\n}\n","import mqtt from \"mqtt\";\nimport type { MqttClient } from \"mqtt\";\nimport {\n  applyMQTTConfig,\n  buildMQTTBrokerUrl,\n  isMQTTEnabled,\n  mqttConfig,\n} from \"./mqttConfig\";\nimport type { MQTTConfig } from \"./mqttConfig\";\n\nconst LOG = \"[StormcloudVideoPlayer][MQTT]\";\n\nexport type MQTTStatus = \"disconnected\" | \"connecting\" | \"connected\" | \"error\";\n\nlet client: MqttClient | null = null;\nlet status: MQTTStatus = \"disconnected\";\n\nexport function getMQTTStatus(): MQTTStatus {\n  return status;\n}\n\nexport function isMQTTConnected(): boolean {\n  return status === \"connected\" && client !== null && client.connected;\n}\n\nexport function isMQTTConfigured(): boolean {\n  return isMQTTEnabled();\n}\n\nexport function configureMQTT(overrides: Partial<MQTTConfig>): void {\n  applyMQTTConfig(overrides);\n  disconnectMQTT();\n}\n\nexport function initMQTTClient(): void {\n  if (client || !isMQTTEnabled()) return;\n\n  const url = buildMQTTBrokerUrl();\n  status = \"connecting\";\n\n  const clientId = `stormcloud-vp-${Math.random().toString(36).slice(2, 9)}`;\n\n  try {\n    client = mqtt.connect(url, {\n      clientId,\n      username: mqttConfig.username,\n      password: mqttConfig.password,\n      keepalive: 60,\n      clean: true,\n      reconnectPeriod: 5000,\n      connectTimeout: 10_000,\n      queueQoSZero: false,\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    return;\n  }\n\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    console.info(`${LOG} connected to ${url}`);\n  });\n\n  client.on(\"reconnect\", () => {\n    status = \"connecting\";\n    console.info(`${LOG} reconnecting…`);\n  });\n\n  client.on(\"offline\", () => {\n    status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n  });\n\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n  });\n\n  client.on(\"close\", () => {\n    if (status === \"connected\") {\n      status = \"disconnected\";\n    }\n  });\n}\n\nexport function ensureMQTTClient(): void {\n  if (isMQTTEnabled() && !client) {\n    initMQTTClient();\n  }\n}\n\nexport function publishMQTT(\n  topic: string,\n  payload: Record<string, unknown>\n): boolean {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n\n  ensureMQTTClient();\n\n  if (!client) {\n    return false;\n  }\n\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\nexport function disconnectMQTT(): void {\n  if (client) {\n    client.end(true);\n    client = null;\n    status = \"disconnected\";\n  }\n}\n","export interface VastEnvironmentSignals {\n  isCtv: boolean;\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  sessionId?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n  deviceTypeHint?: number;\n}\n\nconst AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nconst AIRY_WEBOS_APP_ID    = \"com.freeairytv.webos\";\nconst AIRY_TIZEN_APP_ID    = \"com.freeairytv.samsung\";\nconst AIRY_ROKU_APP_ID     = \"com.freeairytv.roku\";\nconst AIRY_APP_NAME = \"AiryTV Movies & TV\";\nconst AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nconst CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nexport const PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\n\nconst LG_TEST_APP_ID      = \"com.hulu.plus\";\nconst LG_TEST_APP_NAME    = \"Hulu\";\nconst LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\n\nlet _lgTestDeviceId: string | undefined;\nfunction getLgTestDeviceId(): string {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\n\nfunction isLgWebOS(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\n\nfunction getDefaultAppId(): string {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua))                       return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua))                                return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\n\nconst DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\",\n];\n\nconst ANDROID_ID_TYPES = new Set([\"aaid\", \"adid\"]);\n\nexport function resolveVastEnvironmentSignals(isCtv: boolean): VastEnvironmentSignals {\n  const bridgeSignals  = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n\n  const deviceId =\n    bridgeSignals.deviceId  ||\n    readStoredDeviceId()    ||\n    platformDevice.deviceId ||\n    (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : undefined);\n  const deviceIdType =\n    bridgeSignals.deviceIdType  ||\n    readStoredString(\"deviceIdType\") ||\n    readStoredString(\"idtype\") ||\n    platformDevice.deviceIdType ||\n    inferDeviceIdType() ||\n    (lg ? \"lgudid\" : undefined);\n  const platformLat = bridgeSignals.deviceId\n    ? bridgeSignals.limitAdTracking\n    : platformDevice.limitAdTracking;\n  const limitAdTracking =\n    deviceId != null\n      ? platformLat ?? readStoredLimitAdTracking() ?? false\n      : undefined;\n\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl:\n        bridgeSignals.contentUrl ||\n        readStoredString(\"contentUrl\") ||\n        (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId:\n        bridgeSignals.appId ||\n        readStoredString(\"appId\") ||\n        readStoredString(\"msid\") ||\n        (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName:\n        bridgeSignals.appName ||\n        readStoredString(\"appName\") ||\n        readStoredString(\"an\") ||\n        (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceIdType ? { deviceIdType } : {}),\n      ...(limitAdTracking != null ? { limitAdTracking } : {}),\n      deviceTypeHint: 5,\n    };\n  }\n\n  return {\n    isCtv: false,\n    ...(deviceId ? { deviceId } : {}),\n    ...(deviceIdType ? { deviceIdType } : {}),\n    ...(limitAdTracking != null ? { limitAdTracking } : {}),\n  };\n}\n\nexport function inferDeviceIdType(): string | undefined {\n  if (typeof navigator === \"undefined\") {\n    return undefined;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return undefined;\n}\n\nexport function isEquivalentDeviceIdType(\n  tagType: string | undefined,\n  runtimeType: string | undefined\n): boolean {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\n\nexport function resolveNativeDeviceId(): string | undefined {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId =\n    bridgeSignals.deviceId ||\n    readStoredDeviceId() ||\n    platformDevice.deviceId;\n\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return undefined;\n  }\n\n  return deviceId;\n}\n\nexport function getOrCreateStoredUuid(storageKey: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\n\nfunction readPersistentId(storageKey: string): string | undefined {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\n\nfunction writePersistentId(storageKey: string, value: string): void {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {}\n  writeCookie(storageKey, value);\n}\n\nconst PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5; // ~5 years\n\nfunction readCookie(name: string): string | undefined {\n  if (typeof document === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || undefined;\n      }\n    }\n  } catch {}\n\n  return undefined;\n}\n\nfunction writeCookie(name: string, value: string): void {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n\n  try {\n    document.cookie =\n      encodeURIComponent(name) +\n      \"=\" +\n      encodeURIComponent(value) +\n      \";path=/;max-age=\" +\n      PERSISTENT_ID_COOKIE_MAX_AGE +\n      \";SameSite=Lax\";\n  } catch {}\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 0xff;\n    }\n  }\n\n  bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n  bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n\n  return (\n    hex.slice(0, 8) +\n    \"-\" +\n    hex.slice(8, 12) +\n    \"-\" +\n    hex.slice(12, 16) +\n    \"-\" +\n    hex.slice(16, 20) +\n    \"-\" +\n    hex.slice(20, 32)\n  );\n}\n\nfunction performanceNow(): number {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {}\n  return 0;\n}\n\nfunction readPlatformNativeDeviceId(): {\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") return {};\n\n  try {\n    const adinfo = (window as any).webapis?.adinfo;\n    if (adinfo) {\n      const tifa: unknown =\n        typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat: unknown =\n          typeof adinfo.isLATEnabled === \"function\"\n            ? adinfo.isLATEnabled()\n            : undefined;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...(typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}),\n        };\n      }\n    }\n  } catch {}\n\n  try {\n    const webOSDev = (window as any).webOSDev;\n    if (webOSDev) {\n      const lgudid: unknown =\n        typeof webOSDev.LGUDID === \"function\"\n          ? webOSDev.LGUDID()\n          : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {}\n\n  try {\n    const roku = (window as any).Roku;\n    if (roku) {\n      const rida: unknown =\n        typeof roku.getPublisherUniqueId === \"function\"\n          ? roku.getPublisherUniqueId()\n          : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {}\n\n  return {};\n}\n\nconst ZEROED_AD_ID_PATTERNS: ReadonlySet<string> = new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\",\n]);\n\nfunction isMacroPlaceholder(value: string): boolean {\n  const t = value.trim();\n  return !t ||\n    /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) ||\n    /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) ||\n    ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\n\nfunction isZeroedAdId(value: string): boolean {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\n\nfunction readNativeBridgeSignals(): {\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n\n  const candidates = [\n    (window as any).__STORMCLOUD_CTV_AD_INFO__,\n    (window as any).__STORMCLOUD_CTV__,\n    (window as any).stormcloudCtv,\n    (window as any).AiryTV,\n    (window as any).Android,\n    (window as any).webOS,\n    (window as any).tizen,\n    (window as any).amazon,\n  ].filter(Boolean);\n\n  for (const source of candidates) {\n    const contentUrl =\n      readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) ||\n      undefined;\n    const appId =\n      readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) ||\n      undefined;\n    const appName =\n      readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || undefined;\n    const deviceId =\n      readBridgeValue(source, [\n        \"rdid\",\n        \"ifa\",\n        \"advertisingId\",\n        \"adId\",\n        \"deviceId\",\n        \"lgudid\",\n        \"LGUDID\",\n        \"tifa\",\n        \"rida\",\n        \"afai\",\n        \"aaid\",\n      ]) || undefined;\n\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n\n    const deviceIdType =\n      readBridgeValue(source, [\n        \"idtype\",\n        \"deviceIdType\",\n        \"advertisingIdType\",\n        \"idType\",\n      ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\",\n    ]);\n\n    return {\n      ...(contentUrl ? { contentUrl } : {}),\n      ...(appId ? { appId } : {}),\n      ...(appName ? { appName } : {}),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceId && deviceIdType ? { deviceIdType } : {}),\n      ...(deviceId && limitAdTracking != null ? { limitAdTracking } : {}),\n    };\n  }\n\n  return {};\n}\n\nfunction readBridgeValue(source: any, keys: string[]): string | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readBridgeBoolean(source: any, keys: string[]): boolean | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredDeviceId(): string | undefined {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredString(key: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction readStoredLimitAdTracking(): boolean | undefined {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") ||\n      readStoredString(\"limitedAdTracking\") ||\n      readStoredString(\"is_lat\")\n  );\n}\n\nfunction normalizeBoolean(value: unknown): boolean | undefined {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return undefined;\n}\n","import type {\n  ClientInfo,\n  AdDetectInfo,\n  AdLoadedInfo,\n  AdImpressionInfo,\n  PlayerAnalyticsContext,\n  StormcloudVideoPlayerConfig,\n} from \"../types\";\n\nimport { buildPlayerTopic, isMQTTEnabled } from \"./mqttConfig\";\nimport { ensureMQTTClient, publishMQTT } from \"./mqttClient\";\nimport {\n  getOrCreateStoredUuid,\n  PLAYER_ID_STORAGE_KEY,\n  resolveNativeDeviceId,\n} from \"./vastEnvironmentSignals\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function buildAnalyticsContext(\n  config: Pick<StormcloudVideoPlayerConfig, \"debugAdTiming\" | \"isLiveStream\">\n): PlayerAnalyticsContext {\n  const context: PlayerAnalyticsContext = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== undefined) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\n\nexport function getClientInfo(): ClientInfo {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = (navigator as any).deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: (screen?.orientation as any)?.type || \"\",\n    pixelDepth: screen?.pixelDepth,\n  };\n\n  let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch\n      ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n      : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n  ) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n  ) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n    if (\n      ua.includes(\"Android\") &&\n      (maxTouchPoints === 0 ||\n        ua.includes(\"Google TV\") ||\n        ua.includes(\"XiaoMi\"))\n    ) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n\n  isWebApp =\n    window.matchMedia(\"(display-mode: standalone)\").matches ||\n    (window.navigator as any).standalone === true ||\n    window.screen?.orientation?.angle !== undefined;\n\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState,\n  };\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n      let encodedData: BufferSource;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer))\n        .map((b) => b.toString(16).padStart(2, \"0\"))\n        .join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\n\nfunction resolvePlayerIdentitySeed(clientInfo: ClientInfo): string {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\n\ntype PlayerMetricFlags = {\n  adLoaded?: boolean;\n  adDetect?: boolean;\n  captureAt?: string;\n};\n\nfunction canPublish(licenseKey: string | undefined): licenseKey is string {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\n\nasync function buildPlayerMetricEvent(\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n  const clientInfo = getClientInfo();\n\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n\n  const playerId = await getBrowserID(clientInfo);\n\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n\n  const captureAt = flags.captureAt ?? new Date().toISOString();\n\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...(context.inputStreamType\n      ? { input_stream_type: context.inputStreamType }\n      : {}),\n  };\n}\n\nfunction publishTracking(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\",\n  body: Record<string, unknown>\n): void {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\n\nexport async function sendInitialTracking(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false,\n    });\n\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdDetectTracking(\n  licenseKey: string | undefined,\n  adDetectInfo: AdDetectInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdLoadedTracking(\n  licenseKey: string | undefined,\n  adLoadedInfo: AdLoadedInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdImpressionTracking(\n  licenseKey: string | undefined,\n  adImpressionInfo: AdImpressionInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp,\n    });\n\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp,\n        },\n      ],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendHeartbeat(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n","export function polyfillURLSearchParams(): void {\n  if (typeof URLSearchParams !== 'undefined') {\n    return;\n  }\n\n  class URLSearchParamsPolyfill {\n    private params: Map<string, string[]>;\n\n    constructor(init?: string | URLSearchParamsPolyfill) {\n      this.params = new Map();\n\n      if (typeof init === 'string') {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n\n    private parseQueryString(query: string): void {\n      const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n      if (!cleanQuery) return;\n\n      cleanQuery.split('&').forEach((param) => {\n        const [key, value] = param.split('=');\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n\n    private safeDecodeURIComponent(str: string): string {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, ' '));\n      } catch (e) {\n        return str;\n      }\n    }\n\n    append(name: string, value: string): void {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n\n    delete(name: string): void {\n      this.params.delete(name);\n    }\n\n    get(name: string): string | null {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n    }\n\n    getAll(name: string): string[] {\n      return this.params.get(name) || [];\n    }\n\n    has(name: string): boolean {\n      return this.params.has(name);\n    }\n\n    set(name: string, value: string): void {\n      this.params.set(name, [String(value)]);\n    }\n\n    forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n\n    toString(): string {\n      const parts: string[] = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join('&');\n    }\n  }\n\n  // @ts-ignore\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n  if (typeof TextEncoder !== 'undefined') {\n    return;\n  }\n\n  class TextEncoderPolyfill {\n    encoding = 'utf-8';\n\n    encode(str: string): Uint8Array {\n      const utf8: number[] = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 0x80) {\n          utf8.push(charcode);\n        } else if (charcode < 0x800) {\n          utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n        } else if (charcode < 0xd800 || charcode >= 0xe000) {\n          utf8.push(\n            0xe0 | (charcode >> 12),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        } else {\n          i++;\n          charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n          utf8.push(\n            0xf0 | (charcode >> 18),\n            0x80 | ((charcode >> 12) & 0x3f),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n\n  // @ts-ignore\n  window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n  if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n    Promise.prototype.finally = function (callback: () => void) {\n      const constructor = this.constructor as PromiseConstructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) =>\n          constructor.resolve(callback()).then(() => {\n            throw reason;\n          })\n      );\n    };\n  }\n}\n\nexport function polyfillObjectAssign(): void {\n  if (typeof Object.assign !== 'function') {\n    Object.assign = function (target: any, ...sources: any[]) {\n      if (target == null) {\n        throw new TypeError('Cannot convert undefined or null to object');\n      }\n\n      const to = Object(target);\n\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n\n      return to;\n    };\n  }\n}\n\nexport function polyfillArrayFrom(): void {\n  if (!Array.from) {\n    Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError('Array.from requires an array-like object');\n      }\n\n      const len = items.length >>> 0;\n      const result = new Array(len);\n\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n\n      return result;\n    };\n  }\n}\n\nexport function polyfillStringStartsWith(): void {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function (search: string, pos?: number) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\n\nexport function polyfillStringEndsWith(): void {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function (search: string, length?: number) {\n      if (length === undefined || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\n\nexport function polyfillStringIncludes(): void {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function (search: string, start?: number) {\n      if (typeof start !== 'number') {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\n\nexport function initializePolyfills(): void {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n","import {\n  inferDeviceIdType,\n  isEquivalentDeviceIdType,\n} from \"./vastEnvironmentSignals\";\n\nexport interface VastConsentSignals {\n  gdpr?: string | undefined;\n  gdprConsent?: string | undefined;\n  usPrivacy?: string | undefined;\n}\n\nexport interface VastMacroContext {\n  correlator: string;\n  streamCorrelator: string;\n  pod?: number | undefined;\n  adPosition?: number | undefined;\n  podMaxAds?: number | undefined;\n  podMinDurationMs?: number | undefined;\n  podMaxDurationMs?: number | undefined;\n  isCtv?: boolean | undefined;\n  contentUrl?: string | undefined;\n  pageUrl?: string | undefined;\n  adWillPlayMuted?: boolean | undefined;\n  adWillAutoPlay?: boolean | undefined;\n  appId?: string | undefined;\n  appName?: string | undefined;\n  sessionId?: string | undefined;\n  deviceId?: string | undefined;\n  deviceIdType?: string | undefined;\n  limitAdTracking?: boolean | undefined;\n  deviceTypeHint?: number | undefined;\n  adTest?: boolean | undefined;\n  consent?: VastConsentSignals | undefined;\n}\n\nconst UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nconst INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nconst EXAMPLE_COM_URL = /example\\.com/i;\nconst CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\",\n];\n\nconst INLINE_DEVICE_MACRO_REPLACEMENTS: Array<{\n  pattern: RegExp;\n  getValue: (ctx: VastMacroContext) => string | undefined;\n}> = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator },\n];\n\nexport function isMacroPlaceholder(value: string | null | undefined): boolean {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\n\nexport function generateCorrelator(): string {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 0x200000 + ((buf[1] ?? 0) & 0x1fffff);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\n\nfunction expandInlineMacroPlaceholders(baseUrl: string, ctx: VastMacroContext): string {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\n\nfunction applyDeviceIdentityParams(\n  params: URLSearchParams,\n  ctx: VastMacroContext\n): void {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue =\n    ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined;\n\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder(tagLat) ? \"0\" : tagLat!));\n    return;\n  }\n\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));\n\n  if (\n    tagRdidValid &&\n    tagTypeValid &&\n    runtimeType &&\n    !isEquivalentDeviceIdType(tagType!, runtimeType)\n  ) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n\n  if (tagRdidValid) {\n    if (isMacroPlaceholder(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\n\nfunction removeBrokenAppNameOrphans(\n  params: URLSearchParams,\n  appName?: string\n): void {\n  const toDelete: string[] = [];\n\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.trimStart();\n      if (!trimmed) continue;\n      toDelete.push(suffix, ` ${trimmed}`, trimmed);\n    }\n  }\n\n  for (const key of new Set(toDelete)) {\n    if (key) params.delete(key);\n  }\n}\n\nexport function normalizeVastTagUrl(raw: string): string {\n  if (!raw) return raw;\n\n  try {\n    const url = new URL(raw);\n\n    const anValue = url.searchParams.get(\"an\");\n    if (anValue !== null) {\n      const orphanFragments: string[] = [];\n      url.searchParams.forEach((_value, key) => {\n        if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n          orphanFragments.push(key.trim());\n        }\n      });\n      if (orphanFragments.length > 0) {\n        const reconstructed = [anValue.trimEnd(), ...orphanFragments]\n          .filter(Boolean)\n          .join(\" & \");\n\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\n\nexport function applyVastMacros(\n  baseUrl: string,\n  ctx: VastMacroContext\n): string {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url: URL;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n\n  const params = url.searchParams;\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n\n  const optimizedPodMode =\n    ctx.podMaxAds != null ||\n    ctx.podMinDurationMs != null ||\n    ctx.podMaxDurationMs != null;\n\n  if (optimizedPodMode) {\n    params.delete(\"ppos\");\n    params.delete(\"lip\");\n    if (ctx.podMinDurationMs != null) {\n      params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n    }\n    if (ctx.podMaxDurationMs != null) {\n      params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n    }\n    if (ctx.podMaxAds != null) {\n      params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n    }\n  } else if (ctx.adPosition != null) {\n    params.set(\"ppos\", String(ctx.adPosition));\n  }\n\n  const requestUrl = ctx.contentUrl || ctx.pageUrl;\n  if (requestUrl) {\n    params.set(\"url\", requestUrl);\n    if (!ctx.isCtv) {\n      params.set(\"description_url\", requestUrl);\n    }\n  } else {\n    const existingUrl = params.get(\"url\") || \"\";\n    if (EXAMPLE_COM_URL.test(existingUrl)) {\n      params.delete(\"url\");\n      params.delete(\"description_url\");\n    }\n  }\n\n  if (ctx.adWillPlayMuted != null) {\n    params.set(\"vpmute\", ctx.adWillPlayMuted ? \"1\" : \"0\");\n  }\n  if (ctx.adWillAutoPlay != null) {\n    params.set(\"vpa\", ctx.adWillAutoPlay ? \"auto\" : \"click\");\n  }\n\n  if (ctx.appId) {\n    params.set(\"msid\", ctx.appId);\n  }\n  if (ctx.appName) {\n    removeBrokenAppNameOrphans(params, ctx.appName);\n    params.set(\"an\", ctx.appName);\n  }\n  if (ctx.sessionId) {\n    params.set(\"sid\", ctx.sessionId);\n  }\n  if (ctx.deviceTypeHint != null) {\n    params.set(\"dth\", String(ctx.deviceTypeHint));\n  } else if (ctx.isCtv) {\n    params.set(\"dth\", \"5\");\n  }\n\n  applyDeviceIdentityParams(params, ctx);\n\n  if (!ctx.isCtv) {\n    const consent = ctx.consent;\n    if (consent?.gdpr != null) {\n      params.set(\"gdpr\", consent.gdpr);\n    }\n    if (consent?.gdprConsent != null) {\n      params.set(\"gdpr_consent\", consent.gdprConsent);\n    }\n    if (consent?.usPrivacy != null) {\n      params.set(\"us_privacy\", consent.usPrivacy);\n    }\n  }\n\n  if (ctx.adTest) {\n    params.set(\"adtest\", \"on\");\n  }\n\n  const staleKeys: string[] = [];\n  params.forEach((value, key) => {\n    if (isMacroPlaceholder(value)) {\n      staleKeys.push(key);\n    }\n  });\n  for (const key of staleKeys) {\n    params.delete(key);\n  }\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  return url.toString();\n}\n\nfunction replaceCorrelatorFallback(baseUrl: string, correlator: string): string {\n  const correlatorRegex = /([?&])correlator=([^&]*)/;\n  if (correlatorRegex.test(baseUrl)) {\n    return baseUrl.replace(correlatorRegex, `$1correlator=${correlator}`);\n  }\n  const sep = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n  return `${baseUrl}${sep}correlator=${correlator}`;\n}\n\nexport function fetchConsentSignals(\n  timeoutMs: number = 1500\n): Promise<VastConsentSignals> {\n  const signals: VastConsentSignals = {};\n  if (typeof window === \"undefined\") {\n    return Promise.resolve(signals);\n  }\n\n  const tasks: Promise<void>[] = [];\n\n  const tcfApi = (window as any).__tcfapi;\n  if (typeof tcfApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        let settled = false;\n        try {\n          tcfApi(\"addEventListener\", 2, (tcData: any, success: boolean) => {\n            if (settled) return;\n            if (\n              success &&\n              tcData &&\n              (tcData.eventStatus === \"tcloaded\" ||\n                tcData.eventStatus === \"useractioncomplete\")\n            ) {\n              settled = true;\n              signals.gdpr = tcData.gdprApplies ? \"1\" : \"0\";\n              if (typeof tcData.tcString === \"string\" && tcData.tcString) {\n                signals.gdprConsent = tcData.tcString;\n              }\n              try {\n                tcfApi(\"removeEventListener\", 2, () => {}, tcData.listenerId);\n              } catch {}\n              resolve();\n            }\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(() => {\n          if (!settled) {\n            settled = true;\n            resolve();\n          }\n        }, timeoutMs);\n      })\n    );\n  }\n\n  const uspApi = (window as any).__uspapi;\n  if (typeof uspApi === \"function\") {\n    tasks.push(\n      new Promise<void>((resolve) => {\n        try {\n          uspApi(\"getUSPData\", 1, (data: any, success: boolean) => {\n            if (success && typeof data?.uspString === \"string\" && data.uspString) {\n              signals.usPrivacy = data.uspString;\n            }\n            resolve();\n          });\n        } catch {\n          resolve();\n        }\n        setTimeout(resolve, timeoutMs);\n      })\n    );\n  }\n\n  if (tasks.length === 0) {\n    return Promise.resolve(signals);\n  }\n\n  return Promise.all(tasks).then(() => signals);\n}\n","interface NavigatorUAData {\n  platform?: string;\n  brands?: Array<{ brand: string; version: string }>;\n  mobile?: boolean;\n}\n\ndeclare global {\n  interface Navigator {\n    userAgentData?: NavigatorUAData;\n  }\n}\n\nexport interface BrowserInfo {\n  name: string;\n  version: string;\n  majorVersion: number;\n  isSmartTV: boolean;\n  isLegacyTV: boolean;\n  platform: string;\n  supportsModernJS: boolean;\n  webOSVersion?: number | undefined;\n  tizenVersion?: number | undefined;\n  chromeVersion?: number | undefined;\n}\n\nfunction getChromeVersion(ua: string): number {\n  const match = ua.match(/Chrome\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n  const match = ua.match(/AppleWebKit\\/(\\d+)/);\n  return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n  if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n    return navigator.userAgentData.platform;\n  }\n\n  const ua = navigator.userAgent;\n  if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n    return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n  }\n  if (/Win/i.test(ua)) {\n    return 'Win32';\n  }\n  if (/Linux/i.test(ua)) {\n    return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n  }\n  if (/CrOS/i.test(ua)) {\n    return 'CrOS';\n  }\n\n  // eslint-disable-next-line deprecation/deprecation\n  return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n  const ua = navigator.userAgent;\n  const platform = getPlatform();\n\n  let name = 'Unknown';\n  let version = '0';\n  let majorVersion = 0;\n  let isSmartTV = false;\n  let isLegacyTV = false;\n  let supportsModernJS = true;\n  let webOSVersion: number | undefined;\n  let tizenVersion: number | undefined;\n  let chromeVersionNum: number | undefined;\n\n  const chromeVersion = getChromeVersion(ua);\n  const webkitVersion = getWebKitVersion(ua);\n  chromeVersionNum = chromeVersion > 0 ? chromeVersion : undefined;\n\n  if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {\n    name = 'LG WebOS';\n    isSmartTV = true;\n\n    let match = ua.match(/Web0S[/\\s]*([\\d.]+)/i) || ua.match(/webOS[/\\s]*([\\d.]+)/i);\n\n    if (!match || !match[1]) {\n      match = ua.match(/webOSTV[/\\s-]*([\\d.]+)/i) || ua.match(/webOS\\.TV[/\\s-]*([\\d.]+)/i);\n    }\n\n    if (match && match[1]) {\n      version = match[1];\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      webOSVersion = majorVersion;\n    } else if (chromeVersion > 0) {\n      if (chromeVersion >= 79) {\n        webOSVersion = 6;\n        version = '6.0';\n        majorVersion = 6;\n      } else if (chromeVersion >= 68) {\n        webOSVersion = 5;\n        version = '5.0';\n        majorVersion = 5;\n      } else if (chromeVersion >= 53) {\n        webOSVersion = 4;\n        version = '4.0';\n        majorVersion = 4;\n      } else if (chromeVersion >= 38) {\n        webOSVersion = 3;\n        version = '3.0';\n        majorVersion = 3;\n      } else {\n        webOSVersion = 2;\n        version = '2.0';\n        majorVersion = 2;\n      }\n    } else {\n      version = 'Unknown';\n      webOSVersion = undefined;\n    }\n\n    isLegacyTV = webOSVersion !== undefined && webOSVersion < 3;\n  } else if (/Tizen/i.test(ua)) {\n    name = 'Samsung Tizen';\n    isSmartTV = true;\n    const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n    version = match && match[1] ? match[1] : 'Unknown';\n    if (version !== 'Unknown') {\n      const parts = version.split('.');\n      majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n      tizenVersion = majorVersion;\n    }\n\n    isLegacyTV = tizenVersion !== undefined && tizenVersion < 3;\n  } else if (/SMART-TV|SmartTV/i.test(ua)) {\n    name = 'Smart TV';\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else if (/NetCast/i.test(ua)) {\n    name = 'LG NetCast';\n    isSmartTV = true;\n    isLegacyTV = true;\n  } else if (/BRAVIA/i.test(ua)) {\n    name = 'Sony BRAVIA';\n    isSmartTV = true;\n    isLegacyTV = chromeVersion > 0 && chromeVersion < 53;\n  } else {\n    if (chromeVersion > 0) {\n      name = 'Chrome';\n      version = chromeVersion.toString();\n      majorVersion = chromeVersion;\n\n      if (chromeVersion < 50) {\n        supportsModernJS = false;\n      }\n    }\n\n    if (webkitVersion > 0 && webkitVersion < 600) {\n      supportsModernJS = false;\n    }\n  }\n\n  if (typeof Promise === 'undefined' ||\n      typeof Map === 'undefined' ||\n      typeof Set === 'undefined') {\n    supportsModernJS = false;\n  }\n\n  if (typeof URLSearchParams === 'undefined') {\n    supportsModernJS = false;\n  }\n\n  return {\n    name,\n    version,\n    majorVersion,\n    isSmartTV,\n    isLegacyTV,\n    platform,\n    supportsModernJS,\n    webOSVersion,\n    tizenVersion,\n    chromeVersion: chromeVersionNum,\n  };\n}\n\nexport function getBrowserConfigOverrides(): {\n  allowNativeHls?: boolean;\n} {\n  const browser = detectBrowser();\n  const overrides: { allowNativeHls?: boolean } = {};\n\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n  }\n\n  return overrides;\n}\n\nexport function supportsModernJS(): boolean {\n  try {\n    return (\n      typeof Promise !== 'undefined' &&\n      typeof Map !== 'undefined' &&\n      typeof Set !== 'undefined' &&\n      typeof Array.from !== 'undefined' &&\n      typeof Object.assign !== 'undefined' &&\n      typeof Array.prototype.forEach !== 'undefined' &&\n      typeof String.prototype.includes !== 'undefined'\n    );\n  } catch (e) {\n    return false;\n  }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n  if (!debug) return;\n\n  const browser = detectBrowser();\n\n  console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...(browser.webOSVersion !== undefined ? { webOSVersion: browser.webOSVersion } : {}),\n    ...(browser.tizenVersion !== undefined ? { tizenVersion: browser.tizenVersion } : {}),\n    ...(browser.chromeVersion !== undefined ? { chromeVersion: browser.chromeVersion } : {}),\n    userAgent: navigator.userAgent,\n  });\n}\n\nexport function supportsFeature(feature: string): boolean {\n  switch (feature) {\n    case 'urlsearchparams':\n      return typeof URLSearchParams !== 'undefined';\n    case 'textencoder':\n      return typeof TextEncoder !== 'undefined';\n    case 'promises':\n      return typeof Promise !== 'undefined';\n    case 'fetch':\n      return typeof fetch !== 'undefined';\n    case 'crypto':\n      return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n    default:\n      return false;\n  }\n}\n","import type { Scte35Marker, Id3TagInfo } from \"../types\";\n\nexport function parseCueOutDuration(value: string): number | undefined {\n  const num = parseFloat(value.trim());\n  if (!Number.isNaN(num)) return num;\n  const match =\n    value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) ||\n    value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (match && match[1] != null) {\n    const dStr = match[1];\n    const d = parseFloat(dStr);\n    return Number.isNaN(d) ? undefined : d;\n  }\n  return undefined;\n}\n\nexport function parseCueOutCont(\n  value: string\n): { elapsed?: number; duration?: number } | undefined {\n  const res: { elapsed?: number; duration?: number } = {};\n\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return undefined;\n}\n\nexport function parseAttributeList(value: string): Record<string, string> {\n  const attrs: Record<string, string> = {};\n  const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n  let match: RegExpExecArray | null;\n  while ((match = regex.exec(value)) !== null) {\n    const key: string = (match[1] ?? \"\") as string;\n    let rawVal: string = (match[3] ?? match[4] ?? \"\") as string;\n    if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n      rawVal = rawVal.slice(1, -1);\n    }\n    if (key) {\n      attrs[key] = rawVal;\n    }\n  }\n  return attrs;\n}\n\nexport function toNumber(val: unknown): number | undefined {\n  if (val == null) return undefined;\n  const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n  return Number.isNaN(n) ? undefined : n;\n}\n\nexport function isManifestBasedMarker(marker: Scte35Marker): boolean {\n  const raw = marker.raw as any;\n  if (!raw) return false;\n\n  if (raw.tag) {\n    const tag = String(raw.tag);\n    return (\n      tag.includes(\"EXT-X-CUE-OUT\") ||\n      tag.includes(\"EXT-X-CUE-IN\") ||\n      tag.includes(\"EXT-X-DATERANGE\")\n    );\n  }\n\n  if (raw.id3) return false;\n\n  if (raw.splice_command_type) return false;\n\n  return false;\n}\n\nexport function decodeId3ValueToText(value: string | Uint8Array): string | undefined {\n  try {\n    if (typeof value === \"string\") return value;\n    const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n    const text = decoder.decode(value);\n    if (text && /[\\x20-\\x7E]/.test(text)) return text;\n    let out = \"\";\n    for (let i = 0; i < value.length; i++)\n      out += String.fromCharCode(value[i]!);\n    return out;\n  } catch {\n    return undefined;\n  }\n}\n\nexport function getFragmentStartSeconds(frag: any): number | undefined {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return undefined;\n}\n\nexport function parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n  const text = decodeId3ValueToText(tag.value);\n  if (!text) return undefined;\n\n  const cueOutMatch =\n    text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) ||\n    text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n  if (cueOutMatch) {\n    const arg = (cueOutMatch[1] ?? \"\").trim();\n    const dur = parseCueOutDuration(arg);\n    const marker: Scte35Marker = {\n      type: \"start\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      ...(dur !== undefined ? { durationSeconds: dur } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n  if (cueOutContMatch) {\n    const arg = (cueOutContMatch[1] ?? \"\").trim();\n    const cont = parseCueOutCont(arg);\n    const marker: Scte35Marker = {\n      type: \"progress\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      ...(cont?.duration !== undefined\n        ? { durationSeconds: cont.duration }\n        : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n  if (cueInMatch) {\n    const marker: Scte35Marker = {\n      type: \"end\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n  if (daterangeMatch) {\n    const attrs = parseAttributeList(daterangeMatch[1] ?? \"\");\n    const hasScteOut =\n      \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n    const hasScteIn =\n      \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n    const klass = String(attrs[\"CLASS\"] ?? \"\");\n    const duration = toNumber(attrs[\"DURATION\"]);\n    if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n      const marker: Scte35Marker = {\n        type: \"start\",\n        ...(tag.ptsSeconds !== undefined\n          ? { ptsSeconds: tag.ptsSeconds }\n          : {}),\n        ...(duration !== undefined ? { durationSeconds: duration } : {}),\n        raw: { id3: text, attrs },\n      } as Scte35Marker;\n      return marker;\n    }\n    if (hasScteIn) {\n      const marker: Scte35Marker = {\n        type: \"end\",\n        ...(tag.ptsSeconds !== undefined\n          ? { ptsSeconds: tag.ptsSeconds }\n          : {}),\n        raw: { id3: text, attrs },\n      } as Scte35Marker;\n      return marker;\n    }\n  }\n\n  if (/SCTE35-OUT/i.test(text)) {\n    const marker: Scte35Marker = {\n      type: \"start\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n  if (/SCTE35-IN/i.test(text)) {\n    const marker: Scte35Marker = {\n      type: \"end\",\n      ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n      raw: { id3: text },\n    } as Scte35Marker;\n    return marker;\n  }\n\n  if (tag.value instanceof Uint8Array) {\n    const bin = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n\n  return undefined;\n}\n\nexport function normalizeFragmentPayload(payload: unknown): Uint8Array | undefined {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload as ArrayBufferView;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return undefined;\n}\n\n// --- Transport Stream SCTE-35 parsing ---\n\nexport function detectTsPacketFormat(\n  data: Uint8Array\n): { offset: number; packetSize: number; tsPayloadOffset: number } | undefined {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (\n        let packetStart = offset;\n        packetStart + tsPayloadOffset < data.length &&\n        matchedPackets < 5;\n        packetStart += packetSize\n      ) {\n        if (data[packetStart + tsPayloadOffset] !== 0x47) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return undefined;\n}\n\nfunction getPsiSectionStart(\n  payload: Uint8Array,\n  payloadUnitStart: boolean\n): number | undefined {\n  if (!payloadUnitStart) {\n    return undefined;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return undefined;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : undefined;\n}\n\nfunction getPsiSectionLength(data: Uint8Array, offset: number): number {\n  return (((data[offset + 1] ?? 0) & 0x0f) << 8) | (data[offset + 2] ?? 0);\n}\n\nfunction parsePatSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  pmtPids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x00) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber =\n      ((payload[offset] ?? 0) << 8) | (payload[offset + 1] ?? 0);\n    const pid =\n      (((payload[offset + 2] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\n\nfunction descriptorsIdentifyScte35(\n  data: Uint8Array,\n  start: number,\n  end: number\n): boolean {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n\n    const registration =\n      length >= 4\n        ? String.fromCharCode(\n            data[descriptorStart] ?? 0,\n            data[descriptorStart + 1] ?? 0,\n            data[descriptorStart + 2] ?? 0,\n            data[descriptorStart + 3] ?? 0\n          )\n        : \"\";\n    if (tag === 0x8a || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n\n    offset = descriptorEnd;\n  }\n  return false;\n}\n\nfunction parsePmtSection(\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  tsScte35Pids: Set<number>\n): void {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0x02) {\n    return;\n  }\n\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength =\n    (((payload[sectionStart + 10] ?? 0) & 0x0f) << 8) |\n    (payload[sectionStart + 11] ?? 0);\n\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid =\n      (((payload[offset + 1] ?? 0) & 0x1f) << 8) |\n      (payload[offset + 2] ?? 0);\n    const esInfoLength =\n      (((payload[offset + 3] ?? 0) & 0x0f) << 8) |\n      (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n\n    if (\n      streamType === 0x86 ||\n      (streamType === 0x06 &&\n        descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd))\n    ) {\n      tsScte35Pids.add(elementaryPid);\n    }\n\n    offset = descriptorStart + esInfoLength;\n  }\n}\n\nfunction hasProcessedTsScte35Section(\n  section: Uint8Array,\n  processedSections: Set<string>\n): boolean {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = (checksum * 31 + (section[i] ?? 0)) >>> 0;\n  }\n\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\n\nfunction addScte35SectionMarker(\n  section: Uint8Array,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (section[0] !== 0xfc || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n\n  marker.raw = {\n    ...(typeof marker.raw === \"object\" && marker.raw ? marker.raw : {}),\n    source: \"ts-packet\",\n  };\n  markers.push(marker);\n}\n\nfunction appendScte35Bytes(\n  pid: number,\n  bytes: Uint8Array,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\n\nfunction collectScte35SectionsFromPayload(\n  pid: number,\n  payload: Uint8Array,\n  payloadUnitStart: boolean,\n  assemblers: Map<number, { bytes: number[]; expectedLength: number }>,\n  markers: Scte35Marker[],\n  processedSections: Set<string>\n): void {\n  if (payload.length === 0) {\n    return;\n  }\n\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 0xff) {\n      return;\n    }\n\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength,\n      });\n      return;\n    }\n  }\n}\n\nexport function parseScte35FromTsPackets(\n  data: Uint8Array,\n  tsScte35Pids: Set<number>,\n  pmtPids: Set<number>,\n  processedSections: Set<string>\n): Scte35Marker[] {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n\n  const markers: Scte35Marker[] = [];\n  const sectionAssemblers = new Map<\n    number,\n    { bytes: number[]; expectedLength: number }\n  >();\n\n  for (\n    let packetStart = packetInfo.offset;\n    packetStart + packetInfo.packetSize <= data.length;\n    packetStart += packetInfo.packetSize\n  ) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 0x47) {\n      continue;\n    }\n\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (\n      secondByte == null ||\n      thirdByte == null ||\n      fourthByte == null ||\n      (secondByte & 0x80) !== 0\n    ) {\n      continue;\n    }\n\n    const payloadUnitStart = (secondByte & 0x40) !== 0;\n    const pid = ((secondByte & 0x1f) << 8) | thirdByte;\n    const adaptationFieldControl = (fourthByte >> 4) & 0x03;\n    const hasPayload =\n      adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n\n  return markers;\n}\n\n// --- Binary SCTE-35 parsing ---\n\nclass BitReader {\n  private bytePos = 0;\n  private bitPos = 0;\n  constructor(private readonly buf: Uint8Array) {}\n  readBits(numBits: number): number {\n    let result = 0;\n    while (numBits > 0) {\n      if (this.bytePos >= this.buf.length) return result;\n      const remainingInByte = 8 - this.bitPos;\n      const toRead = Math.min(numBits, remainingInByte);\n      const currentByte = this.buf[this.bytePos]!;\n      const shift = remainingInByte - toRead;\n      const mask = ((1 << toRead) - 1) & 0xff;\n      const bits = (currentByte >> shift) & mask;\n      result = (result << toRead) | bits;\n      this.bitPos += toRead;\n      if (this.bitPos >= 8) {\n        this.bitPos = 0;\n        this.bytePos += 1;\n      }\n      numBits -= toRead;\n    }\n    return result >>> 0;\n  }\n  skipBits(n: number): void {\n    this.readBits(n);\n  }\n  get bytePosition(): number {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n}\n\nfunction readSpliceTime(\n  r: BitReader,\n  ptsAdjustmentTicks: number\n): number | undefined {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return undefined;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks =\n    (high * 0x100000000 + low + ptsAdjustmentTicks) % 0x200000000;\n  return ptsTicks / 90000;\n}\n\nfunction markerTypeFromSegmentationTypeId(\n  segmentationTypeId: number\n): Scte35Marker[\"type\"] | undefined {\n  switch (segmentationTypeId) {\n    case 0x10:\n    case 0x22:\n    case 0x30:\n    case 0x32:\n    case 0x34:\n    case 0x36:\n      return \"start\";\n    case 0x11:\n    case 0x23:\n    case 0x31:\n    case 0x33:\n    case 0x35:\n    case 0x37:\n      return \"end\";\n    default:\n      return undefined;\n  }\n}\n\nfunction parseScte35SegmentationDescriptor(\n  descriptor: Uint8Array\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (descriptor.length < 11) {\n    return undefined;\n  }\n\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return undefined;\n  }\n\n  const segmentationEventId =\n    ((descriptor[4] ?? 0) * 0x1000000) +\n    ((descriptor[5] ?? 0) << 16) +\n    ((descriptor[6] ?? 0) << 8) +\n    (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 0x80) !== 0;\n  if (cancelIndicator) {\n    return undefined;\n  }\n\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 0x80) !== 0;\n  const segmentationDurationFlag = (flags & 0x40) !== 0;\n  let offset = 10;\n\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return undefined;\n    }\n  }\n\n  let durationSeconds: number | undefined = undefined;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return undefined;\n    }\n    const durationTicks =\n      ((descriptor[offset] ?? 0) * 0x100000000) +\n      ((descriptor[offset + 1] ?? 0) * 0x1000000) +\n      ((descriptor[offset + 2] ?? 0) << 16) +\n      ((descriptor[offset + 3] ?? 0) << 8) +\n      (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 90000;\n    offset += 5;\n  }\n\n  if (offset + 2 > descriptor.length) {\n    return undefined;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return undefined;\n  }\n\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return undefined;\n  }\n\n  return {\n    type: markerType,\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    segmentationEventId,\n  };\n}\n\nfunction parseScte35SegmentationDescriptors(\n  data: Uint8Array,\n  offset: number\n):\n  | {\n      type: Scte35Marker[\"type\"];\n      durationSeconds?: number;\n      segmentationEventId?: number;\n    }\n  | undefined {\n  if (offset + 2 > data.length) {\n    return undefined;\n  }\n\n  const descriptorLoopLength =\n    ((data[offset] ?? 0) << 8) | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return undefined;\n    }\n\n    if (descriptorTag === 0x02) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n\n    descriptorOffset = descriptorDataEnd;\n  }\n\n  return undefined;\n}\n\nexport function parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\n  const r = new BitReader(data);\n  const tableId = r.readBits(8);\n  if (tableId !== 0xfc) return undefined;\n  r.readBits(1);\n  r.readBits(1);\n  r.readBits(2);\n  const sectionLength = r.readBits(12);\n  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return undefined;\n  }\n  r.readBits(8);\n  r.readBits(1);\n  r.readBits(6);\n  const ptsAdjHigh = r.readBits(1);\n  const ptsAdjLow = r.readBits(32);\n  const ptsAdjustmentTicks = ptsAdjHigh * 0x100000000 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n\n  let markerType: Scte35Marker[\"type\"] | undefined;\n  let durationSeconds: number | undefined = undefined;\n  let ptsSeconds: number | undefined = undefined;\n  let spliceEventId: number | undefined = undefined;\n  const commandBodyStart = r.bytePosition;\n\n  if (spliceCommandType === 5) {\n    spliceEventId = r.readBits(32);\n    const cancel = r.readBits(1) === 1;\n    r.readBits(7);\n    if (cancel) return undefined;\n    const outOfNetwork = r.readBits(1) === 1;\n    const programSpliceFlag = r.readBits(1) === 1;\n    const durationFlag = r.readBits(1) === 1;\n    const spliceImmediateFlag = r.readBits(1) === 1;\n    r.readBits(4);\n    markerType = outOfNetwork ? \"start\" : \"end\";\n\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n    } else if (!programSpliceFlag) {\n      const componentCount = r.readBits(8);\n      for (let i = 0; i < componentCount; i++) {\n        r.readBits(8);\n        if (!spliceImmediateFlag) {\n          const componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === undefined) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n\n    if (durationFlag) {\n      r.readBits(6);\n      r.readBits(1);\n      const high = r.readBits(1);\n      const low = r.readBits(32);\n      const durationTicks = high * 0x100000000 + low;\n      durationSeconds = durationTicks / 90000;\n    }\n    r.readBits(16);\n    r.readBits(8);\n    r.readBits(8);\n  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return undefined;\n  }\n\n  const expectedDescriptorOffset =\n    spliceCommandLength === 0x0fff\n      ? r.bytePosition\n      : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === undefined) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n\n  if (!markerType) {\n    return undefined;\n  }\n\n  const marker: Scte35Marker = {\n    type: markerType,\n    ...(ptsSeconds !== undefined ? { ptsSeconds } : {}),\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...(spliceEventId !== undefined ? { splice_event_id: spliceEventId } : {}),\n      ...(descriptorMarker?.segmentationEventId !== undefined\n        ? { segmentation_event_id: descriptorMarker.segmentationEventId }\n        : {}),\n    },\n  } as Scte35Marker;\n  return marker;\n}\n","import type { Scte35Marker } from \"../types\";\nimport type {\n  NormalizedScte35Cue,\n  Scte35CueContext,\n  Scte35CueSource,\n  Scte35CueReadiness,\n} from \"./playerTypes\";\nimport { getFragmentStartSeconds } from \"./Scte35Parser\";\n\nexport interface Scte35CueManagerCallbacks {\n  onEarlyStartCue(marker: Scte35Marker, fragmentSn: number | undefined, cueKey: string): void;\n  onPlaybackCue(marker: Scte35Marker, cueKey?: string): void;\n  isInAdBreak(): boolean;\n}\n\nexport class Scte35CueManager {\n  private readonly pendingScte35Cues: Map<string, NormalizedScte35Cue> = new Map();\n  private readonly recentScte35CueKeys: Map<string, number> = new Map();\n  private readonly recentScte35CueLimit: number = 200;\n  private pendingScte35CueKeyValue: string | undefined;\n  private activeScte35BreakKeyValue: string | undefined;\n  private scheduledScte35BreakKeyValue: string | undefined;\n\n  readonly tsScte35Pids: Set<number> = new Set();\n  readonly pmtPids: Set<number> = new Set();\n  readonly processedTsScte35Sections: Set<string> = new Set();\n\n  private debug: boolean;\n  private callbacks: Scte35CueManagerCallbacks;\n\n  constructor(debug: boolean, callbacks: Scte35CueManagerCallbacks) {\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n\n  get pendingScte35CueKey(): string | undefined {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value: string | undefined) {\n    this.pendingScte35CueKeyValue = value;\n  }\n\n  get activeScte35BreakKey(): string | undefined {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value: string | undefined) {\n    this.activeScte35BreakKeyValue = value;\n  }\n\n  get scheduledScte35BreakKey(): string | undefined {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value: string | undefined) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n\n  createScte35CueContext(\n    source: Scte35CueSource,\n    readiness: Scte35CueReadiness,\n    frag?: any\n  ): Scte35CueContext {\n    const context: Scte35CueContext = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== undefined) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source,\n        });\n      }\n      return;\n    }\n\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n\n  activatePendingScte35CuesForFragment(frag: any): void {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : undefined;\n    if (fragmentSn === undefined) {\n      return;\n    }\n\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context: Scte35CueContext = {\n        source: cue.source,\n        readiness: \"playback\",\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec =\n        cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n\n  private createScte35Cue(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): NormalizedScte35Cue {\n    const cue: NormalizedScte35Cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context),\n    };\n    if (context.fragmentSn !== undefined) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== undefined) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n\n  private getScte35CueKey(\n    marker: Scte35Marker,\n    context: Scte35CueContext\n  ): string {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n\n    const scteValue =\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) ||\n      this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n\n    if (context.fragmentSn !== undefined) {\n      return `fragment:${context.fragmentSn}`;\n    }\n\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1000)}`;\n  }\n\n  private getPendingScte35CueKey(cue: NormalizedScte35Cue): string {\n    return `${cue.marker.type}:${cue.key}:${\n      cue.fragmentSn !== undefined ? cue.fragmentSn : \"unknown\"\n    }`;\n  }\n\n  private getScte35MarkerRaw(marker: Scte35Marker): any {\n    return typeof marker.raw === \"object\" && marker.raw !== null\n      ? (marker.raw as any)\n      : {};\n  }\n\n  private toIdentityString(value: unknown): string | undefined {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return undefined;\n  }\n\n  isStrongScte35CueKey(key: string | undefined): boolean {\n    return !!(\n      key &&\n      (key.startsWith(\"splice:\") ||\n        key.startsWith(\"segmentation:\") ||\n        key.startsWith(\"daterange:\") ||\n        key.startsWith(\"daterange-scte:\"))\n    );\n  }\n\n  private hasRecentlyHandledScte35Cue(cue: NormalizedScte35Cue): boolean {\n    if (\n      this.activeScte35BreakKeyValue === cue.key ||\n      this.scheduledScte35BreakKeyValue === cue.key\n    ) {\n      return true;\n    }\n\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n\n  private markScte35CueHandled(cue: NormalizedScte35Cue): void {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n\n  private trimRecentScte35CueMaps(): void {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n\n  private shouldAcceptScte35EndCue(cue: NormalizedScte35Cue): boolean {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n\n    if (\n      this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) &&\n      this.isStrongScte35CueKey(cue.key) &&\n      this.activeScte35BreakKeyValue !== cue.key\n    ) {\n      return false;\n    }\n\n    return true;\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  AdBreak,\n  StormcloudApiResponse,\n  AdController,\n} from \"../types\";\nimport type { PalNonceManager } from \"../sdk/pal\";\nimport { applyVastMacros, generateCorrelator, normalizeVastTagUrl } from \"../utils/vastMacros\";\nimport type { VastConsentSignals } from \"../utils/vastMacros\";\nimport { resolveVastEnvironmentSignals } from \"../utils/vastEnvironmentSignals\";\nimport {\n  buildAnalyticsContext,\n  sendHeartbeat,\n  sendInitialTracking,\n} from \"../utils/tracking\";\n\nexport class AdConfigManager {\n  vmapBreaks: AdBreak[] = [];\n  consumedVmapBreakIds: Set<string> = new Set();\n  apiVastTagUrl: string | undefined;\n  apiNumberAds: number | undefined;\n  readonly streamCorrelator: string = generateCorrelator();\n  readonly viewCorrelator: string = generateCorrelator();\n  consentSignals: VastConsentSignals = {};\n  podCounter: number = 0;\n  podAssignedByPrefetch: boolean = false;\n  adRequestPositionInBreak: number = 0;\n\n  private lastHeartbeatTime: number = 0;\n  private heartbeatInterval: number | undefined;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n\n  constructor(config: StormcloudVideoPlayerConfig, video: HTMLVideoElement) {\n    this.config = config;\n    this.video = video;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  isVmapEnabled(): boolean {\n    return !!(this.config.isVmap && this.config.vmapUrl?.trim());\n  }\n\n  async fetchAdConfiguration(): Promise<void> {\n    if (this.isVmapEnabled()) {\n      await this.fetchAndParseVmap(this.config.vmapUrl!);\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] VMAP mode enabled\");\n      }\n      return;\n    }\n\n    const vastMode = this.config.vastMode || \"default\";\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n    }\n\n    if (vastMode === \"adstorm\") {\n      if (!this.config.licenseKey) {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] AdStorm mode requires a license key\"\n          );\n        }\n        return;\n      }\n\n      const vastEndpoint = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${this.config.licenseKey}`;\n      this.apiVastTagUrl = vastEndpoint;\n\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):\",\n          vastEndpoint\n        );\n      }\n      return;\n    }\n\n    if (this.config.vastTagUrl) {\n      this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Using custom VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n      return;\n    }\n\n    const apiUrl = \"https://adstorm.co/api-adstorm-dev/adstorm/ads/web\";\n\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Fetching ad configuration from:\",\n        apiUrl\n      );\n    }\n\n    const headers: Record<string, string> = {};\n    if (this.config.licenseKey) {\n      headers[\"Authorization\"] = `Bearer ${this.config.licenseKey}`;\n    }\n\n    const response = await fetch(apiUrl, { headers });\n    if (!response.ok) {\n      if (this.debug) {\n        console.warn(\n          `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n        );\n      }\n      return;\n    }\n\n    const data: StormcloudApiResponse = await response.json();\n\n    const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n    if (imaPayload) {\n      let decodedPayload = imaPayload;\n      try {\n        decodedPayload = decodeURIComponent(imaPayload);\n      } catch {\n        console.warn(\"[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:\", imaPayload);\n      }\n      console.log(\"[StormcloudVideoPlayer] Raw VAST tag URL (from API):\", decodedPayload);\n      this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Normalized VAST tag URL:\",\n          this.apiVastTagUrl\n        );\n      }\n    } else {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] No VAST tag URL found in /ads/web response\"\n        );\n      }\n    }\n\n    const numberAds = data.response?.options?.vast?.cue_tones?.number_ads;\n    if (numberAds != null && numberAds > 0) {\n      this.apiNumberAds = numberAds;\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n          this.apiNumberAds\n        );\n      }\n    }\n  }\n\n  private async fetchAndParseVmap(vmapUrl: string): Promise<void> {\n    if (!vmapUrl.trim()) {\n      return;\n    }\n\n    try {\n      const response = await fetch(vmapUrl);\n      if (!response.ok) {\n        throw new Error(`Failed to fetch VMAP (${response.status})`);\n      }\n\n      const vmapXml = await response.text();\n      this.vmapBreaks = this.parseVmapToBreaks(vmapXml);\n      this.consumedVmapBreakIds.clear();\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Loaded ${this.vmapBreaks.length} VMAP ad break(s) from:`,\n          vmapUrl\n        );\n      }\n    } catch (error) {\n      this.vmapBreaks = [];\n      this.consumedVmapBreakIds.clear();\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to load VMAP:\", error);\n      }\n    }\n  }\n\n  private parseVmapToBreaks(vmapXml: string): AdBreak[] {\n    if (typeof DOMParser === \"undefined\") {\n      return [];\n    }\n\n    const doc = new DOMParser().parseFromString(vmapXml, \"application/xml\");\n    if (doc.querySelector(\"parsererror\")) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Invalid VMAP XML received\");\n      }\n      return [];\n    }\n\n    const VMAP_NS = \"http://www.iab.net/videosuite/vmap\";\n    let adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, \"AdBreak\"));\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(\n        doc.querySelectorAll(\"AdBreak, vmap\\\\:AdBreak\")\n      );\n    }\n    if (adBreakNodes.length === 0) {\n      adBreakNodes = Array.from(doc.getElementsByTagName(\"*\")).filter(\n        (el) => el.localName === \"AdBreak\"\n      );\n    }\n    const parsed: AdBreak[] = [];\n\n    adBreakNodes.forEach((node, index) => {\n      const timeOffsetRaw = (node.getAttribute(\"timeOffset\") || \"\").trim();\n      const startTimeMs = this.parseVmapTimeOffsetToMs(timeOffsetRaw);\n      if (startTimeMs == null) {\n        return;\n      }\n\n      let adTagNode = node.getElementsByTagNameNS(VMAP_NS, \"AdTagURI\")[0];\n      if (!adTagNode) {\n        adTagNode =\n          (node.querySelector(\"AdTagURI, vmap\\\\:AdTagURI\") as Element | null) ??\n          undefined;\n      }\n      const adTagUrl = (adTagNode?.textContent || \"\").trim();\n      if (!adTagUrl) {\n        return;\n      }\n\n      const breakId =\n        node.getAttribute(\"breakId\") ||\n        `vmap-break-${index}-${timeOffsetRaw || \"unknown\"}`;\n      parsed.push({\n        id: breakId,\n        startTimeMs,\n        vastTagUrl: adTagUrl,\n      });\n    });\n\n    parsed.sort((a, b) => {\n      const aStart = a.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : a.startTimeMs;\n      const bStart = b.startTimeMs < 0 ? Number.MAX_SAFE_INTEGER : b.startTimeMs;\n      return aStart - bStart;\n    });\n\n    return parsed;\n  }\n\n  private parseVmapTimeOffsetToMs(timeOffset: string): number | undefined {\n    if (!timeOffset) {\n      return undefined;\n    }\n\n    const normalized = timeOffset.trim().toLowerCase();\n    if (normalized === \"start\") {\n      return 0;\n    }\n\n    if (normalized === \"end\") {\n      return -1;\n    }\n\n    const hms = timeOffset.match(\n      /^(\\d{1,2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?$/\n    );\n    if (hms) {\n      const [, hh, mm, ss, ms = \"0\"] = hms;\n      const hours = Number(hh);\n      const minutes = Number(mm);\n      const seconds = Number(ss);\n      const millis = Number(ms.padEnd(3, \"0\").slice(0, 3));\n      return ((hours * 3600 + minutes * 60 + seconds) * 1000) + millis;\n    }\n\n    const percent = timeOffset.match(/^(\\d+(?:\\.\\d+)?)%$/);\n    if (percent) {\n      const ratio = Number(percent[1]) / 100;\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000 * ratio);\n      }\n      return undefined;\n    }\n\n    return undefined;\n  }\n\n  getAdBreakKey(adBreak: AdBreak): string {\n    if (adBreak.id) {\n      return adBreak.id;\n    }\n    return `${adBreak.startTimeMs}-${adBreak.vastTagUrl || \"\"}`;\n  }\n\n  resolveBreakStartMs(adBreak: AdBreak): number | undefined {\n    if (adBreak.startTimeMs >= 0) {\n      return adBreak.startTimeMs;\n    }\n\n    if (adBreak.startTimeMs === -1) {\n      const durationSec = this.video.duration;\n      if (Number.isFinite(durationSec) && durationSec > 0) {\n        return Math.floor(durationSec * 1000);\n      }\n    }\n\n    return undefined;\n  }\n\n  findCurrentOrNextBreak(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    let candidate: AdBreak | undefined;\n    const tol = this.config.driftToleranceMs ?? 1000;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n      if (\n        breakStartMs <= nowMs + tol &&\n        (candidate == null ||\n          breakStartMs > (this.resolveBreakStartMs(candidate) ?? 0))\n      ) {\n        candidate = b;\n      }\n    }\n    return candidate;\n  }\n\n  findBreakForTime(nowMs: number): AdBreak | undefined {\n    const schedule: AdBreak[] = this.vmapBreaks;\n    for (const b of schedule) {\n      if (this.consumedVmapBreakIds.has(this.getAdBreakKey(b))) {\n        continue;\n      }\n      const breakStartMs = this.resolveBreakStartMs(b);\n      if (breakStartMs == null) {\n        continue;\n      }\n\n      if (b.durationMs) {\n        const end = breakStartMs + b.durationMs;\n        if (nowMs >= breakStartMs && nowMs < end) {\n          return b;\n        }\n        continue;\n      }\n\n      if (nowMs >= breakStartMs) {\n        return b;\n      }\n    }\n    return undefined;\n  }\n\n  selectVastTagsForBreak(b?: AdBreak): string[] | undefined {\n    if (!b || !b.vastTagUrl) return undefined;\n    if (b.vastTagUrl.includes(\",\")) {\n      return b.vastTagUrl\n        .split(\",\")\n        .map((s) => s.trim())\n        .filter((s) => s.length > 0);\n    }\n    return [b.vastTagUrl];\n  }\n\n  beginNewAdPod(): void {\n    this.podCounter++;\n    this.adRequestPositionInBreak = 0;\n  }\n\n  generateVastUrlsWithCorrelators(\n    baseUrl: string,\n    count: number,\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string[] {\n    const urls: string[] = [];\n\n    for (let i = 0; i < count; i++) {\n      this.adRequestPositionInBreak++;\n\n      const adWillPlayMuted = inAdBreak\n        ? adPlayer.getOriginalMutedState()\n        : this.video.muted;\n      const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n      const urlWithMacros = applyVastMacros(baseUrl, {\n        correlator: this.viewCorrelator,\n        streamCorrelator: this.streamCorrelator,\n        pod: this.podCounter > 0 ? this.podCounter : undefined,\n        adPosition: this.adRequestPositionInBreak,\n        isCtv: envSignals.isCtv,\n        contentUrl: envSignals.contentUrl,\n        pageUrl:\n          !envSignals.isCtv && typeof window !== \"undefined\"\n            ? window.location.href\n            : undefined,\n        adWillPlayMuted,\n        adWillAutoPlay: !!this.config.autoplay,\n        appId: envSignals.appId,\n        appName: envSignals.appName,\n        sessionId: envSignals.sessionId,\n        deviceId: envSignals.deviceId,\n        deviceIdType: envSignals.deviceIdType,\n        limitAdTracking: envSignals.limitAdTracking,\n        deviceTypeHint: envSignals.deviceTypeHint,\n        adTest: this.config.adTest,\n        consent: this.consentSignals,\n      });\n\n      const finalUrl = palNonce.injectNonce(urlWithMacros);\n      console.log(\n        `[StormcloudVideoPlayer] Resolved ad request URL (pod=${this.podCounter}, pos=${this.adRequestPositionInBreak}):`,\n        finalUrl\n      );\n      urls.push(finalUrl);\n    }\n\n    return urls;\n  }\n\n  private readonly defaultPodMaxAds: number = 6;\n\n  resolvePodParams(breakDurationMs?: number): {\n    maxAds: number;\n    minDurationMs: number;\n    maxDurationMs: number | undefined;\n  } {\n    const maxDurationMs =\n      breakDurationMs != null && breakDurationMs > 0\n        ? breakDurationMs\n        : this.config.podMaxDurationMs;\n\n    const maxAds =\n      this.config.podMaxAds && this.config.podMaxAds > 0\n        ? this.config.podMaxAds\n        : this.apiNumberAds && this.apiNumberAds > 0\n          ? this.apiNumberAds\n          : this.defaultPodMaxAds;\n\n    const minDurationMs =\n      this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n\n  generatePodVastUrl(\n    baseUrl: string,\n    podParams: { maxAds: number; minDurationMs: number; maxDurationMs: number | undefined },\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string {\n    const adWillPlayMuted = inAdBreak\n      ? adPlayer.getOriginalMutedState()\n      : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : undefined,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl:\n        !envSignals.isCtv && typeof window !== \"undefined\"\n          ? window.location.href\n          : undefined,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals,\n    });\n\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n\n  // --- Tracking ---\n\n  initializeTracking(): void {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config))\n      .then(() => {\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      })\n      .catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n            error\n          );\n        }\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      });\n  }\n\n  private sendHeartbeatIfNeeded(): void {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n\n  destroyTracking(): void {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = undefined;\n    }\n  }\n}\n","import type { AdController, StormcloudVideoPlayerConfig, Scte35Marker } from \"../types\";\n\nexport interface AdTimingCallbacks {\n  onAdStopTimerFired(): void;\n  onAdStartTimerFired(marker: Scte35Marker, cueKey: string | undefined): void;\n  onWatchdogTimeout(): void;\n  onFailsafeTimeout(): void;\n}\n\nexport class AdTimingService {\n  private adStopTimerId: number | undefined;\n  private adStartTimerId: number | undefined;\n  private adFailsafeTimerId: number | undefined;\n  private adRequestWatchdogId: number | undefined;\n  private adRequestWatchdogToken: number | null = null;\n  private adFailsafeToken: number | null = null;\n\n  ptsDriftEmaMs = 0;\n  expectedAdBreakDurationMs: number | undefined;\n  currentAdBreakStartWallClockMs: number | undefined;\n  scteAdBreakEndWallClockMs: number | undefined;\n  adBreakPlayedDurationMs: number = 0;\n  adBreakEpoch: number = 0;\n\n  adRequestTokenCounter = 0;\n  activeAdRequestToken: number | null = null;\n  currentAdIndex: number = 0;\n  totalAdsInBreak: number = 0;\n  totalAdRequestsInBreak: number = 0;\n  readonly maxTotalAdRequestsPerBreak: number = 10;\n  lastAdRequestTime: number = 0;\n  consecutiveFailures: number = 0;\n  readonly maxConsecutiveFailures: number = 5;\n  readonly minAdRequestIntervalMs: number = 3000;\n  readonly backoffBaseMs: number = 1000;\n  readonly maxBackoffMs: number = 15000;\n  private readonly defaultMinRemainingMsToStartAd: number = 4000;\n\n  failedVastUrls: Set<string> = new Set();\n  temporaryFailureUrls: Map<string, number> = new Map();\n  private readonly temporaryFailureCooldownMs: number = 30000;\n\n  private globalConsecutiveNoFills: number = 0;\n  private readonly globalNoFillThreshold: number = 3;\n  private globalNoFillCooldownUntil: number = 0;\n  private readonly globalNoFillBackoffBaseMs: number = 5000;\n  private readonly globalNoFillBackoffMaxMs: number = 60000;\n  private globalLastGamRequestTime: number = 0;\n  private readonly globalMinGamIntervalMs: number = 3000;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n  private callbacks: AdTimingCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    callbacks: AdTimingCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  // --- Ad stop timer ---\n\n  scheduleAdStopCountdown(remainingMs: number): void {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms) as unknown as number;\n  }\n\n  clearAdStopTimer(): void {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = undefined;\n    }\n  }\n\n  private ensureAdStoppedByTimer(): void {\n    this.adStopTimerId = undefined;\n    this.callbacks.onAdStopTimerFired();\n  }\n\n  // --- Ad start timer ---\n\n  scheduleAdStartIn(\n    delayMs: number,\n    marker: Scte35Marker = { type: \"start\" } as Scte35Marker,\n    cueKey?: string\n  ): void {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms) as unknown as number;\n  }\n\n  clearAdStartTimer(): void {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = undefined;\n    }\n  }\n\n  // --- PTS drift ---\n\n  updatePtsDrift(ptsSecondsSample: number): void {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n\n  resolveScteBreakStartWallClockMs(marker: Scte35Marker): number {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n\n    const nowMs = this.video.currentTime * 1000;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1000 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n\n  // --- Duration boundary ---\n\n  setAdBreakDurationBoundary(durationMs: number | undefined): void {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (\n      durationMs != null &&\n      this.currentAdBreakStartWallClockMs != null\n    ) {\n      this.scteAdBreakEndWallClockMs =\n        this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = undefined;\n    }\n  }\n\n  scheduleAdStopAtBreakBoundary(): void {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n\n  // --- Duration budget ---\n\n  getWallClockRemainingAdMs(): number {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n\n  getAdBreakEndWallClockMs(): number | undefined {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (\n      this.expectedAdBreakDurationMs == null ||\n      this.currentAdBreakStartWallClockMs == null\n    ) {\n      return undefined;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n\n  getDurationBudgetRemainingMs(): number {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n\n  getLoadedAdDurationMs(adController: AdController): number {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1000);\n  }\n\n  adFitsRemainingBudget(durationMs: number): boolean {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n\n  logAdDurationDecision(\n    accepted: boolean,\n    durationMs: number,\n    adController: AdController\n  ): void {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms — requesting another ad`\n      );\n    }\n  }\n\n  recordPlayedAdDuration(adController: AdController): void {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms — total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n\n  ensureLoadedAdFitsBudget(adController: AdController): boolean {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n\n  rejectLoadedAdForDuration(adController: AdController): void {\n    try {\n      adController.destroy();\n    } catch {}\n  }\n\n  markAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n\n  notePodAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n\n  getRemainingAdMs(): number {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n\n  getMinRemainingMsToStartAd(): number {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n\n  hasTimeToStartAnotherAd(): boolean {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return (\n      this.getWallClockRemainingAdMs() > minRemaining &&\n      this.getDurationBudgetRemainingMs() > minRemaining\n    );\n  }\n\n  // --- Circuit breaker ---\n\n  isTemporaryAdError(error: Error): boolean {\n    const message = error?.message?.toLowerCase() || \"\";\n\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n\n  isUrlInCooldown(vastTagUrl: string): boolean {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n\n    return true;\n  }\n\n  cleanupTemporaryFailures(): void {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n\n  isGamInCooldown(): boolean {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n\n  recordGamNoFill(): void {\n    this.globalConsecutiveNoFills++;\n\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n\n  resetGamNoFillCounter(): void {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n\n  async enforceGlobalRateLimit(): Promise<void> {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n\n  // --- Watchdog ---\n\n  startAdRequestWatchdog(token: number): void {\n    this.clearAdRequestWatchdog();\n\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n\n      this.adRequestWatchdogId = undefined;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs) as unknown as number;\n\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n\n  clearAdRequestWatchdog(): void {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = undefined;\n    }\n\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken,\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n\n  // --- Failsafe ---\n\n  startAdFailsafeTimer(token: number): void {\n    this.clearAdFailsafeTimer();\n\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adFailsafeToken = token;\n\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n\n      this.adFailsafeTimerId = undefined;\n      this.adFailsafeToken = null;\n\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused,\n      });\n\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs) as unknown as number;\n\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n\n  clearAdFailsafeTimer(): void {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = undefined;\n    }\n\n    this.adFailsafeToken = null;\n  }\n\n  logAdState(event: string, extra: Record<string, unknown> = {}, adPlayer?: AdController, inAdBreak?: boolean, showAds?: boolean): void {\n    if (!this.debug) {\n      return;\n    }\n\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: new Date().toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra,\n    });\n  }\n\n  // --- Reset for ad break end ---\n\n  resetForBreakEnd(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = undefined;\n    this.currentAdBreakStartWallClockMs = undefined;\n    this.scteAdBreakEndWallClockMs = undefined;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n\n  destroy(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n}\n","import type { AdController, Scte35Marker } from \"../types\";\nimport type { AdTimingService } from \"./AdTimingService\";\n\nexport interface AdPreloadPoolDeps {\n  debug: boolean;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  timing: AdTimingService;\n  generateVastUrlsWithCorrelators(baseUrl: string, count: number): string[];\n  isInAdBreak(): boolean;\n  getPendingAdBreak(): { marker: Scte35Marker; vastUrls: string[]; isFetching: boolean } | null;\n}\n\nexport class AdPreloadPool {\n  private pool: Array<{\n    vastUrl: string;\n    adController: AdController;\n    loadedAt: number;\n    isReady: boolean;\n    loadPromise: Promise<void>;\n    durationSeconds?: number;\n  }> = [];\n  private readonly maxPoolSize: number = 2;\n  private poolActive: boolean = false;\n  private loopRunning: boolean = false;\n\n  private deps: AdPreloadPoolDeps;\n\n  constructor(deps: AdPreloadPoolDeps) {\n    this.deps = deps;\n  }\n\n  get active(): boolean {\n    return this.poolActive;\n  }\n\n  set active(value: boolean) {\n    this.poolActive = value;\n  }\n\n  get isLoopRunning(): boolean {\n    return this.loopRunning;\n  }\n\n  startPreloadPool(\n    baseVastUrl: string,\n    initialUrls: string[],\n    startLoopImmediately: boolean = true\n  ): void {\n    if (this.poolActive) {\n      if (this.deps.debug) {\n        console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n      }\n      return;\n    }\n\n    this.poolActive = true;\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Starting preload pool EARLY (target size: ${this.maxPoolSize})`);\n      console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n    }\n\n    for (const url of initialUrls) {\n      if (this.pool.length < this.maxPoolSize) {\n        this.preloadAdIntoPool(url);\n      }\n    }\n\n    if (startLoopImmediately) {\n      this.preloadPoolLoop(baseVastUrl);\n    } else if (this.deps.debug) {\n      console.log(\n        \"[PRELOAD-POOL] Pre-break mode: preloaded once, waiting for SCTE start to continue fetching\"\n      );\n    }\n  }\n\n  private async preloadAdIntoPool(vastUrl: string): Promise<void> {\n    const timing = this.deps.timing;\n\n    if (timing.isGamInCooldown()) {\n      if (this.deps.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping preload\");\n      }\n      return;\n    }\n\n    if (\n      this.pool.some(entry => entry.vastUrl === vastUrl) ||\n      timing.failedVastUrls.has(vastUrl) ||\n      timing.isUrlInCooldown(vastUrl)\n    ) {\n      return;\n    }\n\n    if (this.pool.length >= this.maxPoolSize) {\n      return;\n    }\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Preloading ad into pool: ${vastUrl}`);\n    }\n\n    const epoch = timing.adBreakEpoch;\n    const loadPromise = (async () => {\n      let hasAdError = false;\n      let adErrorPayload: any = null;\n      let errorListenerCleanup: (() => void) | null = null;\n\n      try {\n        const continueLiveStreamDuringAds = this.deps.shouldContinueLiveStreamDuringAds();\n        const preloadAd = this.deps.createAdPlayer(continueLiveStreamDuringAds);\n        preloadAd.initialize();\n\n        const errorListener = (payload?: any) => {\n          hasAdError = true;\n          adErrorPayload = payload;\n        };\n        preloadAd.on(\"ad_error\", errorListener);\n        errorListenerCleanup = () => preloadAd.off(\"ad_error\", errorListener);\n\n        await timing.enforceGlobalRateLimit();\n        await preloadAd.requestAds(vastUrl);\n\n        preloadAd.pause();\n\n        await new Promise(resolve => setTimeout(resolve, 1500));\n\n        preloadAd.pause();\n\n        if (hasAdError) {\n          const isNoFill = adErrorPayload?.isNoFill ||\n                          adErrorPayload?.code === 303 ||\n                          adErrorPayload?.vastErrorCode === 303;\n\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          preloadAd.destroy();\n\n          timing.recordGamNoFill();\n\n          if (isNoFill) {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload returned no-fill: ${vastUrl}`);\n            }\n            timing.temporaryFailureUrls.set(vastUrl, Date.now());\n          } else {\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n            }\n            if (adErrorPayload && !timing.isTemporaryAdError(adErrorPayload as Error)) {\n              timing.failedVastUrls.add(vastUrl);\n            } else {\n              timing.temporaryFailureUrls.set(vastUrl, Date.now());\n            }\n          }\n          return;\n        }\n\n        if (!this.poolActive || epoch !== timing.adBreakEpoch) {\n          if (this.deps.debug) {\n            console.log(\n              \"[PRELOAD-POOL] Discarding preloaded ad - break ended during fetch\"\n            );\n          }\n          if (errorListenerCleanup) {\n            errorListenerCleanup();\n          }\n          try {\n            preloadAd.destroy();\n          } catch {}\n          return;\n        }\n\n        const poolEntry: {\n          vastUrl: string;\n          adController: AdController;\n          loadedAt: number;\n          isReady: boolean;\n          loadPromise: Promise<void>;\n          durationSeconds?: number;\n        } = {\n          vastUrl,\n          adController: preloadAd,\n          loadedAt: Date.now(),\n          isReady: true,\n          loadPromise: Promise.resolve(),\n        };\n        const loadedDuration = preloadAd.getLoadedAdDuration?.();\n        if (loadedDuration != null && loadedDuration > 0) {\n          poolEntry.durationSeconds = loadedDuration;\n        }\n\n        const lateErrorListener = (payload?: any) => {\n          const index = this.pool.findIndex(entry => entry.vastUrl === vastUrl);\n          if (index >= 0) {\n            this.pool.splice(index, 1);\n            if (this.deps.debug) {\n              console.log(`[PRELOAD-POOL] Late error detected, removed from pool: ${vastUrl}`, payload);\n            }\n            try {\n              preloadAd.destroy();\n            } catch {}\n          }\n        };\n        preloadAd.on(\"ad_error\", lateErrorListener);\n\n        this.pool.push(poolEntry);\n\n        if (this.deps.debug) {\n          console.log(`[PRELOAD-POOL] Ad preloaded (no errors detected within timeout) (pool size: ${this.pool.length}/${this.maxPoolSize}, duration=${poolEntry.durationSeconds ?? \"?\"}s)`);\n        }\n\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n      } catch (error) {\n        if (errorListenerCleanup) {\n          errorListenerCleanup();\n        }\n\n        timing.recordGamNoFill();\n\n        if (this.deps.debug) {\n          console.warn(`[PRELOAD-POOL] Failed to preload ad: ${vastUrl}`, error);\n        }\n\n        if (error instanceof Error && !timing.isTemporaryAdError(error)) {\n          timing.failedVastUrls.add(vastUrl);\n        } else if (error instanceof Error && timing.isTemporaryAdError(error)) {\n          timing.temporaryFailureUrls.set(vastUrl, Date.now());\n        }\n      }\n    })();\n\n    loadPromise.catch(() => {});\n  }\n\n  async preloadPoolLoop(baseVastUrl: string): Promise<void> {\n    if (this.loopRunning) {\n      return;\n    }\n\n    this.loopRunning = true;\n    const epoch = this.deps.timing.adBreakEpoch;\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Starting continuous preload loop\");\n    }\n\n    while (this.poolActive && epoch === this.deps.timing.adBreakEpoch) {\n      if (this.deps.timing.isGamInCooldown()) {\n        if (this.deps.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop\");\n        }\n        break;\n      }\n\n      if (!this.deps.isInAdBreak() && this.pool.length >= this.maxPoolSize) {\n        await new Promise(resolve => setTimeout(resolve, 2000));\n        continue;\n      }\n\n      if (!this.deps.isInAdBreak() && this.deps.getPendingAdBreak() === null) {\n        if (this.deps.debug) {\n          console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n        }\n        break;\n      }\n\n      while (this.pool.length < this.maxPoolSize) {\n        if (\n          !this.poolActive ||\n          epoch !== this.deps.timing.adBreakEpoch ||\n          this.deps.timing.isGamInCooldown()\n        ) {\n          break;\n        }\n\n        if (this.deps.isInAdBreak() && !this.deps.timing.hasTimeToStartAnotherAd()) {\n          if (this.deps.debug) {\n            console.log(\"[PRELOAD-POOL] Not enough ad break time left, stopping preload\");\n          }\n          break;\n        }\n\n        const newUrls = this.deps.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n        const newUrl = newUrls[0];\n\n        if (newUrl && !this.deps.timing.failedVastUrls.has(newUrl) && !this.deps.timing.isUrlInCooldown(newUrl)) {\n          await this.preloadAdIntoPool(newUrl);\n        }\n\n        await new Promise(resolve => setTimeout(resolve, 1000));\n      }\n\n      await new Promise(resolve => setTimeout(resolve, 2000));\n    }\n\n    this.loopRunning = false;\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload loop ended\");\n    }\n  }\n\n  getPreloadedAd(): { vastUrl: string; adController: AdController } | null {\n    if (this.pool.length === 0) {\n      return null;\n    }\n\n    const entry = this.pool.shift();\n    if (!entry || !entry.isReady) {\n      return null;\n    }\n\n    if (this.deps.debug) {\n      console.log(`[PRELOAD-POOL] Using preloaded ad from pool (${this.pool.length} remaining)`);\n    }\n\n    return {\n      vastUrl: entry.vastUrl,\n      adController: entry.adController,\n    };\n  }\n\n  stop(): void {\n    this.poolActive = false;\n    this.loopRunning = false;\n\n    for (const entry of this.pool) {\n      try {\n        entry.adController.destroy();\n      } catch (error) {\n        if (this.deps.debug) {\n          console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n        }\n      }\n    }\n\n    this.pool = [];\n\n    if (this.deps.debug) {\n      console.log(\"[PRELOAD-POOL] Preload pool stopped and cleaned up\");\n    }\n  }\n}\n","export class PlaceholderLayer {\n  private container: HTMLDivElement | undefined;\n  private debug: boolean;\n  private video: HTMLVideoElement;\n\n  constructor(video: HTMLVideoElement, debug: boolean) {\n    this.video = video;\n    this.debug = debug;\n  }\n\n  private ensureContainer(): void {\n    if (this.container) {\n      return;\n    }\n\n    const el = document.createElement(\"div\");\n    el.style.position = \"absolute\";\n    el.style.left = \"0\";\n    el.style.top = \"0\";\n    el.style.right = \"0\";\n    el.style.bottom = \"0\";\n    el.style.display = \"none\";\n    el.style.alignItems = \"center\";\n    el.style.justifyContent = \"center\";\n    el.style.pointerEvents = \"none\";\n    el.style.zIndex = \"5\";\n    el.style.backgroundColor = \"#000\";\n    el.style.transition = \"opacity 0.3s ease-in-out\";\n    el.style.opacity = \"0\";\n\n    if (!this.video.parentElement) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n      }\n      return;\n    }\n\n    this.video.parentElement.appendChild(el);\n    this.container = el;\n  }\n\n  show(): void {\n    this.ensureContainer();\n\n    if (!this.container) {\n      return;\n    }\n\n    if (!this.video.muted) {\n      this.video.muted = true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n      }\n    }\n\n    const wasHidden = this.container.style.display === \"none\" || this.container.style.opacity === \"0\";\n    if (wasHidden) {\n      this.container.style.transition = \"none\";\n    } else {\n      this.container.style.transition = \"opacity 0.3s ease-in-out\";\n    }\n\n    this.container.style.backgroundColor = \"#000\";\n    this.container.style.display = \"flex\";\n    this.container.offsetHeight;\n    this.container.style.opacity = \"1\";\n    this.container.style.pointerEvents = \"auto\";\n\n    if (wasHidden) {\n      requestAnimationFrame(() => {\n        if (this.container) {\n          this.container.style.transition = \"opacity 0.3s ease-in-out\";\n        }\n      });\n    }\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and ad layer)\");\n    }\n  }\n\n  hide(): void {\n    if (!this.container) {\n      return;\n    }\n\n    this.container.style.opacity = \"0\";\n    setTimeout(() => {\n      if (this.container) {\n        this.container.style.display = \"none\";\n        this.container.style.pointerEvents = \"none\";\n        this.container.style.backgroundColor = \"#000\";\n      }\n    }, 300);\n\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n    }\n  }\n\n  destroy(): void {\n    if (this.container) {\n      if (this.container.parentElement) {\n        this.container.parentElement.removeChild(this.container);\n      }\n      this.container = undefined;\n    }\n  }\n}\n","import Hls from \"hls.js\";\nimport type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  Id3TagInfo,\n} from \"../types\";\nimport type { Scte35CueContext } from \"./playerTypes\";\nimport {\n  parseScte35FromId3,\n  parseScte35FromTsPackets,\n  normalizeFragmentPayload,\n  getFragmentStartSeconds,\n  parseCueOutDuration,\n  parseCueOutCont,\n  parseAttributeList,\n  toNumber,\n} from \"./Scte35Parser\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { AdTimingService } from \"./AdTimingService\";\n\nexport interface HlsEngineCallbacks {\n  onManifestParsed(isLive: boolean): Promise<void>;\n  onScte35Cue(marker: Scte35Marker, context: Scte35CueContext): void;\n  activatePendingCuesForFragment(frag: any): void;\n  onFatalDestroy(): void;\n  isInAdBreak(): boolean;\n  hasPendingAdBreak(): boolean;\n}\n\nexport class HlsEngine {\n  hls: Hls | undefined;\n  isLiveStream: boolean = false;\n  nativeHlsMode: boolean = false;\n  videoSrcProtection: string | null = null;\n\n  private bufferedSegmentsCount: number = 0;\n  private shouldAutoplayAfterBuffering: boolean = false;\n  private hasInitialBufferCompleted: boolean = false;\n\n  private readonly config: StormcloudVideoPlayerConfig;\n  private readonly video: HTMLVideoElement;\n  private readonly cueManager: Scte35CueManager;\n  private readonly timing: AdTimingService;\n  private readonly callbacks: HlsEngineCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    cueManager: Scte35CueManager,\n    timing: AdTimingService,\n    callbacks: HlsEngineCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.cueManager = cueManager;\n    this.timing = timing;\n    this.callbacks = callbacks;\n  }\n\n  private get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  shouldUseNativeHls(getStreamType: () => \"hls\" | \"other\"): boolean {\n    const streamType = getStreamType();\n    if (streamType === \"other\") {\n      return true;\n    }\n    const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n    return !!(this.config.allowNativeHls && canNative);\n  }\n\n  async setupNativeHls(): Promise<void> {\n    this.nativeHlsMode = true;\n    this.videoSrcProtection = this.config.src;\n    this.video.src = this.config.src;\n\n    this.isLiveStream = this.config.isLiveStream ?? (this.config.lowLatencyMode ?? false);\n\n    if (this.debug) {\n      const adBehavior = this.isLiveStream\n        ? \"live (main video continues muted during ads)\"\n        : \"vod (main video pauses during ads)\";\n      console.log(\n        \"[StormcloudVideoPlayer] Using native HLS playback:\",\n        {\n          isLive: this.isLiveStream,\n          allowNativeHls: this.config.allowNativeHls,\n          adBehavior,\n        }\n      );\n    }\n\n    if (this.config.autoplay) {\n      await this.video.play()?.catch(() => {});\n    }\n  }\n\n  setupHls(): void {\n    this.hls = new Hls({\n      enableWorker: true,\n      backBufferLength: 30,\n      liveDurationInfinity: true,\n      lowLatencyMode: !!this.config.lowLatencyMode,\n      maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1.0,\n      ...(this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}),\n      maxBufferLength: 30,\n      maxMaxBufferLength: 600,\n      maxBufferSize: 60 * 1000 * 1000,\n      maxBufferHole: 0.5,\n      highBufferWatchdogPeriod: 2,\n      nudgeOffset: 0.1,\n      nudgeMaxRetry: 3,\n      startPosition: -1,\n    });\n\n    this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n      this.hls?.loadSource(this.config.src);\n    });\n\n    this.hls.on(Hls.Events.MANIFEST_PARSED, async (_, _data: any) => {\n      this.isLiveStream =\n        this.config.isLiveStream ??\n        (this.hls?.levels?.some(\n          (level) =>\n            level?.details?.live === true || level?.details?.type === \"LIVE\"\n        ) ?? false);\n\n      await this.callbacks.onManifestParsed(this.isLiveStream);\n\n      this.bufferedSegmentsCount = 0;\n      this.hasInitialBufferCompleted = false;\n      this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n      if (this.debug) {\n        console.log(\n          \"[StormcloudVideoPlayer] Waiting for\",\n          minSegments,\n          \"segments to buffer before playback\"\n        );\n      }\n\n      if (minSegments === 0 || !this.config.autoplay) {\n        this.hasInitialBufferCompleted = true;\n        if (this.config.autoplay) {\n          await this.video.play()?.catch(() => {});\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n      if (this.callbacks.isInAdBreak() || this.callbacks.hasPendingAdBreak()) {\n        return;\n      }\n\n      const details = data?.details;\n      if (!details || !details.fragments || details.fragments.length === 0) {\n        return;\n      }\n\n      const fragmentsToScan = Math.min(5, details.fragments.length);\n\n      for (let i = 0; i < fragmentsToScan; i++) {\n        const frag = details.fragments[i];\n        const tagList: any[] | undefined = frag?.tagList;\n\n        if (!Array.isArray(tagList)) continue;\n\n        for (const entry of tagList) {\n          let tag = \"\";\n          let value = \"\";\n\n          if (Array.isArray(entry)) {\n            tag = String(entry[0] ?? \"\");\n            value = String(entry[1] ?? \"\");\n          } else if (typeof entry === \"string\") {\n            const idx = entry.indexOf(\":\");\n            if (idx >= 0) {\n              tag = entry.substring(0, idx);\n              value = entry.substring(idx + 1);\n            } else {\n              tag = entry;\n            }\n          }\n\n          if (!tag) continue;\n\n          if (tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-DATERANGE\")) {\n            const attrs = tag.includes(\"EXT-X-DATERANGE\")\n              ? parseAttributeList(value)\n              : {};\n            const hasScteOut = tag.includes(\"EXT-X-CUE-OUT\") ||\n              \"SCTE35-OUT\" in attrs ||\n              attrs[\"SCTE35-OUT\"] !== undefined;\n\n            if (hasScteOut) {\n              const durationSeconds = parseCueOutDuration(value);\n              const marker: Scte35Marker = {\n                type: \"start\",\n                ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n                raw: { tag, value, earlyDetection: true },\n              } as Scte35Marker;\n\n              if (this.debug) {\n                console.log(\"[StormcloudVideoPlayer] EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n              }\n\n              this.callbacks.onScte35Cue(marker, {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"early\", frag),\n              });\n              return;\n            }\n          }\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.FRAG_BUFFERED, async (_evt, _data: any) => {\n      if (this.hasInitialBufferCompleted) {\n        return;\n      }\n\n      this.bufferedSegmentsCount++;\n      const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] Buffered segment ${this.bufferedSegmentsCount}/${minSegments}`\n        );\n      }\n\n      if (this.bufferedSegmentsCount >= minSegments) {\n        this.hasInitialBufferCompleted = true;\n\n        if (this.shouldAutoplayAfterBuffering) {\n          if (this.debug) {\n            console.log(\n              `[StormcloudVideoPlayer] Initial buffer complete (${this.bufferedSegmentsCount} segments). Starting playback.`\n            );\n          }\n          await this.video.play()?.catch((err) => {\n            if (this.debug) {\n              console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n            }\n          });\n        }\n      }\n    });\n\n    this.hls.on(Hls.Events.FRAG_PARSING_METADATA, (_evt, data: any) => {\n      const id3Tags: Id3TagInfo[] = (data?.samples || []).map((s: any) => ({\n        key: \"ID3\",\n        value: s?.data,\n        ptsSeconds: s?.pts,\n      }));\n      id3Tags.forEach((tag) => this.onId3Tag(tag));\n    });\n\n    this.hls.on(Hls.Events.FRAG_LOADED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n\n    this.hls.on(Hls.Events.FRAG_DECRYPTED, (_evt, data: any) => {\n      this.processFragmentScte35Payload(\n        data?.payload,\n        typeof data?.frag?.sn === \"number\" ? data.frag.sn : undefined,\n        getFragmentStartSeconds(data?.frag)\n      );\n    });\n\n    this.hls.on(Hls.Events.FRAG_CHANGED, (_evt, data: any) => {\n      const frag = data?.frag;\n      const tagList: any[] | undefined = frag?.tagList;\n      if (!Array.isArray(tagList)) {\n        this.callbacks.activatePendingCuesForFragment(frag);\n        return;\n      }\n\n      for (const entry of tagList) {\n        let tag = \"\";\n        let value = \"\";\n        if (Array.isArray(entry)) {\n          tag = String(entry[0] ?? \"\");\n          value = String(entry[1] ?? \"\");\n        } else if (typeof entry === \"string\") {\n          const idx = entry.indexOf(\":\");\n          if (idx >= 0) {\n            tag = entry.substring(0, idx);\n            value = entry.substring(idx + 1);\n          } else {\n            tag = entry;\n            value = \"\";\n          }\n        }\n\n        if (!tag) continue;\n        if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n          const prog = parseCueOutCont(value);\n          const marker: Scte35Marker = {\n            type: \"progress\",\n            ...(prog?.duration !== undefined\n              ? { durationSeconds: prog.duration }\n              : {}),\n            ...(prog?.elapsed !== undefined\n              ? { ptsSeconds: prog.elapsed }\n              : {}),\n            raw: { tag, value },\n          } as Scte35Marker;\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n          const durationSeconds = parseCueOutDuration(value);\n          const marker: Scte35Marker = {\n            type: \"start\",\n            ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n            raw: { tag, value },\n          } as Scte35Marker;\n          this.callbacks.onScte35Cue(marker, {\n            ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n          });\n        } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n          this.callbacks.onScte35Cue(\n            { type: \"end\", raw: { tag, value } },\n            {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            }\n          );\n        } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n          const attrs = parseAttributeList(value);\n          const hasScteOut =\n            \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== undefined;\n          const hasScteIn =\n            \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== undefined;\n          const klass = String(attrs[\"CLASS\"] ?? \"\");\n          const duration = toNumber(attrs[\"DURATION\"]);\n\n          if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n            const marker: Scte35Marker = {\n              type: \"start\",\n              ...(duration !== undefined ? { durationSeconds: duration } : {}),\n              raw: { tag, value, attrs },\n            } as Scte35Marker;\n            this.callbacks.onScte35Cue(marker, {\n              ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n            });\n          }\n          if (hasScteIn) {\n            this.callbacks.onScte35Cue(\n              { type: \"end\", raw: { tag, value, attrs } },\n              {\n                ...this.cueManager.createScte35CueContext(\"manifest\", \"playback\", frag),\n              }\n            );\n          }\n        }\n      }\n      this.callbacks.activatePendingCuesForFragment(frag);\n    });\n\n    this.hls.on(Hls.Events.ERROR, (_evt, data) => {\n      if (data?.fatal) {\n        switch (data.type) {\n          case Hls.ErrorTypes.NETWORK_ERROR:\n            this.hls?.startLoad();\n            break;\n          case Hls.ErrorTypes.MEDIA_ERROR:\n            this.hls?.recoverMediaError();\n            break;\n          default:\n            this.callbacks.onFatalDestroy();\n            break;\n        }\n      }\n    });\n\n    this.hls.attachMedia(this.video);\n  }\n\n  private onId3Tag(tag: Id3TagInfo): void {\n    if (typeof tag.ptsSeconds === \"number\") {\n      this.timing.updatePtsDrift(tag.ptsSeconds);\n    }\n    const marker = parseScte35FromId3(tag);\n    if (marker) {\n      this.callbacks.onScte35Cue(marker, {\n        source: \"id3\",\n        readiness: \"playback\",\n      });\n    }\n  }\n\n  private processFragmentScte35Payload(\n    payloadData: unknown,\n    fragmentSn?: number,\n    fragmentStartSeconds?: number\n  ): void {\n    const payload = normalizeFragmentPayload(payloadData);\n    if (!payload) {\n      return;\n    }\n\n    const markers = parseScte35FromTsPackets(\n      payload,\n      this.cueManager.tsScte35Pids,\n      this.cueManager.pmtPids,\n      this.cueManager.processedTsScte35Sections\n    );\n    markers.forEach((marker) => {\n      const context: Scte35CueContext = {\n        source: \"ts\",\n        readiness: \"early\",\n      };\n      if (fragmentSn !== undefined) {\n        context.fragmentSn = fragmentSn;\n      }\n      if (fragmentStartSeconds !== undefined) {\n        context.fragmentStartSeconds = fragmentStartSeconds;\n      }\n      this.callbacks.onScte35Cue(marker, context);\n    });\n  }\n\n  getLiveSyncPosition(): number | undefined {\n    const pos = this.hls?.liveSyncPosition;\n    return typeof pos === \"number\" && Number.isFinite(pos) ? pos : undefined;\n  }\n\n  destroy(): void {\n    this.hls?.destroy();\n    this.hls = undefined;\n  }\n}\n","import type { AdController } from \"../types\";\n\nexport function getAdAudioVolume(adPlayer: AdController): number {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\n\nexport function toggleMute(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\n\nexport function toggleFullscreen(\n  video: HTMLVideoElement,\n  debug: boolean\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container\n        .requestFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n          }\n          reject(err);\n        });\n    } else {\n      document\n        .exitFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\n              \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n              err\n            );\n          }\n          reject(err);\n        });\n    }\n  });\n}\n\nexport function isMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): boolean {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\n\nexport function setMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  muted: boolean,\n  debug: boolean\n): void {\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n\n  video.muted = muted;\n\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted,\n      });\n    }\n    return;\n  }\n\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\n\nexport function setVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  volume: number,\n  debug: boolean\n): void {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume,\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\n\nexport function getVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): number {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\n\nexport function isFullscreen(): boolean {\n  return !!document.fullscreenElement;\n}\n\nexport function resizePlayer(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n\n    adPlayer.resize(width, height);\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n} from \"../types\";\nimport {\n  buildAnalyticsContext,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport type { AdTimingService } from \"./AdTimingService\";\nimport type { AdPreloadPool } from \"./AdPreloadPool\";\nimport type { AdConfigManager } from \"./AdConfigManager\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { getAdAudioVolume } from \"./PlayerControls\";\n\nexport interface AdBreakOrchestratorHost {\n  readonly config: StormcloudVideoPlayerConfig;\n  readonly video: HTMLVideoElement;\n  getAdPlayer(): AdController;\n  setAdPlayer(player: AdController): void;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  getLiveSyncPosition(): number | undefined;\n  generateVastUrls(baseUrl: string, count: number): string[];\n  generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string;\n}\n\nexport class AdBreakOrchestrator {\n  inAdBreak = false;\n  showAds: boolean = false;\n  isShowingPlaceholder: boolean = false;\n  adDetectSentForCurrentBreak: boolean = false;\n\n  private continuousFetchingActive: boolean = false;\n  private continuousFetchLoopRunning = false;\n  adRequestQueue: string[] = [];\n  adPodQueue: string[] = [];\n  private readonly maxPlaceholderDurationMs: number = 5000;\n\n  pendingAdBreak: {\n    marker: Scte35Marker;\n    detectedAtFragmentSn?: number;\n    vastUrls: string[];\n    isFetching: boolean;\n    fetchStartTime?: number;\n  } | null = null;\n  prefetchTimerId: number | undefined;\n\n  private readonly host: AdBreakOrchestratorHost;\n  private readonly timing: AdTimingService;\n  private readonly preloadPool: AdPreloadPool;\n  private readonly adConfig: AdConfigManager;\n  private readonly cueManager: Scte35CueManager;\n  private readonly placeholder: PlaceholderLayer;\n\n  constructor(\n    host: AdBreakOrchestratorHost,\n    timing: AdTimingService,\n    preloadPool: AdPreloadPool,\n    adConfig: AdConfigManager,\n    cueManager: Scte35CueManager,\n    placeholder: PlaceholderLayer\n  ) {\n    this.host = host;\n    this.timing = timing;\n    this.preloadPool = preloadPool;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n\n  private get debug(): boolean {\n    return !!this.host.config.debugAdTiming;\n  }\n\n  private get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  private get optimizedPodsEnabled(): boolean {\n    return this.host.config.optimizedPods !== false;\n  }\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload?: any) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      this.timing.consecutiveFailures = 0;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload?: any) => {\n      let errorMessage = \"Ad playback failed\";\n\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n\n      if (!this.inAdBreak) {\n        return;\n      }\n\n      this.timing.consecutiveFailures = 0;\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n\n  recreateAdController(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n\n  clearPendingAdBreak(): void {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = undefined;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = undefined;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n\n  async handleAdStart(_marker: Scte35Marker): Promise<void> {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1000\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\n\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n\n    const adBreakDurationMs =\n      _marker.durationSeconds != null\n        ? _marker.durationSeconds * 1000\n        : scheduled?.durationMs;\n\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    if (\n      this.timing.expectedAdBreakDurationMs == null &&\n      adBreakDurationMs != null\n    ) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n\n    if (this.optimizedPodsEnabled) {\n      const podPlayed = await this.startOptimizedPod(\n        baseVastUrl,\n        adBreakDurationMs,\n        currentMuted,\n        currentVolume\n      );\n      if (podPlayed) {\n        return;\n      }\n      if (this.debug) {\n        console.log(\"[POD] Optimized pod unavailable, falling back to sequential single-ad path\");\n      }\n    }\n\n    let firstAdUrl: string | undefined;\n    let usePreloadedAd = false;\n    let preloadedController: AdController | undefined;\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      firstAdUrl = preloaded.vastUrl;\n      preloadedController = preloaded.adController;\n      usePreloadedAd = true;\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n      }\n    } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n      firstAdUrl = this.adRequestQueue.shift();\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n      }\n\n      this.clearPendingAdBreak();\n    } else {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Generating new ad URLs...\");\n      }\n\n      const firstAdUrlArray = this.host.generateVastUrls(baseVastUrl, 1);\n      firstAdUrl = firstAdUrlArray[0];\n      this.adRequestQueue = [];\n    }\n\n    if (!firstAdUrl) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] Failed to get first ad URL\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] First VAST URL:\", firstAdUrl);\n    }\n\n    try {\n      if (usePreloadedAd && preloadedController) {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloadedController)) {\n          this.timing.rejectLoadedAdForDuration(preloadedController);\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        const adPlayer = this.host.getAdPlayer();\n        const preservedMuted = adPlayer.getOriginalMutedState();\n        const preservedVolume = adPlayer.getOriginalVolume();\n        adPlayer.destroy();\n        this.host.video.muted = true;\n        this.host.setAdPlayer(preloadedController);\n        preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n\n        this.attachImaEventListeners();\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n        }\n\n        preloadedController.resume();\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.active = true;\n        }\n        if (!this.preloadPool.isLoopRunning) {\n          this.preloadPool.preloadPoolLoop(baseVastUrl);\n        }\n\n        await preloadedController.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        preloadedController.setAdVolume(adVolume);\n      } else {\n        const adPlayer = this.host.getAdPlayer();\n        await this.timing.enforceGlobalRateLimit();\n        this.timing.lastAdRequestTime = Date.now();\n        await adPlayer.requestAds(firstAdUrl);\n        sendAdLoadedTracking(\n          this.host.config.licenseKey,\n          { source: \"hls\", vastUrl: firstAdUrl, timestamp: new Date().toISOString() },\n          this.analyticsContext\n        ).catch(() => {});\n\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad request successful, starting playback\");\n        }\n\n        if (!this.timing.ensureLoadedAdFitsBudget(adPlayer)) {\n          this.timing.rejectLoadedAdForDuration(adPlayer);\n          this.recreateAdController();\n          this.startContinuousFetching(baseVastUrl);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.timing.consecutiveFailures = 0;\n        this.startContinuousFetching(baseVastUrl);\n\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n\n        await adPlayer.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        const adVolume = currentMuted ? 0 : currentVolume;\n        adPlayer.setAdVolume(adVolume);\n      }\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[CONTINUOUS-FETCH] First ad request failed:\", error);\n      }\n\n      if (!usePreloadedAd) {\n        const fallbackPreloaded = this.preloadPool.getPreloadedAd();\n        if (fallbackPreloaded) {\n          if (this.debug) {\n            console.log(\"[CONTINUOUS-FETCH] First ad failed, using preloaded fallback\");\n          }\n\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(fallbackPreloaded.adController)) {\n              this.timing.rejectLoadedAdForDuration(fallbackPreloaded.adController);\n              this.startContinuousFetching(baseVastUrl);\n              await this.tryNextAvailableAdWithRateLimit();\n              return;\n            }\n\n            this.swapToPreloadedAdPlayer(fallbackPreloaded.adController);\n\n            this.timing.consecutiveFailures = 0;\n            this.startContinuousFetching(baseVastUrl);\n\n            if (!this.preloadPool.active) {\n              this.preloadPool.active = true;\n              this.preloadPool.preloadPoolLoop(baseVastUrl);\n            }\n\n            const ap = this.host.getAdPlayer();\n            await ap.play();\n            this.timing.markAdStarted();\n\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n\n            const adVolume = currentMuted ? 0 : currentVolume;\n            ap.setAdVolume(adVolume);\n\n            return;\n          } catch (fallbackError) {\n            if (this.debug) {\n              console.warn(\"[CONTINUOUS-FETCH] Preloaded fallback also failed:\", fallbackError);\n            }\n          }\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(firstAdUrl, Date.now());\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n        }\n      } else {\n        this.timing.failedVastUrls.add(firstAdUrl);\n        if (this.debug) {\n          console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n        }\n      }\n      this.timing.consecutiveFailures++;\n\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n\n  private async startOptimizedPod(\n    baseVastUrl: string,\n    breakDurationMs: number | undefined,\n    currentMuted: boolean,\n    currentVolume: number\n  ): Promise<boolean> {\n    let podUrl: string | undefined;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n\n    if (!podUrl) {\n      return false;\n    }\n\n    this.continuousFetchingActive = false;\n\n    this.recreateAdController();\n\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n\n      if (this.debug) {\n        console.log(\n          podCount === 1\n            ? \"[POD] Response contained a single ad; playing it and enabling sequential top-up\"\n            : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n\n      if (\n        this.timing.expectedAdBreakDurationMs != null &&\n        this.timing.getAdBreakEndWallClockMs() == null\n      ) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n\n      if (podCount === 1) {\n        this.continuousFetchingActive = true;\n        this.startContinuousFetching(baseVastUrl);\n        if (!this.preloadPool.active) {\n          this.preloadPool.startPreloadPool(baseVastUrl, []);\n        }\n      }\n\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n\n  private swapToPreloadedAdPlayer(preloadedController: AdController): void {\n    const adPlayer = this.host.getAdPlayer();\n    const preservedMuted = adPlayer.getOriginalMutedState();\n    const preservedVolume = adPlayer.getOriginalVolume();\n    adPlayer.destroy();\n    this.host.video.muted = true;\n    this.host.setAdPlayer(preloadedController);\n    this.attachImaEventListeners();\n    preloadedController.updateOriginalMutedState(preservedMuted, preservedVolume);\n    preloadedController.resume();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n\n  private startContinuousFetching(baseVastUrl: string): void {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n\n  private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n    const epoch = this.timing.adBreakEpoch;\n    while (\n      this.continuousFetchingActive &&\n      this.inAdBreak &&\n      epoch === this.timing.adBreakEpoch\n    ) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        continue;\n      }\n\n      const newAdUrl = this.host.generateVastUrls(baseVastUrl, 1)[0];\n\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise(resolve => setTimeout(resolve, 500));\n        continue;\n      }\n\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n\n      this.adRequestQueue.push(newAdUrl);\n\n      const generationDelay = this.timing.consecutiveFailures > 0\n        ? Math.min(1000 * Math.pow(2, this.timing.consecutiveFailures), 5000)\n        : 500;\n      await new Promise(resolve => setTimeout(resolve, generationDelay));\n    }\n\n    this.continuousFetchLoopRunning = false;\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n\n  stopContinuousFetching(): void {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n\n    this.placeholder.hide();\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n\n  async tryNextAvailableAdWithRateLimit(): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const epoch = this.timing.adBreakEpoch;\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitTime));\n    }\n\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n\n    return this.tryNextAvailableAd(0);\n  }\n\n  private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    this.timing.cleanupTemporaryFailures();\n\n    const preloaded = this.preloadPool.getPreloadedAd();\n    if (preloaded) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Using preloaded ad from pool`);\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: preloaded.vastUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      try {\n        if (!this.timing.ensureLoadedAdFitsBudget(preloaded.adController)) {\n          this.timing.rejectLoadedAdForDuration(preloaded.adController);\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        this.swapToPreloadedAdPlayer(preloaded.adController);\n\n        const ap = this.host.getAdPlayer();\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n\n        this.timing.consecutiveFailures = 0;\n        return;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[CONTINUOUS-FETCH] Preloaded ad failed to play:\", error);\n        }\n      }\n    }\n\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n\n      if (!nextAdUrl) continue;\n\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = (error as Error).message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise(resolve => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n\n    if (!this.isShowingPlaceholder && remaining > 1000) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n\n  async playSingleAd(vastTagUrl: string): Promise<void> {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n\n    this.recreateAdController();\n\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n\n        const preloadedFallback = this.preloadPool.getPreloadedAd();\n        if (preloadedFallback) {\n          if (this.debug) console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n          try {\n            if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n              this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n              throw playError;\n            }\n            this.timing.clearAdFailsafeTimer();\n            this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n            this.timing.consecutiveFailures = 0;\n            const fbAp = this.host.getAdPlayer();\n            await fbAp.play();\n            this.timing.markAdStarted();\n            if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n              this.timing.scheduleAdStopAtBreakBoundary();\n            }\n            fbAp.setAdVolume(getAdAudioVolume(fbAp));\n            return;\n          } catch (fallbackError) {\n            if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n          }\n        }\n\n        if (this.timing.isTemporaryAdError(playError as Error)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error)?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n\n      const preloadedFallback = this.preloadPool.getPreloadedAd();\n      if (preloadedFallback) {\n        if (this.debug) console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n        try {\n          if (!this.timing.ensureLoadedAdFitsBudget(preloadedFallback.adController)) {\n            this.timing.rejectLoadedAdForDuration(preloadedFallback.adController);\n            throw error;\n          }\n          this.timing.clearAdRequestWatchdog();\n          this.timing.clearAdFailsafeTimer();\n          this.swapToPreloadedAdPlayer(preloadedFallback.adController);\n          this.timing.consecutiveFailures = 0;\n          const fbAp = this.host.getAdPlayer();\n          await fbAp.play();\n          this.timing.markAdStarted();\n          fbAp.setAdVolume(getAdAudioVolume(fbAp));\n          return;\n        } catch (fallbackError) {\n          if (this.debug) console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n        }\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n\n  private async showPlaceholderAndWaitForAds(): Promise<void> {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (waitTime < 1000) {\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise(resolve => setTimeout(resolve, checkInterval));\n\n      if (!this.inAdBreak) return;\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = (error as Error).message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n\n  handleAdPodComplete(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n\n    this.timing.resetForBreakEnd();\n\n    this.stopContinuousFetching();\n    this.preloadPool.stop();\n    this.clearPendingAdBreak();\n\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n\n    this.adRequestQueue = [];\n\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = undefined;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    this.host.getAdPlayer().stop().catch(() => {});\n\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n\n    if (this.host.shouldContinueLiveStreamDuringAds()) {\n      const liveSyncPos = this.host.getLiveSyncPosition();\n      if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live break end — snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s → ${liveSyncPos.toFixed(2)}s`\n          );\n        }\n        this.host.video.currentTime = liveSyncPos;\n      }\n\n      if (this.host.video.paused) {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n        this.host.video.play()?.catch(() => {});\n      } else {\n        if (this.debug) console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n      }\n    } else if (this.host.video.paused) {\n      this.host.video.play()?.catch(() => {});\n    }\n  }\n\n  handleAdFailure(): void {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n}\n"]}