{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/player/StormcloudVideoPlayer.cjs","../../src/player/StormcloudVideoPlayer.ts","../../src/sdk/hlsAdPlayer.ts","../../src/utils/devUrl.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/PlaceholderLayer.ts","../../src/player/HlsEngine.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayer","module","exports","import_hls","require","MAX_VAST_WRAPPER_DEPTH","createHlsAdPlayer","contentVideo","options","originalMutedState","adPlaying","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","podAds","podIndex","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","STALL_TIMEOUT_MS","STALL_CHECK_INTERVAL_MS","stallWatchdogId","lastAdProgressTime","lastAdProgressPosition","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","urls","length","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","currentLevel","levels","autoLevel","loadLevel","level","height","bitrate","width","resolutionDiff","widthDiff","heightDiff","fileBitrate","bitrateDiff","bestMatch","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","abs","score","a","b","isHlsMediaFile","mediaFile","type","toLowerCase","url","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","scope","trackingUrls","querySelectorAll","forEach","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","parseAdElement","fetchVastXml","vastTagUrl","credentials","requestVast","response","creds","fetch","mode","headers","referrerPolicy","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","substring","adElements","ads","resolved","sort","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","video","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","noteAdProgress","progress","currentTime","trackingFired","fireTrackingPixels","startStallWatchdog","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","ERROR","_event","data","fatal","canPlayType","load","play","catch","total","clearInterval","handleAdStall","clearStallWatchdog","window","setInterval","paused","releaseAdDecoder","removeAttribute","remove","display","pointerEvents","continueLiveStreamDuringAds","visibility","opacity","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","preloaded","Promise","reject","has","delete","fetchAndParsePod","resolve","contentVolume","stop","previousMutedState","timeoutId","clearTimeout","removeChild","clear","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","getPodAdCount","getPodTotalDurationMs","reduce","PRIVATE_HOST_PATTERNS","isLocalDevHost","host","hostname","replace","some","pattern","test","toDevSafeUrl","rawUrl","URL","protocol","cleanPath","pathname","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","playerVolume","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","JSON","stringify","loadNonceManager","getNonce","getCurrentNonce","injectNonce","searchParams","base","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdTouch","reconnectPeriod","sendAdClick","reset","DEFAULT_MQTT_CONFIG","enabled","brokerAddress","brokerPort","wsPort","username","password","topicPrefix","qos","mqttConfig","applyMQTTConfig","overrides","assign","isMQTTEnabled","buildMQTTBrokerUrl","brokerUrl","buildPlayerTopic","channel","import_mqtt","LOG","KEEPALIVE_SECONDS","CONNECT_TIMEOUT_MS","RECONNECT_BASE_MS","RECONNECT_MAX_MS","MAX_RECONNECT_ATTEMPTS","COOLDOWN_MS","client","status","reconnectAttempts","reconnectTimer","stopped","clearReconnectTimer","teardownClient","removeAllListeners","end","scheduleReconnect","openConnection","delay","jitter","floor","clientId","slice","mqtt","connect","keepalive","clean","connectTimeout","queueQoSZero","reschedulePings","timerVariant","err","info","initMQTTClient","ensureMQTTClient","publish","message","connected","topic","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","navigator","userAgent","getDefaultAppId","ua","DEVICE_ID_STORAGE_KEYS","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","platformLat","isCtv","bridgeSignals","readNativeBridgeSignals","platformDevice","readPlatformNativeDeviceId","lg","deviceId","readStoredDeviceId","limitAdTracking","deviceIdType","readStoredString","inferDeviceIdType","readStoredLimitAdTracking","appId","appName","deviceTypeHint","resolveNativeDeviceId","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","readPersistentId","storageKey","writePersistentId","readCookie","localStorage","setItem","writeCookie","PERSISTENT_ID_COOKIE_MAX_AGE","prefix","parts","cookie","part","entry","decodeURIComponent","bytes","crypto","randomUUID","getOrCreateCtvSessionId","getRandomValues","seed","performanceNow","i","hex","padStart","performance","adinfo","webapis","tifa","isMacroPlaceholder","lat","isLATEnabled","webOSDev","lgudid","LGUDID","isZeroedAdId","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","t","candidates","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","AiryTV","Android","webOS","tizen","amazon","filter","Boolean","contentUrl","readBridgeValue","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","cachedBrowserId","buildAnalyticsContext","config","context","debugAdTiming","isLiveStream","inputStreamType","getClientInfo","screen","platform","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","webosMatch","match","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","domain","origin","path","language","languages","join","cookieEnabled","doNotTrack","referrer","visibilityState","sha256Hex","input","encodedData","utf8","buffer","hashBuffer","hash","char","fallbackHash","timestamp","subtle","digest","Uint8Array","TextEncoder","encode","unescape","charCodeAt","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","getOrCreateStoredUuid","getBrowserID","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","publishMQTT","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","param","append","query","cleanQuery","decodedKey","safeDecodeURIComponent","decodedValue","str","values","String","getAll","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","then","reason","polyfillObjectAssign","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","INLINE_DEVICE_MACRO_REPLACEMENTS","ctx","getValue","CTV_UNSUPPORTED_PARAMS","correlator","trimmed","generateCorrelator","buf","Uint32Array","expandInlineMacroPlaceholders","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","normalizeVastTagUrl","raw","anValue","orphanFragments","reconstructed","_match","val","applyVastMacros","expandedUrl","replaceCorrelatorFallback","streamCorrelator","pod","podMinDurationMs","round","podMaxDurationMs","podMaxAds","requestUrl","pageUrl","existingUrl","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","tasks","uspApi","signals","correlatorRegex","fetchConsentSignals","timeoutMs","tcfApi","__tcfapi","settled","tcData","success","eventStatus","gdprApplies","tcString","listenerId","__uspapi","uspString","getWebKitVersion","getPlatform","userAgentData","version","supportsModernJS","detectBrowser","majorVersion","isLegacyTV","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","getChromeVersion","getBrowserConfigOverrides","browser","allowNativeHls","pauseContentDuringAds","logBrowserInfo","debug","parseCueOutDuration","num","parseFloat","dStr","d","parseCueOutCont","res","elapsedMatch","durationMatch","elapsed","slashMatch","parseAttributeList","attrs","regex","exec","rawVal","toNumber","n","isManifestBasedMarker","marker","id3","splice_command_type","decodeId3ValueToText","decoder","TextDecoder","decode","out","fromCharCode","getFragmentStartSeconds","frag","startPTS","candidate","parseScte35FromId3","cueOutMatch","arg","dur","ptsSeconds","durationSeconds","cueOutContMatch","cont","cueInMatch","daterangeMatch","hasScteOut","hasScteIn","klass","bin","parseScte35Binary","normalizeFragmentPayload","ArrayBuffer","isView","view","byteOffset","byteLength","detectTsPacketFormat","packetSizes","packetSize","tsPayloadOffset","offset","matchedPackets","packetStart","getPsiSectionStart","payloadUnitStart","pointerField","sectionStart","getPsiSectionLength","parsePatSection","pmtPids","sectionLength","sectionEnd","programNumber","pid","descriptorsIdentifyScte35","descriptorStart","descriptorEnd","registration","parsePmtSection","tsScte35Pids","programInfoLength","streamType","elementaryPid","esInfoLength","hasProcessedTsScte35Section","section","processedSections","checksum","size","firstKey","next","addScte35SectionMarker","markers","appendScte35Bytes","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","bits","mask","skipBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","descriptorDataEnd","parseScte35SegmentationDescriptors","descriptorLoopLength","descriptorOffset","descriptorTag","descriptorDataStart","descriptorLength","descriptorMarker","spliceCommandLength","cancel","ptsAdjHigh","ptsAdjLow","spliceCommandType","spliceEventId","outOfNetwork","spliceImmediateFlag","programSpliceFlag","componentPtsSeconds","durationFlag","expectedDescriptorOffset","commandBodyStart","callbacks","splice_event_id","segmentation_event_id","Scte35CueManager","pendingScte35Cues","recentScte35CueKeys","recentScte35CueLimit","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","scheduledScte35BreakKeyValue","createScte35CueContext","readiness","sn","fragmentSn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","onEarlyStartCue","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","onPlaybackCue","activatePendingScte35CuesForFragment","matchingCues","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","isStrongScte35CueKey","hasRecentlyHandledScte35Cue","recentKey","markScte35CueHandled","AdConfigManager","vmapBreaks","consumedVmapBreakIds","viewCorrelator","consentSignals","podCounter","podAssignedByPrefetch","lastHeartbeatTime","defaultPodMaxAds","defaultPodMaxDurationMs","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","json","applyMqttConfigFromResponse","ima","vast","cue_tones","number_ads","apiNumberAds","mqtt_config","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","aStart","bStart","timeOffset","hms","hh","mm","ss","ms","hours","minutes","seconds","millis","percent","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","resolvePodParams","breakDurationMs","maxDurationMs","maxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","adPlayer","palNonce","envSignals","ctvAdRequest","urlWithMacros","sendHeartbeatIfNeeded","autoplay","finalUrl","initializeTracking","heartbeatInterval","destroyTracking","AdTimingService","adRequestWatchdogToken","adBreakEpoch","consecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","defaultMinRemainingMsToStartAd","adFailsafeToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","totalAdsInBreak","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","maxConsecutiveFailures","maxBackoffMs","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalNoFillBackoffMaxMs","globalLastGamRequestTime","globalMinGamIntervalMs","scheduleAdStartIn","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ensureAdStoppedByTimer","adStopTimerId","onAdStopTimerFired","delayMs","clearAdStartTimer","onAdStartTimerFired","cueKey","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","getDurationBudgetRemainingMs","expectedAdBreakDurationMs","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getLoadedAdDurationMs","adController","adFitsRemainingBudget","recordPlayedAdDuration","rejectLoadedAdForDuration","logAdDurationDecision","accepted","remainingBudget","ensureLoadedAdFitsBudget","fits","markAdStarted","notePodAdStarted","getRemainingAdMs","wallClockRemaining","budgetRemaining","getMinRemainingMsToStartAd","configured","minRemainingMsToStartAd","hasTimeToStartAnotherAd","minRemaining","isTemporaryAdError","isUrlInCooldown","failureTime","cleanupTemporaryFailures","isGamInCooldown","recordGamNoFill","globalNoFillThreshold","exponent","backoff","pow","resetGamNoFillCounter","enforceGlobalRateLimit","waitMs","startAdRequestWatchdog","token","clearAdRequestWatchdog","adFailsafeTimeoutMs","adRequestWatchdogId","logAdState","onWatchdogTimeout","startAdFailsafeTimer","clearAdFailsafeTimer","failsafeMs","adFailsafeTimerId","videoPaused","onFailsafeTimeout","showAds","extra","resetForBreakEnd","PlaceholderLayer","ensureContainer","transition","show","offsetHeight","wasHidden","requestAnimationFrame","hide","HlsEngine","cueManager","timing","nativeHlsMode","videoSrcProtection","reloadingLiveStream","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","canNative","setupNativeHls","adBehavior","isLive","setupHls","hls","import_hls2","backBufferLength","liveDurationInfinity","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","hasPendingAdBreak","LEVEL_LOADED","_evt","fragments","fragmentsToScan","tagList","isArray","idx","earlyDetection","FRAG_BUFFERED","FRAG_PARSING_METADATA","id3Tags","samples","pts","onId3Tag","FRAG_LOADED","processFragmentScte35Payload","FRAG_DECRYPTED","FRAG_CHANGED","activatePendingCuesForFragment","prog","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","onFatalDestroy","payloadData","processedTsScte35Sections","getLiveSyncPosition","liveSyncPosition","restartLoadAt","stopLoad"],"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/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n  StormcloudVideoPlayer: () => StormcloudVideoPlayer\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(contentVideo, options) {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = /* @__PURE__ */ new Map();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n  let adVideoElement;\n  let adHls;\n  let adContainerEl;\n  let currentAd;\n  let podAds = [];\n  let podIndex = 0;\n  let sessionId;\n  const preloadedAds = /* @__PURE__ */ new Map();\n  const preloadingAds = /* @__PURE__ */ new Map();\n  let destroyed = false;\n  let pendingTimeouts = [];\n  const STALL_TIMEOUT_MS = 4e3;\n  const STALL_CHECK_INTERVAL_MS = 1e3;\n  let stallWatchdogId;\n  let lastAdProgressTime = 0;\n  let lastAdProgressPosition = 0;\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false\n  };\n  function emit(event, payload) {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n  function generateSessionId() {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n  function fireTrackingPixels(urls) {\n    if (!urls || urls.length === 0) return;\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n        }\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n        }\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n  function getMainStreamQuality() {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level2 = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level2.width || 1920,\n          height: level2.height || 1080,\n          bitrate: level2.bitrate || 5e6\n        };\n      }\n      return null;\n    }\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5e6\n    };\n  }\n  function selectBestMediaFile(mediaFiles) {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n      const fileBitrate = (file.bitrate || 5e3) * 1e3;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n      const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n    scoredFiles.sort((a, b) => a.score - b.score);\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff\n    });\n    return bestMatch.file;\n  }\n  function isHlsMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n  }\n  function isProgressiveMediaFile(mediaFile) {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n  }\n  function createEmptyTrackingUrls() {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: []\n    };\n  }\n  function extractTrackingUrls(scope) {\n    const trackingUrls = createEmptyTrackingUrls();\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n    return trackingUrls;\n  }\n  function mergeTrackingUrls(target, source) {\n    Object.keys(target).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n  function parseVastXml(xmlString) {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: void 0\n        };\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  function parseAdElement(adElement) {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n      const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n      const wrapperUri = adElement.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        };\n      }\n      const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n      const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseInt(durationParts[2] || \"0\", 10);\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles = [];\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n        if (!url) return;\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n        const mediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n        };\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough\n        }\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n  async function fetchVastXml(vastTagUrl, credentials = \"include\") {\n    const requestVast = (creds) => fetch(vastTagUrl, {\n      mode: \"cors\",\n      credentials: creds,\n      headers: {\n        \"Accept\": \"application/xml, text/xml, */*\"\n      },\n      referrerPolicy: \"no-referrer-when-downgrade\"\n    });\n    let response;\n    try {\n      response = await requestVast(credentials);\n    } catch (error) {\n      if (credentials !== \"omit\") {\n        console.warn(\n          `[HlsAdPlayer] VAST fetch failed with credentials=\"${credentials}\", retrying without credentials:`,\n          error\n        );\n        response = await requestVast(\"omit\");\n      } else {\n        throw error;\n      }\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(\n      vastTagUrl,\n      depth === 0 ? \"include\" : \"omit\"\n    );\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2e3)\n    );\n    const parsed = parseVastXml(vastXml);\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n  async function fetchAndParsePod(vastTagUrl) {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n    const ads = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n  function createAdVideoElement() {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n    video.volume = 1;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n    return video;\n  }\n  function setupAdEventListeners() {\n    if (!adVideoElement || !currentAd) return;\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n      noteAdProgress();\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      startStallWatchdog();\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdComplete();\n    });\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n      handleAdError();\n    });\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n  function setAdPlayingFlag(isPlaying) {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n  function resetQuartileTracking(preserveImpression) {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false\n    };\n  }\n  function loadCurrentAdMedia() {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n    if (isHlsAd && import_hls.default.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n      adHls = new import_hls.default({\n        enableWorker: true,\n        lowLatencyMode: false\n      });\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n      adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n      adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (isHlsAd && adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = void 0;\n      }\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n  function advanceToNextPodAd() {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n  function clearStallWatchdog() {\n    if (stallWatchdogId != null) {\n      clearInterval(stallWatchdogId);\n      stallWatchdogId = void 0;\n    }\n  }\n  function noteAdProgress() {\n    lastAdProgressTime = Date.now();\n    if (adVideoElement) {\n      lastAdProgressPosition = adVideoElement.currentTime;\n    }\n  }\n  function handleAdStall() {\n    console.warn(\n      \"[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame\"\n    );\n    clearStallWatchdog();\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.error);\n    }\n    if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n      return;\n    }\n    handleAdError();\n  }\n  function startStallWatchdog() {\n    clearStallWatchdog();\n    noteAdProgress();\n    stallWatchdogId = window.setInterval(() => {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {\n        noteAdProgress();\n        return;\n      }\n      if (adVideoElement.paused) {\n        noteAdProgress();\n        return;\n      }\n      if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {\n        handleAdStall();\n      }\n    }, STALL_CHECK_INTERVAL_MS);\n  }\n  function releaseAdDecoder() {\n    if (adHls) {\n      adHls.destroy();\n      adHls = void 0;\n    }\n    if (adVideoElement) {\n      adVideoElement.pause();\n      adVideoElement.removeAttribute(\"src\");\n      try {\n        adVideoElement.load();\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] adVideoElement.load() threw after src removal:\", error);\n      }\n      adVideoElement.remove();\n      adVideoElement = void 0;\n    }\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n  }\n  function handleAdComplete() {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    clearStallWatchdog();\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    releaseAdDecoder();\n    if (!options?.continueLiveStreamDuringAds) {\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\");\n        contentVideo.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error resuming content playback in live mode:\", error);\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    clearStallWatchdog();\n    adPlaying = false;\n    setAdPlayingFlag(false);\n    contentVideo.muted = true;\n    releaseAdDecoder();\n    if (!options?.continueLiveStreamDuringAds) {\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n    }\n    emit(\"ad_error\");\n  }\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n    async requestAds(vastTagUrl) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n      try {\n        sessionId = generateSessionId();\n        let ads = [];\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n        resetQuartileTracking(true);\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n        emit(\"content_pause\");\n        loadCurrentAdMedia();\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {\n          });\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      clearStallWatchdog();\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      releaseAdDecoder();\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((error) => {\n            console.error(\"[HlsAdPlayer] Error resuming content playback in live mode on stop:\", error);\n          });\n        }\n      }\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n    },\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      clearStallWatchdog();\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      releaseAdDecoder();\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n      adContainerEl = void 0;\n      currentAd = void 0;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n    isAdPlaying() {\n      return adPlaying;\n    },\n    resize(width, height) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n    on(event, listener) {\n      if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n      listeners.get(event).add(listener);\n    },\n    off(event, listener) {\n      listeners.get(event)?.delete(listener);\n    },\n    updateOriginalMutedState(muted, volume) {\n      const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n    setAdVolume(volume) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n    getAdVolume() {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1e3 : 0),\n        0\n      );\n    }\n  };\n}\n\n// src/utils/devUrl.ts\nvar PRIVATE_HOST_PATTERNS = [\n  /^localhost$/i,\n  /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^0\\.0\\.0\\.0$/,\n  /^::1$/,\n  /^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^172\\.(1[6-9]|2\\d|3[0-1])\\.\\d{1,3}\\.\\d{1,3}$/\n];\nfunction isLocalDevHost(hostname) {\n  const host = hostname.replace(/^\\[/, \"\").replace(/\\]$/, \"\").toLowerCase();\n  if (!host) return false;\n  if (host.endsWith(\".local\") || host.endsWith(\".localhost\")) return true;\n  return PRIVATE_HOST_PATTERNS.some((pattern) => pattern.test(host));\n}\nfunction toDevSafeUrl(rawUrl) {\n  if (!rawUrl) return rawUrl ?? \"\";\n  let url;\n  try {\n    url = new URL(rawUrl);\n  } catch {\n    return rawUrl;\n  }\n  if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n    return rawUrl;\n  }\n  if (!isLocalDevHost(url.hostname)) {\n    return rawUrl;\n  }\n  const cleanPath = url.pathname.replace(/\\/{2,}/g, \"/\") || \"/index.html\";\n  return `file://${cleanPath}`;\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 = toDevSafeUrl(\n          options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n        );\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url = toDevSafeUrl(\n          options.descriptionUrl || (typeof window !== \"undefined\" ? window.location.href : \"\")\n        );\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        console.log(\n          \"[PAL] NonceRequest before generateNonce:\",\n          JSON.stringify({\n            adWillAutoPlay: request.adWillAutoPlay,\n            adWillPlayMuted: request.adWillPlayMuted,\n            playerVolume: request.playerVolume,\n            continuousPlayback: request.continuousPlayback,\n            descriptionUrl: request.descriptionUrl,\n            iconsSupported: request.iconsSupported,\n            playerType: request.playerType,\n            playerVersion: request.playerVersion,\n            supportedApiFrameworks: request.supportedApiFrameworks,\n            url: request.url,\n            videoWidth: request.videoWidth,\n            videoHeight: request.videoHeight,\n            ppid: request.ppid,\n            sessionId: request.sessionId\n          }, null, 2)\n        );\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 applyMQTTConfig(overrides) {\n  Object.assign(mqttConfig, overrides);\n}\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 KEEPALIVE_SECONDS = 30;\nvar CONNECT_TIMEOUT_MS = 1e4;\nvar RECONNECT_BASE_MS = 5e3;\nvar RECONNECT_MAX_MS = 6e4;\nvar MAX_RECONNECT_ATTEMPTS = 8;\nvar COOLDOWN_MS = 10 * 6e4;\nvar client = null;\nvar status = \"disconnected\";\nvar reconnectAttempts = 0;\nvar reconnectTimer = null;\nvar stopped = false;\nfunction clearReconnectTimer() {\n  if (reconnectTimer) {\n    clearTimeout(reconnectTimer);\n    reconnectTimer = null;\n  }\n}\nfunction teardownClient() {\n  if (client) {\n    try {\n      client.removeAllListeners();\n      client.end(true);\n    } catch {\n    }\n    client = null;\n  }\n}\nfunction scheduleReconnect() {\n  if (stopped || !isMQTTEnabled() || reconnectTimer) return;\n  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {\n    console.warn(\n      `${LOG} giving up after ${reconnectAttempts} attempts; cooling down for ${COOLDOWN_MS / 6e4}m`\n    );\n    teardownClient();\n    status = \"disconnected\";\n    reconnectTimer = setTimeout(() => {\n      reconnectTimer = null;\n      reconnectAttempts = 0;\n      openConnection();\n    }, COOLDOWN_MS);\n    return;\n  }\n  const delay = Math.min(\n    RECONNECT_MAX_MS,\n    RECONNECT_BASE_MS * 2 ** reconnectAttempts\n  );\n  const jitter = Math.floor(Math.random() * 1e3);\n  reconnectAttempts += 1;\n  reconnectTimer = setTimeout(() => {\n    reconnectTimer = null;\n    openConnection();\n  }, delay + jitter);\n}\nfunction openConnection() {\n  if (stopped || !isMQTTEnabled()) return;\n  teardownClient();\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: KEEPALIVE_SECONDS,\n      clean: true,\n      // Disable MQTT.js internal reconnect; we manage reconnection ourselves.\n      reconnectPeriod: 0,\n      connectTimeout: CONNECT_TIMEOUT_MS,\n      queueQoSZero: false,\n      reschedulePings: true,\n      // Root-cause fix for the Tizen 4.0 \"Keepalive timeout\" loop: MQTT.js's\n      // default timerVariant \"auto\" runs the keepalive interval inside a\n      // Blob-URL Web Worker (via worker-timers). On Samsung Tizen 4.0 (old\n      // WebKit) served from a file:// origin that worker can't tick reliably,\n      // so the keepalive counter trips onKeepaliveTimeout almost immediately\n      // after connect. Force the native setInterval timer instead; the main\n      // thread is free because video is decoded by the native AVPlay pipeline.\n      timerVariant: \"native\"\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    scheduleReconnect();\n    return;\n  }\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    reconnectAttempts = 0;\n    clearReconnectTimer();\n    console.info(`${LOG} connected to ${url}`);\n  });\n  client.on(\"offline\", () => {\n    if (status === \"connected\") status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n    scheduleReconnect();\n  });\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n    scheduleReconnect();\n  });\n  client.on(\"close\", () => {\n    if (status === \"connected\") status = \"disconnected\";\n    scheduleReconnect();\n  });\n}\nfunction initMQTTClient() {\n  if (client || !isMQTTEnabled()) return;\n  stopped = false;\n  reconnectAttempts = 0;\n  openConnection();\n}\nfunction ensureMQTTClient() {\n  if (isMQTTEnabled() && !client && !reconnectTimer) {\n    initMQTTClient();\n  }\n}\nfunction publishMQTT(topic, payload) {\n  if (!isMQTTEnabled()) {\n    return false;\n  }\n  ensureMQTTClient();\n  if (!client || !client.connected) {\n    return false;\n  }\n  try {\n    client.publish(topic, JSON.stringify(payload), { qos: mqttConfig.qos });\n    return true;\n  } catch (err) {\n    console.warn(`${LOG} publish failed on ${topic}:`, err);\n    return false;\n  }\n}\n\n// src/utils/vastEnvironmentSignals.ts\nvar AIRY_ANDROID_APP_ID = \"com.freeairytv.android\";\nvar AIRY_WEBOS_APP_ID = \"com.freeairytv.webos\";\nvar AIRY_TIZEN_APP_ID = \"com.freeairytv.samsung\";\nvar AIRY_ROKU_APP_ID = \"com.freeairytv.roku\";\nvar AIRY_APP_NAME = \"AiryTV Movies & TV\";\nvar AIRY_DEFAULT_CONTENT_URL = \"https://live.airy.tv\";\nvar CTV_SESSION_STORAGE_KEY = \"stormcloud.ctv.sid\";\nvar PLAYER_ID_STORAGE_KEY = \"stormcloud.player.id\";\nvar LG_TEST_APP_ID = \"com.hulu.plus\";\nvar LG_TEST_APP_NAME = \"Hulu\";\nvar LG_TEST_CONTENT_URL = \"https://www.hulu.com/live-tv\";\nvar _lgTestDeviceId;\nfunction getLgTestDeviceId() {\n  if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();\n  return _lgTestDeviceId;\n}\nfunction isLgWebOS() {\n  if (typeof navigator === \"undefined\") return false;\n  return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);\n}\nfunction getDefaultAppId() {\n  if (typeof navigator === \"undefined\") return AIRY_ANDROID_APP_ID;\n  const ua = navigator.userAgent;\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;\n  if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;\n  if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;\n  return AIRY_ANDROID_APP_ID;\n}\nvar DEVICE_ID_STORAGE_KEYS = [\n  \"rdid\",\n  \"ifa\",\n  \"advertisingId\",\n  \"advertising_id\",\n  \"deviceAdvertisingId\",\n  \"aaid\",\n  \"adid\",\n  \"rida\",\n  \"tifa\",\n  \"lgudid\"\n];\nvar ANDROID_ID_TYPES = /* @__PURE__ */ new Set([\"aaid\", \"adid\"]);\nfunction resolveVastEnvironmentSignals(isCtv) {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const lg = isCtv && isLgWebOS();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);\n  const deviceIdType = bridgeSignals.deviceIdType || readStoredString(\"deviceIdType\") || readStoredString(\"idtype\") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? \"lgudid\" : void 0);\n  const platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;\n  const limitAdTracking = deviceId != null ? platformLat ?? readStoredLimitAdTracking() ?? false : void 0;\n  if (isCtv) {\n    return {\n      isCtv: true,\n      contentUrl: bridgeSignals.contentUrl || readStoredString(\"contentUrl\") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),\n      appId: bridgeSignals.appId || readStoredString(\"appId\") || readStoredString(\"msid\") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),\n      appName: bridgeSignals.appName || readStoredString(\"appName\") || readStoredString(\"an\") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),\n      sessionId: getOrCreateCtvSessionId(),\n      ...deviceId ? { deviceId } : {},\n      ...deviceIdType ? { deviceIdType } : {},\n      ...limitAdTracking != null ? { limitAdTracking } : {},\n      deviceTypeHint: 5\n    };\n  }\n  return {\n    isCtv: false,\n    ...deviceId ? { deviceId } : {},\n    ...deviceIdType ? { deviceIdType } : {},\n    ...limitAdTracking != null ? { limitAdTracking } : {}\n  };\n}\nfunction inferDeviceIdType() {\n  if (typeof navigator === \"undefined\") {\n    return void 0;\n  }\n  const ua = navigator.userAgent;\n  if (/Roku/i.test(ua)) return \"rida\";\n  if (/Tizen|Samsung/i.test(ua)) return \"tifa\";\n  if (/AppleTV|Apple TV/i.test(ua)) return \"tvOS\";\n  if (/AFT|Fire TV|Amazon/i.test(ua)) return \"afai\";\n  if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return \"lgudid\";\n  if (/Android|Google TV/i.test(ua)) return \"aaid\";\n  if (/iPhone|iPad|iPod/i.test(ua)) return \"idfa\";\n  return void 0;\n}\nfunction isEquivalentDeviceIdType(tagType, runtimeType) {\n  if (!tagType || !runtimeType) return false;\n  const tag = tagType.toLowerCase();\n  const runtime = runtimeType.toLowerCase();\n  if (tag === runtime) return true;\n  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);\n}\nfunction resolveNativeDeviceId() {\n  const bridgeSignals = readNativeBridgeSignals();\n  const platformDevice = readPlatformNativeDeviceId();\n  const deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;\n  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {\n    return void 0;\n  }\n  return deviceId;\n}\nfunction getOrCreateStoredUuid(storageKey) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  const existing = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\nfunction getOrCreateCtvSessionId() {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\nfunction readPersistentId(storageKey) {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\nfunction writePersistentId(storageKey, value) {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {\n  }\n  writeCookie(storageKey, value);\n}\nvar PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5;\nfunction readCookie(name) {\n  if (typeof document === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || void 0;\n      }\n    }\n  } catch {\n  }\n  return void 0;\n}\nfunction writeCookie(name, value) {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n  try {\n    document.cookie = encodeURIComponent(name) + \"=\" + encodeURIComponent(value) + \";path=/;max-age=\" + PERSISTENT_ID_COOKIE_MAX_AGE + \";SameSite=Lax\";\n  } catch {\n  }\n}\nfunction createUuid() {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = seed * 1103515245 + 12345 & 2147483647;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 255;\n    }\n  }\n  bytes[6] = (bytes[6] ?? 0) & 15 | 64;\n  bytes[8] = (bytes[8] ?? 0) & 63 | 128;\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n  return hex.slice(0, 8) + \"-\" + hex.slice(8, 12) + \"-\" + hex.slice(12, 16) + \"-\" + hex.slice(16, 20) + \"-\" + hex.slice(20, 32);\n}\nfunction performanceNow() {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {\n  }\n  return 0;\n}\nfunction readPlatformNativeDeviceId() {\n  if (typeof window === \"undefined\") return {};\n  try {\n    const adinfo = window.webapis?.adinfo;\n    if (adinfo) {\n      const tifa = typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat = typeof adinfo.isLATEnabled === \"function\" ? adinfo.isLATEnabled() : void 0;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}\n        };\n      }\n    }\n  } catch {\n  }\n  try {\n    const webOSDev = window.webOSDev;\n    if (webOSDev) {\n      const lgudid = typeof webOSDev.LGUDID === \"function\" ? webOSDev.LGUDID() : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {\n  }\n  try {\n    const roku = window.Roku;\n    if (roku) {\n      const rida = typeof roku.getPublisherUniqueId === \"function\" ? roku.getPublisherUniqueId() : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {\n  }\n  return {};\n}\nvar ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\"\n]);\nfunction isMacroPlaceholder(value) {\n  const t = value.trim();\n  return !t || /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\nfunction isZeroedAdId(value) {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\nfunction readNativeBridgeSignals() {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n  const candidates = [\n    window.__STORMCLOUD_CTV_AD_INFO__,\n    window.__STORMCLOUD_CTV__,\n    window.stormcloudCtv,\n    window.AiryTV,\n    window.Android,\n    window.webOS,\n    window.tizen,\n    window.amazon\n  ].filter(Boolean);\n  for (const source of candidates) {\n    const contentUrl = readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) || void 0;\n    const appId = readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) || void 0;\n    const appName = readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || void 0;\n    const deviceId = readBridgeValue(source, [\n      \"rdid\",\n      \"ifa\",\n      \"advertisingId\",\n      \"adId\",\n      \"deviceId\",\n      \"lgudid\",\n      \"LGUDID\",\n      \"tifa\",\n      \"rida\",\n      \"afai\",\n      \"aaid\"\n    ]) || void 0;\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n    const deviceIdType = readBridgeValue(source, [\n      \"idtype\",\n      \"deviceIdType\",\n      \"advertisingIdType\",\n      \"idType\"\n    ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\"\n    ]);\n    return {\n      ...contentUrl ? { contentUrl } : {},\n      ...appId ? { appId } : {},\n      ...appName ? { appName } : {},\n      ...deviceId ? { deviceId } : {},\n      ...deviceId && deviceIdType ? { deviceIdType } : {},\n      ...deviceId && limitAdTracking != null ? { limitAdTracking } : {}\n    };\n  }\n  return {};\n}\nfunction readBridgeValue(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readBridgeBoolean(source, keys) {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {\n      }\n    }\n  }\n  return void 0;\n}\nfunction readStoredDeviceId() {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return void 0;\n}\nfunction readStoredString(key) {\n  if (typeof window === \"undefined\") {\n    return void 0;\n  }\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || void 0;\n  } catch {\n    return void 0;\n  }\n}\nfunction readStoredLimitAdTracking() {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") || readStoredString(\"limitedAdTracking\") || readStoredString(\"is_lat\")\n  );\n}\nfunction normalizeBoolean(value) {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return void 0;\n}\n\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction buildAnalyticsContext(config) {\n  const context = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== void 0) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\nfunction getClientInfo() {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = navigator.deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: screen?.orientation?.type || \"\",\n    pixelDepth: screen?.pixelDepth\n  };\n  let deviceType = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n    if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n  isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState\n  };\n}\nasync function sha256Hex(input) {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n      let encodedData;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\nfunction resolvePlayerIdentitySeed(clientInfo) {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\nasync function getBrowserID(clientInfo) {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\nfunction canPublish(licenseKey) {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\nasync function buildPlayerMetricEvent(context = {}, flags = {}) {\n  const clientInfo = getClientInfo();\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n  const playerId = await getBrowserID(clientInfo);\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n  const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...context.inputStreamType ? { input_stream_type: context.inputStreamType } : {}\n  };\n}\nfunction publishTracking(licenseKey, channel, body) {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false\n    });\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp\n    });\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp\n        }\n      ]\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n  if (!canPublish(licenseKey)) return;\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n\n// src/utils/polyfills.ts\nfunction polyfillURLSearchParams() {\n  if (typeof URLSearchParams !== \"undefined\") {\n    return;\n  }\n  class URLSearchParamsPolyfill {\n    constructor(init) {\n      this.params = /* @__PURE__ */ new Map();\n      if (typeof init === \"string\") {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n    parseQueryString(query) {\n      const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n      if (!cleanQuery) return;\n      cleanQuery.split(\"&\").forEach((param) => {\n        const [key, value] = param.split(\"=\");\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : \"\";\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n    safeDecodeURIComponent(str) {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, \" \"));\n      } catch (e) {\n        return str;\n      }\n    }\n    append(name, value) {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n    delete(name) {\n      this.params.delete(name);\n    }\n    get(name) {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;\n    }\n    getAll(name) {\n      return this.params.get(name) || [];\n    }\n    has(name) {\n      return this.params.has(name);\n    }\n    set(name, value) {\n      this.params.set(name, [String(value)]);\n    }\n    forEach(callback) {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n    toString() {\n      const parts = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join(\"&\");\n    }\n  }\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\nfunction polyfillTextEncoder() {\n  if (typeof TextEncoder !== \"undefined\") {\n    return;\n  }\n  class TextEncoderPolyfill {\n    constructor() {\n      this.encoding = \"utf-8\";\n    }\n    encode(str) {\n      const utf8 = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 128) {\n          utf8.push(charcode);\n        } else if (charcode < 2048) {\n          utf8.push(192 | charcode >> 6, 128 | charcode & 63);\n        } else if (charcode < 55296 || charcode >= 57344) {\n          utf8.push(\n            224 | charcode >> 12,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        } else {\n          i++;\n          charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);\n          utf8.push(\n            240 | charcode >> 18,\n            128 | charcode >> 12 & 63,\n            128 | charcode >> 6 & 63,\n            128 | charcode & 63\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n  window.TextEncoder = TextEncoderPolyfill;\n}\nfunction polyfillPromiseFinally() {\n  if (typeof Promise !== \"undefined\" && !Promise.prototype.finally) {\n    Promise.prototype.finally = function(callback) {\n      const constructor = this.constructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) => constructor.resolve(callback()).then(() => {\n          throw reason;\n        })\n      );\n    };\n  }\n}\nfunction polyfillObjectAssign() {\n  if (typeof Object.assign !== \"function\") {\n    Object.assign = function(target, ...sources) {\n      if (target == null) {\n        throw new TypeError(\"Cannot convert undefined or null to object\");\n      }\n      const to = Object(target);\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to;\n    };\n  }\n}\nfunction polyfillArrayFrom() {\n  if (!Array.from) {\n    Array.from = function(arrayLike, mapFn, thisArg) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError(\"Array.from requires an array-like object\");\n      }\n      const len = items.length >>> 0;\n      const result = new Array(len);\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n      return result;\n    };\n  }\n}\nfunction polyfillStringStartsWith() {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function(search, pos) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\nfunction polyfillStringEndsWith() {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function(search, length) {\n      if (length === void 0 || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\nfunction polyfillStringIncludes() {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function(search, start) {\n      if (typeof start !== \"number\") {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\nfunction initializePolyfills() {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n// src/utils/vastMacros.ts\nvar UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nvar INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nvar EXAMPLE_COM_URL = /example\\.com/i;\nvar CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\"\n];\nvar INLINE_DEVICE_MACRO_REPLACEMENTS = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) => ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0 },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator }\n];\nfunction isMacroPlaceholder2(value) {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\nfunction generateCorrelator() {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 2097152 + ((buf[1] ?? 0) & 2097151);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\nfunction expandInlineMacroPlaceholders(baseUrl, ctx) {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\nfunction applyDeviceIdentityParams(params, ctx) {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue = ctx.limitAdTracking != null ? ctx.limitAdTracking ? \"1\" : \"0\" : void 0;\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder2(tagLat) ? \"0\" : tagLat));\n    return;\n  }\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));\n  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n  if (tagRdidValid) {\n    if (isMacroPlaceholder2(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder2(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\nfunction removeBrokenAppNameOrphans(params, appName) {\n  const toDelete = [];\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.replace(/^\\s+/, \"\");\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.replace(/\\s+$/, \"\"), ...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  params.delete(\"ppos\");\n  params.delete(\"lip\");\n  if (ctx.podMinDurationMs != null) {\n    params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n  }\n  if (ctx.podMaxDurationMs != null) {\n    params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n  }\n  if (ctx.podMaxAds != null) {\n    params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n  }\n  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    overrides.pauseContentDuringAds = true;\n  }\n  return overrides;\n}\nfunction logBrowserInfo(debug = false) {\n  if (!debug) return;\n  const browser = detectBrowser();\n  console.log(\"[StormcloudVideoPlayer] Browser Compatibility Info:\", {\n    browser: `${browser.name} ${browser.version}`,\n    platform: browser.platform,\n    isSmartTV: browser.isSmartTV,\n    isLegacyTV: browser.isLegacyTV,\n    supportsModernJS: browser.supportsModernJS,\n    ...browser.webOSVersion !== void 0 ? { webOSVersion: browser.webOSVersion } : {},\n    ...browser.tizenVersion !== void 0 ? { tizenVersion: browser.tizenVersion } : {},\n    ...browser.chromeVersion !== void 0 ? { chromeVersion: browser.chromeVersion } : {},\n    userAgent: navigator.userAgent\n  });\n}\n\n// src/player/Scte35Parser.ts\nfunction parseCueOutDuration(value) {\n  const num = parseFloat(value.trim());\n  if (!Number.isNaN(num)) return num;\n  const match = value.match(/(?:^|[,\\s])DURATION\\s*=\\s*([0-9.]+)/i) || value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (match && match[1] != null) {\n    const dStr = match[1];\n    const d = parseFloat(dStr);\n    return Number.isNaN(d) ? void 0 : d;\n  }\n  return void 0;\n}\nfunction parseCueOutCont(value) {\n  const res = {};\n  const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n  const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n  if (elapsedMatch && elapsedMatch[1] != null) {\n    const e = parseFloat(elapsedMatch[1]);\n    if (!Number.isNaN(e)) res.elapsed = e;\n  }\n  if (durationMatch && durationMatch[1] != null) {\n    const d = parseFloat(durationMatch[1]);\n    if (!Number.isNaN(d)) res.duration = d;\n  }\n  if (!(\"elapsed\" in res) || !(\"duration\" in res)) {\n    const slashMatch = value.match(/([0-9.]+)\\s*\\/\\s*([0-9.]+)/);\n    if (slashMatch && slashMatch[1] && slashMatch[2]) {\n      const elapsed = parseFloat(slashMatch[1]);\n      const duration = parseFloat(slashMatch[2]);\n      if (!Number.isNaN(elapsed) && !(\"elapsed\" in res)) res.elapsed = elapsed;\n      if (!Number.isNaN(duration) && !(\"duration\" in res)) res.duration = duration;\n    }\n  }\n  if (\"elapsed\" in res || \"duration\" in res) return res;\n  return void 0;\n}\nfunction parseAttributeList(value) {\n  const attrs = {};\n  const regex = /([A-Z0-9-]+)=((\"[^\"]*\")|([^\",]*))(?:,|$)/gi;\n  let match;\n  while ((match = regex.exec(value)) !== null) {\n    const key = match[1] ?? \"\";\n    let rawVal = match[3] ?? match[4] ?? \"\";\n    if (rawVal.startsWith('\"') && rawVal.endsWith('\"')) {\n      rawVal = rawVal.slice(1, -1);\n    }\n    if (key) {\n      attrs[key] = rawVal;\n    }\n  }\n  return attrs;\n}\nfunction toNumber(val) {\n  if (val == null) return void 0;\n  const n = typeof val === \"string\" ? parseFloat(val) : Number(val);\n  return Number.isNaN(n) ? void 0 : n;\n}\nfunction isManifestBasedMarker(marker) {\n  const raw = marker.raw;\n  if (!raw) return false;\n  if (raw.tag) {\n    const tag = String(raw.tag);\n    return tag.includes(\"EXT-X-CUE-OUT\") || tag.includes(\"EXT-X-CUE-IN\") || tag.includes(\"EXT-X-DATERANGE\");\n  }\n  if (raw.id3) return false;\n  if (raw.splice_command_type) return false;\n  return false;\n}\nfunction decodeId3ValueToText(value) {\n  try {\n    if (typeof value === \"string\") return value;\n    const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n    const text = decoder.decode(value);\n    if (text && /[\\x20-\\x7E]/.test(text)) return text;\n    let out = \"\";\n    for (let i = 0; i < value.length; i++)\n      out += String.fromCharCode(value[i]);\n    return out;\n  } catch {\n    return void 0;\n  }\n}\nfunction getFragmentStartSeconds(frag) {\n  const candidates = [frag?.start, frag?.startPTS];\n  for (const candidate of candidates) {\n    if (typeof candidate === \"number\" && Number.isFinite(candidate)) {\n      return candidate;\n    }\n  }\n  return void 0;\n}\nfunction parseScte35FromId3(tag) {\n  const text = decodeId3ValueToText(tag.value);\n  if (!text) return void 0;\n  const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\\r\\n]*))?/i) || text.match(/CUE-OUT(?::([^\\r\\n]*))?/i);\n  if (cueOutMatch) {\n    const arg = (cueOutMatch[1] ?? \"\").trim();\n    const dur = parseCueOutDuration(arg);\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...dur !== void 0 ? { durationSeconds: dur } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\\r\\n]*)/i);\n  if (cueOutContMatch) {\n    const arg = (cueOutContMatch[1] ?? \"\").trim();\n    const cont = parseCueOutCont(arg);\n    const marker = {\n      type: \"progress\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n  if (cueInMatch) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\\r\\n]*)/i);\n  if (daterangeMatch) {\n    const attrs = parseAttributeList(daterangeMatch[1] ?? \"\");\n    const hasScteOut = \"SCTE35-OUT\" in attrs || attrs[\"SCTE35-OUT\"] !== void 0;\n    const hasScteIn = \"SCTE35-IN\" in attrs || attrs[\"SCTE35-IN\"] !== void 0;\n    const klass = String(attrs[\"CLASS\"] ?? \"\");\n    const duration = toNumber(attrs[\"DURATION\"]);\n    if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n      const marker = {\n        type: \"start\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        ...duration !== void 0 ? { durationSeconds: duration } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n    if (hasScteIn) {\n      const marker = {\n        type: \"end\",\n        ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n        raw: { id3: text, attrs }\n      };\n      return marker;\n    }\n  }\n  if (/SCTE35-OUT/i.test(text)) {\n    const marker = {\n      type: \"start\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (/SCTE35-IN/i.test(text)) {\n    const marker = {\n      type: \"end\",\n      ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n      raw: { id3: text }\n    };\n    return marker;\n  }\n  if (tag.value instanceof Uint8Array) {\n    const bin = parseScte35Binary(tag.value);\n    if (bin) return bin;\n  }\n  return void 0;\n}\nfunction normalizeFragmentPayload(payload) {\n  if (payload instanceof Uint8Array) {\n    return payload;\n  }\n  if (payload instanceof ArrayBuffer) {\n    return new Uint8Array(payload);\n  }\n  if (ArrayBuffer.isView(payload)) {\n    const view = payload;\n    return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n  }\n  return void 0;\n}\nfunction detectTsPacketFormat(data) {\n  const packetSizes = [188, 192, 204];\n  for (const packetSize of packetSizes) {\n    const tsPayloadOffset = packetSize === 192 ? 4 : 0;\n    for (let offset = 0; offset < packetSize; offset++) {\n      let matchedPackets = 0;\n      for (let packetStart = offset; packetStart + tsPayloadOffset < data.length && matchedPackets < 5; packetStart += packetSize) {\n        if (data[packetStart + tsPayloadOffset] !== 71) {\n          break;\n        }\n        matchedPackets++;\n      }\n      if (matchedPackets >= 2) {\n        return { offset, packetSize, tsPayloadOffset };\n      }\n    }\n  }\n  return void 0;\n}\nfunction getPsiSectionStart(payload, payloadUnitStart) {\n  if (!payloadUnitStart) {\n    return void 0;\n  }\n  const pointerField = payload[0];\n  if (pointerField == null) {\n    return void 0;\n  }\n  const sectionStart = 1 + pointerField;\n  return sectionStart < payload.length ? sectionStart : void 0;\n}\nfunction getPsiSectionLength(data, offset) {\n  return ((data[offset + 1] ?? 0) & 15) << 8 | (data[offset + 2] ?? 0);\n}\nfunction parsePatSection(payload, payloadUnitStart, pmtPids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 8 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 0) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  for (let offset = sectionStart + 8; offset + 4 <= sectionEnd - 4; offset += 4) {\n    const programNumber = (payload[offset] ?? 0) << 8 | (payload[offset + 1] ?? 0);\n    const pid = ((payload[offset + 2] ?? 0) & 31) << 8 | (payload[offset + 3] ?? 0);\n    if (programNumber !== 0) {\n      pmtPids.add(pid);\n    }\n  }\n}\nfunction descriptorsIdentifyScte35(data, start, end) {\n  let offset = start;\n  while (offset + 2 <= end) {\n    const tag = data[offset] ?? 0;\n    const length = data[offset + 1] ?? 0;\n    const descriptorStart = offset + 2;\n    const descriptorEnd = descriptorStart + length;\n    if (descriptorEnd > end) {\n      return false;\n    }\n    const registration = length >= 4 ? String.fromCharCode(\n      data[descriptorStart] ?? 0,\n      data[descriptorStart + 1] ?? 0,\n      data[descriptorStart + 2] ?? 0,\n      data[descriptorStart + 3] ?? 0\n    ) : \"\";\n    if (tag === 138 || registration === \"CUEI\" || registration === \"SCTE\") {\n      return true;\n    }\n    offset = descriptorEnd;\n  }\n  return false;\n}\nfunction parsePmtSection(payload, payloadUnitStart, tsScte35Pids) {\n  const sectionStart = getPsiSectionStart(payload, payloadUnitStart);\n  if (sectionStart == null || sectionStart + 12 >= payload.length) {\n    return;\n  }\n  if (payload[sectionStart] !== 2) {\n    return;\n  }\n  const sectionLength = getPsiSectionLength(payload, sectionStart);\n  const sectionEnd = Math.min(\n    payload.length,\n    sectionStart + 3 + sectionLength\n  );\n  const programInfoLength = ((payload[sectionStart + 10] ?? 0) & 15) << 8 | (payload[sectionStart + 11] ?? 0);\n  let offset = sectionStart + 12 + programInfoLength;\n  while (offset + 5 <= sectionEnd - 4) {\n    const streamType = payload[offset] ?? 0;\n    const elementaryPid = ((payload[offset + 1] ?? 0) & 31) << 8 | (payload[offset + 2] ?? 0);\n    const esInfoLength = ((payload[offset + 3] ?? 0) & 15) << 8 | (payload[offset + 4] ?? 0);\n    const descriptorStart = offset + 5;\n    const descriptorEnd = Math.min(descriptorStart + esInfoLength, sectionEnd - 4);\n    if (streamType === 134 || streamType === 6 && descriptorsIdentifyScte35(payload, descriptorStart, descriptorEnd)) {\n      tsScte35Pids.add(elementaryPid);\n    }\n    offset = descriptorStart + esInfoLength;\n  }\n}\nfunction hasProcessedTsScte35Section(section, processedSections) {\n  let checksum = 0;\n  for (let i = 0; i < section.length; i++) {\n    checksum = checksum * 31 + (section[i] ?? 0) >>> 0;\n  }\n  const key = `${section.length}:${checksum}`;\n  if (processedSections.has(key)) {\n    return true;\n  }\n  processedSections.add(key);\n  if (processedSections.size > 200) {\n    const firstKey = processedSections.values().next().value;\n    if (firstKey) {\n      processedSections.delete(firstKey);\n    }\n  }\n  return false;\n}\nfunction addScte35SectionMarker(section, markers, processedSections) {\n  if (section[0] !== 252 || hasProcessedTsScte35Section(section, processedSections)) {\n    return;\n  }\n  const marker = parseScte35Binary(section);\n  if (!marker) {\n    return;\n  }\n  marker.raw = {\n    ...typeof marker.raw === \"object\" && marker.raw ? marker.raw : {},\n    source: \"ts-packet\"\n  };\n  markers.push(marker);\n}\nfunction appendScte35Bytes(pid, bytes, assemblers, markers, processedSections) {\n  const assembler = assemblers.get(pid);\n  if (!assembler) {\n    return;\n  }\n  for (let i = 0; i < bytes.length && assembler.bytes.length < assembler.expectedLength; i++) {\n    assembler.bytes.push(bytes[i] ?? 0);\n  }\n  if (assembler.bytes.length >= assembler.expectedLength) {\n    assemblers.delete(pid);\n    addScte35SectionMarker(new Uint8Array(assembler.bytes), markers, processedSections);\n  }\n}\nfunction collectScte35SectionsFromPayload(pid, payload, payloadUnitStart, assemblers, markers, processedSections) {\n  if (payload.length === 0) {\n    return;\n  }\n  let offset = 0;\n  if (payloadUnitStart) {\n    const pointerField = payload[0] ?? 0;\n    const previousAssembler = assemblers.get(pid);\n    if (previousAssembler && pointerField > 0) {\n      appendScte35Bytes(\n        pid,\n        payload.subarray(1, Math.min(1 + pointerField, payload.length)),\n        assemblers,\n        markers,\n        processedSections\n      );\n    }\n    assemblers.delete(pid);\n    offset = 1 + pointerField;\n  } else {\n    appendScte35Bytes(pid, payload, assemblers, markers, processedSections);\n    return;\n  }\n  while (offset + 3 <= payload.length) {\n    const tableId = payload[offset];\n    if (tableId == null || tableId === 255) {\n      return;\n    }\n    const sectionLength = getPsiSectionLength(payload, offset);\n    const totalLength = 3 + sectionLength;\n    if (sectionLength <= 0 || totalLength <= 3) {\n      return;\n    }\n    if (offset + totalLength <= payload.length) {\n      addScte35SectionMarker(\n        payload.subarray(offset, offset + totalLength),\n        markers,\n        processedSections\n      );\n      offset += totalLength;\n    } else {\n      assemblers.set(pid, {\n        bytes: Array.from(payload.subarray(offset)),\n        expectedLength: totalLength\n      });\n      return;\n    }\n  }\n}\nfunction parseScte35FromTsPackets(data, tsScte35Pids, pmtPids, processedSections) {\n  const packetInfo = detectTsPacketFormat(data);\n  if (!packetInfo) {\n    return [];\n  }\n  const markers = [];\n  const sectionAssemblers = /* @__PURE__ */ new Map();\n  for (let packetStart = packetInfo.offset; packetStart + packetInfo.packetSize <= data.length; packetStart += packetInfo.packetSize) {\n    const tsStart = packetStart + packetInfo.tsPayloadOffset;\n    if (data[tsStart] !== 71) {\n      continue;\n    }\n    const secondByte = data[tsStart + 1];\n    const thirdByte = data[tsStart + 2];\n    const fourthByte = data[tsStart + 3];\n    if (secondByte == null || thirdByte == null || fourthByte == null || (secondByte & 128) !== 0) {\n      continue;\n    }\n    const payloadUnitStart = (secondByte & 64) !== 0;\n    const pid = (secondByte & 31) << 8 | thirdByte;\n    const adaptationFieldControl = fourthByte >> 4 & 3;\n    const hasPayload = adaptationFieldControl === 1 || adaptationFieldControl === 3;\n    if (!hasPayload) {\n      continue;\n    }\n    let payloadStart = tsStart + 4;\n    if (adaptationFieldControl === 3) {\n      const adaptationLength = data[payloadStart];\n      if (adaptationLength == null) {\n        continue;\n      }\n      payloadStart += 1 + adaptationLength;\n    }\n    const payloadEnd = Math.min(tsStart + 188, data.length);\n    if (payloadStart >= payloadEnd || payloadStart >= data.length) {\n      continue;\n    }\n    const payload = data.subarray(payloadStart, payloadEnd);\n    if (pid === 0) {\n      parsePatSection(payload, payloadUnitStart, pmtPids);\n    } else if (pmtPids.has(pid)) {\n      parsePmtSection(payload, payloadUnitStart, tsScte35Pids);\n    } else if (tsScte35Pids.has(pid)) {\n      collectScte35SectionsFromPayload(\n        pid,\n        payload,\n        payloadUnitStart,\n        sectionAssemblers,\n        markers,\n        processedSections\n      );\n    }\n  }\n  return markers;\n}\nvar BitReader = class {\n  constructor(buf) {\n    this.buf = buf;\n    this.bytePos = 0;\n    this.bitPos = 0;\n  }\n  readBits(numBits) {\n    let result = 0;\n    while (numBits > 0) {\n      if (this.bytePos >= this.buf.length) return result;\n      const remainingInByte = 8 - this.bitPos;\n      const toRead = Math.min(numBits, remainingInByte);\n      const currentByte = this.buf[this.bytePos];\n      const shift = remainingInByte - toRead;\n      const mask = (1 << toRead) - 1 & 255;\n      const bits = currentByte >> shift & mask;\n      result = result << toRead | bits;\n      this.bitPos += toRead;\n      if (this.bitPos >= 8) {\n        this.bitPos = 0;\n        this.bytePos += 1;\n      }\n      numBits -= toRead;\n    }\n    return result >>> 0;\n  }\n  skipBits(n) {\n    this.readBits(n);\n  }\n  get bytePosition() {\n    return this.bitPos === 0 ? this.bytePos : this.bytePos + 1;\n  }\n};\nfunction readSpliceTime(r, ptsAdjustmentTicks) {\n  const timeSpecifiedFlag = r.readBits(1) === 1;\n  if (!timeSpecifiedFlag) {\n    r.readBits(7);\n    return void 0;\n  }\n  r.readBits(6);\n  const high = r.readBits(1);\n  const low = r.readBits(32);\n  const ptsTicks = (high * 4294967296 + low + ptsAdjustmentTicks) % 8589934592;\n  return ptsTicks / 9e4;\n}\nfunction markerTypeFromSegmentationTypeId(segmentationTypeId) {\n  switch (segmentationTypeId) {\n    case 16:\n    case 34:\n    case 48:\n    case 50:\n    case 52:\n    case 54:\n      return \"start\";\n    case 17:\n    case 35:\n    case 49:\n    case 51:\n    case 53:\n    case 55:\n      return \"end\";\n    default:\n      return void 0;\n  }\n}\nfunction parseScte35SegmentationDescriptor(descriptor) {\n  if (descriptor.length < 11) {\n    return void 0;\n  }\n  const identifier = String.fromCharCode(\n    descriptor[0] ?? 0,\n    descriptor[1] ?? 0,\n    descriptor[2] ?? 0,\n    descriptor[3] ?? 0\n  );\n  if (identifier !== \"CUEI\") {\n    return void 0;\n  }\n  const segmentationEventId = (descriptor[4] ?? 0) * 16777216 + ((descriptor[5] ?? 0) << 16) + ((descriptor[6] ?? 0) << 8) + (descriptor[7] ?? 0);\n  const cancelIndicator = ((descriptor[8] ?? 0) & 128) !== 0;\n  if (cancelIndicator) {\n    return void 0;\n  }\n  const flags = descriptor[9] ?? 0;\n  const programSegmentationFlag = (flags & 128) !== 0;\n  const segmentationDurationFlag = (flags & 64) !== 0;\n  let offset = 10;\n  if (!programSegmentationFlag) {\n    const componentCount = descriptor[offset] ?? 0;\n    offset += 1 + componentCount * 6;\n    if (offset > descriptor.length) {\n      return void 0;\n    }\n  }\n  let durationSeconds = void 0;\n  if (segmentationDurationFlag) {\n    if (offset + 5 > descriptor.length) {\n      return void 0;\n    }\n    const durationTicks = (descriptor[offset] ?? 0) * 4294967296 + (descriptor[offset + 1] ?? 0) * 16777216 + ((descriptor[offset + 2] ?? 0) << 16) + ((descriptor[offset + 3] ?? 0) << 8) + (descriptor[offset + 4] ?? 0);\n    durationSeconds = durationTicks / 9e4;\n    offset += 5;\n  }\n  if (offset + 2 > descriptor.length) {\n    return void 0;\n  }\n  offset += 1;\n  const segmentationUpidLength = descriptor[offset] ?? 0;\n  offset += 1 + segmentationUpidLength;\n  if (offset >= descriptor.length) {\n    return void 0;\n  }\n  const segmentationTypeId = descriptor[offset] ?? 0;\n  const markerType = markerTypeFromSegmentationTypeId(segmentationTypeId);\n  if (!markerType) {\n    return void 0;\n  }\n  return {\n    type: markerType,\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    segmentationEventId\n  };\n}\nfunction parseScte35SegmentationDescriptors(data, offset) {\n  if (offset + 2 > data.length) {\n    return void 0;\n  }\n  const descriptorLoopLength = (data[offset] ?? 0) << 8 | (data[offset + 1] ?? 0);\n  let descriptorOffset = offset + 2;\n  const descriptorEnd = Math.min(\n    data.length,\n    descriptorOffset + descriptorLoopLength\n  );\n  while (descriptorOffset + 2 <= descriptorEnd) {\n    const descriptorTag = data[descriptorOffset] ?? 0;\n    const descriptorLength = data[descriptorOffset + 1] ?? 0;\n    const descriptorDataStart = descriptorOffset + 2;\n    const descriptorDataEnd = descriptorDataStart + descriptorLength;\n    if (descriptorDataEnd > descriptorEnd) {\n      return void 0;\n    }\n    if (descriptorTag === 2) {\n      const descriptorMarker = parseScte35SegmentationDescriptor(\n        data.subarray(descriptorDataStart, descriptorDataEnd)\n      );\n      if (descriptorMarker) {\n        return descriptorMarker;\n      }\n    }\n    descriptorOffset = descriptorDataEnd;\n  }\n  return void 0;\n}\nfunction parseScte35Binary(data) {\n  const r = new BitReader(data);\n  const tableId = r.readBits(8);\n  if (tableId !== 252) return void 0;\n  r.readBits(1);\n  r.readBits(1);\n  r.readBits(2);\n  const sectionLength = r.readBits(12);\n  if (sectionLength <= 0 || data.length < 3 + sectionLength) {\n    return void 0;\n  }\n  r.readBits(8);\n  r.readBits(1);\n  r.readBits(6);\n  const ptsAdjHigh = r.readBits(1);\n  const ptsAdjLow = r.readBits(32);\n  const ptsAdjustmentTicks = ptsAdjHigh * 4294967296 + ptsAdjLow;\n  r.readBits(8);\n  r.readBits(12);\n  const spliceCommandLength = r.readBits(12);\n  const spliceCommandType = r.readBits(8);\n  let markerType;\n  let durationSeconds = void 0;\n  let ptsSeconds = void 0;\n  let spliceEventId = void 0;\n  const commandBodyStart = r.bytePosition;\n  if (spliceCommandType === 5) {\n    spliceEventId = r.readBits(32);\n    const cancel = r.readBits(1) === 1;\n    r.readBits(7);\n    if (cancel) return void 0;\n    const outOfNetwork = r.readBits(1) === 1;\n    const programSpliceFlag = r.readBits(1) === 1;\n    const durationFlag = r.readBits(1) === 1;\n    const spliceImmediateFlag = r.readBits(1) === 1;\n    r.readBits(4);\n    markerType = outOfNetwork ? \"start\" : \"end\";\n    if (programSpliceFlag && !spliceImmediateFlag) {\n      ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n    } else if (!programSpliceFlag) {\n      const componentCount = r.readBits(8);\n      for (let i = 0; i < componentCount; i++) {\n        r.readBits(8);\n        if (!spliceImmediateFlag) {\n          const componentPtsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n          if (ptsSeconds === void 0) {\n            ptsSeconds = componentPtsSeconds;\n          }\n        }\n      }\n    }\n    if (durationFlag) {\n      r.readBits(6);\n      r.readBits(1);\n      const high = r.readBits(1);\n      const low = r.readBits(32);\n      const durationTicks = high * 4294967296 + low;\n      durationSeconds = durationTicks / 9e4;\n    }\n    r.readBits(16);\n    r.readBits(8);\n    r.readBits(8);\n  } else if (spliceCommandType === 6) {\n    ptsSeconds = readSpliceTime(r, ptsAdjustmentTicks);\n  } else {\n    return void 0;\n  }\n  const expectedDescriptorOffset = spliceCommandLength === 4095 ? r.bytePosition : commandBodyStart + spliceCommandLength;\n  const descriptorMarker = parseScte35SegmentationDescriptors(\n    data,\n    expectedDescriptorOffset\n  );\n  if (descriptorMarker) {\n    markerType = descriptorMarker.type;\n    if (durationSeconds === void 0) {\n      durationSeconds = descriptorMarker.durationSeconds;\n    }\n  }\n  if (!markerType) {\n    return void 0;\n  }\n  const marker = {\n    type: markerType,\n    ...ptsSeconds !== void 0 ? { ptsSeconds } : {},\n    ...durationSeconds !== void 0 ? { durationSeconds } : {},\n    raw: {\n      splice_command_type: spliceCommandType,\n      ...spliceEventId !== void 0 ? { splice_event_id: spliceEventId } : {},\n      ...descriptorMarker?.segmentationEventId !== void 0 ? { segmentation_event_id: descriptorMarker.segmentationEventId } : {}\n    }\n  };\n  return marker;\n}\n\n// src/player/Scte35CueManager.ts\nvar Scte35CueManager = class {\n  constructor(debug, callbacks) {\n    this.pendingScte35Cues = /* @__PURE__ */ new Map();\n    this.recentScte35CueKeys = /* @__PURE__ */ new Map();\n    this.recentScte35CueLimit = 200;\n    this.tsScte35Pids = /* @__PURE__ */ new Set();\n    this.pmtPids = /* @__PURE__ */ new Set();\n    this.processedTsScte35Sections = /* @__PURE__ */ new Set();\n    this.debug = debug;\n    this.callbacks = callbacks;\n  }\n  get pendingScte35CueKey() {\n    return this.pendingScte35CueKeyValue;\n  }\n  set pendingScte35CueKey(value) {\n    this.pendingScte35CueKeyValue = value;\n  }\n  get activeScte35BreakKey() {\n    return this.activeScte35BreakKeyValue;\n  }\n  set activeScte35BreakKey(value) {\n    this.activeScte35BreakKeyValue = value;\n  }\n  get scheduledScte35BreakKey() {\n    return this.scheduledScte35BreakKeyValue;\n  }\n  set scheduledScte35BreakKey(value) {\n    this.scheduledScte35BreakKeyValue = value;\n  }\n  createScte35CueContext(source, readiness, frag) {\n    const context = { source, readiness };\n    if (typeof frag?.sn === \"number\") {\n      context.fragmentSn = frag.sn;\n    }\n    const fragmentStartSec = getFragmentStartSeconds(frag);\n    if (fragmentStartSec !== void 0) {\n      context.fragmentStartSeconds = fragmentStartSec;\n    }\n    return context;\n  }\n  onScte35Cue(marker, context) {\n    const cue = this.createScte35Cue(marker, context);\n    const pendingKey = this.getPendingScte35CueKey(cue);\n    if (context.readiness === \"early\") {\n      this.pendingScte35Cues.set(pendingKey, cue);\n      this.trimRecentScte35CueMaps();\n      if (marker.type === \"start\") {\n        this.callbacks.onEarlyStartCue(marker, context.fragmentSn, cue.key);\n      }\n      return;\n    }\n    if (marker.type === \"end\" && !this.shouldAcceptScte35EndCue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring SCTE-35 end cue\", {\n          key: cue.key,\n          activeScte35BreakKey: this.activeScte35BreakKeyValue,\n          inAdBreak: this.callbacks.isInAdBreak(),\n          source: cue.source\n        });\n      }\n      return;\n    }\n    if (marker.type === \"start\" && this.hasRecentlyHandledScte35Cue(cue)) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ignoring duplicate SCTE-35 start cue\", {\n          key: cue.key,\n          source: cue.source\n        });\n      }\n      return;\n    }\n    this.pendingScte35Cues.delete(pendingKey);\n    this.markScte35CueHandled(cue);\n    this.callbacks.onPlaybackCue(marker, cue.key);\n  }\n  activatePendingScte35CuesForFragment(frag) {\n    const fragmentSn = typeof frag?.sn === \"number\" ? frag.sn : void 0;\n    if (fragmentSn === void 0) {\n      return;\n    }\n    const matchingCues = Array.from(this.pendingScte35Cues.entries()).filter(\n      ([, cue]) => cue.fragmentSn === fragmentSn\n    );\n    matchingCues.forEach(([pendingKey, cue]) => {\n      this.pendingScte35Cues.delete(pendingKey);\n      const context = {\n        source: cue.source,\n        readiness: \"playback\"\n      };\n      context.fragmentSn = fragmentSn;\n      const fragmentStartSec = cue.fragmentStartSeconds ?? getFragmentStartSeconds(frag);\n      if (fragmentStartSec !== void 0) {\n        context.fragmentStartSeconds = fragmentStartSec;\n      }\n      this.onScte35Cue(cue.marker, context);\n    });\n  }\n  createScte35Cue(marker, context) {\n    const cue = {\n      marker,\n      source: context.source,\n      readiness: context.readiness,\n      key: this.getScte35CueKey(marker, context)\n    };\n    if (context.fragmentSn !== void 0) {\n      cue.fragmentSn = context.fragmentSn;\n    }\n    if (context.fragmentStartSeconds !== void 0) {\n      cue.fragmentStartSeconds = context.fragmentStartSeconds;\n    }\n    return cue;\n  }\n  getScte35CueKey(marker, context) {\n    const raw = this.getScte35MarkerRaw(marker);\n    const spliceEventId = this.toIdentityString(raw?.splice_event_id);\n    if (spliceEventId) {\n      return `splice:${spliceEventId}`;\n    }\n    const segmentationEventId = this.toIdentityString(raw?.segmentation_event_id);\n    if (segmentationEventId) {\n      return `segmentation:${segmentationEventId}`;\n    }\n    const daterangeId = this.toIdentityString(raw?.attrs?.ID);\n    if (daterangeId) {\n      return `daterange:${daterangeId}`;\n    }\n    const scteValue = this.toIdentityString(raw?.attrs?.[\"SCTE35-OUT\"]) || this.toIdentityString(raw?.attrs?.[\"SCTE35-IN\"]);\n    if (scteValue) {\n      return `daterange-scte:${scteValue}`;\n    }\n    if (typeof marker.ptsSeconds === \"number\" && Number.isFinite(marker.ptsSeconds)) {\n      return `pts:${Math.round(marker.ptsSeconds * 2) / 2}`;\n    }\n    if (context.fragmentSn !== void 0) {\n      return `fragment:${context.fragmentSn}`;\n    }\n    return `${context.source}:wallclock:${Math.floor(Date.now() / 1e3)}`;\n  }\n  getPendingScte35CueKey(cue) {\n    return `${cue.marker.type}:${cue.key}:${cue.fragmentSn !== void 0 ? cue.fragmentSn : \"unknown\"}`;\n  }\n  getScte35MarkerRaw(marker) {\n    return typeof marker.raw === \"object\" && marker.raw !== null ? marker.raw : {};\n  }\n  toIdentityString(value) {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return String(value);\n    }\n    if (typeof value === \"string\" && value.trim().length > 0) {\n      return value.trim();\n    }\n    return void 0;\n  }\n  isStrongScte35CueKey(key) {\n    return !!(key && (key.startsWith(\"splice:\") || key.startsWith(\"segmentation:\") || key.startsWith(\"daterange:\") || key.startsWith(\"daterange-scte:\")));\n  }\n  hasRecentlyHandledScte35Cue(cue) {\n    if (this.activeScte35BreakKeyValue === cue.key || this.scheduledScte35BreakKeyValue === cue.key) {\n      return true;\n    }\n    const recentKey = `${cue.marker.type}:${cue.key}`;\n    return this.recentScte35CueKeys.has(recentKey);\n  }\n  markScte35CueHandled(cue) {\n    this.recentScte35CueKeys.set(`${cue.marker.type}:${cue.key}`, Date.now());\n    this.trimRecentScte35CueMaps();\n  }\n  trimRecentScte35CueMaps() {\n    while (this.recentScte35CueKeys.size > this.recentScte35CueLimit) {\n      const firstKey = this.recentScte35CueKeys.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.recentScte35CueKeys.delete(firstKey);\n    }\n    while (this.pendingScte35Cues.size > this.recentScte35CueLimit) {\n      const firstKey = this.pendingScte35Cues.keys().next().value;\n      if (!firstKey) {\n        break;\n      }\n      this.pendingScte35Cues.delete(firstKey);\n    }\n  }\n  shouldAcceptScte35EndCue(cue) {\n    if (!this.callbacks.isInAdBreak()) {\n      return false;\n    }\n    if (this.isStrongScte35CueKey(this.activeScte35BreakKeyValue) && this.isStrongScte35CueKey(cue.key) && this.activeScte35BreakKeyValue !== cue.key) {\n      return false;\n    }\n    return true;\n  }\n};\n\n// src/player/AdConfigManager.ts\nvar AdConfigManager = class {\n  constructor(config, video) {\n    this.vmapBreaks = [];\n    this.consumedVmapBreakIds = /* @__PURE__ */ new Set();\n    this.streamCorrelator = generateCorrelator();\n    this.viewCorrelator = generateCorrelator();\n    this.consentSignals = {};\n    this.podCounter = 0;\n    this.podAssignedByPrefetch = false;\n    this.lastHeartbeatTime = 0;\n    this.defaultPodMaxAds = 6;\n    this.defaultPodMaxDurationMs = 12e4;\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    this.applyMqttConfigFromResponse(data);\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  applyMqttConfigFromResponse(data) {\n    const mqttConfig2 = data.response?.mqtt_config;\n    if (!mqttConfig2 || typeof mqttConfig2 !== \"object\") {\n      return;\n    }\n    applyMQTTConfig(mqttConfig2);\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Applied MQTT config from /ads/web:\",\n        mqttConfig2\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  }\n  resolvePodParams(breakDurationMs) {\n    const maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;\n    const maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;\n    const minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n  generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {\n    const adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : void 0,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl: !envSignals.isCtv && typeof window !== \"undefined\" ? toDevSafeUrl(window.location.href) : void 0,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals\n    });\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n  // --- Tracking ---\n  initializeTracking() {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config)).then(() => {\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    }).catch((error) => {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n          error\n        );\n      }\n      this.heartbeatInterval = window.setInterval(() => {\n        this.sendHeartbeatIfNeeded();\n      }, 5e3);\n    });\n  }\n  sendHeartbeatIfNeeded() {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n  destroyTracking() {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = void 0;\n    }\n  }\n};\n\n// src/player/AdTimingService.ts\nvar AdTimingService = class {\n  constructor(config, video, callbacks) {\n    this.adRequestWatchdogToken = null;\n    this.adFailsafeToken = null;\n    this.ptsDriftEmaMs = 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.adBreakEpoch = 0;\n    this.adRequestTokenCounter = 0;\n    this.activeAdRequestToken = null;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.totalAdRequestsInBreak = 0;\n    this.maxTotalAdRequestsPerBreak = 10;\n    this.lastAdRequestTime = 0;\n    this.consecutiveFailures = 0;\n    this.maxConsecutiveFailures = 5;\n    this.minAdRequestIntervalMs = 3e3;\n    this.backoffBaseMs = 1e3;\n    this.maxBackoffMs = 15e3;\n    this.defaultMinRemainingMsToStartAd = 4e3;\n    this.failedVastUrls = /* @__PURE__ */ new Set();\n    this.temporaryFailureUrls = /* @__PURE__ */ new Map();\n    this.temporaryFailureCooldownMs = 3e4;\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillThreshold = 3;\n    this.globalNoFillCooldownUntil = 0;\n    this.globalNoFillBackoffBaseMs = 5e3;\n    this.globalNoFillBackoffMaxMs = 6e4;\n    this.globalLastGamRequestTime = 0;\n    this.globalMinGamIntervalMs = 3e3;\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n  get debug() {\n    return !!this.config.debugAdTiming;\n  }\n  // --- Ad stop timer ---\n  scheduleAdStopCountdown(remainingMs) {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms);\n  }\n  clearAdStopTimer() {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = void 0;\n    }\n  }\n  ensureAdStoppedByTimer() {\n    this.adStopTimerId = void 0;\n    this.callbacks.onAdStopTimerFired();\n  }\n  // --- Ad start timer ---\n  scheduleAdStartIn(delayMs, marker = { type: \"start\" }, cueKey) {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms);\n  }\n  clearAdStartTimer() {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = void 0;\n    }\n  }\n  // --- PTS drift ---\n  updatePtsDrift(ptsSecondsSample) {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n  resolveScteBreakStartWallClockMs(marker) {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n    const nowMs = this.video.currentTime * 1e3;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1e3 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n  // --- Duration boundary ---\n  setAdBreakDurationBoundary(durationMs) {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (durationMs != null && this.currentAdBreakStartWallClockMs != null) {\n      this.scteAdBreakEndWallClockMs = this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = void 0;\n    }\n  }\n  scheduleAdStopAtBreakBoundary() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n  // --- Duration budget ---\n  getWallClockRemainingAdMs() {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n  getAdBreakEndWallClockMs() {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null) {\n      return void 0;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n  getDurationBudgetRemainingMs() {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n  getLoadedAdDurationMs(adController) {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1e3);\n  }\n  adFitsRemainingBudget(durationMs) {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n  logAdDurationDecision(accepted, durationMs, adController) {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms \\u2014 requesting another ad`\n      );\n    }\n  }\n  recordPlayedAdDuration(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms \\u2014 total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n  ensureLoadedAdFitsBudget(adController) {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n  rejectLoadedAdForDuration(adController) {\n    try {\n      adController.destroy();\n    } catch {\n    }\n  }\n  markAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n  notePodAdStarted() {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n  getRemainingAdMs() {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n  getMinRemainingMsToStartAd() {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n  hasTimeToStartAnotherAd() {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return this.getWallClockRemainingAdMs() > minRemaining && this.getDurationBudgetRemainingMs() > minRemaining;\n  }\n  // --- Circuit breaker ---\n  isTemporaryAdError(error) {\n    const message = error?.message?.toLowerCase() || \"\";\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n  isUrlInCooldown(vastTagUrl) {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n    return true;\n  }\n  cleanupTemporaryFailures() {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n  isGamInCooldown() {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n  recordGamNoFill() {\n    this.globalConsecutiveNoFills++;\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n  resetGamNoFillCounter() {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n  async enforceGlobalRateLimit() {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n  // --- Watchdog ---\n  startAdRequestWatchdog(token) {\n    this.clearAdRequestWatchdog();\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n      this.adRequestWatchdogId = void 0;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs);\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n  clearAdRequestWatchdog() {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = void 0;\n    }\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n  // --- Failsafe ---\n  startAdFailsafeTimer(token) {\n    this.clearAdFailsafeTimer();\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;\n    this.adFailsafeToken = token;\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n      this.adFailsafeTimerId = void 0;\n      this.adFailsafeToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused\n      });\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs);\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n  clearAdFailsafeTimer() {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = void 0;\n    }\n    this.adFailsafeToken = null;\n  }\n  logAdState(event, extra = {}, adPlayer, inAdBreak, showAds) {\n    if (!this.debug) {\n      return;\n    }\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra\n    });\n  }\n  // --- Reset for ad break end ---\n  resetForBreakEnd() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = void 0;\n    this.currentAdBreakStartWallClockMs = void 0;\n    this.scteAdBreakEndWallClockMs = void 0;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n  destroy() {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n};\n\n// src/player/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.reloadingLiveStream = false;\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      this.reloadingLiveStream = false;\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  restartLoadAt(position) {\n    if (!this.hls) {\n      return;\n    }\n    try {\n      this.hls.stopLoad();\n      this.hls.startLoad(position);\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to restart HLS load at live edge:\", error);\n      }\n    }\n  }\n  recoverMediaError() {\n    if (!this.hls) {\n      return;\n    }\n    try {\n      this.hls.recoverMediaError();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] recoverMediaError() failed:\", error);\n      }\n    }\n  }\n  reloadLiveStream() {\n    const hls = this.hls;\n    if (!hls) {\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hard-reloading live stream (detach \\u2192 reset video \\u2192 re-attach)\");\n    }\n    try {\n      this.reloadingLiveStream = true;\n      hls.stopLoad();\n      hls.detachMedia();\n      try {\n        this.video.removeAttribute(\"src\");\n        this.video.load();\n      } catch (error) {\n        console.warn(\"[StormcloudVideoPlayer] video.load() threw after src removal:\", error);\n      }\n      hls.attachMedia(this.video);\n    } catch (error) {\n      this.reloadingLiveStream = false;\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to hard-reload live stream:\", error);\n      }\n    }\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, 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.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n  get debug() {\n    return !!this.host.config.debugAdTiming;\n  }\n  get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n  nextAdRequestUrl(baseVastUrl) {\n    const remaining = Math.min(\n      this.timing.getWallClockRemainingAdMs(),\n      this.timing.getDurationBudgetRemainingMs()\n    );\n    const breakDurationMs = remaining > 0 ? remaining : void 0;\n    return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n  }\n  attachImaEventListeners() {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      this.timing.consecutiveFailures = 0;\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload) => {\n      let errorMessage = \"Ad playback failed\";\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : cause.message || String(cause);\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n      if (!this.inAdBreak) {\n        return;\n      }\n      this.timing.consecutiveFailures = 0;\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n  recreateAdController() {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n  clearPendingAdBreak() {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = void 0;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = void 0;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n  async handleAdStart(_marker) {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1e3\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n    const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n    if (this.timing.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n    const podPlayed = await this.startOptimizedPod(\n      baseVastUrl,\n      adBreakDurationMs,\n      currentMuted,\n      currentVolume\n    );\n    if (!podPlayed) {\n      if (this.debug) {\n        console.log(\"[POD] Initial pod request did not fill; attempting top-up pod request\");\n      }\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n      await this.tryNextAvailableAdWithRateLimit();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n  async startOptimizedPod(baseVastUrl, breakDurationMs, currentMuted, currentVolume) {\n    let podUrl;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n    if (!podUrl) {\n      return false;\n    }\n    this.continuousFetchingActive = false;\n    this.recreateAdController();\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n      if (this.debug) {\n        console.log(\n          podCount === 1 ? \"[POD] Response contained a single ad; playing it and enabling pod top-up\" : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n      if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n      if (this.timing.isTemporaryAdError(error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\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.nextAdRequestUrl(baseVastUrl);\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    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n      if (!nextAdUrl) continue;\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = error.message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise((resolve) => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n    if (!this.isShowingPlaceholder && remaining > 1e3) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n  async playSingleAd(vastTagUrl) {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n    this.recreateAdController();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: (/* @__PURE__ */ new Date()).toISOString() },\n        this.analyticsContext\n      ).catch(() => {\n      });\n      this.timing.clearAdRequestWatchdog();\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n        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      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.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    this.host.video.style.visibility = \"visible\";\n    this.host.video.style.opacity = \"1\";\n    if (this.host.isLiveStream()) {\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        this.host.restartHlsLoad(liveSyncPos);\n      }\n      this.resumeContentPlayback();\n      this.monitorLiveResumeStall(this.host.video.currentTime);\n      return;\n    }\n    this.resumeContentPlayback();\n  }\n  getBufferedAhead() {\n    const video = this.host.video;\n    const t = video.currentTime;\n    const ranges = video.buffered;\n    for (let i = 0; i < ranges.length; i++) {\n      if (t >= ranges.start(i) - 0.5 && t <= ranges.end(i)) {\n        return ranges.end(i) - t;\n      }\n    }\n    return 0;\n  }\n  describeVideoState() {\n    const v = this.host.video;\n    const networkStates = [\"EMPTY\", \"IDLE\", \"LOADING\", \"NO_SOURCE\"];\n    const readyStates = [\n      \"HAVE_NOTHING\",\n      \"HAVE_METADATA\",\n      \"HAVE_CURRENT_DATA\",\n      \"HAVE_FUTURE_DATA\",\n      \"HAVE_ENOUGH_DATA\"\n    ];\n    const net = networkStates[v.networkState] ?? String(v.networkState);\n    const ready = readyStates[v.readyState] ?? String(v.readyState);\n    const err = v.error ? `code=${v.error.code}${v.error.message ? ` (${v.error.message})` : \"\"}` : \"none\";\n    const ranges = [];\n    for (let i = 0; i < v.buffered.length; i++) {\n      ranges.push(`[${v.buffered.start(i).toFixed(2)}\\u2013${v.buffered.end(i).toFixed(2)}]`);\n    }\n    return `t=${v.currentTime.toFixed(2)}s paused=${v.paused} ended=${v.ended} seeking=${v.seeking} readyState=${ready} networkState=${net} error=${err} buffered=${ranges.length ? ranges.join(\",\") : \"none\"}`;\n  }\n  monitorLiveResumeStall(resumeBaseline) {\n    const pollIntervalMs = 1e3;\n    const graceMs = 5e3;\n    const recoveryCooldownMs = 5e3;\n    const maxRecoveries = 3;\n    const maxMonitorMs = 45e3;\n    const startTime = Date.now();\n    let baseline = resumeBaseline;\n    let recoveries = 0;\n    let lastRecoveryAt = 0;\n    const video = this.host.video;\n    let listenersAttached = false;\n    let onMediaEvent;\n    const diagEvents = [\n      \"loadstart\",\n      \"loadedmetadata\",\n      \"loadeddata\",\n      \"canplay\",\n      \"canplaythrough\",\n      \"play\",\n      \"playing\",\n      \"pause\",\n      \"waiting\",\n      \"stalled\",\n      \"suspend\",\n      \"seeking\",\n      \"seeked\",\n      \"emptied\",\n      \"error\",\n      \"ended\"\n    ];\n    if (this.debug) {\n      onMediaEvent = (e) => {\n        const dt = ((Date.now() - startTime) / 1e3).toFixed(1);\n        console.log(\n          `[ResumeDiag] +${dt}s event=${e.type} \\u2014 ${this.describeVideoState()}`\n        );\n      };\n      for (const name of diagEvents) {\n        video.addEventListener(name, onMediaEvent);\n      }\n      listenersAttached = true;\n      console.log(\n        `[ResumeDiag] +0.0s monitor start \\u2014 ${this.describeVideoState()}`\n      );\n    }\n    const cleanup = () => {\n      if (listenersAttached && onMediaEvent) {\n        for (const name of diagEvents) {\n          video.removeEventListener(name, onMediaEvent);\n        }\n        listenersAttached = false;\n      }\n    };\n    const poll = () => {\n      if (this.inAdBreak) {\n        cleanup();\n        return;\n      }\n      const currentTime = video.currentTime;\n      const advanced = currentTime > baseline + 0.5;\n      const playing = !video.paused && video.readyState >= 3;\n      if (advanced && playing) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live stream resumed successfully after ad break \\u2014 ${this.describeVideoState()}`\n          );\n        }\n        cleanup();\n        return;\n      }\n      if (video.paused) {\n        video.play()?.catch(() => {\n        });\n      }\n      const elapsed = Date.now() - startTime;\n      const bufferedAhead = this.getBufferedAhead();\n      const wedged = bufferedAhead < 0.5 && !advanced;\n      if (elapsed >= maxMonitorMs) {\n        if (this.debug && !advanced) {\n          console.warn(\n            `[StormcloudVideoPlayer] Live stream failed to resume after ${(maxMonitorMs / 1e3).toFixed(0)}s \\u2014 ${this.describeVideoState()}`\n          );\n        }\n        cleanup();\n        return;\n      }\n      const canRecover = wedged && elapsed >= graceMs && Date.now() - lastRecoveryAt >= recoveryCooldownMs && recoveries < maxRecoveries;\n      if (canRecover) {\n        recoveries++;\n        lastRecoveryAt = Date.now();\n        if (recoveries === 1) {\n          if (this.debug) {\n            console.warn(\n              `[StormcloudVideoPlayer] Content wedged after ad break \\u2014 calling recoverMediaError() (recovery ${recoveries}/${maxRecoveries}) \\u2014 ${this.describeVideoState()}`\n            );\n          }\n          this.host.recoverMediaError();\n        } else if (recoveries === 2) {\n          const liveSyncPos = this.host.getLiveSyncPosition();\n          const reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;\n          if (this.debug) {\n            console.warn(\n              `[StormcloudVideoPlayer] Content wedged after ad break \\u2014 restarting HLS load at ${reloadPos.toFixed(2)}s (recovery ${recoveries}/${maxRecoveries}) \\u2014 ${this.describeVideoState()}`\n            );\n          }\n          if (liveSyncPos != null && liveSyncPos > currentTime) {\n            video.currentTime = liveSyncPos;\n          }\n          this.host.restartHlsLoad(reloadPos);\n        } else {\n          if (this.debug) {\n            console.warn(\n              `[StormcloudVideoPlayer] Content still wedged after ad break \\u2014 hard-reloading live stream (recovery ${recoveries}/${maxRecoveries}) \\u2014 ${this.describeVideoState()}`\n            );\n          }\n          this.host.reloadLiveStream();\n        }\n        baseline = video.currentTime;\n        if (video.paused) {\n          video.play()?.catch(() => {\n          });\n        }\n      }\n      window.setTimeout(poll, pollIntervalMs);\n    };\n    window.setTimeout(poll, pollIntervalMs);\n  }\n  resumeContentPlayback(attempt = 0) {\n    const maxAttempts = 5;\n    const video = this.host.video;\n    if (!video.paused) {\n      if (this.debug && attempt === 0) {\n        console.log(\"[StormcloudVideoPlayer] Content video already playing after ads\");\n      }\n      return;\n    }\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resuming content playback after ads (attempt ${attempt + 1}/${maxAttempts}, readyState=${video.readyState})`\n      );\n    }\n    if (video.readyState < 3) {\n      if (attempt + 1 >= maxAttempts) {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] readyState never reached HAVE_FUTURE_DATA, forcing play()\"\n          );\n        }\n        video.play()?.catch(() => {\n        });\n        return;\n      }\n      const onReady = () => {\n        video.removeEventListener(\"canplay\", onReady);\n        this.resumeContentPlayback(attempt + 1);\n      };\n      video.addEventListener(\"canplay\", onReady);\n      const backoffMs = 500 * (attempt + 1);\n      window.setTimeout(() => {\n        video.removeEventListener(\"canplay\", onReady);\n        if (video.paused) {\n          this.resumeContentPlayback(attempt + 1);\n        }\n      }, backoffMs);\n      return;\n    }\n    const playResult = video.play();\n    if (playResult && typeof playResult.catch === \"function\") {\n      playResult.catch((error) => {\n        if (attempt + 1 >= maxAttempts) {\n          if (this.debug) {\n            console.warn(\n              \"[StormcloudVideoPlayer] Failed to resume content playback after ads:\",\n              error\n            );\n          }\n          return;\n        }\n        const backoffMs = 250 * (attempt + 1);\n        window.setTimeout(() => {\n          this.resumeContentPlayback(attempt + 1);\n        }, backoffMs);\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.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        isLiveStream: () => this.hlsEngine.isLiveStream,\n        getLiveSyncPosition: () => this.hlsEngine.getLiveSyncPosition(),\n        restartHlsLoad: (position) => this.hlsEngine.restartLoadAt(position),\n        reloadLiveStream: () => this.hlsEngine.reloadLiveStream(),\n        recoverMediaError: () => this.hlsEngine.recoverMediaError(),\n        generatePodVastUrl: (base, breakDurationMs) => this.generatePodVastUrl(base, breakDurationMs)\n      },\n      this.timing,\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  generatePodVastUrl(baseUrl, breakDurationMs) {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl,\n      podParams,\n      this.adPlayer,\n      this.palNonce,\n      this.adBreak.inAdBreak\n    );\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n  async load() {\n    if (!this.attached) {\n      this.attach();\n    }\n    try {\n      await this.adConfig.fetchAdConfiguration();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\n          \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n          error\n        );\n      }\n    }\n    this.palNonce.generateNonce({\n      videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,\n      videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,\n      adWillAutoPlay: !!this.config.autoplay,\n      adWillPlayMuted: true,\n      playerVolume: 0,\n      continuousPlayback: this.config.lowLatencyMode ?? false\n    }).catch(() => {\n    });\n    fetchConsentSignals().then((signals) => {\n      this.adConfig.consentSignals = signals;\n    }).catch(() => {\n    });\n    this.adConfig.initializeTracking();\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n      const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Native HLS ad behavior:\", {\n          isLive: this.hlsEngine.isLiveStream,\n          continueLiveStreamDuringAds\n        });\n      }\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n    this.hlsEngine.setupHls();\n  }\n  async onManifestParsed(isLive) {\n    if (this.hlsEngine.reloadingLiveStream) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Manifest re-parsed after hard reload \\u2014 skipping ad-player setup\");\n      }\n      return;\n    }\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.config.pauseContentDuringAds) {\n      return false;\n    }\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n    return false;\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n  onScte35Marker(marker, cueKey) {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] SCTE-35 marker detected:\", {\n        type: marker.type,\n        ptsSeconds: marker.ptsSeconds,\n        durationSeconds: marker.durationSeconds,\n        currentTime: this.video.currentTime,\n        raw: marker.raw,\n        hasPendingAdBreak: !!this.adBreak.pendingAdBreak\n      });\n    }\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1e3;\n          if (this.timing.expectedAdBreakDurationMs == null || newDurationMs > this.timing.expectedAdBreakDurationMs) {\n            this.timing.setAdBreakDurationBoundary(newDurationMs);\n            this.timing.scheduleAdStopAtBreakBoundary();\n            if (this.debug) {\n              console.log(\n                `[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${newDurationMs}ms, remaining: ${this.timing.getWallClockRemainingAdMs()}ms`\n              );\n            }\n          }\n        }\n        return;\n      }\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload = {};\n        if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n        if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n        sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n        });\n      }\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n      const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.adBreak.pendingAdBreak?.marker.durationSeconds != null ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n          isManifestMarker: isManifest,\n          forceImmediate,\n          hasPts: typeof marker.ptsSeconds === \"number\",\n          hasPrefetchedAds\n        });\n      }\n      if (isManifest && forceImmediate) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n          );\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      } else if (typeof marker.ptsSeconds === \"number\") {\n        const tol = this.config.driftToleranceMs ?? 1e3;\n        const nowMs = this.video.currentTime * 1e3;\n        const estCurrentPtsMs = nowMs - this.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n            nowMs,\n            estCurrentPtsMs,\n            markerPtsMs: marker.ptsSeconds * 1e3,\n            deltaMs,\n            tolerance: tol\n          });\n        }\n        if (deltaMs > tol) {\n          if (this.debug) {\n            console.log(`[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`);\n          }\n          this.timing.expectedAdBreakDurationMs = durationMs;\n          this.cueManager.scheduledScte35BreakKey = cueKey;\n          this.timing.scheduleAdStartIn(deltaMs, marker, cueKey);\n        } else {\n          if (this.debug) {\n            console.log(\"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\");\n          }\n          this.timing.clearAdStartTimer();\n          this.startScte35AdBreak(marker, cueKey, durationMs);\n        }\n      } else {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad immediately (fallback)\");\n        }\n        this.timing.clearAdStartTimer();\n        this.startScte35AdBreak(marker, cueKey, durationMs);\n      }\n      return;\n    }\n    if (marker.type === \"progress\" && this.adBreak.inAdBreak) {\n      if (marker.durationSeconds != null) {\n        this.timing.setAdBreakDurationBoundary(marker.durationSeconds * 1e3);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n      if (!this.adPlayer.isAdPlaying() && this.timing.activeAdRequestToken === null && this.adBreak.adRequestQueue.length > 0 && this.timing.hasTimeToStartAnotherAd()) {\n        this.adBreak.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n    if (marker.type === \"end\") {\n      if (!this.video.muted) {\n        this.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n        }\n      }\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n          remaining,\n          adPlaying,\n          hasQueuedAds,\n          activeAdRequest: this.timing.activeAdRequestToken !== null\n        });\n      }\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {\n        });\n      }\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n  startScte35AdBreak(marker, cueKey, durationMs) {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = void 0;\n    this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n    this.adBreak.handleAdStart(marker);\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n  onAdStopTimerFired() {\n    if (!this.adBreak.inAdBreak) return;\n    const adPlaying = this.adPlayer.isAdPlaying();\n    const checkIntervalMs = Math.max(\n      250,\n      Math.floor(this.config.adBreakCheckIntervalMs ?? 1e3)\n    );\n    const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n    const maxExtensionMs = typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 0;\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Ad break boundary reached (overrun=${overrunMs}ms) - hard-stopping ads and resuming stream`\n      );\n    }\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {\n      });\n    }\n    this.adBreak.handleAdPodComplete();\n  }\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n  startAdPrefetch(marker, fragmentSn, cueKey) {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1e3);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n    let baseVastUrl;\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      if (this.debug) console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n      return;\n    }\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n    const breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;\n    const generatedUrls = [this.generatePodVastUrl(baseVastUrl, breakDurationMs)];\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now()\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;\n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {\n    });\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(`[PREFETCH] Pre-generated pod request URL`);\n    }\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        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad request failed:\", error);\n        }\n        this.adBreak.handleAdPodComplete();\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.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// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  StormcloudVideoPlayer\n});\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n  AdBreak,\n} from \"../types\";\nimport { createHlsAdPlayer } from \"../sdk/hlsAdPlayer\";\nimport { createPalNonceManager } from \"../sdk/pal\";\nimport type { PalNonceManager } from \"../sdk/pal\";\nimport {\n  buildAnalyticsContext,\n  sendAdDetectTracking,\n} from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { fetchConsentSignals } from \"../utils/vastMacros\";\nimport {\n  logBrowserInfo,\n  getBrowserConfigOverrides,\n} from \"../utils/browserCompat\";\n\nimport { isManifestBasedMarker } from \"./Scte35Parser\";\nimport { Scte35CueManager } from \"./Scte35CueManager\";\nimport { AdConfigManager } from \"./AdConfigManager\";\nimport { AdTimingService } from \"./AdTimingService\";\nimport { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { HlsEngine } from \"./HlsEngine\";\nimport { AdBreakOrchestrator } from \"./AdBreakOrchestrator\";\nimport {\n  toggleMute as ctrlToggleMute,\n  toggleFullscreen as ctrlToggleFullscreen,\n  isMuted as ctrlIsMuted,\n  setMuted as ctrlSetMuted,\n  setVolume as ctrlSetVolume,\n  getVolume as ctrlGetVolume,\n  isFullscreen as ctrlIsFullscreen,\n  resizePlayer as ctrlResizePlayer,\n} from \"./PlayerControls\";\n\nexport class StormcloudVideoPlayer {\n  private readonly video: HTMLVideoElement;\n  private readonly config: StormcloudVideoPlayerConfig;\n  private adPlayer: AdController;\n  private attached = false;\n\n  private timeUpdateHandler?: (event: Event) => void;\n  private endedHandler?: (event: Event) => void;\n  private emptiedHandler?: (event: Event) => void;\n\n  private palNonce: PalNonceManager;\n  private palPlaybackStarted: boolean = false;\n\n  private readonly cueManager: Scte35CueManager;\n  private readonly adConfig: AdConfigManager;\n  private readonly timing: AdTimingService;\n  private readonly placeholder: PlaceholderLayer;\n  private readonly hlsEngine: HlsEngine;\n  private readonly adBreak: AdBreakOrchestrator;\n\n  constructor(config: StormcloudVideoPlayerConfig) {\n    initializePolyfills();\n\n    const browserOverrides = getBrowserConfigOverrides();\n\n    this.config = { ...browserOverrides, ...config };\n    this.video = config.videoElement;\n\n    logBrowserInfo(config.debugAdTiming);\n\n    this.adPlayer = this.createAdPlayer(false);\n    this.palNonce = createPalNonceManager();\n\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\n    this.adConfig = new AdConfigManager(this.config, this.video);\n\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 * 1000 : this.timing.expectedAdBreakDurationMs\n        );\n      },\n      onWatchdogTimeout: () => this.adBreak.handleAdFailure(),\n      onFailsafeTimeout: () => this.adBreak.handleAdFailure(),\n    });\n\n    this.placeholder = new PlaceholderLayer(this.video, !!this.config.debugAdTiming);\n\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\n    this.adBreak = new AdBreakOrchestrator(\n      {\n        config: this.config,\n        video: this.video,\n        getAdPlayer: () => this.adPlayer,\n        setAdPlayer: (p) => { this.adPlayer = p; },\n        createAdPlayer: (c) => this.createAdPlayer(c),\n        shouldContinueLiveStreamDuringAds: () => this.shouldContinueLiveStreamDuringAds(),\n        isLiveStream: () => this.hlsEngine.isLiveStream,\n        getLiveSyncPosition: () => this.hlsEngine.getLiveSyncPosition(),\n        restartHlsLoad: (position) => this.hlsEngine.restartLoadAt(position),\n        reloadLiveStream: () => this.hlsEngine.reloadLiveStream(),\n        recoverMediaError: () => this.hlsEngine.recoverMediaError(),\n        generatePodVastUrl: (base, breakDurationMs) => this.generatePodVastUrl(base, breakDurationMs),\n      },\n      this.timing,\n      this.adConfig,\n      this.cueManager,\n      this.placeholder\n    );\n  }\n\n  private get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  private createAdPlayer(continueLiveStreamDuringAds: boolean): AdController {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Creating HLS ad player\");\n    }\n    return createHlsAdPlayer(this.video, {\n      continueLiveStreamDuringAds,\n      ...(this.config.licenseKey\n        ? { licenseKey: this.config.licenseKey }\n        : {}),\n      ...(this.hlsEngine?.hls ? { mainHlsInstance: this.hlsEngine.hls } : {}),\n    });\n  }\n\n  private generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string {\n    const podParams = this.adConfig.resolvePodParams(breakDurationMs);\n    return this.adConfig.generatePodVastUrl(\n      baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak\n    );\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Lifecycle\n  // ───────────────────────────────────────────────────────────────\n\n  async load(): Promise<void> {\n    if (!this.attached) {\n      this.attach();\n    }\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\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()\n      .then((signals) => {\n        this.adConfig.consentSignals = signals;\n      })\n      .catch(() => {});\n\n    this.adConfig.initializeTracking();\n\n    if (this.hlsEngine.shouldUseNativeHls(() => this.getStreamType())) {\n      await this.hlsEngine.setupNativeHls();\n\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\n      this.adPlayer.destroy();\n      this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);\n      this.adPlayer.initialize();\n      return;\n    }\n\n    this.hlsEngine.setupHls();\n  }\n\n  private async onManifestParsed(isLive: boolean): Promise<void> {\n    if (this.hlsEngine.reloadingLiveStream) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Manifest re-parsed after hard reload — skipping ad-player setup\");\n      }\n      return;\n    }\n\n    if (\n      !this.adConfig.isVmapEnabled() &&\n      !isLive &&\n      this.adConfig.vmapBreaks.length === 0 &&\n      this.adConfig.apiVastTagUrl\n    ) {\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\n    if (this.debug) {\n      const adBehavior = this.shouldContinueLiveStreamDuringAds()\n        ? \"live (main video continues muted during ads)\"\n        : \"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\n    this.adPlayer.destroy();\n    this.adPlayer = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n    this.adPlayer.initialize();\n  }\n\n  private attach(): void {\n    if (this.attached) return;\n    this.attached = true;\n    this.video.autoplay = !!this.config.autoplay;\n    this.video.muted = !!this.config.muted;\n\n    this.adPlayer.initialize();\n    this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n    this.adBreak.attachImaEventListeners();\n\n    this.video.addEventListener(\"play\", () => {\n      if (!this.palPlaybackStarted && !this.adPlayer.isAdPlaying()) {\n        this.palPlaybackStarted = true;\n        this.palNonce.sendPlaybackStart();\n      }\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\n    this.video.addEventListener(\"mousedown\", (e) => {\n      this.palNonce.sendAdTouch(e as MouseEvent);\n    });\n\n    this.video.addEventListener(\"touchstart\", (e) => {\n      this.palNonce.sendAdTouch(e as TouchEvent);\n    });\n\n    this.timeUpdateHandler = () => {\n      this.onTimeUpdate(this.video.currentTime);\n    };\n    this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n    this.emptiedHandler = () => {\n      if (\n        this.hlsEngine.nativeHlsMode &&\n        this.hlsEngine.videoSrcProtection &&\n        !this.adPlayer.isAdPlaying()\n      ) {\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    this.video.addEventListener(\"emptied\", this.emptiedHandler);\n  }\n\n  private shouldContinueLiveStreamDuringAds(): boolean {\n    if (this.config.pauseContentDuringAds) {\n      return false;\n    }\n\n    if (this.hlsEngine.isLiveStream) {\n      return true;\n    }\n\n    const duration = this.video.duration;\n    if (!Number.isFinite(duration) || duration === Infinity) {\n      return true;\n    }\n\n    return false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  SCTE-35 marker orchestration\n  // ───────────────────────────────────────────────────────────────\n\n  private onScte35Marker(marker: Scte35Marker, cueKey?: string): void {\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\n    if (marker.type === \"start\") {\n      if (this.adBreak.inAdBreak) {\n        if (marker.durationSeconds != null) {\n          const newDurationMs = marker.durationSeconds * 1000;\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\n      if (!this.adBreak.adDetectSentForCurrentBreak) {\n        this.adBreak.adDetectSentForCurrentBreak = true;\n        const detectPayload: {\n          durationSeconds?: number;\n          ptsSeconds?: number;\n          detectedAtFragmentSn?: number;\n        } = {};\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: new Date().toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {});\n      }\n\n      const hasPrefetchedAds = this.adBreak.pendingAdBreak && this.adBreak.pendingAdBreak.vastUrls.length > 0;\n\n      const durationMs =\n        marker.durationSeconds != null\n          ? marker.durationSeconds * 1000\n          : (this.adBreak.pendingAdBreak?.marker.durationSeconds != null\n              ? this.adBreak.pendingAdBreak.marker.durationSeconds * 1000\n              : undefined);\n\n      const isManifest = isManifestBasedMarker(marker);\n      const forceImmediate = this.config.immediateManifestAds ?? true;\n\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\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 ?? 1000;\n        const nowMs = this.video.currentTime * 1000;\n        const estCurrentPtsMs = nowMs - this.timing.ptsDriftEmaMs;\n        const deltaMs = Math.floor(marker.ptsSeconds * 1000 - estCurrentPtsMs);\n\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n            nowMs,\n            estCurrentPtsMs,\n            markerPtsMs: marker.ptsSeconds * 1000,\n            deltaMs,\n            tolerance: tol,\n          });\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 * 1000);\n      }\n      this.timing.scheduleAdStopAtBreakBoundary();\n\n      if (\n        !this.adPlayer.isAdPlaying() &&\n        this.timing.activeAdRequestToken === null &&\n        this.adBreak.adRequestQueue.length > 0 &&\n        this.timing.hasTimeToStartAnotherAd()\n      ) {\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\n      const remaining = this.timing.getRemainingAdMs();\n      const adPlaying = this.adPlayer.isAdPlaying();\n      const hasQueuedAds = this.adBreak.adRequestQueue.length > 0;\n\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\n      this.timing.scteAdBreakEndWallClockMs = Date.now();\n      this.timing.clearAdStartTimer();\n      this.timing.clearAdStopTimer();\n\n      if (adPlaying) {\n        this.adPlayer.stop().catch(() => {});\n      }\n\n      this.adBreak.handleAdPodComplete();\n      return;\n    }\n  }\n\n  private startScte35AdBreak(\n    marker: Scte35Marker,\n    cueKey: string | undefined,\n    durationMs: number | undefined\n  ): void {\n    this.adBreak.inAdBreak = true;\n    this.cueManager.activeScte35BreakKey = cueKey ?? this.cueManager.pendingScte35CueKey;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.timing.currentAdBreakStartWallClockMs =\n      this.timing.resolveScteBreakStartWallClockMs(marker);\n    this.timing.setAdBreakDurationBoundary(durationMs);\n\n    this.adBreak.handleAdStart(marker);\n\n    this.timing.scheduleAdStopAtBreakBoundary();\n  }\n\n  private onAdStopTimerFired(): void {\n    if (!this.adBreak.inAdBreak) return;\n\n    const adPlaying = this.adPlayer.isAdPlaying();\n    const checkIntervalMs = Math.max(\n      250,\n      Math.floor(this.config.adBreakCheckIntervalMs ?? 1000)\n    );\n    const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n    const maxExtensionMs =\n      typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0\n        ? maxExtensionMsConfig\n        : 0;\n\n    const endWallClockMs = this.timing.getAdBreakEndWallClockMs() ?? Date.now();\n    const overrunMs = Math.max(0, Date.now() - endWallClockMs);\n\n    const shouldExtendAdBreak = adPlaying && overrunMs < maxExtensionMs;\n\n    if (shouldExtendAdBreak) {\n      this.timing.scheduleAdStopCountdown(checkIntervalMs);\n      return;\n    }\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\n    if (adPlaying) {\n      this.adPlayer.stop().catch(() => {});\n    }\n\n    this.adBreak.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad prefetch\n  // ───────────────────────────────────────────────────────────────\n\n  private startAdPrefetch(\n    marker: Scte35Marker,\n    fragmentSn?: number,\n    cueKey?: string\n  ): void {\n    if (this.adBreak.pendingAdBreak || this.adBreak.inAdBreak) return;\n\n    const scheduled = this.adConfig.findCurrentOrNextBreak(this.video.currentTime * 1000);\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\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\n    this.adConfig.beginNewAdPod();\n    this.adConfig.podAssignedByPrefetch = true;\n\n    const breakDurationMs =\n      marker.durationSeconds != null ? marker.durationSeconds * 1000 : undefined;\n\n    const generatedUrls = [this.generatePodVastUrl(baseVastUrl, breakDurationMs)];\n\n    this.adBreak.pendingAdBreak = {\n      marker,\n      ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n      vastUrls: generatedUrls,\n      isFetching: false,\n      fetchStartTime: Date.now(),\n    };\n    this.cueManager.pendingScte35CueKey = cueKey;\n\n    this.adBreak.adDetectSentForCurrentBreak = true;\n    const detectPayload: {\n      durationSeconds?: number;\n      ptsSeconds?: number;\n      detectedAtFragmentSn?: number;\n    } = {};\n    if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;\n    if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;\n    if (fragmentSn !== undefined) detectPayload.detectedAtFragmentSn = fragmentSn;\n    \n    sendAdDetectTracking(this.config.licenseKey, { source: \"scte35\", timestamp: new Date().toISOString(), ...detectPayload }, buildAnalyticsContext(this.config)).catch(() => {});\n\n    if (this.debug) {\n      console.log(\"[PREFETCH] Starting ad prefetch for upcoming ad break\");\n      console.log(`[PREFETCH] Pre-generated pod request URL`);\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  VMAP time-based ad breaks\n  // ───────────────────────────────────────────────────────────────\n\n  private onTimeUpdate(currentTimeSec: number): void {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n    const nowMs = currentTimeSec * 1000;\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\n  private onVideoEnded(): void {\n    if (!this.adConfig.isVmapEnabled() || this.adConfig.vmapBreaks.length === 0) return;\n    if (this.adPlayer.isAdPlaying() || this.adBreak.inAdBreak) return;\n\n    const durationMs = Number.isFinite(this.video.duration)\n      ? Math.floor(this.video.duration * 1000)\n      : 0;\n    const postroll = this.adConfig.vmapBreaks.find(\n      (b) =>\n        b.startTimeMs === -1 &&\n        !this.adConfig.consumedVmapBreakIds.has(this.adConfig.getAdBreakKey(b))\n    );\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\n  private async handleVmapAdBreak(\n    adBreak: AdBreak,\n    nowMs: number\n  ): Promise<void> {\n    const key = this.adConfig.getAdBreakKey(adBreak);\n    if (this.adConfig.consumedVmapBreakIds.has(key)) return;\n\n    const breakStartMs = this.adConfig.resolveBreakStartMs(adBreak);\n    if (breakStartMs == null) return;\n\n    const durationMs = adBreak.durationMs ?? 0;\n    const endMs = breakStartMs + durationMs;\n    const inWindow =\n      durationMs > 0\n        ? nowMs >= breakStartMs && nowMs < endMs\n        : nowMs >= breakStartMs;\n\n    if (inWindow) {\n      this.adConfig.consumedVmapBreakIds.add(key);\n      const tags = this.adConfig.selectVastTagsForBreak(adBreak);\n      if (!tags || tags.length === 0) return;\n\n      const first = tags[0] as string;\n      const rest = tags.slice(1);\n      this.adBreak.adPodQueue = rest;\n\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\n      try {\n        await this.adBreak.playSingleAd(first);\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] VMAP ad request failed:\", error);\n        }\n        this.adBreak.handleAdPodComplete();\n      }\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Public API\n  // ───────────────────────────────────────────────────────────────\n\n  getCurrentAdIndex(): number {\n    return this.timing.currentAdIndex;\n  }\n\n  getTotalAdsInBreak(): number {\n    return this.timing.totalAdsInBreak;\n  }\n\n  getAdRemainingMs(): number {\n    return this.timing.getRemainingAdMs();\n  }\n\n  isAdPlaying(): boolean {\n    return this.adBreak.inAdBreak && this.adPlayer.isAdPlaying();\n  }\n\n  isShowingAds(): boolean {\n    return this.adBreak.showAds;\n  }\n\n  getStreamType(): \"hls\" | \"other\" {\n    const url = this.config.src.toLowerCase();\n    if (\n      url.includes(\".m3u8\") ||\n      url.includes(\"/hls/\") ||\n      url.includes(\"application/vnd.apple.mpegurl\")\n    ) {\n      return \"hls\";\n    }\n    return \"other\";\n  }\n\n  shouldShowNativeControls(): boolean {\n    const streamType = this.getStreamType();\n    if (streamType === \"other\") {\n      return !(this.config.showCustomControls ?? false);\n    }\n    return !!(\n      this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n    );\n  }\n\n  isLive(): boolean {\n    return this.hlsEngine.isLiveStream;\n  }\n\n  get videoElement(): HTMLVideoElement {\n    return this.video;\n  }\n\n  toggleMute(): void {\n    ctrlToggleMute(this.video, this.adPlayer, this.debug);\n  }\n\n  toggleFullscreen(): Promise<void> {\n    return ctrlToggleFullscreen(this.video, this.debug);\n  }\n\n  isMuted(): boolean {\n    return ctrlIsMuted(this.video, this.adPlayer);\n  }\n\n  setMuted(muted: boolean): void {\n    ctrlSetMuted(this.video, this.adPlayer, muted, this.debug);\n  }\n\n  setVolume(volume: number): void {\n    ctrlSetVolume(this.video, this.adPlayer, volume, this.debug);\n  }\n\n  getVolume(): number {\n    return ctrlGetVolume(this.video, this.adPlayer);\n  }\n\n  isFullscreen(): boolean {\n    return ctrlIsFullscreen();\n  }\n\n  resize(): void {\n    ctrlResizePlayer(this.video, this.adPlayer, this.debug);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Destroy\n  // ───────────────────────────────────────────────────────────────\n\n  destroy(): void {\n    this.adBreak.stopContinuousFetching();\n    this.timing.destroy();\n    this.adBreak.clearPendingAdBreak();\n    this.placeholder.destroy();\n\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\n    this.adConfig.destroyTracking();\n    this.hlsEngine.destroy();\n    this.adPlayer?.destroy();\n\n    if (this.palPlaybackStarted) {\n      this.palPlaybackStarted = false;\n      this.palNonce.sendPlaybackEnd();\n    }\n    this.palNonce.reset();\n\n    this.adBreak.adRequestQueue = [];\n    this.timing.consecutiveFailures = 0;\n  }\n}\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n  url: string;\n  type: string;\n  width: number;\n  height: number;\n  bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n  impression: string[];\n  start: string[];\n  firstQuartile: string[];\n  midpoint: string[];\n  thirdQuartile: string[];\n  complete: string[];\n  mute: string[];\n  unmute: string[];\n  pause: string[];\n  resume: string[];\n  fullscreen: string[];\n  exitFullscreen: string[];\n  skip: string[];\n  error: string[];\n}\n\ninterface VastAd {\n  id: string;\n  title: string;\n  duration: number;\n  mediaFiles: VastMediaFile[];\n  trackingUrls: VastTrackingUrls;\n  clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = new Map<string, Set<(payload?: any) => void>>();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n\n  let adVideoElement: HTMLVideoElement | undefined;\n  let adHls: Hls | undefined;\n  let adContainerEl: HTMLDivElement | undefined;\n  let currentAd: VastAd | undefined;\n  let podAds: VastAd[] = [];\n  let podIndex = 0;\n  let sessionId: string | undefined;\n  const preloadedAds = new Map<string, VastAd>();\n  const preloadingAds = new Map<string, Promise<void>>();\n  let destroyed = false;\n  let pendingTimeouts: number[] = [];\n\n  const STALL_TIMEOUT_MS = 4000;\n  const STALL_CHECK_INTERVAL_MS = 1000;\n  let stallWatchdogId: number | undefined;\n  let lastAdProgressTime = 0;\n  let lastAdProgressPosition = 0;\n\n  let trackingFired = {\n    impression: false,\n    start: false,\n    firstQuartile: false,\n    midpoint: false,\n    thirdQuartile: false,\n    complete: false,\n  };\n\n  function emit(event: string, payload?: any): void {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const fn of Array.from(set)) {\n      try {\n        fn(payload);\n      } catch (error) {\n        console.warn(\n          `[HlsAdPlayer] Error in event listener for ${event}:`,\n          error\n        );\n      }\n    }\n  }\n\n  function generateSessionId(): string {\n    return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  function fireTrackingPixels(urls: string[]): void {\n    if (!urls || urls.length === 0) return;\n\n    urls.forEach((url) => {\n      try {\n        let trackingUrl = url;\n\n        if (sessionId) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }session_id=${sessionId}`;\n        }\n\n        if (licenseKey) {\n          trackingUrl = `${trackingUrl}${\n            trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n          }license_key=${licenseKey}`;\n        }\n\n        const img = new Image(1, 1);\n        img.src = trackingUrl;\n        console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n      } catch (error) {\n        console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n      }\n    });\n  }\n\n  function getMainStreamQuality(): {\n    width: number;\n    height: number;\n    bitrate: number;\n  } | null {\n    if (!mainHlsInstance || !mainHlsInstance.levels) {\n      return null;\n    }\n\n    const currentLevel = mainHlsInstance.currentLevel;\n    if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n      const autoLevel = mainHlsInstance.loadLevel;\n      if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n        const level = mainHlsInstance.levels[autoLevel];\n        return {\n          width: level.width || 1920,\n          height: level.height || 1080,\n          bitrate: level.bitrate || 5000000,\n        };\n      }\n      return null;\n    }\n\n    const level = mainHlsInstance.levels[currentLevel];\n    return {\n      width: level.width || 1920,\n      height: level.height || 1080,\n      bitrate: level.bitrate || 5000000,\n    };\n  }\n\n  function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n    if (mediaFiles.length === 0) {\n      throw new Error(\"No media files available\");\n    }\n\n    const firstFile = mediaFiles[0];\n    if (!firstFile) {\n      throw new Error(\"No media files available\");\n    }\n\n    if (mediaFiles.length === 1) {\n      return firstFile;\n    }\n\n    const mainQuality = getMainStreamQuality();\n    if (!mainQuality) {\n      console.log(\n        \"[HlsAdPlayer] No main stream quality info, using first media file\"\n      );\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n    const scoredFiles = mediaFiles.map((file) => {\n      const widthDiff = Math.abs(file.width - mainQuality.width);\n      const heightDiff = Math.abs(file.height - mainQuality.height);\n      const resolutionDiff = widthDiff + heightDiff;\n\n      const fileBitrate = (file.bitrate || 5000) * 1000;\n      const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n      const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n      return { file, score, resolutionDiff, bitrateDiff };\n    });\n\n    scoredFiles.sort((a, b) => a.score - b.score);\n\n    const bestMatch = scoredFiles[0];\n    if (!bestMatch) {\n      console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n      return firstFile;\n    }\n\n    console.log(\"[HlsAdPlayer] Selected media file:\", {\n      url: bestMatch.file.url,\n      resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n      bitrate: bestMatch.file.bitrate,\n      score: bestMatch.score,\n      resolutionDiff: bestMatch.resolutionDiff,\n      bitrateDiff: bestMatch.bitrateDiff,\n    });\n\n    return bestMatch.file;\n  }\n\n  function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type === \"application/x-mpegurl\" ||\n      type === \"application/vnd.apple.mpegurl\" ||\n      type.includes(\"mpegurl\") ||\n      url.includes(\".m3u8\")\n    );\n  }\n\n  function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n    const type = mediaFile.type.toLowerCase();\n    const url = mediaFile.url.toLowerCase();\n    return (\n      type.startsWith(\"video/\") ||\n      url.endsWith(\".mp4\") ||\n      url.includes(\".mp4?\")\n    );\n  }\n\n  function createEmptyTrackingUrls(): VastTrackingUrls {\n    return {\n      impression: [],\n      start: [],\n      firstQuartile: [],\n      midpoint: [],\n      thirdQuartile: [],\n      complete: [],\n      mute: [],\n      unmute: [],\n      pause: [],\n      resume: [],\n      fullscreen: [],\n      exitFullscreen: [],\n      skip: [],\n      error: [],\n    };\n  }\n\n  function extractTrackingUrls(scope: Document | Element): VastTrackingUrls {\n    const trackingUrls = createEmptyTrackingUrls();\n\n    scope.querySelectorAll(\"Impression\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.impression.push(url);\n    });\n\n    scope.querySelectorAll(\"Tracking\").forEach((el) => {\n      const event = el.getAttribute(\"event\");\n      const url = el.textContent?.trim();\n      if (event && url) {\n        const eventKey = event as keyof VastTrackingUrls;\n        if (trackingUrls[eventKey]) {\n          trackingUrls[eventKey].push(url);\n        }\n      }\n    });\n\n    scope.querySelectorAll(\"Error\").forEach((el) => {\n      const url = el.textContent?.trim();\n      if (url) trackingUrls.error.push(url);\n    });\n\n    return trackingUrls;\n  }\n\n  function mergeTrackingUrls(\n    target: VastTrackingUrls,\n    source: VastTrackingUrls\n  ): VastTrackingUrls {\n    (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n      if (source[key] && source[key].length > 0) {\n        target[key] = target[key].concat(source[key]);\n      }\n    });\n    return target;\n  }\n\n  function parseVastXml(xmlString: string): VastParseResult {\n    try {\n      const parser = new DOMParser();\n      const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n      const parserError = xmlDoc.querySelector(\"parsererror\");\n      if (parserError) {\n        console.error(\n          \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n          parserError.textContent\n        );\n        return { type: \"empty\" };\n      }\n\n      const adElement = xmlDoc.querySelector(\"Ad\");\n      if (!adElement) {\n        console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n        return { type: \"empty\" };\n      }\n\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = xmlDoc\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = xmlDoc\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        console.log(\n          `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n        );\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      console.log(\n        `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n      );\n\n      mediaFileElements.forEach((mf, index) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        console.log(\n          `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n        );\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: undefined,\n        };\n\n        if (!url) {\n          console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n          return;\n        }\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr\n          ? parseInt(bitrateAttr, 10)\n          : undefined;\n        mediaFile.bitrate =\n          bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n          console.log(\n            `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n          );\n        } else {\n          console.log(\n            `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n          );\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(xmlDoc),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  function parseAdElement(adElement: Element): VastParseResult {\n    try {\n      const adId = adElement.getAttribute(\"id\") || \"unknown\";\n      const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n      const clickThrough = adElement\n        .querySelector(\"ClickThrough\")\n        ?.textContent?.trim();\n\n      const wrapperUri = adElement\n        .querySelector(\"VASTAdTagURI\")\n        ?.textContent?.trim();\n      if (wrapperUri) {\n        return {\n          type: \"wrapper\",\n          vastAdTagUri: wrapperUri,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        };\n      }\n\n      const isNoAdAvailable =\n        adId === \"empty\" ||\n        title.toLowerCase().includes(\"no ad available\") ||\n        title.toLowerCase() === \"no ad available\";\n\n      const durationText =\n        adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n      const durationParts = durationText.split(\":\");\n      const duration =\n        parseInt(durationParts[0] || \"0\", 10) * 3600 +\n        parseInt(durationParts[1] || \"0\", 10) * 60 +\n        parseInt(durationParts[2] || \"0\", 10);\n\n      const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n      const mediaFiles: VastMediaFile[] = [];\n\n      mediaFileElements.forEach((mf) => {\n        const type = mf.getAttribute(\"type\") || \"\";\n        const url = mf.textContent?.trim() || \"\";\n        const width = mf.getAttribute(\"width\") || \"\";\n        const height = mf.getAttribute(\"height\") || \"\";\n\n        if (!url) return;\n\n        const bitrateAttr = mf.getAttribute(\"bitrate\");\n        const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n        const mediaFile: VastMediaFile = {\n          url,\n          type,\n          width: parseInt(width || \"1920\", 10),\n          height: parseInt(height || \"1080\", 10),\n          bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n        };\n\n        if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n          mediaFiles.push(mediaFile);\n        }\n      });\n\n      if (mediaFiles.length === 0) {\n        if (isNoAdAvailable) {\n          console.warn(\n            \"[HlsAdPlayer] Pod <Ad> indicates no ad available\"\n          );\n        } else {\n          console.warn(\"[HlsAdPlayer] No supported media files in pod <Ad>\");\n        }\n        return { type: \"empty\" };\n      }\n\n      return {\n        type: \"inline\",\n        ad: {\n          id: adId,\n          title,\n          duration,\n          mediaFiles,\n          trackingUrls: extractTrackingUrls(adElement),\n          clickThrough,\n        },\n      };\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Error parsing pod <Ad> element:\", error);\n      return { type: \"empty\" };\n    }\n  }\n\n  async function fetchVastXml(\n    vastTagUrl: string,\n    credentials: RequestCredentials = \"include\"\n  ): Promise<string> {\n    const requestVast = (creds: RequestCredentials) =>\n      fetch(vastTagUrl, {\n        mode: \"cors\",\n        credentials: creds,\n        headers: {\n          \"Accept\": \"application/xml, text/xml, */*\",\n        },\n        referrerPolicy: \"no-referrer-when-downgrade\",\n      });\n\n    let response: Response;\n    try {\n      response = await requestVast(credentials);\n    } catch (error) {\n      if (credentials !== \"omit\") {\n        console.warn(\n          `[HlsAdPlayer] VAST fetch failed with credentials=\"${credentials}\", retrying without credentials:`,\n          error\n        );\n        response = await requestVast(\"omit\");\n      } else {\n        throw error;\n      }\n    }\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(\n      vastTagUrl,\n      depth === 0 ? \"include\" : \"omit\"\n    );\n    console.log(\"[HlsAdPlayer] VAST XML received\");\n    console.log(\n      \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n      vastXml.substring(0, 2000)\n    );\n\n    const parsed = parseVastXml(vastXml);\n\n    if (parsed.type === \"empty\") {\n      return null;\n    }\n\n    if (parsed.type === \"wrapper\") {\n      if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n        console.warn(\n          `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n        );\n        return null;\n      }\n\n      mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n      return fetchAndParseVastAd(\n        parsed.vastAdTagUri,\n        depth + 1,\n        accumulatedTracking\n      );\n    }\n\n    mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n    return parsed.ad;\n  }\n\n  async function fetchAndParsePod(vastTagUrl: string): Promise<VastAd[]> {\n    const vastXml = await fetchVastXml(vastTagUrl);\n    console.log(\"[HlsAdPlayer] Pod VAST XML received\");\n\n    const parser = new DOMParser();\n    const xmlDoc = parser.parseFromString(vastXml, \"text/xml\");\n\n    if (xmlDoc.querySelector(\"parsererror\")) {\n      console.error(\"[HlsAdPlayer] Pod VAST XML parsing error (malformed)\");\n      return [];\n    }\n\n    const adElements = Array.from(xmlDoc.querySelectorAll(\"Ad\"));\n    if (adElements.length === 0) {\n      console.warn(\"[HlsAdPlayer] No <Ad> elements found in pod VAST response\");\n      return [];\n    }\n\n    adElements.sort((a, b) => {\n      const aSeq = parseInt(a.getAttribute(\"sequence\") || \"\", 10);\n      const bSeq = parseInt(b.getAttribute(\"sequence\") || \"\", 10);\n      const aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;\n      const bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;\n      return aVal - bVal;\n    });\n\n    const ads: VastAd[] = [];\n    for (const adElement of adElements) {\n      const parsed = parseAdElement(adElement);\n\n      if (parsed.type === \"inline\") {\n        ads.push(parsed.ad);\n      } else if (parsed.type === \"wrapper\") {\n        try {\n          const resolved = await fetchAndParseVastAd(\n            parsed.vastAdTagUri,\n            1,\n            parsed.trackingUrls\n          );\n          if (resolved) {\n            ads.push(resolved);\n          }\n        } catch (error) {\n          console.warn(\n            \"[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:\",\n            error\n          );\n        }\n      }\n    }\n\n    console.log(`[HlsAdPlayer] Parsed ${ads.length} ad(s) from pod VAST response`);\n    return ads;\n  }\n\n  function createAdVideoElement(): HTMLVideoElement {\n    const video = document.createElement(\"video\");\n    video.style.position = \"absolute\";\n    video.style.left = \"0\";\n    video.style.top = \"0\";\n    video.style.width = \"100%\";\n    video.style.height = \"100%\";\n    video.style.objectFit = \"contain\";\n    video.style.backgroundColor = \"#000\";\n    video.playsInline = true;\n    video.muted = false;\n\n    video.volume = 1.0;\n    console.log(\n      `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n    );\n\n    return video;\n  }\n\n  function setupAdEventListeners(): void {\n    if (!adVideoElement || !currentAd) return;\n\n    adVideoElement.addEventListener(\"timeupdate\", () => {\n      if (!currentAd || !adVideoElement) return;\n\n      noteAdProgress();\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      startStallWatchdog();\n      if (!currentAd || trackingFired.start) return;\n      trackingFired.start = true;\n      fireTrackingPixels(currentAd.trackingUrls.start);\n      console.log(\"[HlsAdPlayer] Ad started playing\");\n    });\n\n    adVideoElement.addEventListener(\"ended\", () => {\n      if (!currentAd || trackingFired.complete) return;\n      trackingFired.complete = true;\n      fireTrackingPixels(currentAd.trackingUrls.complete);\n      console.log(\"[HlsAdPlayer] Ad completed\");\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdComplete();\n    });\n\n    adVideoElement.addEventListener(\"error\", (e) => {\n      if (!adPlaying) return;\n      console.error(\"[HlsAdPlayer] Ad video error:\", e);\n      if (currentAd) {\n        fireTrackingPixels(currentAd.trackingUrls.error);\n      }\n\n      if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n        return;\n      }\n\n      handleAdError();\n    });\n\n    adVideoElement.addEventListener(\"volumechange\", () => {\n      if (!currentAd) return;\n      if (adVideoElement!.muted) {\n        fireTrackingPixels(currentAd.trackingUrls.mute);\n      } else {\n        fireTrackingPixels(currentAd.trackingUrls.unmute);\n      }\n    });\n\n    adVideoElement.addEventListener(\"pause\", () => {\n      if (currentAd && !adVideoElement!.ended) {\n        fireTrackingPixels(currentAd.trackingUrls.pause);\n      }\n    });\n\n    adVideoElement.addEventListener(\"play\", () => {\n      if (currentAd && adVideoElement!.currentTime > 0) {\n        fireTrackingPixels(currentAd.trackingUrls.resume);\n      }\n    });\n  }\n\n  function setAdPlayingFlag(isPlaying: boolean): void {\n    if (isPlaying) {\n      contentVideo.dataset.stormcloudAdPlaying = \"true\";\n    } else {\n      delete contentVideo.dataset.stormcloudAdPlaying;\n    }\n  }\n\n  function resetQuartileTracking(preserveImpression: boolean): void {\n    trackingFired = {\n      impression: preserveImpression ? trackingFired.impression : false,\n      start: false,\n      firstQuartile: false,\n      midpoint: false,\n      thirdQuartile: false,\n      complete: false,\n    };\n  }\n\n  function loadCurrentAdMedia(): void {\n    if (!adVideoElement || !currentAd) {\n      throw new Error(\"No ad video element or ad to load\");\n    }\n\n    const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n    if (!mediaFile) {\n      throw new Error(\"No media file available for ad\");\n    }\n\n    const isHlsAd = isHlsMediaFile(mediaFile);\n    console.log(\n      `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad (pod ${podIndex + 1}/${podAds.length || 1}) from: ${mediaFile.url}`\n    );\n\n    if (isHlsAd && Hls.isSupported()) {\n      if (adHls) {\n        adHls.destroy();\n      }\n\n      adHls = new Hls({\n        enableWorker: true,\n        lowLatencyMode: false,\n      });\n\n      adHls.loadSource(mediaFile.url);\n      adHls.attachMedia(adVideoElement);\n\n      adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n        console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n        adVideoElement!.play().catch((error) => {\n          console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n          handleAdError();\n        });\n      });\n\n      adHls.on(Hls.Events.ERROR, (_event, data) => {\n        console.error(\"[HlsAdPlayer] HLS error:\", data);\n        if (data.fatal) {\n          handleAdError();\n        }\n      });\n    } else if (\n      isHlsAd &&\n      adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n    ) {\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n        handleAdError();\n      });\n    } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n      if (adHls) {\n        adHls.destroy();\n        adHls = undefined;\n      }\n\n      adVideoElement.src = mediaFile.url;\n      adVideoElement.load();\n      adVideoElement.play().catch((error) => {\n        console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n        handleAdError();\n      });\n    } else {\n      throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n    }\n  }\n\n  function advanceToNextPodAd(): boolean {\n    if (podIndex >= podAds.length - 1) {\n      return false;\n    }\n\n    podIndex++;\n    currentAd = podAds[podIndex];\n    resetQuartileTracking(false);\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.impression);\n      trackingFired.impression = true;\n      console.log(\n        `[HlsAdPlayer] Advancing to next pod ad (${podIndex + 1}/${podAds.length}): ${currentAd.title}, duration: ${currentAd.duration}s`\n      );\n    }\n\n    try {\n      loadCurrentAdMedia();\n      emit(\"pod_ad_started\", { index: podIndex, total: podAds.length });\n      return true;\n    } catch (error) {\n      console.error(\"[HlsAdPlayer] Failed to load next pod ad:\", error);\n      return false;\n    }\n  }\n\n  function clearStallWatchdog(): void {\n    if (stallWatchdogId != null) {\n      clearInterval(stallWatchdogId);\n      stallWatchdogId = undefined;\n    }\n  }\n\n  function noteAdProgress(): void {\n    lastAdProgressTime = Date.now();\n    if (adVideoElement) {\n      lastAdProgressPosition = adVideoElement.currentTime;\n    }\n  }\n\n  function handleAdStall(): void {\n    console.warn(\n      \"[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame\"\n    );\n    clearStallWatchdog();\n\n    if (currentAd) {\n      fireTrackingPixels(currentAd.trackingUrls.error);\n    }\n\n    if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {\n      return;\n    }\n\n    handleAdError();\n  }\n\n  function startStallWatchdog(): void {\n    clearStallWatchdog();\n    noteAdProgress();\n    stallWatchdogId = window.setInterval(() => {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {\n        noteAdProgress();\n        return;\n      }\n\n      if (adVideoElement.paused) {\n        noteAdProgress();\n        return;\n      }\n\n      if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {\n        handleAdStall();\n      }\n    }, STALL_CHECK_INTERVAL_MS) as unknown as number;\n  }\n\n  function releaseAdDecoder(): void {\n    if (adHls) {\n      adHls.destroy();\n      adHls = undefined;\n    }\n\n    if (adVideoElement) {\n      adVideoElement.pause();\n      adVideoElement.removeAttribute(\"src\");\n      try {\n        adVideoElement.load();\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] adVideoElement.load() threw after src removal:\", error);\n      }\n      adVideoElement.remove();\n      adVideoElement = undefined;\n    }\n\n    if (adContainerEl) {\n      adContainerEl.style.display = \"none\";\n      adContainerEl.style.pointerEvents = \"none\";\n    }\n  }\n\n  function handleAdComplete(): void {\n    console.log(\"[HlsAdPlayer] Handling ad completion\");\n    clearStallWatchdog();\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    releaseAdDecoder();\n\n    if (!options?.continueLiveStreamDuringAds) {\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\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((error) => {\n          console.error(\"[HlsAdPlayer] Error resuming content playback in live mode:\", error);\n        });\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    clearStallWatchdog();\n    adPlaying = false;\n    setAdPlayingFlag(false);\n\n    contentVideo.muted = true;\n\n    releaseAdDecoder();\n\n    if (!options?.continueLiveStreamDuringAds) {\n      contentVideo.style.visibility = \"visible\";\n      contentVideo.style.opacity = \"1\";\n    }\n\n    emit(\"ad_error\");\n  }\n\n  return {\n    initialize() {\n      console.log(\"[HlsAdPlayer] Initializing\");\n\n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"30\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n    },\n\n    async requestAds(vastTagUrl: string) {\n      console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n      if (adPlaying) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n        );\n        return Promise.reject(new Error(\"Ad already playing\"));\n      }\n\n      try {\n        sessionId = generateSessionId();\n        let ads: VastAd[] = [];\n\n        if (preloadedAds.has(vastTagUrl)) {\n          const preloaded = preloadedAds.get(vastTagUrl);\n          preloadedAds.delete(vastTagUrl);\n          if (preloaded) {\n            ads = [preloaded];\n          }\n          console.log(\n            \"[HlsAdPlayer] Using preloaded VAST response:\",\n            vastTagUrl\n          );\n        } else {\n          ads = await fetchAndParsePod(vastTagUrl);\n        }\n\n        if (!ads.length) {\n          console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n          emit(\"ad_error\");\n          return Promise.reject(new Error(\"No ads available from VAST response\"));\n        }\n\n        podAds = ads;\n        podIndex = 0;\n        currentAd = ads[0];\n        console.log(\n          `[HlsAdPlayer] Pod parsed: ${ads.length} ad(s), first=\"${currentAd?.title}\", duration=${currentAd?.duration}s`\n        );\n\n        if (currentAd) {\n          fireTrackingPixels(currentAd.trackingUrls.impression);\n          trackingFired.impression = true;\n        }\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n        emit(\"ad_error\");\n        return Promise.reject(error);\n      }\n    },\n    async play() {\n      if (!currentAd) {\n        console.warn(\n          \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n        );\n        return Promise.reject(new Error(\"No ad loaded\"));\n      }\n\n      console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n      try {\n        if (!adVideoElement) {\n          adVideoElement = createAdVideoElement();\n          adContainerEl?.appendChild(adVideoElement);\n          setupAdEventListeners();\n        }\n\n        resetQuartileTracking(true);\n\n        const contentVolume = contentVideo.volume;\n        originalVolume = Math.max(\n          0,\n          Math.min(1, contentVolume || originalVolume)\n        );\n\n        if (!options?.continueLiveStreamDuringAds) {\n          contentVideo.pause();\n          console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n        } else {\n          console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n        }\n\n        console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n        contentVideo.muted = true;\n        adPlaying = true;\n        setAdPlayingFlag(true);\n\n        if (adVideoElement) {\n          adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n          adVideoElement.muted = originalMutedState;\n          console.log(\n            `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n          );\n        }\n\n        if (adContainerEl) {\n          adContainerEl.style.display = \"flex\";\n          adContainerEl.style.pointerEvents = \"auto\";\n        }\n\n        emit(\"content_pause\");\n\n        loadCurrentAdMedia();\n\n        return Promise.resolve();\n      } catch (error) {\n        console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n        handleAdError();\n        return Promise.reject(error);\n      }\n    },\n    pause() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && !adVideoElement.paused) {\n          adVideoElement.pause();\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n      }\n    },\n    resume() {\n      if (!adPlaying || !adVideoElement) {\n        return;\n      }\n\n      try {\n        if (adVideoElement && adVideoElement.paused) {\n          adVideoElement.play().catch(() => {});\n        }\n      } catch (error) {\n        console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n      }\n    },\n    async stop() {\n      console.log(\"[HlsAdPlayer] Stopping ad\");\n      clearStallWatchdog();\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      releaseAdDecoder();\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((error) => {\n            console.error(\"[HlsAdPlayer] Error resuming content playback in live mode on stop:\", error);\n          });\n        }\n      }\n\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n    },\n\n    destroy() {\n      console.log(\"[HlsAdPlayer] Destroying\");\n      destroyed = true;\n      clearStallWatchdog();\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      releaseAdDecoder();\n\n      if (adContainerEl?.parentElement) {\n        adContainerEl.parentElement.removeChild(adContainerEl);\n      }\n\n      adContainerEl = undefined;\n      currentAd = undefined;\n      podAds = [];\n      podIndex = 0;\n      listeners.clear();\n      preloadedAds.clear();\n      preloadingAds.clear();\n    },\n\n    isAdPlaying() {\n      return adPlaying;\n    },\n\n    resize(width: number, height: number) {\n      console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n      if (adContainerEl) {\n        adContainerEl.style.width = `${width}px`;\n        adContainerEl.style.height = `${height}px`;\n      }\n\n      if (adVideoElement) {\n        adVideoElement.style.width = `${width}px`;\n        adVideoElement.style.height = `${height}px`;\n      }\n    },\n\n    on(event: string, listener: (payload?: any) => void) {\n      if (!listeners.has(event)) listeners.set(event, new Set());\n      listeners.get(event)!.add(listener);\n    },\n\n    off(event: string, listener: (payload?: any) => void) {\n      listeners.get(event)?.delete(listener);\n    },\n\n    updateOriginalMutedState(muted: boolean, volume?: number) {\n      const nextVolume =\n        typeof volume === \"number\" && !Number.isNaN(volume)\n          ? Math.max(0, Math.min(1, volume))\n          : originalVolume;\n      console.log(\n        `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n      );\n      originalMutedState = muted;\n      originalVolume = nextVolume;\n    },\n\n    getOriginalMutedState() {\n      return originalMutedState;\n    },\n    getOriginalVolume() {\n      return originalVolume;\n    },\n\n    setAdVolume(volume: number) {\n      if (adVideoElement && adPlaying) {\n        const clamped = Math.max(0, Math.min(1, volume));\n        adVideoElement.volume = clamped;\n        adVideoElement.muted = clamped === 0;\n      }\n    },\n\n    getAdVolume(): number {\n      if (adVideoElement && adPlaying) {\n        return adVideoElement.volume;\n      }\n      return 1;\n    },\n    showPlaceholder() {\n      contentVideo.style.opacity = \"0\";\n      contentVideo.style.visibility = \"hidden\";\n      \n      if (!adContainerEl) {\n        const container = document.createElement(\"div\");\n        container.style.position = \"absolute\";\n        container.style.left = \"0\";\n        container.style.top = \"0\";\n        container.style.right = \"0\";\n        container.style.bottom = \"0\";\n        container.style.display = \"none\";\n        container.style.alignItems = \"center\";\n        container.style.justifyContent = \"center\";\n        container.style.pointerEvents = \"none\";\n        container.style.zIndex = \"10\";\n        container.style.backgroundColor = \"#000\";\n\n        contentVideo.parentElement?.appendChild(container);\n        adContainerEl = container;\n      }\n\n      if (adContainerEl) {\n        adContainerEl.style.display = \"flex\";\n        adContainerEl.style.pointerEvents = \"auto\";\n      }\n    },\n    hidePlaceholder() {\n      if (adContainerEl) {\n        adContainerEl.style.display = \"none\";\n        adContainerEl.style.pointerEvents = \"none\";\n      }\n      \n      if (!adPlaying) {\n        contentVideo.style.visibility = \"visible\";\n        contentVideo.style.opacity = \"1\";\n      }\n    },\n    getLoadedAdDuration() {\n      return currentAd?.duration;\n    },\n    getLoadedAdId() {\n      return currentAd?.id;\n    },\n    getPodAdCount() {\n      return podAds.length;\n    },\n    getPodTotalDurationMs() {\n      return podAds.reduce(\n        (total, ad) => total + (ad.duration > 0 ? ad.duration * 1000 : 0),\n        0\n      );\n    },\n  };\n}\n","const PRIVATE_HOST_PATTERNS: RegExp[] = [\n  /^localhost$/i,\n  /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^0\\.0\\.0\\.0$/,\n  /^::1$/,\n  /^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/,\n  /^172\\.(1[6-9]|2\\d|3[0-1])\\.\\d{1,3}\\.\\d{1,3}$/,\n];\n\nexport function isLocalDevHost(hostname: string): boolean {\n  const host = hostname.replace(/^\\[/, \"\").replace(/\\]$/, \"\").toLowerCase();\n  if (!host) return false;\n  if (host.endsWith(\".local\") || host.endsWith(\".localhost\")) return true;\n  return PRIVATE_HOST_PATTERNS.some((pattern) => pattern.test(host));\n}\n\nexport function toDevSafeUrl(rawUrl: string | undefined): string {\n  if (!rawUrl) return rawUrl ?? \"\";\n\n  let url: URL;\n  try {\n    url = new URL(rawUrl);\n  } catch {\n    return rawUrl;\n  }\n\n  if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n    return rawUrl;\n  }\n\n  if (!isLocalDevHost(url.hostname)) {\n    return rawUrl;\n  }\n\n  const cleanPath = url.pathname.replace(/\\/{2,}/g, \"/\") || \"/index.html\";\n  return `file://${cleanPath}`;\n}\n","import { toDevSafeUrl } from \"../utils/devUrl\";\n\ndeclare 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 = toDevSafeUrl(\n          options.descriptionUrl ||\n            (typeof window !== \"undefined\" ? window.location.href : \"\")\n        );\n        request.iconsSupported = true;\n        request.playerType = \"StormcloudVideoPlayer\";\n        request.playerVersion = \"1.0\";\n        request.supportedApiFrameworks = \"2,7,9\";\n        request.url = toDevSafeUrl(\n          options.descriptionUrl ||\n            (typeof window !== \"undefined\" ? window.location.href : \"\")\n        );\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        console.log(\n          \"[PAL] NonceRequest before generateNonce:\",\n          JSON.stringify({\n            adWillAutoPlay: request.adWillAutoPlay,\n            adWillPlayMuted: request.adWillPlayMuted,\n            playerVolume: request.playerVolume,\n            continuousPlayback: request.continuousPlayback,\n            descriptionUrl: request.descriptionUrl,\n            iconsSupported: request.iconsSupported,\n            playerType: request.playerType,\n            playerVersion: request.playerVersion,\n            supportedApiFrameworks: request.supportedApiFrameworks,\n            url: request.url,\n            videoWidth: request.videoWidth,\n            videoHeight: request.videoHeight,\n            ppid: request.ppid,\n            sessionId: request.sessionId,\n          }, null, 2)\n        );\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\nconst KEEPALIVE_SECONDS = 30;\nconst CONNECT_TIMEOUT_MS = 10_000;\n\nconst RECONNECT_BASE_MS = 5_000;\nconst RECONNECT_MAX_MS = 60_000;\nconst MAX_RECONNECT_ATTEMPTS = 8;\nconst COOLDOWN_MS = 10 * 60_000;\n\nexport type MQTTStatus = \"disconnected\" | \"connecting\" | \"connected\" | \"error\";\n\nlet client: MqttClient | null = null;\nlet status: MQTTStatus = \"disconnected\";\nlet reconnectAttempts = 0;\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\nlet stopped = false;\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\nfunction clearReconnectTimer(): void {\n  if (reconnectTimer) {\n    clearTimeout(reconnectTimer);\n    reconnectTimer = null;\n  }\n}\n\nfunction teardownClient(): void {\n  if (client) {\n    try {\n      client.removeAllListeners();\n      client.end(true);\n    } catch {\n      // ignore teardown errors\n    }\n    client = null;\n  }\n}\n\nfunction scheduleReconnect(): void {\n  if (stopped || !isMQTTEnabled() || reconnectTimer) return;\n\n  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {\n    console.warn(\n      `${LOG} giving up after ${reconnectAttempts} attempts; cooling down for ${\n        COOLDOWN_MS / 60_000\n      }m`\n    );\n    teardownClient();\n    status = \"disconnected\";\n    reconnectTimer = setTimeout(() => {\n      reconnectTimer = null;\n      reconnectAttempts = 0;\n      openConnection();\n    }, COOLDOWN_MS);\n    return;\n  }\n\n  const delay = Math.min(\n    RECONNECT_MAX_MS,\n    RECONNECT_BASE_MS * 2 ** reconnectAttempts\n  );\n  const jitter = Math.floor(Math.random() * 1_000);\n  reconnectAttempts += 1;\n\n  reconnectTimer = setTimeout(() => {\n    reconnectTimer = null;\n    openConnection();\n  }, delay + jitter);\n}\n\nfunction openConnection(): void {\n  if (stopped || !isMQTTEnabled()) return;\n\n  teardownClient();\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: KEEPALIVE_SECONDS,\n      clean: true,\n      // Disable MQTT.js internal reconnect; we manage reconnection ourselves.\n      reconnectPeriod: 0,\n      connectTimeout: CONNECT_TIMEOUT_MS,\n      queueQoSZero: false,\n      reschedulePings: true,\n      // Root-cause fix for the Tizen 4.0 \"Keepalive timeout\" loop: MQTT.js's\n      // default timerVariant \"auto\" runs the keepalive interval inside a\n      // Blob-URL Web Worker (via worker-timers). On Samsung Tizen 4.0 (old\n      // WebKit) served from a file:// origin that worker can't tick reliably,\n      // so the keepalive counter trips onKeepaliveTimeout almost immediately\n      // after connect. Force the native setInterval timer instead; the main\n      // thread is free because video is decoded by the native AVPlay pipeline.\n      timerVariant: \"native\",\n    });\n  } catch (err) {\n    status = \"error\";\n    console.warn(`${LOG} connect() threw:`, err);\n    scheduleReconnect();\n    return;\n  }\n\n  client.on(\"connect\", () => {\n    status = \"connected\";\n    reconnectAttempts = 0;\n    clearReconnectTimer();\n    console.info(`${LOG} connected to ${url}`);\n  });\n\n  client.on(\"offline\", () => {\n    if (status === \"connected\") status = \"disconnected\";\n    console.warn(`${LOG} offline`);\n    scheduleReconnect();\n  });\n\n  client.on(\"error\", (err) => {\n    status = \"error\";\n    console.warn(`${LOG} error:`, err.message);\n    scheduleReconnect();\n  });\n\n  client.on(\"close\", () => {\n    if (status === \"connected\") status = \"disconnected\";\n    scheduleReconnect();\n  });\n}\n\nexport function initMQTTClient(): void {\n  if (client || !isMQTTEnabled()) return;\n  stopped = false;\n  reconnectAttempts = 0;\n  openConnection();\n}\n\nexport function ensureMQTTClient(): void {\n  if (isMQTTEnabled() && !client && !reconnectTimer) {\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 || !client.connected) {\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  stopped = true;\n  clearReconnectTimer();\n  teardownClient();\n  reconnectAttempts = 0;\n  status = \"disconnected\";\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 = readPersistentId(storageKey);\n  if (existing) {\n    writePersistentId(storageKey, existing);\n    return existing;\n  }\n\n  const id = createUuid();\n  writePersistentId(storageKey, id);\n  return id;\n}\n\nfunction getOrCreateCtvSessionId(): string {\n  const existing = readPersistentId(CTV_SESSION_STORAGE_KEY);\n  if (existing) {\n    writePersistentId(CTV_SESSION_STORAGE_KEY, existing);\n    return existing;\n  }\n\n  const sessionId = createUuid();\n  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);\n  return sessionId;\n}\n\nfunction readPersistentId(storageKey: string): string | undefined {\n  return readStoredString(storageKey) || readCookie(storageKey);\n}\n\nfunction writePersistentId(storageKey: string, value: string): void {\n  try {\n    window.localStorage?.setItem(storageKey, value);\n  } catch {}\n  writeCookie(storageKey, value);\n}\n\nconst PERSISTENT_ID_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5; // ~5 years\n\nfunction readCookie(name: string): string | undefined {\n  if (typeof document === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const prefix = encodeURIComponent(name) + \"=\";\n    const parts = document.cookie ? document.cookie.split(\";\") : [];\n    for (const part of parts) {\n      const entry = part.trim();\n      if (entry.startsWith(prefix)) {\n        return decodeURIComponent(entry.slice(prefix.length)) || undefined;\n      }\n    }\n  } catch {}\n\n  return undefined;\n}\n\nfunction writeCookie(name: string, value: string): void {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n\n  try {\n    document.cookie =\n      encodeURIComponent(name) +\n      \"=\" +\n      encodeURIComponent(value) +\n      \";path=/;max-age=\" +\n      PERSISTENT_ID_COOKIE_MAX_AGE +\n      \";SameSite=Lax\";\n  } catch {}\n}\n\nfunction createUuid(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n\n  const bytes = new Uint8Array(16);\n  if (typeof crypto !== \"undefined\" && typeof crypto.getRandomValues === \"function\") {\n    crypto.getRandomValues(bytes);\n  } else {\n    let seed = Date.now() ^ Math.floor(performanceNow() * 1e3);\n    for (let i = 0; i < 16; i++) {\n      seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n      bytes[i] = (seed ^ Math.floor(Math.random() * 256)) & 0xff;\n    }\n  }\n\n  bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n  bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n  let hex = \"\";\n  for (let i = 0; i < 16; i++) {\n    hex += (bytes[i] ?? 0).toString(16).padStart(2, \"0\");\n  }\n\n  return (\n    hex.slice(0, 8) +\n    \"-\" +\n    hex.slice(8, 12) +\n    \"-\" +\n    hex.slice(12, 16) +\n    \"-\" +\n    hex.slice(16, 20) +\n    \"-\" +\n    hex.slice(20, 32)\n  );\n}\n\nfunction performanceNow(): number {\n  try {\n    if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n      return performance.now();\n    }\n  } catch {}\n  return 0;\n}\n\nfunction readPlatformNativeDeviceId(): {\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") return {};\n\n  try {\n    const adinfo = (window as any).webapis?.adinfo;\n    if (adinfo) {\n      const tifa: unknown =\n        typeof adinfo.getTIFA === \"function\" ? adinfo.getTIFA() : adinfo.tifa;\n      if (typeof tifa === \"string\" && tifa && !isMacroPlaceholder(tifa)) {\n        const lat: unknown =\n          typeof adinfo.isLATEnabled === \"function\"\n            ? adinfo.isLATEnabled()\n            : undefined;\n        return {\n          deviceId: tifa,\n          deviceIdType: \"tifa\",\n          ...(typeof lat === \"boolean\" ? { limitAdTracking: lat } : {}),\n        };\n      }\n    }\n  } catch {}\n\n  try {\n    const webOSDev = (window as any).webOSDev;\n    if (webOSDev) {\n      const lgudid: unknown =\n        typeof webOSDev.LGUDID === \"function\"\n          ? webOSDev.LGUDID()\n          : webOSDev.lgudid ?? webOSDev.LGUDID;\n      if (typeof lgudid === \"string\" && lgudid) {\n        if (isZeroedAdId(lgudid)) {\n          return { deviceIdType: \"lgudid\", limitAdTracking: true };\n        }\n        if (!isMacroPlaceholder(lgudid)) {\n          return { deviceId: lgudid, deviceIdType: \"lgudid\", limitAdTracking: false };\n        }\n      }\n    }\n  } catch {}\n\n  try {\n    const roku = (window as any).Roku;\n    if (roku) {\n      const rida: unknown =\n        typeof roku.getPublisherUniqueId === \"function\"\n          ? roku.getPublisherUniqueId()\n          : roku.rida;\n      if (typeof rida === \"string\" && rida && !isMacroPlaceholder(rida)) {\n        return { deviceId: rida, deviceIdType: \"rida\", limitAdTracking: false };\n      }\n    }\n  } catch {}\n\n  return {};\n}\n\nconst ZEROED_AD_ID_PATTERNS: ReadonlySet<string> = new Set([\n  \"38400000-8cf0-11bd-b23e-10b96e40000d\",\n  \"00000000-0000-0000-0000-000000000000\",\n]);\n\nfunction isMacroPlaceholder(value: string): boolean {\n  const t = value.trim();\n  return !t ||\n    /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/.test(t) ||\n    /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(t) ||\n    ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());\n}\n\nfunction isZeroedAdId(value: string): boolean {\n  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());\n}\n\nfunction readNativeBridgeSignals(): {\n  contentUrl?: string;\n  appId?: string;\n  appName?: string;\n  deviceId?: string;\n  deviceIdType?: string;\n  limitAdTracking?: boolean;\n} {\n  if (typeof window === \"undefined\") {\n    return {};\n  }\n\n  const candidates = [\n    (window as any).__STORMCLOUD_CTV_AD_INFO__,\n    (window as any).__STORMCLOUD_CTV__,\n    (window as any).stormcloudCtv,\n    (window as any).AiryTV,\n    (window as any).Android,\n    (window as any).webOS,\n    (window as any).tizen,\n    (window as any).amazon,\n  ].filter(Boolean);\n\n  for (const source of candidates) {\n    const contentUrl =\n      readBridgeValue(source, [\"contentUrl\", \"url\", \"videoUrl\", \"canonicalUrl\"]) ||\n      undefined;\n    const appId =\n      readBridgeValue(source, [\"appId\", \"msid\", \"applicationId\", \"packageName\"]) ||\n      undefined;\n    const appName =\n      readBridgeValue(source, [\"appName\", \"an\", \"applicationName\"]) || undefined;\n    const deviceId =\n      readBridgeValue(source, [\n        \"rdid\",\n        \"ifa\",\n        \"advertisingId\",\n        \"adId\",\n        \"deviceId\",\n        \"lgudid\",\n        \"LGUDID\",\n        \"tifa\",\n        \"rida\",\n        \"afai\",\n        \"aaid\",\n      ]) || undefined;\n\n    if (!contentUrl && !deviceId && !appId && !appName) continue;\n\n    const deviceIdType =\n      readBridgeValue(source, [\n        \"idtype\",\n        \"deviceIdType\",\n        \"advertisingIdType\",\n        \"idType\",\n      ]) || inferDeviceIdType();\n    const limitAdTracking = readBridgeBoolean(source, [\n      \"is_lat\",\n      \"limitAdTracking\",\n      \"limitedAdTracking\",\n      \"lat\",\n    ]);\n\n    return {\n      ...(contentUrl ? { contentUrl } : {}),\n      ...(appId ? { appId } : {}),\n      ...(appName ? { appName } : {}),\n      ...(deviceId ? { deviceId } : {}),\n      ...(deviceId && deviceIdType ? { deviceIdType } : {}),\n      ...(deviceId && limitAdTracking != null ? { limitAdTracking } : {}),\n    };\n  }\n\n  return {};\n}\n\nfunction readBridgeValue(source: any, keys: string[]): string | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    if (typeof value === \"string\" && value) {\n      return value;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = value.call(source);\n        if (typeof result === \"string\" && result) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readBridgeBoolean(source: any, keys: string[]): boolean | undefined {\n  for (const key of keys) {\n    const value = source?.[key];\n    const normalized = normalizeBoolean(value);\n    if (normalized != null) {\n      return normalized;\n    }\n    if (typeof value === \"function\") {\n      try {\n        const result = normalizeBoolean(value.call(source));\n        if (result != null) {\n          return result;\n        }\n      } catch {}\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredDeviceId(): string | undefined {\n  for (const key of DEVICE_ID_STORAGE_KEYS) {\n    const value = readStoredString(key);\n    if (value) {\n      return value;\n    }\n  }\n  return undefined;\n}\n\nfunction readStoredString(key: string): string | undefined {\n  if (typeof window === \"undefined\") {\n    return undefined;\n  }\n\n  try {\n    const value = window.localStorage?.getItem(key);\n    return value || undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction readStoredLimitAdTracking(): boolean | undefined {\n  return normalizeBoolean(\n    readStoredString(\"limitAdTracking\") ||\n      readStoredString(\"limitedAdTracking\") ||\n      readStoredString(\"is_lat\")\n  );\n}\n\nfunction normalizeBoolean(value: unknown): boolean | undefined {\n  if (typeof value === \"boolean\") {\n    return value;\n  }\n  if (typeof value === \"number\") {\n    return value === 1;\n  }\n  if (typeof value === \"string\") {\n    const normalized = value.toLowerCase();\n    if (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\") {\n      return true;\n    }\n    if (normalized === \"0\" || normalized === \"false\" || normalized === \"no\") {\n      return false;\n    }\n  }\n  return undefined;\n}\n","import type {\n  ClientInfo,\n  AdDetectInfo,\n  AdLoadedInfo,\n  AdImpressionInfo,\n  PlayerAnalyticsContext,\n  StormcloudVideoPlayerConfig,\n} from \"../types\";\n\nimport { buildPlayerTopic, isMQTTEnabled } from \"./mqttConfig\";\nimport { ensureMQTTClient, publishMQTT } from \"./mqttClient\";\nimport {\n  getOrCreateStoredUuid,\n  PLAYER_ID_STORAGE_KEY,\n  resolveNativeDeviceId,\n} from \"./vastEnvironmentSignals\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function buildAnalyticsContext(\n  config: Pick<StormcloudVideoPlayerConfig, \"debugAdTiming\" | \"isLiveStream\">\n): PlayerAnalyticsContext {\n  const context: PlayerAnalyticsContext = {};\n  if (config.debugAdTiming) {\n    context.debugAdTiming = true;\n  }\n  if (config.isLiveStream !== undefined) {\n    context.inputStreamType = config.isLiveStream ? \"live\" : \"vod\";\n  }\n  return context;\n}\n\nexport function getClientInfo(): ClientInfo {\n  const ua = navigator.userAgent;\n  const platform = navigator.platform;\n  const vendor = navigator.vendor || \"\";\n  const maxTouchPoints = navigator.maxTouchPoints || 0;\n  const memory = (navigator as any).deviceMemory || null;\n  const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n  const screenInfo = {\n    width: screen?.width,\n    height: screen?.height,\n    availWidth: screen?.availWidth,\n    availHeight: screen?.availHeight,\n    orientation: (screen?.orientation as any)?.type || \"\",\n    pixelDepth: screen?.pixelDepth,\n  };\n\n  let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n  let brand = \"Unknown\";\n  let os = \"Unknown\";\n  let model = \"\";\n  let isSmartTV = false;\n  let isAndroid = false;\n  let isWebView = false;\n  let isWebApp = false;\n\n  if (ua.includes(\"Web0S\")) {\n    brand = \"LG\";\n    os = \"webOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n    model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n  } else if (ua.includes(\"Tizen\")) {\n    brand = \"Samsung\";\n    os = \"Tizen\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n    const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n    const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n    model = tizenMatch\n      ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n      : \"Tizen TV\";\n  } else if (ua.includes(\"Philips\")) {\n    brand = \"Philips\";\n    os = \"Saphi\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n    brand = \"Sharp\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n  ) {\n    brand = \"Sony\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (\n    ua.includes(\"Android\") &&\n    (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n  ) {\n    brand = \"LG\";\n    os = \"Android TV\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n    brand = \"Roku\";\n    os = \"Roku OS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  } else if (ua.includes(\"AppleTV\")) {\n    brand = \"Apple\";\n    os = \"tvOS\";\n    isSmartTV = true;\n    deviceType = \"tv\";\n  }\n\n  if (ua.includes(\"Android\")) {\n    isAndroid = true;\n    os = \"Android\";\n    deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n    if (\n      ua.includes(\"Android\") &&\n      (maxTouchPoints === 0 ||\n        ua.includes(\"Google TV\") ||\n        ua.includes(\"XiaoMi\"))\n    ) {\n      deviceType = \"tv\";\n      isSmartTV = true;\n      brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n    }\n\n    const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n    if (androidModelMatch && androidModelMatch[1]) {\n      model = androidModelMatch[1];\n    }\n  }\n\n  if (/iPad|iPhone|iPod/.test(ua)) {\n    os = \"iOS\";\n    deviceType = \"mobile\";\n    brand = \"Apple\";\n    if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n      deviceType = \"tablet\";\n    }\n  }\n\n  if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n    if (ua.includes(\"Windows\")) {\n      os = \"Windows\";\n      deviceType = \"desktop\";\n    } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n      os = \"macOS\";\n      deviceType = \"desktop\";\n      if (maxTouchPoints > 1) deviceType = \"tablet\";\n    } else if (ua.includes(\"Linux\")) {\n      os = \"Linux\";\n      deviceType = \"desktop\";\n    }\n  }\n\n  if (brand === \"Unknown\") {\n    if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n    if (vendor.includes(\"Apple\")) brand = \"Apple\";\n    if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n  }\n\n  isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n  if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n    isWebView = true;\n  }\n\n  isWebApp =\n    window.matchMedia(\"(display-mode: standalone)\").matches ||\n    (window.navigator as any).standalone === true ||\n    window.screen?.orientation?.angle !== undefined;\n\n  return {\n    brand,\n    os,\n    model: model || ua.substring(0, 50) + \"...\",\n    deviceType,\n    isSmartTV,\n    isAndroid,\n    isWebView,\n    isWebApp,\n    domain: window.location.hostname,\n    origin: window.location.origin,\n    path: window.location.pathname,\n    userAgent: ua,\n    vendor,\n    platform,\n    screen: screenInfo,\n    hardwareConcurrency,\n    deviceMemory: memory,\n    maxTouchPoints,\n    language: navigator.language,\n    languages: navigator.languages?.join(\",\") || \"\",\n    cookieEnabled: navigator.cookieEnabled,\n    doNotTrack: navigator.doNotTrack || \"\",\n    referrer: document.referrer,\n    visibilityState: document.visibilityState,\n  };\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n  if (typeof crypto !== \"undefined\" && crypto.subtle?.digest) {\n    try {\n      await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n      let encodedData: BufferSource;\n      if (typeof TextEncoder !== \"undefined\") {\n        encodedData = new TextEncoder().encode(input);\n      } else {\n        const utf8 = unescape(encodeURIComponent(input));\n        const buffer = new Uint8Array(utf8.length);\n        for (let i = 0; i < utf8.length; i++) {\n          buffer[i] = utf8.charCodeAt(i);\n        }\n        encodedData = buffer;\n      }\n\n      const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n      return Array.from(new Uint8Array(hashBuffer))\n        .map((b) => b.toString(16).padStart(2, \"0\"))\n        .join(\"\");\n    } catch {\n      console.warn(\n        \"[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash\"\n      );\n    }\n  }\n\n  let hash = 0;\n  for (let i = 0; i < input.length; i++) {\n    const char = input.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n\n  const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n  const timestamp = Date.now().toString(16).padStart(12, \"0\");\n  const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n  return (fallbackHash + timestamp + random).padEnd(64, \"0\");\n}\n\nfunction resolvePlayerIdentitySeed(clientInfo: ClientInfo): string {\n  const nativeDeviceId = resolveNativeDeviceId();\n  if (nativeDeviceId) {\n    return `device:${nativeDeviceId}`;\n  }\n\n  const persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);\n  if (persistedId) {\n    return `persisted:${persistedId}`;\n  }\n\n  return `fingerprint:${JSON.stringify(clientInfo)}`;\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n  if (cachedBrowserId) {\n    return cachedBrowserId;\n  }\n\n  cachedBrowserId = await sha256Hex(resolvePlayerIdentitySeed(clientInfo));\n  return cachedBrowserId;\n}\n\ntype PlayerMetricFlags = {\n  adLoaded?: boolean;\n  adDetect?: boolean;\n  captureAt?: string;\n};\n\nfunction canPublish(licenseKey: string | undefined): licenseKey is string {\n  return Boolean(isMQTTEnabled() && licenseKey);\n}\n\nasync function buildPlayerMetricEvent(\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n  const clientInfo = getClientInfo();\n\n  const debugAdTiming = !!context.debugAdTiming;\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] clientInfo: \", JSON.stringify(clientInfo, null, 2));\n  }\n\n  const playerId = await getBrowserID(clientInfo);\n\n  if (debugAdTiming) {\n    console.log(\"[StormcloudVideoPlayer] playerId: \", playerId);\n  }\n\n  const captureAt = flags.captureAt ?? new Date().toISOString();\n\n  return {\n    player_id: playerId,\n    device_type: clientInfo.deviceType,\n    os: clientInfo.os.toLowerCase(),\n    ad_loaded: flags.adLoaded ?? false,\n    ad_detect: flags.adDetect ?? false,\n    capture_at: captureAt,\n    ...(context.inputStreamType\n      ? { input_stream_type: context.inputStreamType }\n      : {}),\n  };\n}\n\nfunction publishTracking(\n  licenseKey: string,\n  channel: \"metrics\" | \"impressions\" | \"heartbeat\",\n  body: Record<string, unknown>\n): void {\n  ensureMQTTClient();\n  publishMQTT(buildPlayerTopic(licenseKey, channel), body);\n}\n\nexport async function sendInitialTracking(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      adLoaded: false,\n      adDetect: false,\n    });\n\n    publishTracking(licenseKey, \"metrics\", {\n      events: [metricEvent],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdDetectTracking(\n  licenseKey: string | undefined,\n  adDetectInfo: AdDetectInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adDetect: true,\n      captureAt: adDetectInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdLoadedTracking(\n  licenseKey: string | undefined,\n  adLoadedInfo: AdLoadedInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  try {\n    await sendHeartbeat(licenseKey, context, {\n      adLoaded: true,\n      captureAt: adLoadedInfo.timestamp,\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendAdImpressionTracking(\n  licenseKey: string | undefined,\n  adImpressionInfo: AdImpressionInfo,\n  context: PlayerAnalyticsContext = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const metricEvent = await buildPlayerMetricEvent(context, {\n      captureAt: adImpressionInfo.timestamp,\n    });\n\n    publishTracking(licenseKey, \"heartbeat\", metricEvent);\n    publishTracking(licenseKey, \"impressions\", {\n      events: [\n        {\n          player_id: metricEvent.player_id,\n          ad_played_count: 1,\n          ad_url: adImpressionInfo.adUrl,\n          capture_at: adImpressionInfo.timestamp,\n        },\n      ],\n    });\n  } catch (error) {\n    console.error(\n      \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n      error\n    );\n  }\n}\n\nexport async function sendHeartbeat(\n  licenseKey?: string,\n  context: PlayerAnalyticsContext = {},\n  flags: PlayerMetricFlags = {}\n): Promise<void> {\n  if (!canPublish(licenseKey)) return;\n\n  try {\n    const heartbeatData = await buildPlayerMetricEvent(context, flags);\n    publishTracking(licenseKey, \"heartbeat\", heartbeatData);\n  } catch (error) {\n    console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n  }\n}\n","export function polyfillURLSearchParams(): void {\n  if (typeof URLSearchParams !== 'undefined') {\n    return;\n  }\n\n  class URLSearchParamsPolyfill {\n    private params: Map<string, string[]>;\n\n    constructor(init?: string | URLSearchParamsPolyfill) {\n      this.params = new Map();\n\n      if (typeof init === 'string') {\n        this.parseQueryString(init);\n      } else if (init instanceof URLSearchParamsPolyfill) {\n        init.forEach((value, key) => {\n          this.append(key, value);\n        });\n      }\n    }\n\n    private parseQueryString(query: string): void {\n      const cleanQuery = query.startsWith('?') ? query.slice(1) : query;\n      if (!cleanQuery) return;\n\n      cleanQuery.split('&').forEach((param) => {\n        const [key, value] = param.split('=');\n        if (key) {\n          const decodedKey = this.safeDecodeURIComponent(key);\n          const decodedValue = value ? this.safeDecodeURIComponent(value) : '';\n          this.append(decodedKey, decodedValue);\n        }\n      });\n    }\n\n    private safeDecodeURIComponent(str: string): string {\n      try {\n        return decodeURIComponent(str.replace(/\\+/g, ' '));\n      } catch (e) {\n        return str;\n      }\n    }\n\n    append(name: string, value: string): void {\n      const values = this.params.get(name) || [];\n      values.push(String(value));\n      this.params.set(name, values);\n    }\n\n    delete(name: string): void {\n      this.params.delete(name);\n    }\n\n    get(name: string): string | null {\n      const values = this.params.get(name);\n      return values && values.length > 0 && values[0] !== undefined ? values[0] : null;\n    }\n\n    getAll(name: string): string[] {\n      return this.params.get(name) || [];\n    }\n\n    has(name: string): boolean {\n      return this.params.has(name);\n    }\n\n    set(name: string, value: string): void {\n      this.params.set(name, [String(value)]);\n    }\n\n    forEach(callback: (value: string, key: string, parent: URLSearchParamsPolyfill) => void): void {\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          callback(value, key, this);\n        });\n      });\n    }\n\n    toString(): string {\n      const parts: string[] = [];\n      this.params.forEach((values, key) => {\n        values.forEach((value) => {\n          parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\n        });\n      });\n      return parts.join('&');\n    }\n  }\n\n  // @ts-ignore\n  window.URLSearchParams = URLSearchParamsPolyfill;\n}\n\nexport function polyfillTextEncoder(): void {\n  if (typeof TextEncoder !== 'undefined') {\n    return;\n  }\n\n  class TextEncoderPolyfill {\n    encoding = 'utf-8';\n\n    encode(str: string): Uint8Array {\n      const utf8: number[] = [];\n      for (let i = 0; i < str.length; i++) {\n        let charcode = str.charCodeAt(i);\n        if (charcode < 0x80) {\n          utf8.push(charcode);\n        } else if (charcode < 0x800) {\n          utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));\n        } else if (charcode < 0xd800 || charcode >= 0xe000) {\n          utf8.push(\n            0xe0 | (charcode >> 12),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        } else {\n          i++;\n          charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));\n          utf8.push(\n            0xf0 | (charcode >> 18),\n            0x80 | ((charcode >> 12) & 0x3f),\n            0x80 | ((charcode >> 6) & 0x3f),\n            0x80 | (charcode & 0x3f)\n          );\n        }\n      }\n      return new Uint8Array(utf8);\n    }\n  }\n\n  // @ts-ignore\n  window.TextEncoder = TextEncoderPolyfill;\n}\n\nexport function polyfillPromiseFinally(): void {\n  if (typeof Promise !== 'undefined' && !Promise.prototype.finally) {\n    Promise.prototype.finally = function (callback: () => void) {\n      const constructor = this.constructor as PromiseConstructor;\n      return this.then(\n        (value) => constructor.resolve(callback()).then(() => value),\n        (reason) =>\n          constructor.resolve(callback()).then(() => {\n            throw reason;\n          })\n      );\n    };\n  }\n}\n\nexport function polyfillObjectAssign(): void {\n  if (typeof Object.assign !== 'function') {\n    Object.assign = function (target: any, ...sources: any[]) {\n      if (target == null) {\n        throw new TypeError('Cannot convert undefined or null to object');\n      }\n\n      const to = Object(target);\n\n      for (let i = 0; i < sources.length; i++) {\n        const nextSource = sources[i];\n\n        if (nextSource != null) {\n          for (const nextKey in nextSource) {\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n\n      return to;\n    };\n  }\n}\n\nexport function polyfillArrayFrom(): void {\n  if (!Array.from) {\n    Array.from = function (arrayLike: any, mapFn?: any, thisArg?: any) {\n      const items = Object(arrayLike);\n      if (arrayLike == null) {\n        throw new TypeError('Array.from requires an array-like object');\n      }\n\n      const len = items.length >>> 0;\n      const result = new Array(len);\n\n      for (let i = 0; i < len; i++) {\n        if (mapFn) {\n          result[i] = mapFn.call(thisArg, items[i], i);\n        } else {\n          result[i] = items[i];\n        }\n      }\n\n      return result;\n    };\n  }\n}\n\nexport function polyfillStringStartsWith(): void {\n  if (!String.prototype.startsWith) {\n    String.prototype.startsWith = function (search: string, pos?: number) {\n      pos = !pos || pos < 0 ? 0 : +pos;\n      return this.substring(pos, pos + search.length) === search;\n    };\n  }\n}\n\nexport function polyfillStringEndsWith(): void {\n  if (!String.prototype.endsWith) {\n    String.prototype.endsWith = function (search: string, length?: number) {\n      if (length === undefined || length > this.length) {\n        length = this.length;\n      }\n      return this.substring(length - search.length, length) === search;\n    };\n  }\n}\n\nexport function polyfillStringIncludes(): void {\n  if (!String.prototype.includes) {\n    String.prototype.includes = function (search: string, start?: number) {\n      if (typeof start !== 'number') {\n        start = 0;\n      }\n      if (start + search.length > this.length) {\n        return false;\n      }\n      return this.indexOf(search, start) !== -1;\n    };\n  }\n}\n\nexport function initializePolyfills(): void {\n  polyfillObjectAssign();\n  polyfillArrayFrom();\n  polyfillStringStartsWith();\n  polyfillStringEndsWith();\n  polyfillStringIncludes();\n  polyfillURLSearchParams();\n  polyfillTextEncoder();\n  polyfillPromiseFinally();\n}\n\n","import {\n  inferDeviceIdType,\n  isEquivalentDeviceIdType,\n} from \"./vastEnvironmentSignals\";\n\nexport interface VastConsentSignals {\n  gdpr?: string | undefined;\n  gdprConsent?: string | undefined;\n  usPrivacy?: string | undefined;\n}\n\nexport interface VastMacroContext {\n  correlator: string;\n  streamCorrelator: string;\n  pod?: number | undefined;\n  podMaxAds?: number | undefined;\n  podMinDurationMs?: number | undefined;\n  podMaxDurationMs?: number | undefined;\n  isCtv?: boolean | undefined;\n  contentUrl?: string | undefined;\n  pageUrl?: string | undefined;\n  adWillPlayMuted?: boolean | undefined;\n  adWillAutoPlay?: boolean | undefined;\n  appId?: string | undefined;\n  appName?: string | undefined;\n  sessionId?: string | undefined;\n  deviceId?: string | undefined;\n  deviceIdType?: string | undefined;\n  limitAdTracking?: boolean | undefined;\n  deviceTypeHint?: number | undefined;\n  adTest?: boolean | undefined;\n  consent?: VastConsentSignals | undefined;\n}\n\nconst UNEXPANDED_MACRO_PATTERN = /^(\\[[^\\]]*\\]|\\{[^}]*\\}|%%[^%]*%%)$/;\nconst INVALID_VAST_PARAM_KEY = /^\\s|\\s$/;\nconst EXAMPLE_COM_URL = /example\\.com/i;\nconst CTV_UNSUPPORTED_PARAMS = [\n  \"description_url\",\n  \"tfcd\",\n  \"npa\",\n  \"min_ad_duration\",\n  \"max_ad_duration\",\n  \"unviewed_position_start\",\n  \"impl\",\n  \"vad_type\",\n  \"gdpr\",\n  \"gdpr_consent\",\n  \"us_privacy\",\n];\n\nconst INLINE_DEVICE_MACRO_REPLACEMENTS: Array<{\n  pattern: RegExp;\n  getValue: (ctx: VastMacroContext) => string | undefined;\n}> = [\n  { pattern: /\\[RDID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IFA\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[ADVERTISING[_-]?ID(?:ENTIFIER)?\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[DEVICE[_-]?ID\\]/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\[IDTYPE\\]/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /\\{rdid\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{device[_-]?id\\}/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /\\{idtype\\}/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_IDENTIFIER_PLAIN%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%ADVERTISING_ID_OPT_OUT%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%ADVERTISING_ID_TYPE%%/gi, getValue: (ctx) => ctx.deviceIdType },\n  { pattern: /%%ADVERTISING_ID%%/gi, getValue: (ctx) => ctx.deviceId },\n  { pattern: /%%LIMIT_AD_TRACKING%%/gi, getValue: (ctx) =>\n      ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined },\n  { pattern: /%%MSID%%/gi, getValue: (ctx) => ctx.appId },\n  { pattern: /%%APP_NAME%%/gi, getValue: (ctx) => ctx.appName },\n  { pattern: /%%SESSION_ID%%/gi, getValue: (ctx) => ctx.sessionId },\n  { pattern: /%%CORRELATOR%%/gi, getValue: (ctx) => ctx.correlator },\n];\n\nexport function isMacroPlaceholder(value: string | null | undefined): boolean {\n  if (value == null) return true;\n  const trimmed = value.trim();\n  if (!trimmed) return true;\n  if (UNEXPANDED_MACRO_PATTERN.test(trimmed)) return true;\n  return /^(unknown|null|undefined|none|n\\/a|\\$\\{[^}]+\\})$/i.test(trimmed);\n}\n\nexport function generateCorrelator(): string {\n  if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n    try {\n      const buf = new Uint32Array(2);\n      crypto.getRandomValues(buf);\n      const value = (buf[0] ?? 0) * 0x200000 + ((buf[1] ?? 0) & 0x1fffff);\n      if (value > 0) {\n        return String(value);\n      }\n    } catch {\n    }\n  }\n  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);\n}\n\nfunction expandInlineMacroPlaceholders(baseUrl: string, ctx: VastMacroContext): string {\n  let url = baseUrl;\n  for (const { pattern, getValue } of INLINE_DEVICE_MACRO_REPLACEMENTS) {\n    const value = getValue(ctx);\n    if (value != null && value !== \"\") {\n      url = url.replace(pattern, encodeURIComponent(value));\n    }\n  }\n  return url;\n}\n\nfunction applyDeviceIdentityParams(\n  params: URLSearchParams,\n  ctx: VastMacroContext\n): void {\n  const runtimeId = ctx.deviceId?.trim();\n  const runtimeType = ctx.deviceIdType?.trim() || inferDeviceIdType();\n  const tagRdid = params.get(\"rdid\");\n  const tagType = params.get(\"idtype\");\n  const tagLat = params.get(\"is_lat\");\n  const latValue =\n    ctx.limitAdTracking != null ? (ctx.limitAdTracking ? \"1\" : \"0\") : undefined;\n\n  if (runtimeId) {\n    params.set(\"rdid\", runtimeId);\n    params.set(\"idtype\", runtimeType || tagType || \"aaid\");\n    params.set(\"is_lat\", latValue ?? (isMacroPlaceholder(tagLat) ? \"0\" : tagLat!));\n    return;\n  }\n\n  const tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder(tagRdid));\n  const tagTypeValid = Boolean(tagType && !isMacroPlaceholder(tagType));\n\n  if (\n    tagRdidValid &&\n    tagTypeValid &&\n    runtimeType &&\n    !isEquivalentDeviceIdType(tagType!, runtimeType)\n  ) {\n    params.delete(\"rdid\");\n    params.delete(\"idtype\");\n    params.delete(\"is_lat\");\n    return;\n  }\n\n  if (tagRdidValid) {\n    if (isMacroPlaceholder(tagType) && runtimeType) {\n      params.set(\"idtype\", runtimeType);\n    }\n    if (isMacroPlaceholder(tagLat)) {\n      params.set(\"is_lat\", latValue ?? \"0\");\n    }\n    return;\n  }\n\n  params.delete(\"rdid\");\n  params.delete(\"idtype\");\n  params.delete(\"is_lat\");\n}\n\nfunction removeBrokenAppNameOrphans(\n  params: URLSearchParams,\n  appName?: string\n): void {\n  const toDelete: string[] = [];\n\n  params.forEach((_value, key) => {\n    if (!key || INVALID_VAST_PARAM_KEY.test(key)) {\n      toDelete.push(key);\n    }\n  });\n\n  if (appName && appName.includes(\"&\")) {\n    for (const suffix of appName.split(\"&\").slice(1)) {\n      const trimmed = suffix.replace(/^\\s+/, \"\");\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.replace(/\\s+$/, \"\"), ...orphanFragments]\n          .filter(Boolean)\n          .join(\" & \");\n\n        url.searchParams.forEach((_value, key) => {\n          if (key && INVALID_VAST_PARAM_KEY.test(key)) {\n            url.searchParams.delete(key);\n          }\n        });\n        url.searchParams.set(\"an\", reconstructed);\n\n        return url.toString().replace(\n          /([?&]an=)([^&]*)/,\n          (_match, prefix, val) => prefix + val.replace(/\\+/g, \"%20\")\n        );\n      }\n    }\n\n    removeBrokenAppNameOrphans(url.searchParams);\n    return url.toString();\n  } catch {\n    return raw;\n  }\n}\n\nexport function applyVastMacros(\n  baseUrl: string,\n  ctx: VastMacroContext\n): string {\n  const expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);\n  let url: URL;\n  try {\n    url = new URL(normalizeVastTagUrl(expandedUrl));\n  } catch {\n    return replaceCorrelatorFallback(expandedUrl, ctx.correlator);\n  }\n\n  const params = url.searchParams;\n\n  removeBrokenAppNameOrphans(params, ctx.appName);\n\n  params.set(\"correlator\", ctx.correlator);\n  params.set(\"scor\", ctx.streamCorrelator);\n  if (ctx.isCtv) {\n    for (const key of CTV_UNSUPPORTED_PARAMS) {\n      params.delete(key);\n    }\n  }\n\n  if (ctx.pod != null) {\n    params.set(\"pod\", String(ctx.pod));\n  }\n\n  params.delete(\"ppos\");\n  params.delete(\"lip\");\n  if (ctx.podMinDurationMs != null) {\n    params.set(\"pmnd\", String(Math.max(0, Math.round(ctx.podMinDurationMs))));\n  }\n  if (ctx.podMaxDurationMs != null) {\n    params.set(\"pmxd\", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));\n  }\n  if (ctx.podMaxAds != null) {\n    params.set(\"pmad\", String(Math.max(1, Math.round(ctx.podMaxAds))));\n  }\n\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  pauseContentDuringAds?: boolean;\n} {\n  const browser = detectBrowser();\n  const overrides: {\n    allowNativeHls?: boolean;\n    pauseContentDuringAds?: boolean;\n  } = {};\n\n  if (browser.isSmartTV) {\n    overrides.allowNativeHls = true;\n    overrides.pauseContentDuringAds = 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 { toDevSafeUrl } from \"../utils/devUrl\";\nimport {\n  buildAnalyticsContext,\n  sendHeartbeat,\n  sendInitialTracking,\n} from \"../utils/tracking\";\nimport { applyMQTTConfig } from \"../utils/mqttConfig\";\n\nexport class AdConfigManager {\n  vmapBreaks: AdBreak[] = [];\n  consumedVmapBreakIds: Set<string> = new Set();\n  apiVastTagUrl: string | undefined;\n  apiNumberAds: number | undefined;\n  readonly streamCorrelator: string = generateCorrelator();\n  readonly viewCorrelator: string = generateCorrelator();\n  consentSignals: VastConsentSignals = {};\n  podCounter: number = 0;\n  podAssignedByPrefetch: boolean = false;\n\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    this.applyMqttConfigFromResponse(data);\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 applyMqttConfigFromResponse(data: StormcloudApiResponse): void {\n    const mqttConfig = data.response?.mqtt_config;\n    if (!mqttConfig || typeof mqttConfig !== \"object\") {\n      return;\n    }\n\n    applyMQTTConfig(mqttConfig);\n\n    if (this.debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Applied MQTT config from /ads/web:\",\n        mqttConfig\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  }\n\n  private readonly defaultPodMaxAds: number = 6;\n  private readonly defaultPodMaxDurationMs: number = 120000;\n\n  resolvePodParams(breakDurationMs?: number): {\n    maxAds: number;\n    minDurationMs: number;\n    maxDurationMs: number;\n  } {\n    const maxDurationMs =\n      breakDurationMs != null && breakDurationMs > 0\n        ? breakDurationMs\n        : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0\n          ? this.config.podMaxDurationMs\n          : this.defaultPodMaxDurationMs;\n\n    const maxAds =\n      this.config.podMaxAds && this.config.podMaxAds > 0\n        ? this.config.podMaxAds\n        : this.apiNumberAds && this.apiNumberAds > 0\n          ? this.apiNumberAds\n          : this.defaultPodMaxAds;\n\n    const minDurationMs =\n      this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;\n\n    return { maxAds, minDurationMs, maxDurationMs };\n  }\n\n  generatePodVastUrl(\n    baseUrl: string,\n    podParams: { maxAds: number; minDurationMs: number; maxDurationMs: number },\n    adPlayer: AdController,\n    palNonce: PalNonceManager,\n    inAdBreak: boolean\n  ): string {\n    const adWillPlayMuted = inAdBreak\n      ? adPlayer.getOriginalMutedState()\n      : this.video.muted;\n    const envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);\n\n    const urlWithMacros = applyVastMacros(baseUrl, {\n      correlator: this.viewCorrelator,\n      streamCorrelator: this.streamCorrelator,\n      pod: this.podCounter > 0 ? this.podCounter : undefined,\n      podMaxAds: podParams.maxAds,\n      podMinDurationMs: podParams.minDurationMs,\n      podMaxDurationMs: podParams.maxDurationMs,\n      isCtv: envSignals.isCtv,\n      contentUrl: envSignals.contentUrl,\n      pageUrl:\n        !envSignals.isCtv && typeof window !== \"undefined\"\n          ? toDevSafeUrl(window.location.href)\n          : undefined,\n      adWillPlayMuted,\n      adWillAutoPlay: !!this.config.autoplay,\n      appId: envSignals.appId,\n      appName: envSignals.appName,\n      sessionId: envSignals.sessionId,\n      deviceId: envSignals.deviceId,\n      deviceIdType: envSignals.deviceIdType,\n      limitAdTracking: envSignals.limitAdTracking,\n      deviceTypeHint: envSignals.deviceTypeHint,\n      adTest: this.config.adTest,\n      consent: this.consentSignals,\n    });\n\n    const finalUrl = palNonce.injectNonce(urlWithMacros);\n    console.log(\n      `[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=${this.podCounter}, pmad=${podParams.maxAds}, pmnd=${podParams.minDurationMs}, pmxd=${podParams.maxDurationMs ?? \"?\"}):`,\n      finalUrl\n    );\n    return finalUrl;\n  }\n\n  // --- Tracking ---\n\n  initializeTracking(): void {\n    sendInitialTracking(this.config.licenseKey, buildAnalyticsContext(this.config))\n      .then(() => {\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      })\n      .catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n            error\n          );\n        }\n        this.heartbeatInterval = window.setInterval(() => {\n          this.sendHeartbeatIfNeeded();\n        }, 5000);\n      });\n  }\n\n  private sendHeartbeatIfNeeded(): void {\n    const now = Date.now();\n    if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n      this.lastHeartbeatTime = now;\n      sendHeartbeat(this.config.licenseKey, buildAnalyticsContext(this.config)).catch((error) => {\n        if (this.debug) {\n          console.warn(\n            \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n            error\n          );\n        }\n      });\n    }\n  }\n\n  destroyTracking(): void {\n    if (this.heartbeatInterval) {\n      clearInterval(this.heartbeatInterval);\n      this.heartbeatInterval = undefined;\n    }\n  }\n}\n","import type { AdController, StormcloudVideoPlayerConfig, Scte35Marker } from \"../types\";\n\nexport interface AdTimingCallbacks {\n  onAdStopTimerFired(): void;\n  onAdStartTimerFired(marker: Scte35Marker, cueKey: string | undefined): void;\n  onWatchdogTimeout(): void;\n  onFailsafeTimeout(): void;\n}\n\nexport class AdTimingService {\n  private adStopTimerId: number | undefined;\n  private adStartTimerId: number | undefined;\n  private adFailsafeTimerId: number | undefined;\n  private adRequestWatchdogId: number | undefined;\n  private adRequestWatchdogToken: number | null = null;\n  private adFailsafeToken: number | null = null;\n\n  ptsDriftEmaMs = 0;\n  expectedAdBreakDurationMs: number | undefined;\n  currentAdBreakStartWallClockMs: number | undefined;\n  scteAdBreakEndWallClockMs: number | undefined;\n  adBreakPlayedDurationMs: number = 0;\n  adBreakEpoch: number = 0;\n\n  adRequestTokenCounter = 0;\n  activeAdRequestToken: number | null = null;\n  currentAdIndex: number = 0;\n  totalAdsInBreak: number = 0;\n  totalAdRequestsInBreak: number = 0;\n  readonly maxTotalAdRequestsPerBreak: number = 10;\n  lastAdRequestTime: number = 0;\n  consecutiveFailures: number = 0;\n  readonly maxConsecutiveFailures: number = 5;\n  readonly minAdRequestIntervalMs: number = 3000;\n  readonly backoffBaseMs: number = 1000;\n  readonly maxBackoffMs: number = 15000;\n  private readonly defaultMinRemainingMsToStartAd: number = 4000;\n\n  failedVastUrls: Set<string> = new Set();\n  temporaryFailureUrls: Map<string, number> = new Map();\n  private readonly temporaryFailureCooldownMs: number = 30000;\n\n  private globalConsecutiveNoFills: number = 0;\n  private readonly globalNoFillThreshold: number = 3;\n  private globalNoFillCooldownUntil: number = 0;\n  private readonly globalNoFillBackoffBaseMs: number = 5000;\n  private readonly globalNoFillBackoffMaxMs: number = 60000;\n  private globalLastGamRequestTime: number = 0;\n  private readonly globalMinGamIntervalMs: number = 3000;\n\n  private config: StormcloudVideoPlayerConfig;\n  private video: HTMLVideoElement;\n  private callbacks: AdTimingCallbacks;\n\n  constructor(\n    config: StormcloudVideoPlayerConfig,\n    video: HTMLVideoElement,\n    callbacks: AdTimingCallbacks\n  ) {\n    this.config = config;\n    this.video = video;\n    this.callbacks = callbacks;\n  }\n\n  get debug(): boolean {\n    return !!this.config.debugAdTiming;\n  }\n\n  // --- Ad stop timer ---\n\n  scheduleAdStopCountdown(remainingMs: number): void {\n    this.clearAdStopTimer();\n    const ms = Math.max(0, Math.floor(remainingMs));\n    if (ms === 0) {\n      this.ensureAdStoppedByTimer();\n      return;\n    }\n    this.adStopTimerId = window.setTimeout(() => {\n      this.ensureAdStoppedByTimer();\n    }, ms) as unknown as number;\n  }\n\n  clearAdStopTimer(): void {\n    if (this.adStopTimerId != null) {\n      clearTimeout(this.adStopTimerId);\n      this.adStopTimerId = undefined;\n    }\n  }\n\n  private ensureAdStoppedByTimer(): void {\n    this.adStopTimerId = undefined;\n    this.callbacks.onAdStopTimerFired();\n  }\n\n  // --- Ad start timer ---\n\n  scheduleAdStartIn(\n    delayMs: number,\n    marker: Scte35Marker = { type: \"start\" } as Scte35Marker,\n    cueKey?: string\n  ): void {\n    this.clearAdStartTimer();\n    const ms = Math.max(0, Math.floor(delayMs));\n    if (ms === 0) {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n      return;\n    }\n    this.adStartTimerId = window.setTimeout(() => {\n      this.callbacks.onAdStartTimerFired(marker, cueKey);\n    }, ms) as unknown as number;\n  }\n\n  clearAdStartTimer(): void {\n    if (this.adStartTimerId != null) {\n      clearTimeout(this.adStartTimerId);\n      this.adStartTimerId = undefined;\n    }\n  }\n\n  // --- PTS drift ---\n\n  updatePtsDrift(ptsSecondsSample: number): void {\n    const sampleMs = (this.video.currentTime - ptsSecondsSample) * 1000;\n    if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 60000) return;\n    const alpha = 0.1;\n    this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;\n  }\n\n  resolveScteBreakStartWallClockMs(marker: Scte35Marker): number {\n    const nowWallClockMs = Date.now();\n    if (typeof marker.ptsSeconds !== \"number\") {\n      return nowWallClockMs;\n    }\n\n    const nowMs = this.video.currentTime * 1000;\n    const estimatedCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n    const deltaMs = marker.ptsSeconds * 1000 - estimatedCurrentPtsMs;\n    if (!Number.isFinite(deltaMs)) {\n      return nowWallClockMs;\n    }\n\n    return nowWallClockMs + Math.floor(deltaMs);\n  }\n\n  // --- Duration boundary ---\n\n  setAdBreakDurationBoundary(durationMs: number | undefined): void {\n    this.expectedAdBreakDurationMs = durationMs;\n    if (\n      durationMs != null &&\n      this.currentAdBreakStartWallClockMs != null\n    ) {\n      this.scteAdBreakEndWallClockMs =\n        this.currentAdBreakStartWallClockMs + durationMs;\n    } else {\n      this.scteAdBreakEndWallClockMs = undefined;\n    }\n  }\n\n  scheduleAdStopAtBreakBoundary(): void {\n    if (this.expectedAdBreakDurationMs == null) {\n      return;\n    }\n    this.scheduleAdStopCountdown(this.getWallClockRemainingAdMs());\n  }\n\n  // --- Duration budget ---\n\n  getWallClockRemainingAdMs(): number {\n    const endWallClockMs = this.getAdBreakEndWallClockMs();\n    if (endWallClockMs != null) {\n      return Math.max(0, endWallClockMs - Date.now());\n    }\n    return 0;\n  }\n\n  getAdBreakEndWallClockMs(): number | undefined {\n    if (this.scteAdBreakEndWallClockMs != null) {\n      return this.scteAdBreakEndWallClockMs;\n    }\n    if (\n      this.expectedAdBreakDurationMs == null ||\n      this.currentAdBreakStartWallClockMs == null\n    ) {\n      return undefined;\n    }\n    return this.currentAdBreakStartWallClockMs + this.expectedAdBreakDurationMs;\n  }\n\n  getDurationBudgetRemainingMs(): number {\n    if (this.expectedAdBreakDurationMs == null) {\n      return 0;\n    }\n    return Math.max(0, this.expectedAdBreakDurationMs - this.adBreakPlayedDurationMs);\n  }\n\n  getLoadedAdDurationMs(adController: AdController): number {\n    const durationSec = adController.getLoadedAdDuration?.();\n    if (durationSec == null || durationSec <= 0) {\n      return 0;\n    }\n    return Math.round(durationSec * 1000);\n  }\n\n  adFitsRemainingBudget(durationMs: number): boolean {\n    if (durationMs <= 0) {\n      return true;\n    }\n    return durationMs <= this.getDurationBudgetRemainingMs();\n  }\n\n  logAdDurationDecision(\n    accepted: boolean,\n    durationMs: number,\n    adController: AdController\n  ): void {\n    if (!this.debug) {\n      return;\n    }\n    const remainingBudget = this.getDurationBudgetRemainingMs();\n    const adId = adController.getLoadedAdId?.() ?? \"unknown\";\n    if (accepted) {\n      console.log(\n        `[AD-DURATION] Accepted ad id=${adId}, duration=${durationMs}ms, budget remaining after play=${Math.max(0, remainingBudget - durationMs)}ms`\n      );\n    } else {\n      console.log(\n        `[AD-DURATION] Rejected ad id=${adId}, duration=${durationMs}ms exceeds remaining budget=${remainingBudget}ms — requesting another ad`\n      );\n    }\n  }\n\n  recordPlayedAdDuration(adController: AdController): void {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    if (durationMs <= 0) {\n      return;\n    }\n    this.adBreakPlayedDurationMs += durationMs;\n    if (this.debug) {\n      console.log(\n        `[AD-DURATION] Played ${durationMs}ms — total played=${this.adBreakPlayedDurationMs}ms / ${this.expectedAdBreakDurationMs ?? \"?\"}ms`\n      );\n    }\n  }\n\n  ensureLoadedAdFitsBudget(adController: AdController): boolean {\n    const durationMs = this.getLoadedAdDurationMs(adController);\n    const fits = this.adFitsRemainingBudget(durationMs);\n    this.logAdDurationDecision(fits, durationMs, adController);\n    return fits;\n  }\n\n  rejectLoadedAdForDuration(adController: AdController): void {\n    try {\n      adController.destroy();\n    } catch {}\n  }\n\n  markAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n    this.totalAdRequestsInBreak++;\n    this.lastAdRequestTime = Date.now();\n  }\n\n  notePodAdStarted(): void {\n    this.currentAdIndex++;\n    this.totalAdsInBreak = this.currentAdIndex;\n  }\n\n  getRemainingAdMs(): number {\n    const wallClockRemaining = this.getWallClockRemainingAdMs();\n    const budgetRemaining = this.getDurationBudgetRemainingMs();\n    if (this.expectedAdBreakDurationMs == null) {\n      return wallClockRemaining;\n    }\n    return Math.min(wallClockRemaining, budgetRemaining);\n  }\n\n  getMinRemainingMsToStartAd(): number {\n    const configured = this.config.minRemainingMsToStartAd;\n    if (typeof configured === \"number\" && configured >= 0) {\n      return configured;\n    }\n    return this.defaultMinRemainingMsToStartAd;\n  }\n\n  hasTimeToStartAnotherAd(): boolean {\n    const minRemaining = this.getMinRemainingMsToStartAd();\n    return (\n      this.getWallClockRemainingAdMs() > minRemaining &&\n      this.getDurationBudgetRemainingMs() > minRemaining\n    );\n  }\n\n  // --- Circuit breaker ---\n\n  isTemporaryAdError(error: Error): boolean {\n    const message = error?.message?.toLowerCase() || \"\";\n\n    if (message.includes(\"no ads available\") || message.includes(\"no fill\") || message.includes(\"nofill\")) {\n      return true;\n    }\n    if (message.includes(\"timeout\")) {\n      return true;\n    }\n    if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n      return true;\n    }\n    if (message.includes(\"ad playback error\")) {\n      return true;\n    }\n    return false;\n  }\n\n  isUrlInCooldown(vastTagUrl: string): boolean {\n    const failureTime = this.temporaryFailureUrls.get(vastTagUrl);\n    if (failureTime == null) {\n      return false;\n    }\n\n    const elapsed = Date.now() - failureTime;\n    if (elapsed >= this.temporaryFailureCooldownMs) {\n      this.temporaryFailureUrls.delete(vastTagUrl);\n      return false;\n    }\n\n    return true;\n  }\n\n  cleanupTemporaryFailures(): void {\n    const now = Date.now();\n    for (const [url, timestamp] of this.temporaryFailureUrls) {\n      if (now - timestamp >= this.temporaryFailureCooldownMs) {\n        this.temporaryFailureUrls.delete(url);\n      }\n    }\n  }\n\n  isGamInCooldown(): boolean {\n    return Date.now() < this.globalNoFillCooldownUntil;\n  }\n\n  recordGamNoFill(): void {\n    this.globalConsecutiveNoFills++;\n\n    if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {\n      const exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;\n      const backoff = Math.min(\n        this.globalNoFillBackoffBaseMs * Math.pow(2, exponent),\n        this.globalNoFillBackoffMaxMs\n      );\n      this.globalNoFillCooldownUntil = Date.now() + backoff;\n\n      if (this.debug) {\n        console.log(\n          `[CIRCUIT-BREAKER] GAM cooldown activated: ${backoff}ms (${this.globalConsecutiveNoFills} consecutive no-fills)`\n        );\n      }\n    }\n  }\n\n  resetGamNoFillCounter(): void {\n    if (this.globalConsecutiveNoFills > 0 && this.debug) {\n      console.log(\n        `[CIRCUIT-BREAKER] Resetting no-fill counter (was ${this.globalConsecutiveNoFills})`\n      );\n    }\n    this.globalConsecutiveNoFills = 0;\n    this.globalNoFillCooldownUntil = 0;\n  }\n\n  async enforceGlobalRateLimit(): Promise<void> {\n    const now = Date.now();\n    const elapsed = now - this.globalLastGamRequestTime;\n    if (elapsed < this.globalMinGamIntervalMs) {\n      const waitMs = this.globalMinGamIntervalMs - elapsed;\n      if (this.debug) {\n        console.log(`[RATE-LIMIT] Waiting ${waitMs}ms before next GAM request`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitMs));\n    }\n    this.globalLastGamRequestTime = Date.now();\n  }\n\n  // --- Watchdog ---\n\n  startAdRequestWatchdog(token: number): void {\n    this.clearAdRequestWatchdog();\n\n    const timeoutMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adRequestWatchdogToken = token;\n    this.adRequestWatchdogId = window.setTimeout(() => {\n      if (this.adRequestWatchdogToken !== token) {\n        return;\n      }\n\n      this.adRequestWatchdogId = undefined;\n      this.adRequestWatchdogToken = null;\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_request_timeout\", { token, timeoutMs });\n      this.callbacks.onWatchdogTimeout();\n    }, timeoutMs) as unknown as number;\n\n    this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n  }\n\n  clearAdRequestWatchdog(): void {\n    if (this.adRequestWatchdogId != null) {\n      clearTimeout(this.adRequestWatchdogId);\n      this.adRequestWatchdogId = undefined;\n    }\n\n    if (this.adRequestWatchdogToken != null) {\n      this.logAdState(\"ad_request_watchdog_cleared\", {\n        token: this.adRequestWatchdogToken,\n      });\n      this.adRequestWatchdogToken = null;\n    }\n  }\n\n  // --- Failsafe ---\n\n  startAdFailsafeTimer(token: number): void {\n    this.clearAdFailsafeTimer();\n\n    const failsafeMs = this.config.adFailsafeTimeoutMs ?? 10000;\n    this.adFailsafeToken = token;\n\n    this.adFailsafeTimerId = window.setTimeout(() => {\n      if (this.adFailsafeToken !== token) {\n        return;\n      }\n\n      this.adFailsafeTimerId = undefined;\n      this.adFailsafeToken = null;\n\n      if (this.activeAdRequestToken === token) {\n        this.activeAdRequestToken = null;\n      }\n\n      this.logAdState(\"ad_failsafe_triggered\", {\n        token,\n        failsafeMs,\n        videoPaused: this.video.paused,\n      });\n\n      this.callbacks.onFailsafeTimeout();\n    }, failsafeMs) as unknown as number;\n\n    this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n  }\n\n  clearAdFailsafeTimer(): void {\n    if (this.adFailsafeTimerId != null) {\n      clearTimeout(this.adFailsafeTimerId);\n      this.logAdState(\"ad_failsafe_cleared\", { token: this.adFailsafeToken });\n      this.adFailsafeTimerId = undefined;\n    }\n\n    this.adFailsafeToken = null;\n  }\n\n  logAdState(event: string, extra: Record<string, unknown> = {}, adPlayer?: AdController, inAdBreak?: boolean, showAds?: boolean): void {\n    if (!this.debug) {\n      return;\n    }\n\n    console.log(\"[StormcloudVideoPlayer][AdState]\", {\n      event,\n      timestamp: new Date().toISOString(),\n      showAds: showAds ?? false,\n      adPlaying: adPlayer?.isAdPlaying() ?? false,\n      inAdBreak: inAdBreak ?? false,\n      activeAdRequestToken: this.activeAdRequestToken,\n      ...extra,\n    });\n  }\n\n  // --- Reset for ad break end ---\n\n  resetForBreakEnd(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdRequestWatchdog();\n    this.clearAdFailsafeTimer();\n    this.activeAdRequestToken = null;\n    this.expectedAdBreakDurationMs = undefined;\n    this.currentAdBreakStartWallClockMs = undefined;\n    this.scteAdBreakEndWallClockMs = undefined;\n    this.adBreakPlayedDurationMs = 0;\n    this.currentAdIndex = 0;\n    this.totalAdsInBreak = 0;\n    this.consecutiveFailures = 0;\n    this.globalConsecutiveNoFills = 0;\n    this.adBreakEpoch++;\n  }\n\n  destroy(): void {\n    this.clearAdStopTimer();\n    this.clearAdStartTimer();\n    this.clearAdFailsafeTimer();\n    this.clearAdRequestWatchdog();\n  }\n}\n","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  reloadingLiveStream: boolean = false;\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      this.reloadingLiveStream = false;\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  restartLoadAt(position: number): void {\n    if (!this.hls) {\n      return;\n    }\n    try {\n      this.hls.stopLoad();\n      this.hls.startLoad(position);\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to restart HLS load at live edge:\", error);\n      }\n    }\n  }\n\n  recoverMediaError(): void {\n    if (!this.hls) {\n      return;\n    }\n    try {\n      this.hls.recoverMediaError();\n    } catch (error) {\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] recoverMediaError() failed:\", error);\n      }\n    }\n  }\n\n  reloadLiveStream(): void {\n    const hls = this.hls;\n    if (!hls) {\n      return;\n    }\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Hard-reloading live stream (detach → reset video → re-attach)\");\n    }\n    try {\n      this.reloadingLiveStream = true;\n      hls.stopLoad();\n      hls.detachMedia();\n      try {\n        this.video.removeAttribute(\"src\");\n        this.video.load();\n      } catch (error) {\n        console.warn(\"[StormcloudVideoPlayer] video.load() threw after src removal:\", error);\n      }\n      hls.attachMedia(this.video);\n    } catch (error) {\n      this.reloadingLiveStream = false;\n      if (this.debug) {\n        console.warn(\"[StormcloudVideoPlayer] Failed to hard-reload live stream:\", error);\n      }\n    }\n  }\n\n  destroy(): void {\n    this.hls?.destroy();\n    this.hls = undefined;\n  }\n}\n"]}