{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/players/index.cjs","../../src/players/index.ts","../../src/utils.ts","../../src/patterns.ts","../../src/players/HlsPlayer.tsx","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/pal.ts","../../src/utils/mqttClient.ts","../../src/utils/mqttConfig.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","__getOwnPropDesc","defineProperty","getOwnPropertyDescriptor","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__getOwnPropNames","__toESM","mod","isNodeMode","__toCommonJS","__esModule","value","players_exports","players_default","module","exports","import_react","require","lazy","reactLazy","IS_GLOBAL","globalThis","window","document","IS_IOS","IS_BROWSER","test","navigator","userAgent","IS_SAFARI","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","canPlay","hls","url","dash","audio","file","import_hls","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","widthDiff","map","abs","heightDiff","bitrateDiff","fileBitrate","score","resolutionDiff","sort","a","b","bestMatch","resolution","xmlDoc","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","mute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","fetchVastXml","vastTagUrl","response","fetch","mode","credentials","headers","referrerPolicy","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","substring","createAdVideoElement","video","createElement","style","position","left","top","objectFit","progress","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","continueLiveStreamDuringAds","paused","play","catch","container","initialize","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","Promise","reject","has","delete","resolve","contentVolume","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","ERROR","data","fatal","canPlayType","load","stop","previousMutedState","visibility","opacity","timeoutId","clearTimeout","remove","clear","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","Number","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","PAL_SDK_URL","_nonceLoader","_palLoadPromise","loadPalSdk","goog","pal","existing","timeout","setTimeout","script","async","setAttribute","onload","onerror","head","getOrCreateNonceLoader","consentSettings","ConsentSettings","allowStorage","NonceLoader","createPalNonceManager","currentNonce","currentNonceManager","generateNonce","loader","request","manager","NonceRequest","adWillAutoPlay","adWillPlayMuted","client","status","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","initMQTTClient","clientId","slice","mqtt","connect","keepalive","clean","reconnectPeriod","connectTimeout","queueQoSZero","err","info","ensureMQTTClient","message","publishMQTT","topic","publish","JSON","stringify","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_TIZEN_APP_ID","AIRY_ROKU_APP_ID","AIRY_APP_NAME","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","PLAYER_ID_STORAGE_KEY","LG_TEST_APP_ID","LG_TEST_APP_NAME","LG_TEST_CONTENT_URL","_lgTestDeviceId","getLgTestDeviceId","createUuid","isLgWebOS","getDefaultAppId","ua","DEVICE_ID_STORAGE_KEYS","platformLat","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","isCtv","bridgeSignals","platformDevice","readNativeBridgeSignals","readPlatformNativeDeviceId","lg","deviceId","limitAdTracking","readStoredLimitAdTracking","contentUrl","readStoredString","appId","appName","getOrCreateCtvSessionId","deviceTypeHint","deviceIdType","tagType","isEquivalentDeviceIdType","runtimeType","tag","runtime","resolveNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","localStorage","setItem","crypto","randomUUID","char","floor","nibble","adinfo","webapis","tifa","getTIFA","lat","isLATEnabled","webOSDev","lgudid","LGUDID","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","AiryTV","webOS","tizen","amazon","filter","Boolean","candidates","readBridgeValue","inferDeviceIdType","readBridgeBoolean","result","normalized","normalizeBoolean","readStoredDeviceId","getItem","cachedBrowserId","getClientInfo","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","tizenMatch","match","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","i","hashBuffer","hash","fallbackHash","timestamp","subtle","digest","Uint8Array","TextEncoder","encode","unescape","charCodeAt","padStart","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","getBrowserID","canPublish","buildPlayerMetricEvent","context","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","inputStreamType","input_stream_type","publishTracking","body","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","values","String","getAll","callback","parts","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","indexOf","initializePolyfills","UNEXPANDED_MACRO_PATTERN","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","pattern","getValue","ctx","correlator","trimmed","generateCorrelator","getRandomValues","buf","Uint32Array","MAX_SAFE_INTEGER","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","trimStart","raw","anValue","orphanFragments","reconstructed","trimEnd","_match","prefix","val","applyVastMacros","expandedUrl","expandInlineMacroPlaceholders","normalizeVastTagUrl","replaceCorrelatorFallback","streamCorrelator","pod","adPosition","requestUrl","pageUrl","existingUrl","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","correlatorRegex","fetchConsentSignals","timeoutMs","signals","tasks","tcfApi","__tcfapi","settled","tcData","success","eventStatus","gdprApplies","tcString","listenerId","__uspapi","uspApi","uspString","webOSVersion","supportsModernJS","majorVersion","getChromeVersion","getWebKitVersion","getPlatform","userAgentData","detectBrowser","isLegacyTV","tizenVersion","chromeVersionNum","chromeVersion","version","webkitVersion","getBrowserConfigOverrides","overrides","browser","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","isFinite","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteIn","klass","hasScteOut","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","checksum","section","processedSections","size","firstKey","next","addScte35SectionMarker","markers","appendScte35Bytes","bytes","assemblers","assembler","expectedLength","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","secondByte","thirdByte","fourthByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","BitReader","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorTag","cancel","programSpliceFlag","descriptorOffset","descriptorLength","descriptorDataStart","descriptorDataEnd","descriptorMarker","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","outOfNetwork","durationFlag","spliceImmediateFlag","componentPtsSeconds","expectedDescriptorOffset","splice_event_id","segmentation_event_id","Scte35CueManager","pendingScte35Cues","recentScte35CueKeys","recentScte35CueLimit","processedTsScte35Sections","callbacks","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","scheduledScte35BreakKeyValue","createScte35CueContext","readiness","sn","fragmentSn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","hasRecentlyHandledScte35Cue","markScte35CueHandled","onPlaybackCue","activatePendingScte35CuesForFragment","matchingCues","entries","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","round","isStrongScte35CueKey","recentKey","AdConfigManager","config","vmapBreaks","consumedVmapBreakIds","consentSignals","podCounter","podAssignedByPrefetch","adRequestPositionInBreak","lastHeartbeatTime","debugAdTiming","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","json","ima","vast","cue_tones","number_ads","apiNumberAds","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","adTagNode","adTagUrl","breakId","aStart","startTimeMs","bStart","parseVmapTimeOffsetToMs","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","ctvAdRequest","urlWithMacros","autoplay","finalUrl","initializeTracking","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","destroyTracking","clearInterval","AdTimingService","adRequestWatchdogToken","adFailsafeToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillThreshold","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStopCountdown","clearAdStartTimer","scheduleAdStopAtBreakBoundary","adController","ensureLoadedAdFitsBudget","remainingMs","ensureAdStoppedByTimer","adStopTimerId","clearAdStopTimer","onAdStopTimerFired","scheduleAdStartIn","delayMs","cueKey","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","expectedAdBreakDurationMs","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","fits","rejectLoadedAdForDuration","markAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","isGamInCooldown","recordGamNoFill","resetGamNoFillCounter","exponent","backoff","pow","enforceGlobalRateLimit","waitMs","clearAdRequestWatchdog","startAdFailsafeTimer","startAdRequestWatchdog","token","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","onWatchdogTimeout","clearAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","onFailsafeTimeout","showAds","active","startLoopImmediately","poolActive","extra","resetForBreakEnd","AdPreloadPool","deps","maxPoolSize","loopRunning","isLoopRunning","startPreloadPool","initialUrls","pool","preloadAdIntoPool","preloadPoolLoop","baseVastUrl","vastUrl","timing","epoch","loadPromise","some","entry","hasAdError","adErrorPayload","errorListenerCleanup","preloadAd","errorListener","isNoFill","poolEntry","loadedDuration","lateErrorListener","shouldContinueLiveStreamDuringAds","createAdPlayer","requestAds","code","vastErrorCode","loadedAt","isReady","findIndex","splice","newUrls","newUrl","getPendingAdBreak","getPreloadedAd","PlaceholderLayer","ensureContainer","transition","show","wasHidden","offsetHeight","requestAnimationFrame","hide","removeChild","HlsEngine","cueManager","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","canNative","shouldUseNativeHls","getStreamType","setupNativeHls","adBehavior","isLive","setupHls","import_hls2","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","fragments","fragmentsToScan","tagList","isArray","idx","earlyDetection","FRAG_BUFFERED","_evt","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","payloadData","getLiveSyncPosition","liveSyncPosition","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","requestFullscreen","isMuted","setMuted","clampedVolume","getVolume","isFullscreen","onFatalDestroy","resizePlayer","clientWidth","clientHeight","AdBreakOrchestrator","host","preloadPool","adConfig","placeholder","isShowingPlaceholder","adDetectSentForCurrentBreak"],"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/players/index.ts\nvar players_exports = {};\n__export(players_exports, {\n  default: () => players_default\n});\nmodule.exports = __toCommonJS(players_exports);\n\n// src/utils.ts\nvar import_react = require(\"react\");\nvar lazy = import_react.lazy;\nvar IS_BROWSER = typeof window !== \"undefined\" && window.document;\nvar IS_GLOBAL = typeof globalThis !== \"undefined\" && globalThis.window && globalThis.window.document;\nvar IS_IOS = IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nvar IS_SAFARI = IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n// src/patterns.ts\nvar HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nvar HLS_PATHS = /\\/hls\\//i;\nvar DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nvar VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nvar AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\nvar canPlay = {\n  hls: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n  dash: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n  video: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n  audio: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n  file: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  }\n};\n\n// src/players/HlsPlayer.tsx\nvar import_react2 = require(\"react\");\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 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(xmlDoc) {\n    const trackingUrls = createEmptyTrackingUrls();\n    xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n    xmlDoc.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    xmlDoc.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  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  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      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      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 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 ad;\n        if (preloadedAds.has(vastTagUrl)) {\n          ad = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ad = await fetchAndParseVastAd(vastTagUrl);\n        }\n        if (!ad) {\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        currentAd = ad;\n        console.log(\n          `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n        );\n        fireTrackingPixels(ad.trackingUrls.impression);\n        trackingFired.impression = true;\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        trackingFired = {\n          impression: trackingFired.impression,\n          start: false,\n          firstQuartile: false,\n          midpoint: false,\n          thirdQuartile: false,\n          complete: false\n        };\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        const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n        if (!mediaFile) {\n          throw new Error(\"No media file available for ad\");\n        }\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n        emit(\"content_pause\");\n        const isHlsAd = isHlsMediaFile(mediaFile);\n        console.log(\n          `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad 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        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    },\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      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  };\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 = readStoredString(storageKey);\n  if (existing) {\n    return existing;\n  }\n  const id = createUuid();\n  try {\n    window.localStorage?.setItem(storageKey, id);\n  } catch {\n  }\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readStoredString(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    return existing;\n  }\n  const sessionId = createUuid();\n  try {\n    window.localStorage?.setItem(CTV_SESSION_STORAGE_KEY, sessionId);\n  } catch {\n  }\n  return sessionId;\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (char) => {\n    const value = Math.floor(Math.random() * 16);\n    const nibble = char === \"x\" ? value : value & 3 | 8;\n    return nibble.toString(16);\n  });\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 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 playerId = await getBrowserID(clientInfo);\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  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.consentSignals = {};\n    this.podCounter = 0;\n    this.podAssignedByPrefetch = false;\n    this.adRequestPositionInBreak = 0;\n    this.lastHeartbeatTime = 0;\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: generateCorrelator(),\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  // --- Tracking ---\n  initializeTracking() {\n    sendInitialTracking(this.config.licenseKey).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).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  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  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n  attachImaEventListeners() {\n    const adPlayer = this.host.getAdPlayer();\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      ).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      ).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    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      ).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        ).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  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      ).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      ).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      },\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  // ───────────────────────────────────────────────────────────────\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 }).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 generatedUrls = 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 }).catch(() => {\n    });\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(`[PREFETCH] Pre-generated ${generatedUrls.length} VAST URLs`);\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/players/HlsPlayer.tsx\nvar HlsPlayer = class extends import_react2.Component {\n  constructor() {\n    super(...arguments);\n    this.player = null;\n    this.mounted = false;\n    this.load = async () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      try {\n        if (this.player) {\n          this.player.destroy();\n          this.player = null;\n        }\n        const config = {\n          src: this.props.src,\n          videoElement: this.props.videoElement\n        };\n        if (this.props.autoplay !== void 0)\n          config.autoplay = this.props.autoplay;\n        if (this.props.muted !== void 0) config.muted = this.props.muted;\n        if (this.props.lowLatencyMode !== void 0)\n          config.lowLatencyMode = this.props.lowLatencyMode;\n        if (this.props.allowNativeHls !== void 0)\n          config.allowNativeHls = this.props.allowNativeHls;\n        if (this.props.isLiveStream !== void 0)\n          config.isLiveStream = this.props.isLiveStream;\n        if (this.props.driftToleranceMs !== void 0)\n          config.driftToleranceMs = this.props.driftToleranceMs;\n        if (this.props.immediateManifestAds !== void 0)\n          config.immediateManifestAds = this.props.immediateManifestAds;\n        if (this.props.debugAdTiming !== void 0)\n          config.debugAdTiming = this.props.debugAdTiming;\n        if (this.props.showCustomControls !== void 0)\n          config.showCustomControls = this.props.showCustomControls;\n        if (this.props.onVolumeToggle !== void 0)\n          config.onVolumeToggle = this.props.onVolumeToggle;\n        if (this.props.onFullscreenToggle !== void 0)\n          config.onFullscreenToggle = this.props.onFullscreenToggle;\n        if (this.props.onControlClick !== void 0)\n          config.onControlClick = this.props.onControlClick;\n        if (this.props.licenseKey !== void 0)\n          config.licenseKey = this.props.licenseKey;\n        if (this.props.adFailsafeTimeoutMs !== void 0)\n          config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n        if (this.props.minSegmentsBeforePlay !== void 0)\n          config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n        if (this.props.ctvAdRequest !== void 0)\n          config.ctvAdRequest = this.props.ctvAdRequest;\n        this.player = new StormcloudVideoPlayer(config);\n        this.props.onMount?.(this);\n        await this.player.load();\n        if (this.mounted) {\n          this.props.onReady?.();\n        }\n      } catch (error) {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      }\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[HlsPlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n          this.props.onPlay?.();\n        } else {\n          console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n        this.props.onPause?.();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"player\") return this.player;\n      if (key === \"video\") return this.props.videoElement;\n      if (key === \"hls\" && this.player) return this.player.hls;\n      return null;\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nHlsPlayer.displayName = \"HlsPlayer\";\nHlsPlayer.canPlay = canPlay.hls;\n\n// src/players/FilePlayer.tsx\nvar import_react3 = require(\"react\");\nvar FilePlayer = class extends import_react3.Component {\n  constructor() {\n    super(...arguments);\n    this.mounted = false;\n    this.ready = false;\n    this.load = () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      const video = this.props.videoElement;\n      const handleLoadedMetadata = () => {\n        if (this.mounted && !this.ready) {\n          this.ready = true;\n          this.props.onReady?.();\n        }\n      };\n      const handlePlay = () => {\n        if (this.mounted) {\n          this.props.onPlay?.();\n        }\n      };\n      const handlePause = () => {\n        if (this.mounted) {\n          this.props.onPause?.();\n        }\n      };\n      const handleEnded = () => {\n        if (this.mounted) {\n          this.props.onEnded?.();\n        }\n      };\n      const handleError = (error) => {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      };\n      const handleLoadedData = () => {\n        if (this.mounted) {\n          this.props.onLoaded?.();\n        }\n      };\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"play\", handlePlay);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      video.addEventListener(\"error\", handleError);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.src = this.props.src;\n      if (this.props.autoplay !== void 0) video.autoplay = this.props.autoplay;\n      if (this.props.muted !== void 0) video.muted = this.props.muted;\n      if (this.props.loop !== void 0) video.loop = this.props.loop;\n      if (this.props.controls !== void 0) video.controls = this.props.controls;\n      if (this.props.playsInline !== void 0)\n        video.playsInline = this.props.playsInline;\n      if (this.props.preload !== void 0)\n        video.preload = this.props.preload;\n      if (this.props.poster !== void 0) video.poster = this.props.poster;\n      this.props.onMount?.(this);\n      return () => {\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"play\", handlePlay);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n        video.removeEventListener(\"error\", handleError);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n      };\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[FilePlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n        } else {\n          console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.setLoop = (loop) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.loop = loop;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"video\") return this.props.videoElement;\n      return null;\n    };\n    this.enablePIP = async () => {\n      if (this.props.videoElement && \"requestPictureInPicture\" in this.props.videoElement) {\n        try {\n          await this.props.videoElement.requestPictureInPicture();\n        } catch (error) {\n          console.warn(\"Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n    this.disablePIP = async () => {\n      if (document.pictureInPictureElement) {\n        try {\n          await document.exitPictureInPicture();\n        } catch (error) {\n          console.warn(\"Exit Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nFilePlayer.displayName = \"FilePlayer\";\nFilePlayer.canPlay = canPlay.file;\n\n// src/players/index.ts\nvar players = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer }))\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url) => {\n      return canPlay.file(url) && (document.pictureInPictureEnabled || typeof document.webkitSupportsPresentationMode === \"function\");\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer }))\n  }\n];\nvar players_default = players;\n","import { lazy } from \"../utils\";\nimport { canPlay } from \"../patterns\";\nimport HlsPlayer from \"./HlsPlayer\";\nimport FilePlayer from \"./FilePlayer\";\n\nexport interface PlayerConfig {\n  key: string;\n  name: string;\n  canPlay: (url: string) => boolean;\n  canEnablePIP?: (url: string) => boolean;\n  lazyPlayer?: any;\n}\n\nconst players: PlayerConfig[] = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer })),\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url: string) => {\n      return (\n        canPlay.file(url) &&\n        (document.pictureInPictureEnabled ||\n          typeof (document as any).webkitSupportsPresentationMode ===\n            \"function\")\n      );\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer })),\n  },\n];\n\nexport default players;\n","import { lazy as reactLazy } from \"react\";\n\nexport const lazy = reactLazy;\n\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n  object: T,\n  keys: K[]\n): Omit<T, K> => {\n  const result = { ...object };\n  keys.forEach((key) => {\n    delete result[key];\n  });\n  return result;\n};\n\nexport const isMediaStream = (url: any): url is MediaStream => {\n  return (\n    typeof window !== \"undefined\" &&\n    window.MediaStream &&\n    url instanceof window.MediaStream\n  );\n};\n\nexport const supportsWebKitPresentationMode = (): boolean => {\n  if (typeof window === \"undefined\") return false;\n  const video = document.createElement(\"video\");\n  return \"webkitSupportsPresentationMode\" in video;\n};\n\nexport const randomString = (): string => {\n  return Math.random().toString(36).substr(2, 9);\n};\n\nexport const parseQuery = (url: string): Record<string, string> => {\n  const query: Record<string, string> = {};\n  const queryString = url.split(\"?\")[1] || \"\";\n\n  if (!queryString) return query;\n\n  const manualParse = (qs: string) => {\n    qs.split(\"&\").forEach((param) => {\n      const [key, value] = param.split(\"=\");\n      if (key) {\n        try {\n          query[decodeURIComponent(key)] = value\n            ? decodeURIComponent(value.replace(/\\+/g, \" \"))\n            : \"\";\n        } catch (e) {\n          query[key] = value || \"\";\n        }\n      }\n    });\n  };\n\n  if (typeof URLSearchParams !== \"undefined\") {\n    try {\n      const params = new URLSearchParams(queryString);\n      params.forEach((value, key) => {\n        query[key] = value;\n      });\n      return query;\n    } catch (e) {\n      manualParse(queryString);\n    }\n  } else {\n    manualParse(queryString);\n  }\n\n  return query;\n};\n\nexport const merge = <T extends Record<string, any>>(\n  target: T,\n  ...sources: Partial<T>[]\n): T => {\n  if (!sources.length) return target;\n  const source = sources.shift();\n\n  if (isObject(target) && isObject(source)) {\n    for (const key in source) {\n      if (isObject(source[key])) {\n        if (!target[key]) Object.assign(target, { [key]: {} });\n        merge(target[key] as any, source[key] as any);\n      } else {\n        Object.assign(target, { [key]: source[key] });\n      }\n    }\n  }\n\n  return merge(target, ...sources);\n};\n\nconst isObject = (item: any): item is Record<string, any> => {\n  return item && typeof item === \"object\" && !Array.isArray(item);\n};\n\nexport const IS_BROWSER = typeof window !== \"undefined\" && window.document;\nexport const IS_GLOBAL =\n  typeof globalThis !== \"undefined\" &&\n  globalThis.window &&\n  globalThis.window.document;\nexport const IS_IOS =\n  IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nexport const IS_SAFARI =\n  IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\nexport const SUPPORTS_HLS = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/vnd.apple.mpegurl\"));\n};\n\nexport const SUPPORTS_DASH = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/dash+xml\"));\n};\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n  hls: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n\n  dash: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n\n  video: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n\n  audio: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n\n  file: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  },\n};\n","import { Component } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport { canPlay } from \"../patterns\";\n\nexport interface HlsPlayerProps extends StormcloudVideoPlayerConfig {\n  onMount?: (player: any) => void;\n  onReady?: () => void;\n  onPlay?: () => void;\n  onPause?: () => void;\n  onEnded?: () => void;\n  onLoaded?: () => void;\n  onError?: (error: any) => void;\n}\n\nexport default class HlsPlayer extends Component<HlsPlayerProps> {\n  static displayName = \"HlsPlayer\";\n\n  static canPlay = canPlay.hls;\n\n  private player: StormcloudVideoPlayer | null = null;\n  private mounted = false;\n\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n\n  componentDidUpdate(prevProps: HlsPlayerProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n\n  load = async () => {\n    if (!this.props.videoElement || !this.props.src) return;\n\n    try {\n      if (this.player) {\n        this.player.destroy();\n        this.player = null;\n      }\n\n      const config: StormcloudVideoPlayerConfig = {\n        src: this.props.src,\n        videoElement: this.props.videoElement,\n      };\n\n      if (this.props.autoplay !== undefined)\n        config.autoplay = this.props.autoplay;\n      if (this.props.muted !== undefined) config.muted = this.props.muted;\n      if (this.props.lowLatencyMode !== undefined)\n        config.lowLatencyMode = this.props.lowLatencyMode;\n      if (this.props.allowNativeHls !== undefined)\n        config.allowNativeHls = this.props.allowNativeHls;\n      if (this.props.isLiveStream !== undefined)\n        config.isLiveStream = this.props.isLiveStream;\n      if (this.props.driftToleranceMs !== undefined)\n        config.driftToleranceMs = this.props.driftToleranceMs;\n      if (this.props.immediateManifestAds !== undefined)\n        config.immediateManifestAds = this.props.immediateManifestAds;\n      if (this.props.debugAdTiming !== undefined)\n        config.debugAdTiming = this.props.debugAdTiming;\n      if (this.props.showCustomControls !== undefined)\n        config.showCustomControls = this.props.showCustomControls;\n      if (this.props.onVolumeToggle !== undefined)\n        config.onVolumeToggle = this.props.onVolumeToggle;\n      if (this.props.onFullscreenToggle !== undefined)\n        config.onFullscreenToggle = this.props.onFullscreenToggle;\n      if (this.props.onControlClick !== undefined)\n        config.onControlClick = this.props.onControlClick;\n      if (this.props.licenseKey !== undefined)\n        config.licenseKey = this.props.licenseKey;\n      if (this.props.adFailsafeTimeoutMs !== undefined)\n        config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n      if (this.props.minSegmentsBeforePlay !== undefined)\n        config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n      if (this.props.ctvAdRequest !== undefined)\n        config.ctvAdRequest = this.props.ctvAdRequest;\n\n      this.player = new StormcloudVideoPlayer(config);\n\n      this.props.onMount?.(this);\n\n      await this.player.load();\n\n      if (this.mounted) {\n        this.props.onReady?.();\n      }\n    } catch (error) {\n      if (this.mounted) {\n        this.props.onError?.(error);\n      }\n    }\n  };\n\n  play = () => {\n    if (this.props.videoElement) {\n      const video = this.props.videoElement;\n      const hasValidSource =\n        video.src ||\n        (video.currentSrc && video.currentSrc !== \"\") ||\n        video.readyState >= 1;\n\n      if (hasValidSource) {\n        video.play()?.catch((error) => {\n          console.error(\"[HlsPlayer] Failed to play:\", error);\n          this.props.onError?.(error);\n        });\n        this.props.onPlay?.();\n      } else {\n        console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n      }\n    }\n  };\n\n  pause = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.pause();\n      this.props.onPause?.();\n    }\n  };\n\n  stop = () => {\n    this.pause();\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = 0;\n    }\n  };\n\n  seekTo = (seconds: number, keepPlaying?: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = seconds;\n      if (!keepPlaying) {\n        this.pause();\n      }\n    }\n  };\n\n  setVolume = (volume: number) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n    }\n  };\n\n  mute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = true;\n    }\n  };\n\n  unmute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = false;\n    }\n  };\n\n  setPlaybackRate = (rate: number) => {\n    if (this.props.videoElement && rate > 0) {\n      this.props.videoElement.playbackRate = rate;\n    }\n  };\n\n  getDuration = (): number | null => {\n    if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n      return this.props.videoElement.duration;\n    }\n    return null;\n  };\n\n  getCurrentTime = (): number | null => {\n    if (\n      this.props.videoElement &&\n      isFinite(this.props.videoElement.currentTime)\n    ) {\n      return this.props.videoElement.currentTime;\n    }\n    return null;\n  };\n\n  getSecondsLoaded = (): number | null => {\n    if (\n      this.props.videoElement &&\n      this.props.videoElement.buffered.length > 0\n    ) {\n      return this.props.videoElement.buffered.end(\n        this.props.videoElement.buffered.length - 1\n      );\n    }\n    return null;\n  };\n\n  getInternalPlayer = (key = \"player\") => {\n    if (key === \"player\") return this.player;\n    if (key === \"video\") return this.props.videoElement;\n    if (key === \"hls\" && this.player) return (this.player as any).hls;\n    return null;\n  };\n\n  render() {\n    return null;\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 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(xmlDoc: Document): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    xmlDoc.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    xmlDoc.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  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  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      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      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 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 ad: VastAd | null | undefined;\n\n        if (preloadedAds.has(vastTagUrl)) {\n          ad = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ad = await fetchAndParseVastAd(vastTagUrl);\n        }\n\n        if (!ad) {\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        currentAd = ad;\n        console.log(\n          `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n        );\n\n        fireTrackingPixels(ad.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\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        trackingFired = {\n          impression: trackingFired.impression,\n          start: false,\n          firstQuartile: false,\n          midpoint: false,\n          thirdQuartile: false,\n          complete: false,\n        };\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        const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n        if (!mediaFile) {\n          throw new Error(\"No media file available for ad\");\n        }\n\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n\n        emit(\"content_pause\");\n\n        const isHlsAd = isHlsMediaFile(mediaFile);\n        console.log(\n          `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad 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 (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        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    },\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      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  };\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","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 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","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 = readStoredString(storageKey);\n  if (existing) {\n    return existing;\n  }\n\n  const id = createUuid();\n  try {\n    window.localStorage?.setItem(storageKey, id);\n  } catch {}\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readStoredString(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  try {\n    window.localStorage?.setItem(CTV_SESSION_STORAGE_KEY, sessionId);\n  } catch {}\n  return sessionId;\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (char) => {\n    const value = Math.floor(Math.random() * 16);\n    const nibble = char === \"x\" ? value : (value & 0x3) | 0x8;\n    return nibble.toString(16);\n  });\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} from \"../types\";\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 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  const playerId = await getBrowserID(clientInfo);\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  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  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 { sendHeartbeat, sendInitialTracking } 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  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: generateCorrelator(),\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  // --- Tracking ---\n\n  initializeTracking(): void {\n    sendInitialTracking(this.config.licenseKey)\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).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  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  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}\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  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\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      ).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      ).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    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      ).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        ).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  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      ).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      ).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"]}