{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/players/index.cjs","../../src/players/index.ts","../../src/utils.ts","../../src/patterns.ts","../../src/players/HlsPlayer.tsx","../../src/sdk/hlsAdPlayer.ts","../../src/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","../../src/player/PlayerControls.ts","../../src/player/AdBreakOrchestrator.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","__hasOwnProp","getPrototypeOf","prototype","hasOwnProperty","name","all","target","get","enumerable","__copyProps","to","from","except","desc","call","key","mod","__toESM","isNodeMode","__esModule","value","__toCommonJS","players_exports","__export","default","players_default","exports","import_react","require","lazy","reactLazy","IS_BROWSER","window","document","IS_GLOBAL","globalThis","IS_IOS","test","navigator","userAgent","IS_SAFARI","HLS_EXTENSIONS","HLS_PATHS","DASH_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","canPlay","hls","url","dash","video","audio","file","import_hls","MAX_VAST_WRAPPER_DEPTH","adVideoElement","currentAd","createHlsAdPlayer","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adContainerEl","podAds","podIndex","sessionId","preloadedAds","destroyed","STALL_TIMEOUT_MS","lastAdProgressTime","lastAdProgressPosition","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","console","warn","currentLevel","bitrate","level","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","autoLevel","loadLevel","width","height","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","scope","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","xmlDoc","parser","DOMParser","parseFromString","xmlString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateValue","bitrateAttr","ad","id","parseAdElement","fetchVastXml","vastTagUrl","credentials","requestVast","response","creds","fetch","mode","headers","referrerPolicy","statusText","text","fetchAndParseVastAd","parsed","depth","accumulatedTracking","vastXml","substring","parseVastXml","fetchAndParsePod","adElements","ads","resolved","aSeq","bSeq","aVal","Number","isFinite","MAX_SAFE_INTEGER","bVal","createAdVideoElement","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","noteAdProgress","progress","currentTime","advanceToNextPodAd","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","resetQuartileTracking","preserveImpression","loadCurrentAdMedia","isHlsAd","Hls","isSupported","adHls","destroy","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","play","catch","ERROR","_event","data","fatal","clearStallWatchdog","canPlayType","load","total","stallWatchdogId","clearInterval","handleAdStall","startStallWatchdog","setInterval","paused","STALL_CHECK_INTERVAL_MS","releaseAdDecoder","removeAttribute","remove","display","pointerEvents","continueLiveStreamDuringAds","visibility","opacity","initialize","container","right","bottom","alignItems","justifyContent","parentElement","appendChild","requestAds","preloaded","Promise","reject","has","delete","resolve","contentVolume","stop","previousMutedState","pendingTimeouts","timeoutId","clearTimeout","removeChild","clear","preloadingAds","isAdPlaying","resize","listener","Set","add","off","updateOriginalMutedState","nextVolume","isNaN","getOriginalMutedState","getOriginalVolume","setAdVolume","clamped","getAdVolume","showPlaceholder","zIndex","hidePlaceholder","getLoadedAdDuration","getLoadedAdId","getPodAdCount","getPodTotalDurationMs","reduce","PRIVATE_HOST_PATTERNS","isLocalDevHost","hostname","host","replace","some","pattern","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","playerVolume","adWillPlayMuted","continuousPlayback","descriptionUrl","location","href","iconsSupported","playerType","playerVersion","supportedApiFrameworks","videoWidth","videoHeight","ppid","JSON","stringify","loadNonceManager","teardownClient","getNonce","getCurrentNonce","injectNonce","searchParams","base","sep","encodeURIComponent","sendPlaybackStart","sendPlaybackEnd","sendAdClick","sendAdTouch","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","removeAllListeners","end","scheduleReconnect","openConnection","delay","jitter","floor","clientId","err","slice","mqtt","connect","keepalive","clean","reconnectPeriod","queueQoSZero","reschedulePings","timerVariant","info","message","ensureMQTTClient","initMQTTClient","publishMQTT","topic","connected","publish","AIRY_APP_NAME","AIRY_ANDROID_APP_ID","AIRY_WEBOS_APP_ID","AIRY_TIZEN_APP_ID","AIRY_ROKU_APP_ID","AIRY_DEFAULT_CONTENT_URL","CTV_SESSION_STORAGE_KEY","PLAYER_ID_STORAGE_KEY","LG_TEST_CONTENT_URL","_lgTestDeviceId","createUuid","isLgWebOS","getDefaultAppId","ua","DEVICE_ID_STORAGE_KEYS","ANDROID_ID_TYPES","resolveVastEnvironmentSignals","isCtv","platformLat","bridgeSignals","readNativeBridgeSignals","platformDevice","readPlatformNativeDeviceId","lg","deviceId","readStoredDeviceId","limitAdTracking","getLgTestDeviceId","deviceIdType","readStoredString","inferDeviceIdType","contentUrl","appId","LG_TEST_APP_ID","deviceTypeHint","isEquivalentDeviceIdType","tagType","runtimeType","tag","runtime","resolveNativeDeviceId","isMacroPlaceholder","isZeroedAdId","getOrCreateStoredUuid","storageKey","readPersistentId","writePersistentId","getOrCreateCtvSessionId","readCookie","localStorage","setItem","writeCookie","prefix","parts","cookie","part","entry","decodeURIComponent","PERSISTENT_ID_COOKIE_MAX_AGE","bytes","crypto","randomUUID","Uint8Array","getRandomValues","seed","performanceNow","i","hex","padStart","performance","adinfo","webapis","tifa","getTIFA","lat","isLATEnabled","webOSDev","lgudid","LGUDID","roku","Roku","rida","getPublisherUniqueId","ZEROED_AD_ID_PATTERNS","t","candidates","__STORMCLOUD_CTV_AD_INFO__","__STORMCLOUD_CTV__","stormcloudCtv","AiryTV","Android","webOS","tizen","amazon","filter","Boolean","readBridgeValue","appName","readBridgeBoolean","result","normalized","normalizeBoolean","getItem","readStoredLimitAdTracking","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","TextEncoder","encode","unescape","charCodeAt","padEnd","resolvePlayerIdentitySeed","clientInfo","nativeDeviceId","persistedId","getBrowserID","canPublish","buildPlayerMetricEvent","flags","playerId","captureAt","toISOString","player_id","device_type","ad_loaded","adLoaded","ad_detect","adDetect","capture_at","input_stream_type","publishTracking","body","sendInitialTracking","metricEvent","events","sendAdDetectTracking","adDetectInfo","sendHeartbeat","sendAdLoadedTracking","adLoadedInfo","sendAdImpressionTracking","adImpressionInfo","ad_played_count","ad_url","adUrl","heartbeatData","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","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","pos","polyfillStringStartsWith","search","polyfillStringEndsWith","polyfillStringIncludes","indexOf","initializePolyfills","UNEXPANDED_MACRO_PATTERN","INVALID_VAST_PARAM_KEY","EXAMPLE_COM_URL","CTV_UNSUPPORTED_PARAMS","INLINE_DEVICE_MACRO_REPLACEMENTS","getValue","ctx","correlator","trimmed","generateCorrelator","buf","Uint32Array","expandInlineMacroPlaceholders","baseUrl","applyDeviceIdentityParams","runtimeId","tagRdid","tagLat","latValue","tagRdidValid","tagTypeValid","removeBrokenAppNameOrphans","toDelete","_value","suffix","normalizeVastTagUrl","raw","anValue","orphanFragments","reconstructed","val","_match","applyVastMacros","expandedUrl","replaceCorrelatorFallback","streamCorrelator","pod","podMinDurationMs","round","podMaxAds","requestUrl","pageUrl","existingUrl","correlatorRegex","consent","gdpr","gdprConsent","usPrivacy","adTest","staleKeys","fetchConsentSignals","timeoutMs","signals","tasks","tcfApi","__tcfapi","settled","tcData","success","gdprApplies","tcString","listenerId","uspApi","__uspapi","uspString","getChromeVersion","getPlatform","userAgentData","detectBrowser","version","majorVersion","isLegacyTV","supportsModernJS","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","webkitVersion","getWebKitVersion","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","programInfoLength","esInfoLength","streamType","elementaryPid","tsScte35Pids","hasProcessedTsScte35Section","section","processedSections","checksum","size","firstKey","next","addScte35SectionMarker","markers","assemblers","appendScte35Bytes","assembler","expectedLength","collectScte35SectionsFromPayload","previousAssembler","subarray","tableId","totalLength","parseScte35FromTsPackets","packetInfo","sectionAssemblers","tsStart","fourthByte","secondByte","thirdByte","adaptationFieldControl","hasPayload","payloadStart","adaptationLength","payloadEnd","parsePmtSection","BitReader","bytePos","bitPos","readBits","numBits","remainingInByte","toRead","currentByte","shift","mask","bits","skipBits","bytePosition","readSpliceTime","r","ptsAdjustmentTicks","timeSpecifiedFlag","high","low","ptsTicks","markerTypeFromSegmentationTypeId","segmentationTypeId","parseScte35SegmentationDescriptor","descriptor","identifier","segmentationEventId","cancelIndicator","programSegmentationFlag","segmentationDurationFlag","componentCount","durationTicks","segmentationUpidLength","markerType","descriptorTag","parseScte35SegmentationDescriptors","descriptorOffset","descriptorLoopLength","descriptorLength","descriptorDataEnd","descriptorMarker","descriptorDataStart","ptsAdjHigh","ptsAdjLow","spliceCommandLength","spliceCommandType","spliceEventId","commandBodyStart","cancel","outOfNetwork","programSpliceFlag","spliceImmediateFlag","componentPtsSeconds","durationFlag","expectedDescriptorOffset","splice_event_id","segmentation_event_id","Scte35CueManager","callbacks","pendingScte35Cues","recentScte35CueKeys","recentScte35CueLimit","processedTsScte35Sections","pendingScte35CueKey","pendingScte35CueKeyValue","activeScte35BreakKey","activeScte35BreakKeyValue","scheduledScte35BreakKey","createScte35CueContext","readiness","sn","fragmentSn","fragmentStartSec","fragmentStartSeconds","onScte35Cue","cue","createScte35Cue","pendingKey","getPendingScte35CueKey","trimRecentScte35CueMaps","shouldAcceptScte35EndCue","inAdBreak","isInAdBreak","hasRecentlyHandledScte35Cue","markScte35CueHandled","onPlaybackCue","activatePendingScte35CuesForFragment","matchingCues","entries","getScte35CueKey","getScte35MarkerRaw","toIdentityString","daterangeId","ID","scteValue","isStrongScte35CueKey","scheduledScte35BreakKeyValue","recentKey","AdConfigManager","vmapBreaks","consumedVmapBreakIds","viewCorrelator","consentSignals","podAssignedByPrefetch","lastHeartbeatTime","defaultPodMaxAds","defaultPodMaxDurationMs","isVmapEnabled","isVmap","vmapUrl","fetchAdConfiguration","vastMode","vastEndpoint","apiUrl","imaPayload","decodedPayload","numberAds","fetchAndParseVmap","apiVastTagUrl","ok","json","applyMqttConfigFromResponse","vast","cue_tones","number_ads","apiNumberAds","mqtt_config","vmapXml","parseVmapToBreaks","doc","VMAP_NS","adBreakNodes","getElementsByTagNameNS","getElementsByTagName","localName","node","timeOffsetRaw","startTimeMs","parseVmapTimeOffsetToMs","adTagNode","adTagUrl","breakId","bStart","timeOffset","percent","aStart","hms","hh","mm","ss","ms","hours","minutes","seconds","millis","ratio","durationSec","getAdBreakKey","adBreak","resolveBreakStartMs","findCurrentOrNextBreak","nowMs","schedule","tol","driftToleranceMs","breakStartMs","findBreakForTime","durationMs","selectVastTagsForBreak","s","beginNewAdPod","podCounter","resolvePodParams","breakDurationMs","maxDurationMs","podMaxDurationMs","maxAds","minDurationMs","podExactDuration","generatePodVastUrl","podParams","adPlayer","palNonce","urlWithMacros","envSignals","autoplay","finalUrl","initializeTracking","sendHeartbeatIfNeeded","heartbeatInterval","destroyTracking","totalAdRequestsInBreak","globalNoFillBackoffMaxMs","globalLastGamRequestTime","AdTimingService","adRequestWatchdogToken","adFailsafeToken","ptsDriftEmaMs","adBreakPlayedDurationMs","adBreakEpoch","adRequestTokenCounter","activeAdRequestToken","currentAdIndex","totalAdsInBreak","maxTotalAdRequestsPerBreak","lastAdRequestTime","consecutiveFailures","maxConsecutiveFailures","minAdRequestIntervalMs","backoffBaseMs","maxBackoffMs","defaultMinRemainingMsToStartAd","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","globalConsecutiveNoFills","globalNoFillCooldownUntil","globalNoFillBackoffBaseMs","globalMinGamIntervalMs","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","adStopTimerId","ensureAdStoppedByTimer","cueKey","onAdStopTimerFired","scheduleAdStartIn","delayMs","clearAdStartTimer","onAdStartTimerFired","adStartTimerId","updatePtsDrift","ptsSecondsSample","sampleMs","alpha","resolveScteBreakStartWallClockMs","nowWallClockMs","estimatedCurrentPtsMs","deltaMs","setAdBreakDurationBoundary","expectedAdBreakDurationMs","currentAdBreakStartWallClockMs","scteAdBreakEndWallClockMs","scheduleAdStopAtBreakBoundary","getWallClockRemainingAdMs","endWallClockMs","getAdBreakEndWallClockMs","getDurationBudgetRemainingMs","getLoadedAdDurationMs","adController","adFitsRemainingBudget","logAdDurationDecision","accepted","remainingBudget","recordPlayedAdDuration","ensureLoadedAdFitsBudget","fits","rejectLoadedAdForDuration","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","extra","showAds","resetForBreakEnd","PlaceholderLayer","ensureContainer","transition","wasHidden","show","offsetHeight","requestAnimationFrame","hide","HlsEngine","cueManager","timing","nativeHlsMode","videoSrcProtection","reloadingLiveStream","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","shouldUseNativeHls","getStreamType","canNative","setupNativeHls","adBehavior","isLive","setupHls","import_hls2","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","_data","minSegments","details","live","onManifestParsed","minSegmentsBeforePlay","LEVEL_LOADED","_evt","hasPendingAdBreak","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","getLiveSyncPosition","liveSyncPosition","restartLoadAt","stopLoad","reloadLiveStream","detachMedia","getAdAudioVolume","toggleMute","newMutedState","restoreVolume","toggleFullscreen","fullscreenElement","isMuted","setMuted","setVolume","clampedVolume","getVolume","isFullscreen","resizePlayer","clientWidth","clientHeight","AdBreakOrchestrator","adConfig","placeholder","isShowingPlaceholder","adDetectSentForCurrentBreak","continuousFetchingActive","continuousFetchLoopRunning","adRequestQueue","adPodQueue","maxPlaceholderDurationMs","pendingAdBreak","analyticsContext","nextAdRequestUrl","baseVastUrl","remaining","attachImaEventListeners","getAdPlayer","adIndex","queuedUrls","tryNextAvailableAdWithRateLimit","errorPayload","errorCode","code","errorMessage","vastErrorCode","cause","innerError","causeMessage","handleAdFailure"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n  if (from && typeof from === \"object\" || typeof from === \"function\") {\n    for (let key of __getOwnPropNames(from))\n      if (!__hasOwnProp.call(to, key) && key !== except)\n        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n  }\n  return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n  // If the importer is in node compatibility mode or this is not an ESM\n  // file that has been converted to a CommonJS file using a Babel-\n  // compatible transform (i.e. \"__esModule\" has not been set), then set\n  // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n  isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n  mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/players/index.ts\nvar players_exports = {};\n__export(players_exports, {\n  default: () => players_default\n});\nmodule.exports = __toCommonJS(players_exports);\n\n// src/utils.ts\nvar import_react = require(\"react\");\nvar lazy = import_react.lazy;\nvar IS_BROWSER = typeof window !== \"undefined\" && window.document;\nvar IS_GLOBAL = typeof globalThis !== \"undefined\" && globalThis.window && globalThis.window.document;\nvar IS_IOS = IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nvar IS_SAFARI = IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n// src/patterns.ts\nvar HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nvar HLS_PATHS = /\\/hls\\//i;\nvar DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nvar VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nvar AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\nvar canPlay = {\n  hls: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n  dash: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n  video: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n  audio: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n  file: (url) => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  }\n};\n\n// src/players/HlsPlayer.tsx\nvar import_react2 = require(\"react\");\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(contentVideo, options) {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = /* @__PURE__ */ new Map();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n  let adVideoElement;\n  let adHls;\n  let adContainerEl;\n  let currentAd;\n  let 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\n// src/players/HlsPlayer.tsx\nvar HlsPlayer = class extends import_react2.Component {\n  constructor() {\n    super(...arguments);\n    this.player = null;\n    this.mounted = false;\n    this.load = async () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      try {\n        if (this.player) {\n          this.player.destroy();\n          this.player = null;\n        }\n        const config = {\n          src: this.props.src,\n          videoElement: this.props.videoElement\n        };\n        if (this.props.autoplay !== void 0)\n          config.autoplay = this.props.autoplay;\n        if (this.props.muted !== void 0) config.muted = this.props.muted;\n        if (this.props.lowLatencyMode !== void 0)\n          config.lowLatencyMode = this.props.lowLatencyMode;\n        if (this.props.allowNativeHls !== void 0)\n          config.allowNativeHls = this.props.allowNativeHls;\n        if (this.props.isLiveStream !== void 0)\n          config.isLiveStream = this.props.isLiveStream;\n        if (this.props.driftToleranceMs !== void 0)\n          config.driftToleranceMs = this.props.driftToleranceMs;\n        if (this.props.immediateManifestAds !== void 0)\n          config.immediateManifestAds = this.props.immediateManifestAds;\n        if (this.props.debugAdTiming !== void 0)\n          config.debugAdTiming = this.props.debugAdTiming;\n        if (this.props.showCustomControls !== void 0)\n          config.showCustomControls = this.props.showCustomControls;\n        if (this.props.onVolumeToggle !== void 0)\n          config.onVolumeToggle = this.props.onVolumeToggle;\n        if (this.props.onFullscreenToggle !== void 0)\n          config.onFullscreenToggle = this.props.onFullscreenToggle;\n        if (this.props.onControlClick !== void 0)\n          config.onControlClick = this.props.onControlClick;\n        if (this.props.licenseKey !== void 0)\n          config.licenseKey = this.props.licenseKey;\n        if (this.props.adFailsafeTimeoutMs !== void 0)\n          config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n        if (this.props.minSegmentsBeforePlay !== void 0)\n          config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n        if (this.props.ctvAdRequest !== void 0)\n          config.ctvAdRequest = this.props.ctvAdRequest;\n        this.player = new StormcloudVideoPlayer(config);\n        this.props.onMount?.(this);\n        await this.player.load();\n        if (this.mounted) {\n          this.props.onReady?.();\n        }\n      } catch (error) {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      }\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[HlsPlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n          this.props.onPlay?.();\n        } else {\n          console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n        this.props.onPause?.();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"player\") return this.player;\n      if (key === \"video\") return this.props.videoElement;\n      if (key === \"hls\" && this.player) return this.player.hls;\n      return null;\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nHlsPlayer.displayName = \"HlsPlayer\";\nHlsPlayer.canPlay = canPlay.hls;\n\n// src/players/FilePlayer.tsx\nvar import_react3 = require(\"react\");\nvar FilePlayer = class extends import_react3.Component {\n  constructor() {\n    super(...arguments);\n    this.mounted = false;\n    this.ready = false;\n    this.load = () => {\n      if (!this.props.videoElement || !this.props.src) return;\n      const video = this.props.videoElement;\n      const handleLoadedMetadata = () => {\n        if (this.mounted && !this.ready) {\n          this.ready = true;\n          this.props.onReady?.();\n        }\n      };\n      const handlePlay = () => {\n        if (this.mounted) {\n          this.props.onPlay?.();\n        }\n      };\n      const handlePause = () => {\n        if (this.mounted) {\n          this.props.onPause?.();\n        }\n      };\n      const handleEnded = () => {\n        if (this.mounted) {\n          this.props.onEnded?.();\n        }\n      };\n      const handleError = (error) => {\n        if (this.mounted) {\n          this.props.onError?.(error);\n        }\n      };\n      const handleLoadedData = () => {\n        if (this.mounted) {\n          this.props.onLoaded?.();\n        }\n      };\n      video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n      video.addEventListener(\"play\", handlePlay);\n      video.addEventListener(\"pause\", handlePause);\n      video.addEventListener(\"ended\", handleEnded);\n      video.addEventListener(\"error\", handleError);\n      video.addEventListener(\"loadeddata\", handleLoadedData);\n      video.src = this.props.src;\n      if (this.props.autoplay !== void 0) video.autoplay = this.props.autoplay;\n      if (this.props.muted !== void 0) video.muted = this.props.muted;\n      if (this.props.loop !== void 0) video.loop = this.props.loop;\n      if (this.props.controls !== void 0) video.controls = this.props.controls;\n      if (this.props.playsInline !== void 0)\n        video.playsInline = this.props.playsInline;\n      if (this.props.preload !== void 0)\n        video.preload = this.props.preload;\n      if (this.props.poster !== void 0) video.poster = this.props.poster;\n      this.props.onMount?.(this);\n      return () => {\n        video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n        video.removeEventListener(\"play\", handlePlay);\n        video.removeEventListener(\"pause\", handlePause);\n        video.removeEventListener(\"ended\", handleEnded);\n        video.removeEventListener(\"error\", handleError);\n        video.removeEventListener(\"loadeddata\", handleLoadedData);\n      };\n    };\n    this.play = () => {\n      if (this.props.videoElement) {\n        const video = this.props.videoElement;\n        const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n        if (hasValidSource) {\n          video.play()?.catch((error) => {\n            console.error(\"[FilePlayer] Failed to play:\", error);\n            this.props.onError?.(error);\n          });\n        } else {\n          console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n        }\n      }\n    };\n    this.pause = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.pause();\n      }\n    };\n    this.stop = () => {\n      this.pause();\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = 0;\n      }\n    };\n    this.seekTo = (seconds, keepPlaying) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.currentTime = seconds;\n        if (!keepPlaying) {\n          this.pause();\n        }\n      }\n    };\n    this.setVolume = (volume) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n      }\n    };\n    this.mute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = true;\n      }\n    };\n    this.unmute = () => {\n      if (this.props.videoElement) {\n        this.props.videoElement.muted = false;\n      }\n    };\n    this.setPlaybackRate = (rate) => {\n      if (this.props.videoElement && rate > 0) {\n        this.props.videoElement.playbackRate = rate;\n      }\n    };\n    this.setLoop = (loop) => {\n      if (this.props.videoElement) {\n        this.props.videoElement.loop = loop;\n      }\n    };\n    this.getDuration = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n        return this.props.videoElement.duration;\n      }\n      return null;\n    };\n    this.getCurrentTime = () => {\n      if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n        return this.props.videoElement.currentTime;\n      }\n      return null;\n    };\n    this.getSecondsLoaded = () => {\n      if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n        return this.props.videoElement.buffered.end(\n          this.props.videoElement.buffered.length - 1\n        );\n      }\n      return null;\n    };\n    this.getInternalPlayer = (key = \"player\") => {\n      if (key === \"video\") return this.props.videoElement;\n      return null;\n    };\n    this.enablePIP = async () => {\n      if (this.props.videoElement && \"requestPictureInPicture\" in this.props.videoElement) {\n        try {\n          await this.props.videoElement.requestPictureInPicture();\n        } catch (error) {\n          console.warn(\"Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n    this.disablePIP = async () => {\n      if (document.pictureInPictureElement) {\n        try {\n          await document.exitPictureInPicture();\n        } catch (error) {\n          console.warn(\"Exit Picture-in-Picture failed:\", error);\n        }\n      }\n    };\n  }\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n  componentWillUnmount() {\n    this.mounted = false;\n  }\n  componentDidUpdate(prevProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n  render() {\n    return null;\n  }\n};\nFilePlayer.displayName = \"FilePlayer\";\nFilePlayer.canPlay = canPlay.file;\n\n// src/players/index.ts\nvar players = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer }))\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url) => {\n      return canPlay.file(url) && (document.pictureInPictureEnabled || typeof document.webkitSupportsPresentationMode === \"function\");\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer }))\n  }\n];\nvar players_default = players;\n","import { lazy } from \"../utils\";\nimport { canPlay } from \"../patterns\";\nimport HlsPlayer from \"./HlsPlayer\";\nimport FilePlayer from \"./FilePlayer\";\n\nexport interface PlayerConfig {\n  key: string;\n  name: string;\n  canPlay: (url: string) => boolean;\n  canEnablePIP?: (url: string) => boolean;\n  lazyPlayer?: any;\n}\n\nconst players: PlayerConfig[] = [\n  {\n    key: \"hls\",\n    name: \"HLS Player\",\n    canPlay: canPlay.hls,\n    lazyPlayer: lazy(() => Promise.resolve({ default: HlsPlayer })),\n  },\n  {\n    key: \"file\",\n    name: \"File Player\",\n    canPlay: canPlay.file,\n    canEnablePIP: (url: string) => {\n      return (\n        canPlay.file(url) &&\n        (document.pictureInPictureEnabled ||\n          typeof (document as any).webkitSupportsPresentationMode ===\n            \"function\")\n      );\n    },\n    lazyPlayer: lazy(() => Promise.resolve({ default: FilePlayer })),\n  },\n];\n\nexport default players;\n","import { lazy as reactLazy } from \"react\";\n\nexport const lazy = reactLazy;\n\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n  object: T,\n  keys: K[]\n): Omit<T, K> => {\n  const result = { ...object };\n  keys.forEach((key) => {\n    delete result[key];\n  });\n  return result;\n};\n\nexport const isMediaStream = (url: any): url is MediaStream => {\n  return (\n    typeof window !== \"undefined\" &&\n    window.MediaStream &&\n    url instanceof window.MediaStream\n  );\n};\n\nexport const supportsWebKitPresentationMode = (): boolean => {\n  if (typeof window === \"undefined\") return false;\n  const video = document.createElement(\"video\");\n  return \"webkitSupportsPresentationMode\" in video;\n};\n\nexport const randomString = (): string => {\n  return Math.random().toString(36).substr(2, 9);\n};\n\nexport const parseQuery = (url: string): Record<string, string> => {\n  const query: Record<string, string> = {};\n  const queryString = url.split(\"?\")[1] || \"\";\n\n  if (!queryString) return query;\n\n  const manualParse = (qs: string) => {\n    qs.split(\"&\").forEach((param) => {\n      const [key, value] = param.split(\"=\");\n      if (key) {\n        try {\n          query[decodeURIComponent(key)] = value\n            ? decodeURIComponent(value.replace(/\\+/g, \" \"))\n            : \"\";\n        } catch (e) {\n          query[key] = value || \"\";\n        }\n      }\n    });\n  };\n\n  if (typeof URLSearchParams !== \"undefined\") {\n    try {\n      const params = new URLSearchParams(queryString);\n      params.forEach((value, key) => {\n        query[key] = value;\n      });\n      return query;\n    } catch (e) {\n      manualParse(queryString);\n    }\n  } else {\n    manualParse(queryString);\n  }\n\n  return query;\n};\n\nexport const merge = <T extends Record<string, any>>(\n  target: T,\n  ...sources: Partial<T>[]\n): T => {\n  if (!sources.length) return target;\n  const source = sources.shift();\n\n  if (isObject(target) && isObject(source)) {\n    for (const key in source) {\n      if (isObject(source[key])) {\n        if (!target[key]) Object.assign(target, { [key]: {} });\n        merge(target[key] as any, source[key] as any);\n      } else {\n        Object.assign(target, { [key]: source[key] });\n      }\n    }\n  }\n\n  return merge(target, ...sources);\n};\n\nconst isObject = (item: any): item is Record<string, any> => {\n  return item && typeof item === \"object\" && !Array.isArray(item);\n};\n\nexport const IS_BROWSER = typeof window !== \"undefined\" && window.document;\nexport const IS_GLOBAL =\n  typeof globalThis !== \"undefined\" &&\n  globalThis.window &&\n  globalThis.window.document;\nexport const IS_IOS =\n  IS_BROWSER && /iPad|iPhone|iPod/.test(navigator.userAgent);\nexport const IS_SAFARI =\n  IS_BROWSER && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\nexport const SUPPORTS_HLS = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/vnd.apple.mpegurl\"));\n};\n\nexport const SUPPORTS_DASH = (): boolean => {\n  if (!IS_BROWSER) return false;\n  const video = document.createElement(\"video\");\n  return Boolean(video.canPlayType(\"application/dash+xml\"));\n};\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n  hls: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n  },\n\n  dash: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return DASH_EXTENSIONS.test(url);\n  },\n\n  video: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url);\n  },\n\n  audio: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return AUDIO_EXTENSIONS.test(url);\n  },\n\n  file: (url: string): boolean => {\n    if (!url || typeof url !== \"string\") return false;\n    return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n  },\n};\n","import { Component } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport { canPlay } from \"../patterns\";\n\nexport interface HlsPlayerProps extends StormcloudVideoPlayerConfig {\n  onMount?: (player: any) => void;\n  onReady?: () => void;\n  onPlay?: () => void;\n  onPause?: () => void;\n  onEnded?: () => void;\n  onLoaded?: () => void;\n  onError?: (error: any) => void;\n}\n\nexport default class HlsPlayer extends Component<HlsPlayerProps> {\n  static displayName = \"HlsPlayer\";\n\n  static canPlay = canPlay.hls;\n\n  private player: StormcloudVideoPlayer | null = null;\n  private mounted = false;\n\n  componentDidMount() {\n    this.mounted = true;\n    this.load();\n  }\n\n  componentWillUnmount() {\n    this.mounted = false;\n    if (this.player) {\n      this.player.destroy();\n      this.player = null;\n    }\n  }\n\n  componentDidUpdate(prevProps: HlsPlayerProps) {\n    if (prevProps.src !== this.props.src) {\n      this.load();\n    }\n  }\n\n  load = async () => {\n    if (!this.props.videoElement || !this.props.src) return;\n\n    try {\n      if (this.player) {\n        this.player.destroy();\n        this.player = null;\n      }\n\n      const config: StormcloudVideoPlayerConfig = {\n        src: this.props.src,\n        videoElement: this.props.videoElement,\n      };\n\n      if (this.props.autoplay !== undefined)\n        config.autoplay = this.props.autoplay;\n      if (this.props.muted !== undefined) config.muted = this.props.muted;\n      if (this.props.lowLatencyMode !== undefined)\n        config.lowLatencyMode = this.props.lowLatencyMode;\n      if (this.props.allowNativeHls !== undefined)\n        config.allowNativeHls = this.props.allowNativeHls;\n      if (this.props.isLiveStream !== undefined)\n        config.isLiveStream = this.props.isLiveStream;\n      if (this.props.driftToleranceMs !== undefined)\n        config.driftToleranceMs = this.props.driftToleranceMs;\n      if (this.props.immediateManifestAds !== undefined)\n        config.immediateManifestAds = this.props.immediateManifestAds;\n      if (this.props.debugAdTiming !== undefined)\n        config.debugAdTiming = this.props.debugAdTiming;\n      if (this.props.showCustomControls !== undefined)\n        config.showCustomControls = this.props.showCustomControls;\n      if (this.props.onVolumeToggle !== undefined)\n        config.onVolumeToggle = this.props.onVolumeToggle;\n      if (this.props.onFullscreenToggle !== undefined)\n        config.onFullscreenToggle = this.props.onFullscreenToggle;\n      if (this.props.onControlClick !== undefined)\n        config.onControlClick = this.props.onControlClick;\n      if (this.props.licenseKey !== undefined)\n        config.licenseKey = this.props.licenseKey;\n      if (this.props.adFailsafeTimeoutMs !== undefined)\n        config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;\n      if (this.props.minSegmentsBeforePlay !== undefined)\n        config.minSegmentsBeforePlay = this.props.minSegmentsBeforePlay;\n      if (this.props.ctvAdRequest !== undefined)\n        config.ctvAdRequest = this.props.ctvAdRequest;\n\n      this.player = new StormcloudVideoPlayer(config);\n\n      this.props.onMount?.(this);\n\n      await this.player.load();\n\n      if (this.mounted) {\n        this.props.onReady?.();\n      }\n    } catch (error) {\n      if (this.mounted) {\n        this.props.onError?.(error);\n      }\n    }\n  };\n\n  play = () => {\n    if (this.props.videoElement) {\n      const video = this.props.videoElement;\n      const hasValidSource =\n        video.src ||\n        (video.currentSrc && video.currentSrc !== \"\") ||\n        video.readyState >= 1;\n\n      if (hasValidSource) {\n        video.play()?.catch((error) => {\n          console.error(\"[HlsPlayer] Failed to play:\", error);\n          this.props.onError?.(error);\n        });\n        this.props.onPlay?.();\n      } else {\n        console.warn(\"[HlsPlayer] Cannot play: video has no valid source\");\n      }\n    }\n  };\n\n  pause = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.pause();\n      this.props.onPause?.();\n    }\n  };\n\n  stop = () => {\n    this.pause();\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = 0;\n    }\n  };\n\n  seekTo = (seconds: number, keepPlaying?: boolean) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.currentTime = seconds;\n      if (!keepPlaying) {\n        this.pause();\n      }\n    }\n  };\n\n  setVolume = (volume: number) => {\n    if (this.props.videoElement) {\n      this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n    }\n  };\n\n  mute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = true;\n    }\n  };\n\n  unmute = () => {\n    if (this.props.videoElement) {\n      this.props.videoElement.muted = false;\n    }\n  };\n\n  setPlaybackRate = (rate: number) => {\n    if (this.props.videoElement && rate > 0) {\n      this.props.videoElement.playbackRate = rate;\n    }\n  };\n\n  getDuration = (): number | null => {\n    if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n      return this.props.videoElement.duration;\n    }\n    return null;\n  };\n\n  getCurrentTime = (): number | null => {\n    if (\n      this.props.videoElement &&\n      isFinite(this.props.videoElement.currentTime)\n    ) {\n      return this.props.videoElement.currentTime;\n    }\n    return null;\n  };\n\n  getSecondsLoaded = (): number | null => {\n    if (\n      this.props.videoElement &&\n      this.props.videoElement.buffered.length > 0\n    ) {\n      return this.props.videoElement.buffered.end(\n        this.props.videoElement.buffered.length - 1\n      );\n    }\n    return null;\n  };\n\n  getInternalPlayer = (key = \"player\") => {\n    if (key === \"player\") return this.player;\n    if (key === \"video\") return this.props.videoElement;\n    if (key === \"hls\" && this.player) return (this.player as any).hls;\n    return null;\n  };\n\n  render() {\n    return null;\n  }\n}\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n  url: string;\n  type: string;\n  width: number;\n  height: number;\n  bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n  impression: string[];\n  start: string[];\n  firstQuartile: string[];\n  midpoint: string[];\n  thirdQuartile: string[];\n  complete: string[];\n  mute: string[];\n  unmute: string[];\n  pause: string[];\n  resume: string[];\n  fullscreen: string[];\n  exitFullscreen: string[];\n  skip: string[];\n  error: string[];\n}\n\ninterface VastAd {\n  id: string;\n  title: string;\n  duration: number;\n  mediaFiles: VastMediaFile[];\n  trackingUrls: VastTrackingUrls;\n  clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n  | { type: \"inline\"; ad: VastAd }\n  | {\n      type: \"wrapper\";\n      vastAdTagUri: string;\n      trackingUrls: VastTrackingUrls;\n      clickThrough?: string | undefined;\n    }\n  | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n  contentVideo: HTMLVideoElement,\n  options?: {\n    continueLiveStreamDuringAds?: boolean;\n    licenseKey?: string;\n    mainHlsInstance?: Hls;\n  }\n): AdController {\n  let adPlaying = false;\n  let originalMutedState = false;\n  let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n  const listeners = new Map<string, Set<(payload?: any) => void>>();\n  const licenseKey = options?.licenseKey;\n  const mainHlsInstance = options?.mainHlsInstance;\n\n  let adVideoElement: HTMLVideoElement | undefined;\n  let adHls: Hls | undefined;\n  let adContainerEl: HTMLDivElement | undefined;\n  let currentAd: VastAd | undefined;\n  let 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","import type { AdController } from \"../types\";\n\nexport function getAdAudioVolume(adPlayer: AdController): number {\n  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();\n}\n\nexport function toggleMute(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (adPlayer.isAdPlaying()) {\n    const newMutedState = !adPlayer.getOriginalMutedState();\n    const restoreVolume = adPlayer.getOriginalVolume() || 1;\n\n    adPlayer.updateOriginalMutedState(newMutedState, video.volume);\n    adPlayer.setAdVolume(newMutedState ? 0 : restoreVolume);\n\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n        newMutedState\n      );\n    }\n  } else {\n    video.muted = !video.muted;\n    adPlayer.updateOriginalMutedState(video.muted, video.volume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] Muted:\", video.muted);\n    }\n  }\n}\n\nexport function toggleFullscreen(\n  video: HTMLVideoElement,\n  debug: boolean\n): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (!document.fullscreenElement) {\n      const container = video.parentElement;\n      if (!container) {\n        reject(new Error(\"No parent container found for fullscreen\"));\n        return;\n      }\n      container\n        .requestFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n          }\n          reject(err);\n        });\n    } else {\n      document\n        .exitFullscreen()\n        .then(() => {\n          if (debug) {\n            console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n          }\n          resolve();\n        })\n        .catch((err) => {\n          if (debug) {\n            console.error(\n              \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n              err\n            );\n          }\n          reject(err);\n        });\n    }\n  });\n}\n\nexport function isMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): boolean {\n  if (adPlayer.isAdPlaying()) {\n    return adPlayer.getOriginalMutedState();\n  }\n  return video.muted;\n}\n\nexport function setMuted(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  muted: boolean,\n  debug: boolean\n): void {\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying && muted === video.muted) {\n    if (debug) {\n      console.log(\n        \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n        { muted }\n      );\n    }\n    return;\n  }\n\n  video.muted = muted;\n\n  if (adPlaying) {\n    adPlayer.updateOriginalMutedState(muted, video.volume);\n    adPlayer.setAdVolume(muted ? 0 : 1);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n        muted,\n      });\n    }\n    return;\n  }\n\n  adPlayer.updateOriginalMutedState(muted, video.volume);\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n  }\n}\n\nexport function setVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  volume: number,\n  debug: boolean\n): void {\n  const clampedVolume = Math.max(0, Math.min(1, volume));\n  const adPlaying = adPlayer.isAdPlaying();\n\n  if (adPlaying) {\n    adPlayer.setAdVolume(clampedVolume);\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n        volume: clampedVolume,\n      });\n    }\n  } else {\n    video.volume = clampedVolume;\n    video.muted = clampedVolume === 0;\n    adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n    if (debug) {\n      console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n    }\n  }\n}\n\nexport function getVolume(\n  video: HTMLVideoElement,\n  adPlayer: AdController\n): number {\n  const adPlaying = adPlayer.isAdPlaying();\n  if (adPlaying) {\n    return adPlayer.getAdVolume();\n  }\n  return video.volume;\n}\n\nexport function isFullscreen(): boolean {\n  return !!document.fullscreenElement;\n}\n\nexport function resizePlayer(\n  video: HTMLVideoElement,\n  adPlayer: AdController,\n  debug: boolean\n): void {\n  if (debug) {\n    console.log(\"[StormcloudVideoPlayer] Resizing player\");\n  }\n\n  if (adPlayer && adPlayer.isAdPlaying()) {\n    const width = video.clientWidth || 640;\n    const height = video.clientHeight || 480;\n\n    if (debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n      );\n    }\n\n    adPlayer.resize(width, height);\n  }\n}\n","import type {\n  StormcloudVideoPlayerConfig,\n  Scte35Marker,\n  AdController,\n} from \"../types\";\nimport {\n  buildAnalyticsContext,\n  sendAdLoadedTracking,\n  sendAdImpressionTracking,\n} from \"../utils/tracking\";\nimport type { AdTimingService } from \"./AdTimingService\";\nimport type { AdConfigManager } from \"./AdConfigManager\";\nimport type { Scte35CueManager } from \"./Scte35CueManager\";\nimport type { PlaceholderLayer } from \"./PlaceholderLayer\";\nimport { getAdAudioVolume } from \"./PlayerControls\";\n\nexport interface AdBreakOrchestratorHost {\n  readonly config: StormcloudVideoPlayerConfig;\n  readonly video: HTMLVideoElement;\n  getAdPlayer(): AdController;\n  setAdPlayer(player: AdController): void;\n  createAdPlayer(continueLiveStreamDuringAds: boolean): AdController;\n  shouldContinueLiveStreamDuringAds(): boolean;\n  isLiveStream(): boolean;\n  getLiveSyncPosition(): number | undefined;\n  restartHlsLoad(position: number): void;\n  reloadLiveStream(): void;\n  recoverMediaError(): void;\n  generatePodVastUrl(baseUrl: string, breakDurationMs?: number): string;\n}\n\nexport class AdBreakOrchestrator {\n  inAdBreak = false;\n  showAds: boolean = false;\n  isShowingPlaceholder: boolean = false;\n  adDetectSentForCurrentBreak: boolean = false;\n\n  private continuousFetchingActive: boolean = false;\n  private continuousFetchLoopRunning = false;\n  adRequestQueue: string[] = [];\n  adPodQueue: string[] = [];\n  private readonly maxPlaceholderDurationMs: number = 5000;\n\n  pendingAdBreak: {\n    marker: Scte35Marker;\n    detectedAtFragmentSn?: number;\n    vastUrls: string[];\n    isFetching: boolean;\n    fetchStartTime?: number;\n  } | null = null;\n  prefetchTimerId: number | undefined;\n\n  private readonly host: AdBreakOrchestratorHost;\n  private readonly timing: AdTimingService;\n  private readonly adConfig: AdConfigManager;\n  private readonly cueManager: Scte35CueManager;\n  private readonly placeholder: PlaceholderLayer;\n\n  constructor(\n    host: AdBreakOrchestratorHost,\n    timing: AdTimingService,\n    adConfig: AdConfigManager,\n    cueManager: Scte35CueManager,\n    placeholder: PlaceholderLayer\n  ) {\n    this.host = host;\n    this.timing = timing;\n    this.adConfig = adConfig;\n    this.cueManager = cueManager;\n    this.placeholder = placeholder;\n  }\n\n  private get debug(): boolean {\n    return !!this.host.config.debugAdTiming;\n  }\n\n  private get analyticsContext() {\n    return buildAnalyticsContext(this.host.config);\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  IMA event listeners\n  // ───────────────────────────────────────────────────────────────\n\n  private nextAdRequestUrl(baseVastUrl: string): string {\n    const remaining = Math.min(\n      this.timing.getWallClockRemainingAdMs(),\n      this.timing.getDurationBudgetRemainingMs()\n    );\n    const breakDurationMs = remaining > 0 ? remaining : undefined;\n    return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n  }\n\n  attachImaEventListeners(): void {\n    const adPlayer = this.host.getAdPlayer();\n    adPlayer.on(\"pod_ad_started\", (payload?: any) => {\n      this.timing.notePodAdStarted();\n      if (this.debug) {\n        console.log(\n          `[POD] Playing pod ad ${payload?.index != null ? payload.index + 1 : \"?\"}/${payload?.total ?? \"?\"}`\n        );\n      }\n    });\n    adPlayer.on(\"all_ads_completed\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      this.timing.consecutiveFailures = 0;\n\n      if (this.debug) {\n        console.log(\n          `[StormcloudVideoPlayer] all_ads_completed event received - remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.inAdBreak) {\n        if (this.timing.hasTimeToStartAnotherAd()) {\n          this.tryNextAvailableAdWithRateLimit();\n        } else {\n          this.handleAdPodComplete();\n        }\n      }\n    });\n    adPlayer.on(\"ad_error\", (errorPayload?: any) => {\n      let errorMessage = \"Ad playback failed\";\n\n      if (errorPayload) {\n        const errorCode = errorPayload.code || errorPayload.errorCode || \"unknown\";\n        const vastErrorCode = errorPayload.vastErrorCode;\n        const message = errorPayload.message || errorPayload.errorMessage || \"Unknown error\";\n        const cause = errorPayload.cause || errorPayload.innerError || errorPayload.error;\n\n        errorMessage = `Ad error: AdError ${errorCode}: ${message}`;\n\n        if (vastErrorCode && vastErrorCode !== \"N/A\" && vastErrorCode !== errorCode) {\n          errorMessage += ` (VAST Error Code: ${vastErrorCode})`;\n        }\n\n        if (cause) {\n          const causeMessage = typeof cause === \"string\" ? cause : (cause.message || String(cause));\n          errorMessage += `. Caused by: ${causeMessage}`;\n        }\n      }\n\n      console.error(\"[AD-ERROR]\", errorMessage, errorPayload || \"\");\n      this.handleAdFailure();\n    });\n    adPlayer.on(\"content_pause\", () => {\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = true;\n      this.timing.resetGamNoFillCounter();\n\n      if (this.inAdBreak && this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n        }\n      }\n\n      this.host.getAdPlayer().setAdVolume(getAdAudioVolume(this.host.getAdPlayer()));\n\n      if (this.isShowingPlaceholder) {\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n        }\n        this.host.getAdPlayer().hidePlaceholder();\n        this.isShowingPlaceholder = false;\n      }\n    });\n    adPlayer.on(\"content_resume\", () => {\n      sendAdImpressionTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", adIndex: this.timing.currentAdIndex, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      if (!this.host.video.muted) {\n        this.host.video.muted = true;\n        if (this.debug) {\n          console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n        }\n      }\n\n      this.timing.clearAdFailsafeTimer();\n      this.timing.clearAdRequestWatchdog();\n      this.timing.activeAdRequestToken = null;\n      this.showAds = false;\n\n      if (!this.inAdBreak) {\n        return;\n      }\n\n      this.timing.consecutiveFailures = 0;\n\n      this.timing.recordPlayedAdDuration(this.host.getAdPlayer());\n      const remaining = this.timing.getRemainingAdMs();\n\n      if (this.debug) {\n        console.log(\n          `[CONTINUOUS-FETCH] content_resume event: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}`,\n          this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n        );\n      }\n\n      if (this.timing.hasTimeToStartAnotherAd()) {\n        this.tryNextAvailableAdWithRateLimit();\n      } else {\n        this.handleAdPodComplete();\n      }\n    });\n  }\n\n  recreateAdController(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Recreating AdController for new ad\");\n    }\n\n    const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n    const adPlayer = this.host.getAdPlayer();\n    if (shouldShowPlaceholder && adPlayer) {\n      if (this.debug) {\n        console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old AdController\");\n      }\n      this.placeholder.show();\n      adPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n\n    const preservedMutedState = adPlayer.getOriginalMutedState();\n    const preservedVolumeState = adPlayer.getOriginalVolume();\n\n    if (adPlayer) {\n      try {\n        adPlayer.destroy();\n        this.host.video.muted = true;\n      } catch (error) {\n        if (this.debug) {\n          console.warn(\"[StormcloudVideoPlayer] Error destroying old AdController:\", error);\n        }\n      }\n    }\n\n    const continueLiveStreamDuringAds = this.host.shouldContinueLiveStreamDuringAds();\n    const newAdPlayer = this.host.createAdPlayer(continueLiveStreamDuringAds);\n    this.host.setAdPlayer(newAdPlayer);\n\n    newAdPlayer.initialize();\n    newAdPlayer.updateOriginalMutedState(preservedMutedState, preservedVolumeState);\n    this.attachImaEventListeners();\n\n    if (shouldShowPlaceholder) {\n      this.placeholder.show();\n      newAdPlayer.showPlaceholder();\n      this.isShowingPlaceholder = true;\n    }\n  }\n\n  clearPendingAdBreak(): void {\n    if (this.prefetchTimerId != null) {\n      clearTimeout(this.prefetchTimerId);\n      this.prefetchTimerId = undefined;\n    }\n    this.pendingAdBreak = null;\n    this.cueManager.pendingScte35CueKey = undefined;\n    this.adConfig.podAssignedByPrefetch = false;\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break start\n  // ───────────────────────────────────────────────────────────────\n\n  async handleAdStart(_marker: Scte35Marker): Promise<void> {\n    const scheduled = this.adConfig.findCurrentOrNextBreak(\n      this.host.video.currentTime * 1000\n    );\n    if (scheduled) {\n      this.adConfig.consumedVmapBreakIds.add(this.adConfig.getAdBreakKey(scheduled));\n    }\n    const tags = this.adConfig.selectVastTagsForBreak(scheduled);\n\n    let baseVastUrl: string;\n\n    if (tags && tags.length > 0 && tags[0]) {\n      baseVastUrl = tags[0];\n    } else if (this.adConfig.apiVastTagUrl) {\n      baseVastUrl = this.adConfig.apiVastTagUrl;\n    } else {\n      this.clearPendingAdBreak();\n      return;\n    }\n\n    const adBreakDurationMs =\n      _marker.durationSeconds != null\n        ? _marker.durationSeconds * 1000\n        : scheduled?.durationMs;\n\n    if (this.debug) {\n      const mode = this.host.config.isLiveStream ? \"LIVE\" : \"VOD\";\n      console.log(\n        `[CONTINUOUS-FETCH] ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n      );\n    }\n\n    this.timing.failedVastUrls.clear();\n    this.timing.temporaryFailureUrls.clear();\n    this.timing.consecutiveFailures = 0;\n    this.continuousFetchingActive = true;\n    this.isShowingPlaceholder = false;\n    this.timing.totalAdRequestsInBreak = 0;\n\n    if (this.adConfig.podAssignedByPrefetch) {\n      this.adConfig.podAssignedByPrefetch = false;\n    } else {\n      this.adConfig.beginNewAdPod();\n    }\n\n    const currentMuted = this.host.video.muted;\n    const currentVolume = this.host.video.volume;\n    this.host.getAdPlayer().updateOriginalMutedState(currentMuted, currentVolume);\n\n    this.inAdBreak = true;\n    this.timing.adBreakPlayedDurationMs = 0;\n    this.timing.currentAdIndex = 0;\n    this.timing.totalAdsInBreak = 0;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    if (\n      this.timing.expectedAdBreakDurationMs == null &&\n      adBreakDurationMs != null\n    ) {\n      this.timing.expectedAdBreakDurationMs = adBreakDurationMs;\n    }\n\n    const podPlayed = await this.startOptimizedPod(\n      baseVastUrl,\n      adBreakDurationMs,\n      currentMuted,\n      currentVolume\n    );\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  // ───────────────────────────────────────────────────────────────\n  //  Optimized pod (single multi-ad request)\n  // ───────────────────────────────────────────────────────────────\n\n  private async startOptimizedPod(\n    baseVastUrl: string,\n    breakDurationMs: number | undefined,\n    currentMuted: boolean,\n    currentVolume: number\n  ): Promise<boolean> {\n    let podUrl: string | undefined;\n    if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n      podUrl = this.pendingAdBreak.vastUrls[0];\n      this.clearPendingAdBreak();\n    } else {\n      podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);\n    }\n\n    if (!podUrl) {\n      return false;\n    }\n\n    this.continuousFetchingActive = false;\n\n    this.recreateAdController();\n\n    const adPlayer = this.host.getAdPlayer();\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      await adPlayer.requestAds(podUrl);\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) {\n        return true;\n      }\n\n      const podCount = adPlayer.getPodAdCount?.() ?? 1;\n      if (podCount < 1) {\n        return false;\n      }\n\n      if (this.debug) {\n        console.log(\n          podCount === 1\n            ? \"[POD] Response contained a single ad; playing it and enabling pod top-up\"\n            : `[POD] Optimized pod returned ${podCount} ads; playing pod in one controller`\n        );\n      }\n\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: podUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.startAdFailsafeTimer(requestToken);\n      await adPlayer.play();\n      this.timing.markAdStarted();\n\n      if (\n        this.timing.expectedAdBreakDurationMs != null &&\n        this.timing.getAdBreakEndWallClockMs() == null\n      ) {\n        this.timing.scheduleAdStopAtBreakBoundary();\n      }\n\n      adPlayer.setAdVolume(currentMuted ? 0 : currentVolume);\n      this.timing.consecutiveFailures = 0;\n\n      this.continuousFetchingActive = true;\n      this.startContinuousFetching(baseVastUrl);\n\n      return true;\n    } catch (error) {\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      if (this.debug) {\n        console.warn(\"[POD] Optimized pod request/play failed:\", error);\n      }\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(podUrl, Date.now());\n      }\n\n      this.continuousFetchingActive = true;\n      this.recreateAdController();\n      return false;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Continuous fetching\n  // ───────────────────────────────────────────────────────────────\n\n  private startContinuousFetching(baseVastUrl: string): void {\n    if (!this.continuousFetchingActive) {\n      return;\n    }\n\n    if (this.continuousFetchLoopRunning) {\n      if (this.debug) {\n        console.log(\"[CONTINUOUS-FETCH] Fetch loop already running, skipping duplicate start\");\n      }\n      return;\n    }\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Starting continuous ad fetching loop\");\n    }\n\n    this.continuousFetchLoopRunning = true;\n    this.continuousFetchLoop(baseVastUrl);\n  }\n\n  private async continuousFetchLoop(baseVastUrl: string): Promise<void> {\n    const epoch = this.timing.adBreakEpoch;\n    while (\n      this.continuousFetchingActive &&\n      this.inAdBreak &&\n      epoch === this.timing.adBreakEpoch\n    ) {\n      const remaining = Math.min(\n        this.timing.getWallClockRemainingAdMs(),\n        this.timing.getDurationBudgetRemainingMs()\n      );\n\n      if (remaining <= this.timing.getMinRemainingMsToStartAd()) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Not enough ad break time left (wall=${this.timing.getWallClockRemainingAdMs()}ms, budget=${this.timing.getDurationBudgetRemainingMs()}ms), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.isGamInCooldown()) {\n        if (this.debug) {\n          console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation\");\n        }\n        break;\n      }\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), stopping URL generation`);\n        }\n        break;\n      }\n\n      if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] Maximum ad requests reached (${this.timing.maxTotalAdRequestsPerBreak}), stopping`);\n        }\n        break;\n      }\n\n      const maxQueueSize = 5;\n      if (this.adRequestQueue.length >= maxQueueSize) {\n        if (this.debug) {\n          console.log(`[CONTINUOUS-FETCH] URL queue full (${this.adRequestQueue.length}), waiting...`);\n        }\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        continue;\n      }\n\n      const newAdUrl = this.nextAdRequestUrl(baseVastUrl);\n\n      if (!newAdUrl || this.timing.failedVastUrls.has(newAdUrl) || this.timing.isUrlInCooldown(newAdUrl)) {\n        await new Promise(resolve => setTimeout(resolve, 500));\n        continue;\n      }\n\n      if (this.debug) {\n        const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n        console.log(\n          `[CONTINUOUS-FETCH] Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n          { queuedUrls: queuedUrlsPreview }\n        );\n      }\n\n      this.adRequestQueue.push(newAdUrl);\n\n      const generationDelay = this.timing.consecutiveFailures > 0\n        ? Math.min(1000 * Math.pow(2, this.timing.consecutiveFailures), 5000)\n        : 500;\n      await new Promise(resolve => setTimeout(resolve, generationDelay));\n    }\n\n    this.continuousFetchLoopRunning = false;\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] URL generation loop ended (queued: ${this.adRequestQueue.length})`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n  }\n\n  stopContinuousFetching(): void {\n    this.continuousFetchingActive = false;\n    this.continuousFetchLoopRunning = false;\n\n    this.placeholder.hide();\n\n    if (this.debug) {\n      console.log(\"[CONTINUOUS-FETCH] Stopping continuous ad fetching\");\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad iteration\n  // ───────────────────────────────────────────────────────────────\n\n  async tryNextAvailableAdWithRateLimit(): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const epoch = this.timing.adBreakEpoch;\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    const backoffMultiplier = Math.pow(2, this.timing.consecutiveFailures);\n    const backoffDelay = Math.min(this.timing.backoffBaseMs * backoffMultiplier, this.timing.maxBackoffMs);\n    const effectiveMinInterval = this.timing.minAdRequestIntervalMs + (this.timing.consecutiveFailures > 0 ? backoffDelay : 0);\n\n    const timeSinceLastRequest = Date.now() - this.timing.lastAdRequestTime;\n    if (timeSinceLastRequest < effectiveMinInterval) {\n      const waitTime = effectiveMinInterval - timeSinceLastRequest;\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.timing.consecutiveFailures} failures)`);\n      }\n      await new Promise(resolve => setTimeout(resolve, waitTime));\n    }\n\n    if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) {\n      return;\n    }\n\n    return this.tryNextAvailableAd(0);\n  }\n\n  private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n    if (!this.inAdBreak) {\n      return;\n    }\n\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (!this.timing.hasTimeToStartAnotherAd()) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Not enough time remaining (${remaining}ms) to start another ad, ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) {\n        console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully\");\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Too many consecutive failures (${this.timing.consecutiveFailures}), ending ad break`);\n      }\n      this.handleAdPodComplete();\n      return;\n    }\n\n    this.timing.cleanupTemporaryFailures();\n\n    while (this.adRequestQueue.length > 0) {\n      const nextAdUrl = this.adRequestQueue.shift();\n\n      if (!nextAdUrl) continue;\n\n      if (this.timing.failedVastUrls.has(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping permanently-failed URL, trying next...\");\n        continue;\n      }\n\n      if (this.timing.isUrlInCooldown(nextAdUrl)) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping URL in cooldown (recent no-fill), trying next...\");\n        continue;\n      }\n\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Requesting next ad via HLS ad player (${this.timing.currentAdIndex + 1}, ${this.adRequestQueue.length} remaining in queue)`);\n      }\n\n      try {\n        await this.playSingleAd(nextAdUrl);\n        this.timing.consecutiveFailures = 0;\n      } catch (error) {\n        const errorMessage = (error as Error).message;\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad request failed:\", errorMessage);\n\n        if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n          await this.tryNextAvailableAdWithRateLimit();\n          return;\n        }\n\n        if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n          this.timing.consecutiveFailures++;\n        }\n\n        await this.tryNextAvailableAdWithRateLimit();\n      }\n      return;\n    }\n\n    const maxRetries = 3;\n    if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2000) {\n      if (this.debug) {\n        console.log(`[CONTINUOUS-FETCH] Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n      }\n      await new Promise(resolve => setTimeout(resolve, 500));\n      await this.tryNextAvailableAd(retryCount + 1);\n      return;\n    }\n\n    if (!this.isShowingPlaceholder && remaining > 1000) {\n      this.showPlaceholderAndWaitForAds();\n    } else {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] No more ads available, ending ad break\");\n      this.handleAdPodComplete();\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Single ad playback\n  // ───────────────────────────────────────────────────────────────\n\n  async playSingleAd(vastTagUrl: string): Promise<void> {\n    const adPlayer = this.host.getAdPlayer();\n    if (adPlayer.isAdPlaying()) return;\n\n    if (this.timing.failedVastUrls.has(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n      throw new Error(\"VAST URL permanently failed\");\n    }\n\n    if (this.timing.isUrlInCooldown(vastTagUrl)) {\n      if (this.debug) console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n      throw new Error(\"VAST URL in cooldown after no-fill\");\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n      throw new Error(\"Too many consecutive failures\");\n    }\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.warn(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request\");\n      throw new Error(\"GAM in cooldown\");\n    }\n\n    this.recreateAdController();\n\n    const requestToken = ++this.timing.adRequestTokenCounter;\n    this.timing.activeAdRequestToken = requestToken;\n    this.timing.startAdRequestWatchdog(requestToken);\n\n    try {\n      await this.timing.enforceGlobalRateLimit();\n      this.timing.lastAdRequestTime = Date.now();\n      const ap = this.host.getAdPlayer();\n      await ap.requestAds(vastTagUrl);\n      sendAdLoadedTracking(\n        this.host.config.licenseKey,\n        { source: \"hls\", vastUrl: vastTagUrl, timestamp: new Date().toISOString() },\n        this.analyticsContext\n      ).catch(() => {});\n\n      this.timing.clearAdRequestWatchdog();\n\n      if (this.timing.activeAdRequestToken !== requestToken) return;\n\n      if (!this.timing.ensureLoadedAdFitsBudget(ap)) {\n        this.timing.rejectLoadedAdForDuration(ap);\n        this.recreateAdController();\n        throw new Error(\"ad_duration_exceeds_budget\");\n      }\n\n      try {\n        this.timing.startAdFailsafeTimer(requestToken);\n        await ap.play();\n        this.timing.markAdStarted();\n\n        if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {\n          this.timing.scheduleAdStopAtBreakBoundary();\n        }\n\n        ap.setAdVolume(getAdAudioVolume(ap));\n        this.timing.consecutiveFailures = 0;\n        this.timing.temporaryFailureUrls.delete(vastTagUrl);\n      } catch (playError) {\n        if (this.debug) console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n\n        if (this.timing.isTemporaryAdError(playError as Error)) {\n          this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n          if (this.debug) console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n        } else {\n          this.timing.failedVastUrls.add(vastTagUrl);\n          if (this.debug) console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n        }\n\n        this.timing.clearAdFailsafeTimer();\n        if (this.timing.activeAdRequestToken === requestToken) {\n          this.timing.activeAdRequestToken = null;\n        }\n        throw playError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error)?.message || \"\";\n      if (this.debug) console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n\n      if (this.timing.isTemporaryAdError(error as Error)) {\n        this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());\n        if (this.debug) console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n      } else {\n        this.timing.failedVastUrls.add(vastTagUrl);\n        if (this.debug) console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n      }\n\n      this.timing.clearAdRequestWatchdog();\n      this.timing.clearAdFailsafeTimer();\n      if (this.timing.activeAdRequestToken === requestToken) {\n        this.timing.activeAdRequestToken = null;\n      }\n      throw error;\n    }\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Placeholder wait\n  // ───────────────────────────────────────────────────────────────\n\n  private async showPlaceholderAndWaitForAds(): Promise<void> {\n    const remaining = this.timing.getRemainingAdMs();\n    const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n\n    if (this.timing.isGamInCooldown()) {\n      if (this.debug) console.log(\"[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(\"[CONTINUOUS-FETCH] Skipping placeholder - too many consecutive failures\");\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (waitTime < 1000) {\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.debug) {\n      console.log(`[CONTINUOUS-FETCH] Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n    }\n\n    this.isShowingPlaceholder = true;\n    this.host.getAdPlayer().showPlaceholder();\n\n    const checkInterval = 300;\n    const maxChecks = Math.floor(waitTime / checkInterval);\n\n    for (let i = 0; i < maxChecks; i++) {\n      await new Promise(resolve => setTimeout(resolve, checkInterval));\n\n      if (!this.inAdBreak) return;\n\n      if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Too many failures during placeholder wait\");\n        break;\n      }\n\n      if (!this.timing.hasTimeToStartAnotherAd()) {\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Not enough time remaining during placeholder wait, ending ad break\");\n        break;\n      }\n\n      while (this.adRequestQueue.length > 0) {\n        if (!this.timing.hasTimeToStartAnotherAd()) break;\n\n        const nextAdUrl = this.adRequestQueue.shift();\n        if (!nextAdUrl) continue;\n        if (this.timing.failedVastUrls.has(nextAdUrl)) continue;\n        if (this.timing.isUrlInCooldown(nextAdUrl)) continue;\n\n        if (this.debug) console.log(\"[CONTINUOUS-FETCH] Ad URL available, requesting via HLS ad player\");\n\n        this.isShowingPlaceholder = false;\n        this.host.getAdPlayer().hidePlaceholder();\n\n        try {\n          await this.playSingleAd(nextAdUrl);\n          this.timing.consecutiveFailures = 0;\n        } catch (error) {\n          const errorMessage = (error as Error).message;\n          if (errorMessage.includes(\"ad_duration_exceeds_budget\")) {\n            await this.tryNextAvailableAdWithRateLimit();\n            return;\n          }\n          if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n            this.timing.consecutiveFailures++;\n          }\n          await this.tryNextAvailableAdWithRateLimit();\n        }\n        return;\n      }\n    }\n\n    if (this.debug) console.log(\"[CONTINUOUS-FETCH] Placeholder timeout, ending ad break\");\n\n    this.isShowingPlaceholder = false;\n    this.host.getAdPlayer().hidePlaceholder();\n    this.handleAdPodComplete();\n  }\n\n  // ───────────────────────────────────────────────────────────────\n  //  Ad break completion\n  // ───────────────────────────────────────────────────────────────\n\n  handleAdPodComplete(): void {\n    if (this.debug) {\n      console.log(\"[StormcloudVideoPlayer] Ad pod complete - cleaning up\");\n    }\n\n    this.timing.resetForBreakEnd();\n\n    this.stopContinuousFetching();\n    this.clearPendingAdBreak();\n\n    if (this.isShowingPlaceholder) {\n      this.host.getAdPlayer().hidePlaceholder();\n      this.isShowingPlaceholder = false;\n    }\n\n    this.adRequestQueue = [];\n\n    this.inAdBreak = false;\n    this.adDetectSentForCurrentBreak = false;\n    this.cueManager.activeScte35BreakKey = undefined;\n    this.cueManager.scheduledScte35BreakKey = undefined;\n    this.adPodQueue = [];\n    this.showAds = false;\n\n    this.host.getAdPlayer().stop().catch(() => {});\n\n    const restoredMuted = this.host.getAdPlayer().getOriginalMutedState();\n    const restoredVolume = this.host.getAdPlayer().getOriginalVolume();\n\n    if (this.host.video.muted !== restoredMuted) {\n      this.host.video.muted = restoredMuted;\n    }\n    if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {\n      this.host.video.volume = restoredVolume;\n    }\n\n    this.host.video.style.visibility = \"visible\";\n    this.host.video.style.opacity = \"1\";\n\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 — snapping to live edge: ${this.host.video.currentTime.toFixed(2)}s → ${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\n    this.resumeContentPlayback();\n  }\n\n  private getBufferedAhead(): number {\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\n  private describeVideoState(): string {\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\n      ? `code=${v.error.code}${v.error.message ? ` (${v.error.message})` : \"\"}`\n      : \"none\";\n    const ranges: string[] = [];\n    for (let i = 0; i < v.buffered.length; i++) {\n      ranges.push(`[${v.buffered.start(i).toFixed(2)}–${v.buffered.end(i).toFixed(2)}]`);\n    }\n    return (\n      `t=${v.currentTime.toFixed(2)}s paused=${v.paused} ended=${v.ended} seeking=${v.seeking} ` +\n      `readyState=${ready} networkState=${net} error=${err} ` +\n      `buffered=${ranges.length ? ranges.join(\",\") : \"none\"}`\n    );\n  }\n\n  private monitorLiveResumeStall(resumeBaseline: number): void {\n    const pollIntervalMs = 1000;\n    const graceMs = 5000;\n    const recoveryCooldownMs = 5000;\n    const maxRecoveries = 3;\n    const maxMonitorMs = 45000;\n\n    const startTime = Date.now();\n    let baseline = resumeBaseline;\n    let recoveries = 0;\n    let lastRecoveryAt = 0;\n\n    const video = this.host.video;\n    let listenersAttached = false;\n    let onMediaEvent: ((e: Event) => void) | undefined;\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: Event) => {\n        const dt = ((Date.now() - startTime) / 1000).toFixed(1);\n        console.log(\n          `[ResumeDiag] +${dt}s event=${e.type} — ${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 — ${this.describeVideoState()}`\n      );\n    }\n\n    const cleanup = (): void => {\n      if (listenersAttached && onMediaEvent) {\n        for (const name of diagEvents) {\n          video.removeEventListener(name, onMediaEvent);\n        }\n        listenersAttached = false;\n      }\n    };\n\n    const poll = (): void => {\n      if (this.inAdBreak) {\n        cleanup();\n        return;\n      }\n\n      const currentTime = video.currentTime;\n      const advanced = currentTime > baseline + 0.5;\n      const playing = !video.paused && video.readyState >= 3;\n\n      if (advanced && playing) {\n        if (this.debug) {\n          console.log(\n            `[StormcloudVideoPlayer] Live stream resumed successfully after ad break — ${this.describeVideoState()}`\n          );\n        }\n        cleanup();\n        return;\n      }\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\n      if (elapsed >= maxMonitorMs) {\n        if (this.debug && !advanced) {\n          console.warn(\n            `[StormcloudVideoPlayer] Live stream failed to resume after ${(maxMonitorMs / 1000).toFixed(0)}s — ${this.describeVideoState()}`\n          );\n        }\n        cleanup();\n        return;\n      }\n\n      const canRecover =\n        wedged &&\n        elapsed >= graceMs &&\n        Date.now() - lastRecoveryAt >= recoveryCooldownMs &&\n        recoveries < maxRecoveries;\n\n      if (canRecover) {\n        recoveries++;\n        lastRecoveryAt = Date.now();\n\n        if (recoveries === 1) {\n          if (this.debug) {\n            console.warn(\n              `[StormcloudVideoPlayer] Content wedged after ad break — calling recoverMediaError() (recovery ${recoveries}/${maxRecoveries}) — ${this.describeVideoState()}`\n            );\n          }\n          this.host.recoverMediaError();\n        } else if (recoveries === 2) {\n          const liveSyncPos = this.host.getLiveSyncPosition();\n          const reloadPos =\n            liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;\n\n          if (this.debug) {\n            console.warn(\n              `[StormcloudVideoPlayer] Content wedged after ad break — restarting HLS load at ${reloadPos.toFixed(2)}s (recovery ${recoveries}/${maxRecoveries}) — ${this.describeVideoState()}`\n            );\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 — hard-reloading live stream (recovery ${recoveries}/${maxRecoveries}) — ${this.describeVideoState()}`\n            );\n          }\n          this.host.reloadLiveStream();\n        }\n\n        baseline = video.currentTime;\n        if (video.paused) {\n          video.play()?.catch(() => {});\n        }\n      }\n\n      window.setTimeout(poll, pollIntervalMs);\n    };\n\n    window.setTimeout(poll, pollIntervalMs);\n  }\n\n  private resumeContentPlayback(attempt: number = 0): void {\n    const maxAttempts = 5;\n    const video = this.host.video;\n\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\n    if (this.debug) {\n      console.log(\n        `[StormcloudVideoPlayer] Resuming content playback after ads (attempt ${attempt + 1}/${maxAttempts}, readyState=${video.readyState})`\n      );\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        return;\n      }\n\n      const onReady = (): void => {\n        video.removeEventListener(\"canplay\", onReady);\n        this.resumeContentPlayback(attempt + 1);\n      };\n      video.addEventListener(\"canplay\", onReady);\n\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\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\n  handleAdFailure(): void {\n    this.timing.consecutiveFailures++;\n    this.timing.recordGamNoFill();\n    const remaining = this.timing.getRemainingAdMs();\n\n    if (this.debug) {\n      console.log(\n        `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.timing.consecutiveFailures}`,\n        this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n      );\n    }\n\n    if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {\n      if (this.debug) console.log(`[CONTINUOUS-FETCH] Max consecutive failures reached (${this.timing.consecutiveFailures}), ending ad break gracefully`);\n      this.handleAdPodComplete();\n      return;\n    }\n\n    if (this.timing.hasTimeToStartAnotherAd()) {\n      this.tryNextAvailableAdWithRateLimit();\n    } else {\n      if (this.debug) console.log(\"[AD-ERROR] Ad failed and not enough time remaining for another ad. Failed URLs:\", this.timing.failedVastUrls.size);\n      this.handleAdPodComplete();\n    }\n  }\n}\n"]}