stormcloud-video-player 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +245 -156
  2. package/dist/stormcloud-vp.min.js +1 -1
  3. package/lib/index.cjs +9759 -5311
  4. package/lib/index.cjs.map +1 -1
  5. package/lib/index.d.cts +193 -17
  6. package/lib/index.d.ts +193 -17
  7. package/lib/index.js +9761 -5329
  8. package/lib/index.js.map +1 -1
  9. package/lib/player/StormcloudVideoPlayer.cjs +7090 -1508
  10. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  11. package/lib/player/StormcloudVideoPlayer.d.cts +95 -9
  12. package/lib/players/HlsPlayer.cjs +7107 -1525
  13. package/lib/players/HlsPlayer.cjs.map +1 -1
  14. package/lib/players/HlsPlayer.d.cts +1 -1
  15. package/lib/players/index.cjs +7098 -1516
  16. package/lib/players/index.cjs.map +1 -1
  17. package/lib/sdk/hlsAdPlayer.cjs +302 -266
  18. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  19. package/lib/sdk/hlsAdPlayer.d.cts +2 -2
  20. package/lib/sdk/ima.cjs +1375 -0
  21. package/lib/sdk/ima.cjs.map +1 -0
  22. package/lib/sdk/ima.d.cts +12 -0
  23. package/lib/sdk/prebid.cjs +564 -0
  24. package/lib/sdk/prebid.cjs.map +1 -0
  25. package/lib/sdk/prebid.d.cts +5 -0
  26. package/lib/sdk/prebidController.cjs +1560 -0
  27. package/lib/sdk/prebidController.cjs.map +1 -0
  28. package/lib/sdk/prebidController.d.cts +11 -0
  29. package/lib/sdk/vastParser.cjs +393 -0
  30. package/lib/sdk/vastParser.cjs.map +1 -0
  31. package/lib/sdk/vastParser.d.cts +45 -0
  32. package/lib/{types-Ca4ZDaWw.d.cts → types-g2d4Akez.d.cts} +72 -3
  33. package/lib/ui/StormcloudVideoPlayer.cjs +7130 -1530
  34. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  35. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  36. package/lib/utils/browserCompat.cjs +222 -20
  37. package/lib/utils/browserCompat.cjs.map +1 -1
  38. package/lib/utils/browserCompat.d.cts +9 -1
  39. package/lib/utils/tracking.d.cts +1 -1
  40. package/package.json +2 -1
  41. package/lib/sdk/adstormPlayer.cjs +0 -908
  42. package/lib/sdk/adstormPlayer.cjs.map +0 -1
  43. package/lib/sdk/adstormPlayer.d.cts +0 -9
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/sdk/adstormPlayer.ts","../../src/player/StormcloudVideoPlayer.ts","../../src/utils/polyfills.ts","../../src/utils/browserCompat.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","exports","import_react","require","import_hls","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","replaceFlvExtension","isUnsupportedFormat","indexOf","replace","isSupportedFormat","mimeType","includes","licenseKey","options","debug","adPlaying","originalMutedState","originalVolume","Math","max","min","contentVideo","volume","listeners","Map","adVideoElement","currentAd","destroyed","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","console","emit","event","payload","set","Array","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","durationParts","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","type","trim","originalUrl","push","trackingUrls","el","eventKey","clickThrough","id","selectBestMediaFile","mp4Files","filter","candidates","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","ad","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","adContainerEl","opacity","setTimeout","pointerEvents","visibility","display","vastUrl","response","xmlText","fetch","headers","ok","Error","status","statusText","text","initialize","container","right","bottom","alignItems","justifyContent","transition","parentElement","appendChild","requestAds","parsed","Promise","reject","isNaN","fetchVast","resolve","play","mediaFile","pause","offsetHeight","stop","destroy","remove","removeChild","clear","isAdPlaying","resize","on","listener","has","Set","getOriginalMutedState","add","off","delete","updateOriginalMutedState","nextVolume","Number","getOriginalVolume","getAdVolume","showPlaceholder","hidePlaceholder","polyfillURLSearchParams","URLSearchParams","URLSearchParamsPolyfill","init","params","parseQueryString","append","query","cleanQuery","param","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","values","String","getAll","callback","toString","parts","join","window","polyfillTextEncoder","TextEncoder","TextEncoderPolyfill","encoding","encode","utf8","i","charcode","charCodeAt","Uint8Array","finally","constructor","then","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","startsWith","search","pos","substring","polyfillStringEndsWith","endsWith","polyfillStringIncludes","initializePolyfills","polyfillPromiseFinally","getChromeVersion","ua","match","getWebKitVersion","getPlatform","navigator","userAgentData","platform","userAgent","test","detectBrowser","version","majorVersion","isSmartTV","isLegacyTV","supportsModernJS","chromeVersion","webkitVersion","logBrowserInfo","browser","getBrowserConfigOverrides","overrides","allowNativeHls","StormcloudVideoPlayer","config","attached","inAdBreak","ptsDriftEmaMs","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","browserOverrides","videoElement","debugAdTiming","adPlayer","createAdStormPlayer","load","attach","shouldUseNativeHls","lowLatencyMode","isLive","autoplay","catch","hls","Hls","enableWorker","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","loadSource","Events","MANIFEST_PARSED","level","details","live","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","minSegments","levels","some","minSegmentsBeforePlay","FRAG_BUFFERED","err","FRAG_PARSING_METADATA","_evt","data","id3Tags","samples","map","s","ptsSeconds","pts","tag","onId3Tag","FRAG_CHANGED","frag","tagList","isArray","entry","idx","parseCueOutDuration","onScte35Marker","raw","prog","parseCueOutCont","elapsed","attrs","parseAttributeList","hasScteOut","hasScteIn","klass","toNumber","ERROR","fatal","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","attachMedia","handleAdPodComplete","timeUpdateHandler","emptiedHandler","wasPaused","paused","streamType","getStreamType","canNative","canPlayType","updatePtsDrift","marker","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","dur","id3","cueOutContMatch","cont","cueInMatch","decoder","TextDecoder","decode","out","fromCharCode","durationMs","handleAdStart","num","d","elapsedMatch","durationMatch","res","regex","rawVal","val","n","scheduleAdStopCountdown","remainingMs","clearAdStopTimer","ms","floor","adStopTimerId","clearTimeout","ptsSecondsSample","sampleMs","isFinite","alpha","expectedAdBreakDurationMs","restoredMuted","restoredVolume","isShowingAds","shouldShowNativeControls","showCustomControls","toggleMute","currentMuted","newMutedState","setAdVolume","toggleFullscreen","fullscreenElement","requestFullscreen","exitFullscreen","isMuted","setMuted","setVolume","clampedVolume","isFullscreen","clientHeight","removeEventListener","getCurrentAdIndex","getTotalAdsInBreak","React","memo","props","driftToleranceMs","immediateManifestAds","hideLoadingIndicator","onVolumeToggle","onFullscreenToggle","onControlClick","onReady","wrapperClassName","wrapperStyle","className","controls","preload","poster","children","restVideoAttrs","useRef","useState","setAdStatus","setShouldShowNativeControls","setIsMuted","setIsFullscreen","setIsPlaying","setCurrentTime","setDuration","playbackRate","setPlaybackRate","showVolumeSlider","setShowVolumeSlider","showSpeedMenu","setShowSpeedMenu","isLoading","setIsLoading","isBuffering","setIsBuffering","showLicenseWarning","setShowLicenseWarning","innerWidth","innerHeight","viewportWidth","isPortrait","setViewportWidth","setIsPortrait","getResponsiveScale","seconds","minutes","padStart","remainingSeconds","videoRef","current","currentSrc","readyState","getBoundingClientRect","clickX","rect","newTime","newVolume","rate","useMemo","prop","cfg","player","showNative","criticalPropsKey","playerRef","currentIndex","prev","showAds","totalAds","setInterval","checkAdStatus","clearInterval","interval","useEffect","handleResize","currentTimeValue","durationValue","volumeValue","rateValue","updateStates","handleFullscreenChange","bufferingTimeoutRef","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handlePause","handleEnded","import_jsx_runtime","jsxs","Fragment","jsx","overflow","minHeight","maxWidth","maxHeight","borderRadius","boxShadow","ref","aspectRatio","import_fa","FaSpinner","color","animation","transform","background","padding","backdropFilter","border","textAlign","margin","fontSize","fontWeight","marginBottom","textShadow","lineHeight","showCenterPlay","adStatus","onClick","handleCenterPlayClick","cursor","onMouseEnter","currentTarget","borderColor","onMouseLeave","FaPlay","size","marginLeft","shouldShowEnhancedControls","handleTimelineSeek","flexWrap","gap","responsiveScale","handlePlayPause","minWidth","FaPause","FaVolumeMute","FaVolumeDown","FaVolumeUp","flexDirection","onMouseDown","preventDefault","sliderElement","handleMouseMove","moveEvent","y","clientY","percentage","handleVolumeChange"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/player/StormcloudVideoPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\n\n// src/sdk/adstormPlayer.ts\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = 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 let adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\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(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\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(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\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 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.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 const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\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.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"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 = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n log(`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 log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\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.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n }\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/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 if (/Web0S|webOS/i.test(ua)) {\n name = \"LG WebOS\";\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\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 }\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\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 };\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 userAgent: navigator.userAgent\n });\n}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\n\n// src/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false\n });\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls\n });\n }\n this.adPlayer.initialize();\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new import_hls.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_hls.default.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async () => {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream\n });\n }\n this.adPlayer.initialize();\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(import_hls.default.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(import_hls.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_hls.default.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\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\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\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 } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...duration !== void 0 ? { durationSeconds: duration } : {},\n raw: { tag, value, attrs }\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(import_hls.default.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case import_hls.default.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case import_hls.default.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\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.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.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 shouldUseNativeHls() {\n const streamType = this.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 onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.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 = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n ...dur !== void 0 ? { durationSeconds: dur } : {},\n raw: { id3: text }\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 = this.parseCueOutCont(arg);\n return {\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 }\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},\n raw: { id3: text }\n };\n }\n return void 0;\n }\n 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 }\n return out;\n } catch {\n return void 0;\n }\n }\n async onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\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 });\n }\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : 3e4;\n this.expectedAdBreakDurationMs = durationMs;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds\n });\n }\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.handleAdStart(marker);\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.clearAdStopTimer();\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n this.handleAdPodComplete();\n return;\n }\n }\n async handleAdStart(marker) {\n const durationSeconds = marker.durationSeconds ?? 30;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n 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 d = parseFloat(match[1]);\n return Number.isNaN(d) ? void 0 : d;\n }\n return void 0;\n }\n parseCueOutCont(value) {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res = {};\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) return res;\n return void 0;\n }\n 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 }\n 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 }\n scheduleAdStopCountdown(remainingMs) {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms);\n }\n clearAdStopTimer() {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = void 0;\n }\n }\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 handleAdPodComplete() {\n this.clearAdStopTimer();\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.adPlayer.stop().catch(() => {\n });\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n isAdPlaying() {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n isShowingAds() {\n return this.adPlayer.isAdPlaying();\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 toggleMute() {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => resolve()).catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n isMuted() {\n return this.video.muted;\n }\n setMuted(muted) {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n destroy() {\n this.clearAdStopTimer();\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n getCurrentAdIndex() {\n return 0;\n }\n getTotalAdsInBreak() {\n return 1;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\"\n];\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = (0, import_react.useRef)(null);\n const playerRef = (0, import_react.useRef)(null);\n const bufferingTimeoutRef = (0, import_react.useRef)(null);\n const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n const [isMuted, setIsMuted] = import_react.default.useState(false);\n const [isFullscreen, setIsFullscreen] = import_react.default.useState(false);\n const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n const [currentTime, setCurrentTime] = import_react.default.useState(0);\n const [duration, setDuration] = import_react.default.useState(0);\n const [volume, setVolume] = import_react.default.useState(1);\n const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n const [isLoading, setIsLoading] = import_react.default.useState(true);\n const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n const [viewportWidth, setViewportWidth] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = (0, import_react.useMemo)(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs\n ]);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n try {\n if (autoplay !== void 0 && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n (0, import_react.useEffect)(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: onControlClick,\n style: {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\"\n }\n }\n )\n ]\n }\n )\n ] });\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\"\n ];\n for (const prop of uiProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\"\n ];\n for (const prop of callbackProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n return true;\n }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAds = playerRef.current.isShowingAds();\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 100);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = videoRef.current.volume;\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n if (playerRef.current && !playerRef.current.isShowingAds()) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","import type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: 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\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \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 \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\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 log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\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(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \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(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = 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 parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.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 const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\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.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\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 setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n \n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n \n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"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 = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n \n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n log(`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 log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\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.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n };\n}\n\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n AdController,\n} from \"../types\";\nimport { createAdStormPlayer } from \"../sdk/adstormPlayer\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport { getBrowserConfigOverrides, logBrowserInfo } from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private adPlayer: AdController;\n private attached = false;\n private inAdBreak = false;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...config, ...browserOverrides };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n if (!this.config.licenseKey) {\n console.warn(\"[StormcloudVideoPlayer] No license key provided - ads will not work\");\n }\n\n this.adPlayer = createAdStormPlayer(this.video, {\n licenseKey: this.config.licenseKey || \"\",\n debug: this.config.debugAdTiming ?? false,\n });\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Using native HLS playback:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n });\n }\n\n this.adPlayer.initialize();\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\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 () => {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n });\n }\n\n this.adPlayer.initialize();\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.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.FRAG_BUFFERED, async () => {\n if (this.hasInitialBufferCompleted) {\n return;\n }\n\n this.bufferedSegmentsCount++;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Initial buffer complete. Starting playback.`\n );\n }\n await this.video.play()?.catch((err) => {\n if (this.config.debugAdTiming) {\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_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) 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\n if (!tag) continue;\n \n if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n this.onScte35Marker({\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.parseCueOutCont(value);\n this.onScte35Marker({\n type: \"progress\",\n ...(prog?.duration !== undefined ? { durationSeconds: prog.duration } : {}),\n ...(prog?.elapsed !== undefined ? { ptsSeconds: prog.elapsed } : {}),\n raw: { tag, value },\n });\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.parseAttributeList(value);\n const hasScteOut = \"SCTE35-OUT\" in attrs;\n const hasScteIn = \"SCTE35-IN\" in attrs;\n const klass = String(attrs[\"CLASS\"] ?? \"\");\n const duration = this.toNumber(attrs[\"DURATION\"]) ?? this.toNumber(attrs[\"PLANNED-DURATION\"]);\n\n if (hasScteOut || /com\\.apple\\.hls\\.cue/i.test(klass)) {\n this.onScte35Marker({\n type: \"start\",\n ...(duration !== undefined ? { durationSeconds: duration } : {}),\n raw: { tag, value, attrs },\n });\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\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.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.adPlayer.initialize();\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n this.adPlayer.on(\"all_ads_completed\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad completed - ending ad break\");\n }\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"ad_error\", () => {\n console.error(\"[StormcloudVideoPlayer] Ad error occurred\");\n if (this.inAdBreak) {\n this.handleAdPodComplete();\n }\n });\n \n this.adPlayer.on(\"content_pause\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content paused for ad\");\n }\n });\n \n this.adPlayer.on(\"content_resume\", () => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content resuming after ad\");\n }\n });\n\n this.timeUpdateHandler = () => {\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.adPlayer.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Video src was cleared, restoring\");\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.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 private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.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 = this.parseCueOutDuration(arg);\n return {\n type: \"start\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(dur !== undefined ? { durationSeconds: dur } : {}),\n raw: { id3: text },\n };\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 = this.parseCueOutCont(arg);\n return {\n type: \"progress\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n ...(cont?.duration !== undefined ? { durationSeconds: cont.duration } : {}),\n raw: { id3: text },\n };\n }\n\n const cueInMatch = text.match(/EXT-X-CUE-IN\\b/i) || text.match(/CUE-IN\\b/i);\n if (cueInMatch) {\n return {\n type: \"end\",\n ...(tag.ptsSeconds !== undefined ? { ptsSeconds: tag.ptsSeconds } : {}),\n raw: { id3: text },\n };\n }\n\n return undefined;\n }\n\n private 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 }\n return out;\n } catch {\n return undefined;\n }\n }\n\n private async onScte35Marker(marker: Scte35Marker): Promise<void> {\n if (this.config.debugAdTiming) {\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 });\n }\n\n if (marker.type === \"start\") {\n if (this.inAdBreak) {\n return;\n }\n\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : 30000;\n \n this.expectedAdBreakDurationMs = durationMs;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break:\", {\n durationMs,\n durationSeconds: marker.durationSeconds,\n });\n }\n\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n\n await this.handleAdStart(marker);\n\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n return;\n }\n\n if (marker.type === \"end\") {\n if (!this.inAdBreak) return;\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.clearAdStopTimer();\n\n if (this.adPlayer.isAdPlaying()) {\n await this.adPlayer.stop();\n }\n\n this.handleAdPodComplete();\n return;\n }\n }\n\n private async handleAdStart(marker: Scte35Marker): Promise<void> {\n const durationSeconds = marker.durationSeconds ?? 30;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Requesting ads for duration:\", durationSeconds);\n }\n\n try {\n await this.adPlayer.requestAds(String(durationSeconds));\n \n await this.adPlayer.play();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Ad request/play failed:\", error);\n }\n this.handleAdPodComplete();\n }\n }\n\n private 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 d = parseFloat(match[1]);\n return Number.isNaN(d) ? undefined : d;\n }\n return undefined;\n }\n\n private parseCueOutCont(value: string): { elapsed?: number; duration?: number } | undefined {\n const elapsedMatch = value.match(/Elapsed\\s*=\\s*([0-9.]+)/i);\n const durationMatch = value.match(/Duration\\s*=\\s*([0-9.]+)/i);\n const res: { elapsed?: number; duration?: number } = {};\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) return res;\n return undefined;\n }\n\n private 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\n private 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\n private scheduleAdStopCountdown(remainingMs: number): void {\n this.clearAdStopTimer();\n const ms = Math.max(0, Math.floor(remainingMs));\n if (ms === 0) {\n this.handleAdPodComplete();\n return;\n }\n this.adStopTimerId = window.setTimeout(() => {\n this.handleAdPodComplete();\n }, ms) as unknown as number;\n }\n\n private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private 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 private handleAdPodComplete(): void {\n this.clearAdStopTimer();\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n\n this.adPlayer.stop().catch(() => {});\n\n const restoredMuted = this.adPlayer.getOriginalMutedState();\n const restoredVolume = this.adPlayer.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad break complete\");\n }\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.adPlayer.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.adPlayer.isAdPlaying();\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n toggleMute(): void {\n if (this.adPlayer.isAdPlaying()) {\n const currentMuted = this.video.muted;\n const newMutedState = !currentMuted;\n\n this.adPlayer.updateOriginalMutedState(newMutedState, this.video.volume);\n this.adPlayer.setAdVolume(newMutedState ? 0 : 1);\n } else {\n this.video.muted = !this.video.muted;\n this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container\n .requestFullscreen()\n .then(() => resolve())\n .catch(reject);\n } else {\n document.exitFullscreen().then(() => resolve()).catch(reject);\n }\n });\n }\n\n isMuted(): boolean {\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n this.video.muted = muted;\n this.adPlayer.updateOriginalMutedState(muted, this.video.volume);\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(muted ? 0 : 1);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (this.adPlayer.isAdPlaying()) {\n this.adPlayer.setAdVolume(clampedVolume);\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.adPlayer.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n }\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.adPlayer && this.adPlayer.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 360;\n this.adPlayer.resize(width, height);\n }\n }\n\n destroy(): void {\n this.clearAdStopTimer();\n\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n\n this.hls?.destroy();\n this.adPlayer?.destroy();\n }\n\n getCurrentAdIndex(): number {\n return 0;\n }\n\n getTotalAdsInBreak(): number {\n return 1;\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","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}\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\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\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 }\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 }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\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 }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsModernJS = false;\n isLegacyTV = true;\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\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 };\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 userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { allowNativeHls?: boolean } = {};\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function 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"]}
1
+ {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/ui/StormcloudVideoPlayer.cjs","../../src/ui/StormcloudVideoPlayer.tsx","../../src/utils/browserCompat.ts","../../src/player/StormcloudVideoPlayer.ts","../../src/sdk/ima.ts","../../src/sdk/vastParser.ts","../../src/sdk/hlsAdPlayer.ts","../../src/sdk/prebid.ts","../../src/sdk/prebidController.ts","../../src/utils/tracking.ts","../../src/utils/polyfills.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","StormcloudVideoPlayer_exports","StormcloudVideoPlayerComponent","module","exports","import_react","require","import_hls","match","ua","parseInt","getWebKitVersion","navigator","userAgentData","platform","test","detectBrowser","userAgent","getPlatform","version","majorVersion","isSmartTV","isLegacyTV","supportsIMA","supportsModernJS","recommendedAdPlayer","webOSVersion","tizenVersion","chromeVersionNum","chromeVersion","getChromeVersion","webkitVersion","parts","split","toString","Promise","Map","Set","URLSearchParams","supportsGoogleIMA","browser","document","createElement","video","e","logBrowserInfo","debug","imaSupport","log","getBrowserConfigOverrides","createImaController","contentVideoHidden","options","style","adVideo","playsInline","volume","originalVolume","opacity","set","overrides","adPlayerType","allowNativeHls","adPlaying","originalMutedState","Number","isNaN","Math","max","min","listeners","adVideoElement","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","hideContentVideo","transition","setTimeout","visibility","muted","showContentVideo","offsetHeight","createAdVideoElement","position","top","left","width","height","objectFit","zIndex","addEventListener","once","emit","event","payload","Array","fn","ensureImaLoaded","window","warn","reject","Error","frameEl","frameElement","sandboxAttr","getAttribute","tokens","map","t","trim","filter","length","allowsScripts","has","console","error","google","ima","resolve","existing","querySelector","timeout","clearTimeout","script","setAttribute","onload","onerror","head","appendChild","adsManager","adsLoader","adDisplayContainer","adContainerEl","lastAdTagUrl","retryAttempts","backoffBaseMs","adsLoadedPromise","adsLoadedResolve","adsLoadedReject","makeAdsRequest","vastTagUrl","adsRequest","companionSizes","AdsRequest","ciuSzsValue","size","currentLocation","location","topLocation","currentUrl","href","topUrl","currentDomain","hostname","modifiedVastTagUrl","url","URL","searchParams","baseUrl","paramsToRemove","forEach","param","includes","replace","RegExp","params","separator","adTagUrl","videoWidth","offsetWidth","clientWidth","videoHeight","clientHeight","linearAdSlotWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","setCompanionSlots","companionSlots","slot","CompanionAdSlot","push","setAdWillAutoPlay","willAutoPlay","paused","autoplay","setAdWillPlayMuted","willPlayMuted","vastLoadTimeout","requestAds","ensurePlaceholderContainer","container","right","bottom","display","alignItems","justifyContent","pointerEvents","backgroundColor","parentElement","destroyAdsManager","destroy","destroyAdsLoader","initialize","then","AdDisplayContainer","catch","currentReject","adsLoaderCls","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","evt","adsRenderingSettings","AdsRenderingSettings","enablePreloading","getAdsManager","AdEvent","AdErrorEvent","AD_ERROR","errorEvent","getError","errorCode","getErrorCode","vastErrorCode","getVastErrorCode","errorMessage","getMessage","innerError","getInnerError","inner","message","String","cause","isNoFill","delay","maxRetries","pow","code","continueLiveStreamDuringAds","play","CONTENT_PAUSE_REQUESTED","pause","setVolume","adVolume","STARTED","CONTENT_RESUME_REQUESTED","ALL_ADS_COMPLETED","adErrorEvent","init","ViewMode","NORMAL","start","resume","stop","removeChild","isAdPlaying","resize","on","listener","add","off","delete","updateOriginalMutedState","nextVolume","getOriginalMutedState","getOriginalVolume","setAdVolume","clampedVolume","getAdVolume","getVolume","showPlaceholder","wasHidden","requestAnimationFrame","hidePlaceholder","parseVastXml","mediaFiles","xmlString","isHlsType","type","isMp4Type","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","adElement","adId","title","isNoAdAvailable","toLowerCase","textContent","durationParts","durationText","duration","round","parseFloat","mediaFileElements","querySelectorAll","mf","index","mute","substring","isMp4","accepted","isHls","bitrateAttr","bitrateValue","bitrate","sort","a","b","aIsMp4","bIsMp4","impression","firstQuartile","midpoint","thirdQuartile","complete","unmute","fullscreen","exitFullscreen","skip","el","trackingUrls","eventKey","clickThrough","id","fetchAndParseVastAd","response","vastXml","fetch","mode","credentials","headers","Accept","referrerPolicy","ok","statusText","text","fireTrackingPixels","urls","sessionId","licenseKey","trackingUrl","img","Image","src","createHlsAdPlayer","contentVideo","mainHlsInstance","adHls","currentAd","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","generateSessionId","Date","now","random","substr","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","selectBestMediaFile","firstFile","mainQuality","scoredFiles","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","score","bitrateDiff","bestMatch","resolution","fetchAndParseVastAdLocal","setupAdEventListeners","progress","currentTime","handleAdComplete","handleAdError","ended","ad","contentVolume","mediaFile","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","Events","MANIFEST_PARSED","ERROR","data","fatal","canPlayType","previousMutedState","timeoutId","clear","config","args","DEFAULT_TIMEOUT_MS","AUCTION_PATH","createPrebidManager","initialized","serverUrl","resolveServerUrl","extUrl","parseResponse","buildRequest","req","JSON","parse","stringify","ortbRequest","slice","ext","prebid","cache","vastxml","targeting","includewinners","includebidderkeys","device","language","w","screen","innerWidth","h","innerHeight","site","page","domain","bids","seatbids","seatbid","currency","cur","seat","bidArray","bid","cacheUrl","adm","bidResponse","bidder","cpm","price","impId","impid","creativeId","crid","vastUrl","adomain","winner","cpmFloor","toFixed","blob","Blob","createObjectURL","imp","bidders","keys","join","requestBids","auctionUrl","request","controller","fetchOptions","body","tmax","AbortController","abort","method","signal","status","json","responsetimemillis","errors","prebidConfig","prebidDebug","getVastUrl","extractVastUrl","isInitialized","LOG","createPrebidController","createEmptyTrackingState","prebidManager","prebidInitialized","isHlsMediaFile","ensurePrebidInitialized","enabled","runPrebidAuction","startPlayback","startHlsPlayback","startNativePlayback","load","import_hls2","_event","remove","cachedBrowserId","getClientInfo","vendor","maxTouchPoints","memory","deviceMemory","hardwareConcurrency","screenInfo","availWidth","availHeight","orientation","pixelDepth","deviceType","brand","os","model","isAndroid","isWebView","isWebApp","webosMatch","tizenMatch","tvMatch","androidModelMatch","outerHeight","outerWidth","matchMedia","matches","standalone","angle","origin","path","pathname","languages","cookieEnabled","doNotTrack","referrer","visibilityState","getBrowserID","clientInfo","fingerprintString","encodedData","utf8","buffer","i","hashBuffer","hashArray","hashHex","hash","char","fallbackHash","timestamp","crypto","subtle","digest","Uint8Array","TextEncoder","encode","unescape","encodeURIComponent","charCodeAt","padStart","padEnd","sendInitialTracking","browserId","trackingData","sendHeartbeat","heartbeatData","toISOString","polyfillURLSearchParams","URLSearchParamsPolyfill","parseQueryString","append","query","cleanQuery","startsWith","decodedKey","safeDecodeURIComponent","decodedValue","str","decodeURIComponent","values","getAll","callback","polyfillTextEncoder","TextEncoderPolyfill","encoding","charcode","polyfillPromiseFinally","finally","constructor","reason","polyfillObjectAssign","assign","sources","TypeError","nextSource","nextKey","polyfillArrayFrom","arrayLike","mapFn","thisArg","items","len","result","polyfillStringStartsWith","search","pos","polyfillStringEndsWith","endsWith","polyfillStringIncludes","indexOf","initializePolyfills","StormcloudVideoPlayer","attached","inAdBreak","ptsDriftEmaMs","adPodQueue","lastHeartbeatTime","currentAdIndex","totalAdsInBreak","showAds","isLiveStream","nativeHlsMode","videoSrcProtection","bufferedSegmentsCount","shouldAutoplayAfterBuffering","hasInitialBufferCompleted","adRequestTokenCounter","activeAdRequestToken","adRequestWatchdogToken","adFailsafeToken","failedVastUrls","temporaryFailureUrls","temporaryFailureCooldownMs","continuousFetchingActive","adRequestQueue","maxPlaceholderDurationMs","isShowingPlaceholder","totalAdRequestsInBreak","maxTotalAdRequestsPerBreak","pendingAdBreak","consecutiveFailures","maxConsecutiveFailures","lastAdRequestTime","minAdRequestIntervalMs","maxBackoffMs","preloadPool","maxPreloadPoolSize","preloadPoolActive","preloadPoolLoopRunning","continuousFetchLoopRunning","browserOverrides","videoElement","createAdPlayer","vastMode","debugAdTiming","hls","attach","fetchAdConfiguration","initializeTracking","shouldUseNativeHls","isLive","adBehavior","import_hls3","backBufferLength","liveDurationInfinity","maxLiveSyncPlaybackRate","liveSyncDuration","maxBufferLength","maxMaxBufferLength","maxBufferSize","maxBufferHole","highBufferWatchdogPeriod","nudgeOffset","nudgeMaxRetry","startPosition","MEDIA_ATTACHED","_","minSegments","some","details","live","shouldContinueLiveStreamDuringAds","minSegmentsBeforePlay","LEVEL_LOADED","_evt","fragments","fragmentsToScan","frag","tagList","isArray","entry","tag","idx","attrs","parseAttributeList","hasScteOut","durationSeconds","parseCueOutDuration","marker","raw","earlyDetection","startAdPrefetch","sn","FRAG_BUFFERED","err","FRAG_PARSING_METADATA","id3Tags","samples","s","ptsSeconds","pts","onId3Tag","FRAG_CHANGED","prog","parseCueOutCont","elapsed","onScte35Marker","hasScteIn","klass","toNumber","remaining","queuedUrls","ErrorTypes","NETWORK_ERROR","startLoad","MEDIA_ERROR","recoverMediaError","attachImaEventListeners","getRemainingAdMs","tryNextAvailableAdWithRateLimit","handleAdPodComplete","errorPayload","causeMessage","handleAdFailure","clearAdFailsafeTimer","clearAdRequestWatchdog","expectedAdBreakDurationMs","adStopTimerId","currentAdBreakStartWallClockMs","scheduleAdStopCountdown","currentMuted","currentVolume","recreateImaController","shouldShowPlaceholder","showPlaceholderLayer","placeholderContainer","hidePlaceholderLayer","emptiedHandler","timeUpdateHandler","onTimeUpdate","wasPaused","dur","cueInMatch","streamType","getStreamType","canNative","updatePtsDrift","parseScte35FromId3","decodeId3ValueToText","cueOutMatch","arg","id3","cueOutContMatch","cont","daterangeMatch","decoder","bin","parseScte35Binary","TextDecoder","decode","out","hasPendingAdBreak","hasPrefetchedAds","vastUrls","durationMs","isManifestMarker","isManifestBasedMarker","forceImmediate","immediateManifestAds","hasPts","clearAdStartTimer","handleAdStart","tol","driftToleranceMs","nowMs","estCurrentPtsMs","deltaMs","floor","markerPtsMs","tolerance","scheduleAdStartIn","elapsedMs","remainingMs","hasQueuedAds","activeAdRequest","clearAdStopTimer","num","dStr","d","rawVal","BitReader","buf","bytePos","r","readBits","ptsAdjHigh","res","elapsedMatch","durationMatch","slashMatch","regex","exec","val","n","splice_command_type","numBits","remainingInByte","bitPos","toRead","currentByte","shift","mask","bits","skipBits","tableId","sectionLength","ptsAdjLow","spliceCommandType","cancel","outOfNetwork","programSpliceFlag","durationFlag","spliceImmediateFlag","timeSpecifiedFlag","componentCount","high","low","durationTicks","heartbeatInterval","setInterval","sendHeartbeatIfNeeded","vastEndpoint","apiUrl","imaPayload","numberAds","apiVastTagUrl","vast","cue_tones","number_ads","apiNumberAds","isPrebidMode","getCurrentAdIndex","getTotalAdsInBreak","generateVastUrlsWithCorrelators","count","baseTimestamp","uniqueCorrelator","urlWithCorrelator","correlatorRegex","isShowingAds","shouldShowNativeControls","showCustomControls","fragmentSn","detectedAtFragmentSn","isFetching","fetchStartTime","scheduled","findCurrentOrNextBreak","tags","selectVastTagsForBreak","baseVastUrl","urlsToPregenerate","generatedUrls","startPreloadPool","clearPendingAdBreak","prefetchTimerId","initialUrls","preloadAdIntoPool","preloadPoolLoop","isUrlInCooldown","errorListenerCleanup","adErrorPayload","loadPromise","hasAdError","preloadIma","errorListener","poolEntry","lateErrorListener","imaController","loadedAt","isReady","findIndex","splice","isTemporaryAdError","newUrls","newUrl","getPreloadedAd","stopPreloadPool","_marker","isPrebid","adBreakDurationMs","firstAdUrl","usePreloadedAd","preloadedController","preloaded","firstAdUrlArray","fallbackPreloaded","fallbackError","startContinuousFetching","continuousFetchLoop","maxQueueSize","newAdUrl","queuedUrlsPreview","generationDelay","stopContinuousFetching","backoffMultiplier","backoffDelay","effectiveMinInterval","timeSinceLastRequest","waitTime","tryNextAvailableAd","retryCount","nextAdUrl","cleanupTemporaryFailures","playSingleAd","showPlaceholderAndWaitForAds","checkInterval","maxChecks","candidate","schedule","startTimeMs","currentTimeSec","breakToPlay","findBreakForTime","handleMidAdJoin","adBreak","endMs","first","rest","ensureAdStoppedByTimer","ms","pendingAds","checkIntervalMs","adBreakCheckIntervalMs","maxExtensionMsConfig","maxAdBreakExtensionMs","maxExtensionMs","elapsedSinceStartMs","expectedDurationMs","shouldExtendAdBreak","overrunMs","delayMs","adStartTimerId","ptsSecondsSample","isFinite","sampleMs","alpha","failureTime","playError","preloadedFallback","requestToken","startAdRequestWatchdog","startAdFailsafeTimer"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar StormcloudVideoPlayer_exports = {};\n__export(StormcloudVideoPlayer_exports, {\n StormcloudVideoPlayerComponent: () => StormcloudVideoPlayerComponent\n});\nmodule.exports = __toCommonJS(StormcloudVideoPlayer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/player/StormcloudVideoPlayer.ts\nvar import_hls3 = __toESM(require(\"hls.js\"), 1);\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 supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer = \"ima\";\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 if (webOSVersion !== void 0 && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (webOSVersion !== void 0 && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\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 if (tizenVersion !== void 0 && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (tizenVersion !== void 0 && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = \"Smart TV\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = \"LG NetCast\";\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n } else if (/BRAVIA/i.test(ua)) {\n name = \"Sony BRAVIA\";\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = \"ima\";\n } else {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = \"Chrome\";\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\n }\n }\n }\n if (typeof Promise === \"undefined\" || typeof Map === \"undefined\" || typeof Set === \"undefined\") {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = \"hls\";\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 supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum\n };\n}\nfunction supportsGoogleIMA() {\n const browser = detectBrowser();\n if (browser.isLegacyTV) {\n return false;\n }\n if (typeof document === \"undefined\" || typeof document.createElement !== \"function\") {\n return false;\n }\n try {\n const video = document.createElement(\"video\");\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n if (typeof Promise === \"undefined\") {\n return false;\n }\n return browser.supportsIMA;\n}\nfunction logBrowserInfo(debug = false) {\n if (!debug) return;\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\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 supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\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}\nfunction getBrowserConfigOverrides() {\n const browser = detectBrowser();\n const overrides = {};\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = \"hls\";\n }\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n return overrides;\n}\n\n// src/sdk/ima.ts\nfunction createImaController(video, options) {\n let adPlaying = false;\n let contentVideoHidden = false;\n let originalMutedState = false;\n let originalVolume = typeof video.volume === \"number\" && !Number.isNaN(video.volume) ? Math.max(0, Math.min(1, video.volume)) : 1;\n const listeners = /* @__PURE__ */ new Map();\n let adVideoElement;\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n function hideContentVideo() {\n if (!contentVideoHidden) {\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.style.opacity = \"0\";\n setTimeout(() => {\n video.style.visibility = \"hidden\";\n }, 300);\n video.muted = true;\n video.volume = 0;\n contentVideoHidden = true;\n }\n }\n function showContentVideo() {\n if (contentVideoHidden) {\n video.style.visibility = \"visible\";\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.offsetHeight;\n video.style.opacity = \"1\";\n video.muted = originalMutedState;\n video.volume = originalVolume;\n contentVideoHidden = false;\n }\n }\n function createAdVideoElement() {\n const adVideo = document.createElement(\"video\");\n adVideo.style.position = \"absolute\";\n adVideo.style.top = \"0\";\n adVideo.style.left = \"0\";\n adVideo.style.width = \"100%\";\n adVideo.style.height = \"100%\";\n adVideo.style.objectFit = \"contain\";\n adVideo.style.backgroundColor = \"transparent\";\n adVideo.style.zIndex = \"15\";\n adVideo.playsInline = true;\n adVideo.volume = originalVolume;\n adVideo.muted = originalMutedState;\n adVideo.style.opacity = \"0\";\n adVideo.addEventListener(\n \"canplay\",\n () => {\n adVideo.style.opacity = \"1\";\n },\n { once: true }\n );\n return adVideo;\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 {\n }\n }\n }\n function ensureImaLoaded() {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n try {\n const frameEl = window.frameElement;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr.split(/\\s+/).map((t) => t.trim()).filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {\n }\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n );\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 1e4);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n let adsManager;\n let adsLoader;\n let adDisplayContainer;\n let adContainerEl;\n let lastAdTagUrl;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise;\n let adsLoadedResolve;\n let adsLoadedReject;\n function makeAdsRequest(google, vastTagUrl) {\n const adsRequest = new google.ima.AdsRequest();\n const companionSizes = [\n { width: 728, height: 90 },\n { width: 300, height: 250 },\n { width: 180, height: 150 },\n { width: 120, height: 60 },\n { width: 88, height: 31 },\n { width: 300, height: 60 },\n { width: 300, height: 100 },\n { width: 320, height: 50 },\n { width: 468, height: 60 },\n { width: 300, height: 600 },\n { width: 160, height: 600 }\n ];\n const ciuSzsValue = companionSizes.map((size) => `fluid|${size.width}x${size.height}`).join(\",\");\n const currentLocation = typeof window !== \"undefined\" ? window.location : null;\n const topLocation = typeof window !== \"undefined\" && window.top ? window.top.location : currentLocation;\n const currentUrl = currentLocation?.href || \"\";\n const topUrl = topLocation?.href || currentUrl;\n const currentDomain = currentLocation?.hostname || \"\";\n let modifiedVastTagUrl = vastTagUrl;\n try {\n const url = new URL(vastTagUrl);\n url.searchParams.set(\"ciu_szs\", ciuSzsValue);\n if (!url.searchParams.has(\"mpt\")) {\n url.searchParams.set(\"mpt\", \"h5_vsi\");\n }\n if (!url.searchParams.has(\"ctv\")) {\n url.searchParams.set(\"ctv\", \"0\");\n }\n if (!url.searchParams.has(\"gdpr\")) {\n url.searchParams.set(\"gdpr\", \"0\");\n }\n if (!url.searchParams.has(\"top\") && topUrl) {\n url.searchParams.set(\"top\", topUrl);\n }\n if (!url.searchParams.has(\"loc\") && currentUrl) {\n url.searchParams.set(\"loc\", currentUrl);\n }\n if (!url.searchParams.has(\"cdm\") && currentDomain) {\n url.searchParams.set(\"cdm\", currentDomain);\n }\n if (!url.searchParams.has(\"eoidce\")) {\n url.searchParams.set(\"eoidce\", \"1\");\n }\n if (!url.searchParams.has(\"fbidx\")) {\n url.searchParams.set(\"fbidx\", \"0\");\n }\n modifiedVastTagUrl = url.toString();\n } catch (e) {\n let baseUrl = vastTagUrl;\n const paramsToRemove = [\"ciu_szs\", \"mpt\", \"ctv\", \"gdpr\", \"top\", \"loc\", \"cdm\", \"eoidce\", \"fbidx\"];\n paramsToRemove.forEach((param) => {\n if (baseUrl.includes(`${param}=`)) {\n baseUrl = baseUrl.replace(new RegExp(`[?&]${param}=[^&]*`, \"g\"), \"\");\n }\n });\n baseUrl = baseUrl.replace(/[?&]$/, \"\");\n const params = new URLSearchParams();\n params.set(\"ciu_szs\", ciuSzsValue);\n params.set(\"mpt\", \"h5_vsi\");\n params.set(\"ctv\", \"0\");\n params.set(\"gdpr\", \"0\");\n if (topUrl) params.set(\"top\", topUrl);\n if (currentUrl) params.set(\"loc\", currentUrl);\n if (currentDomain) params.set(\"cdm\", currentDomain);\n params.set(\"eoidce\", \"1\");\n params.set(\"fbidx\", \"0\");\n const separator = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n modifiedVastTagUrl = `${baseUrl}${separator}${params.toString()}`;\n }\n adsRequest.adTagUrl = modifiedVastTagUrl;\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 480;\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n if (typeof adsRequest.setCompanionSlots === \"function\") {\n try {\n const companionSlots = [];\n for (const size of companionSizes) {\n const slot = new google.ima.CompanionAdSlot();\n slot.width = size.width;\n slot.height = size.height;\n companionSlots.push(slot);\n }\n adsRequest.setCompanionSlots(companionSlots);\n } catch (error) {\n console.warn(\"[IMA] Failed to set companion slots:\", error);\n }\n }\n if (typeof adsRequest.setAdWillAutoPlay === \"function\") {\n try {\n const willAutoPlay = !video.paused || video.autoplay;\n adsRequest.setAdWillAutoPlay(willAutoPlay);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillAutoPlay:\", error);\n }\n }\n if (typeof adsRequest.setAdWillPlayMuted === \"function\") {\n try {\n const willPlayMuted = video.muted || video.volume === 0;\n adsRequest.setAdWillPlayMuted(willPlayMuted);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillPlayMuted:\", error);\n }\n }\n adsRequest.vastLoadTimeout = 1e4;\n adsLoader.requestAds(adsRequest);\n }\n function ensurePlaceholderContainer() {\n if (adContainerEl) {\n return;\n }\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 container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n video.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n function destroyAdsManager() {\n if (adsManager) {\n try {\n adsManager.destroy();\n } catch {\n }\n adsManager = void 0;\n }\n if (adVideoElement) {\n adVideoElement.style.opacity = \"0\";\n }\n }\n function destroyAdsLoader() {\n if (adsLoader) {\n try {\n adsLoader.destroy();\n } catch {\n }\n adsLoader = void 0;\n }\n }\n return {\n initialize() {\n ensureImaLoaded().then(() => {\n const google = window.google;\n ensurePlaceholderContainer();\n if (!adDisplayContainer && adContainerEl) {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n adDisplayContainer = new google.ima.AdDisplayContainer(\n adContainerEl,\n adVideoElement\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {\n }\n }\n }).catch(() => {\n });\n },\n async requestAds(vastTagUrl) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n return Promise.reject(error);\n }\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n return Promise.reject(error);\n }\n if (adPlaying) {\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n destroyAdsManager();\n destroyAdsLoader();\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n let currentReject;\n adsLoadedPromise = new Promise((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n }, 1e4);\n });\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n if (!adDisplayContainer) {\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 = \"transparent\";\n container.style.transition = \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n video.parentElement.appendChild(container);\n adContainerEl = container;\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n adVideoElement\n );\n }\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n if (!videoWidth || !videoHeight || videoWidth === 0 || videoHeight === 0) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n currentReject?.(error);\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n return Promise.reject(error);\n }\n if (!adsLoader) {\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt) => {\n try {\n const adsRenderingSettings = new google.ima.AdsRenderingSettings();\n adsRenderingSettings.enablePreloading = true;\n adsManager = evt.getAdsManager(video, adsRenderingSettings);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent) => {\n const error = errorEvent.getError();\n const errorCode = error.getErrorCode?.() || \"unknown\";\n const vastErrorCode = error.getVastErrorCode?.() || \"N/A\";\n const errorMessage = error.getMessage?.() || \"Unknown error\";\n let innerError;\n try {\n if (typeof error.getInnerError === \"function\") {\n const inner = error.getInnerError();\n if (inner) {\n innerError = typeof inner === \"string\" ? inner : inner.message || String(inner);\n }\n }\n if (!innerError && error.cause) {\n innerError = typeof error.cause === \"string\" ? error.cause : error.cause.message || String(error.cause);\n }\n if (!innerError && error.innerError) {\n innerError = typeof error.innerError === \"string\" ? error.innerError : error.innerError.message || String(error.innerError);\n }\n } catch (e) {\n }\n const isNoFill = errorCode === 303 || vastErrorCode === 303;\n destroyAdsManager();\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n hideContentVideo();\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n if (lastAdTagUrl && retryAttempts < maxRetries && !isNoFill) {\n const delay = backoffBaseMs * Math.pow(2, retryAttempts++);\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl);\n } catch {\n }\n }, delay);\n } else {\n emit(\"ad_error\", {\n code: errorCode,\n vastErrorCode,\n message: errorMessage,\n cause: innerError,\n isNoFill\n });\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play()?.catch(() => {\n });\n }\n }\n }\n }\n );\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n }\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume = originalMutedState ? 0 : originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adsManager) {\n try {\n adsManager.setVolume(adVolume);\n } catch {\n }\n }\n emit(\"content_pause\");\n }\n );\n adsManager.addEventListener(AdEvent.STARTED, () => {\n setAdPlayingFlag(true);\n hideContentVideo();\n if (adVideoElement) {\n const adVolume = originalVolume;\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n if (adsManager) {\n try {\n adsManager.setVolume(originalMutedState ? 0 : adVolume);\n } catch {\n }\n }\n }\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n });\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n hideContentVideo();\n emit(\"content_resume\");\n }\n );\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n hideContentVideo();\n emit(\"all_ads_completed\");\n });\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = void 0;\n adsLoadedReject = void 0;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n hideContentVideo();\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent) => {\n const error = adErrorEvent.getError();\n const errorCode = error.getErrorCode?.() || \"unknown\";\n const vastErrorCode = error.getVastErrorCode?.() || \"N/A\";\n const errorMessage = error.getMessage?.() || \"Unknown error\";\n let innerError;\n try {\n if (typeof error.getInnerError === \"function\") {\n const inner = error.getInnerError();\n if (inner) {\n innerError = typeof inner === \"string\" ? inner : inner.message || String(inner);\n }\n }\n if (!innerError && error.cause) {\n innerError = typeof error.cause === \"string\" ? error.cause : error.cause.message || String(error.cause);\n }\n if (!innerError && error.innerError) {\n innerError = typeof error.innerError === \"string\" ? error.innerError : error.innerError.message || String(error.innerError);\n }\n } catch (e) {\n }\n const isNoFill = errorCode === 303 || vastErrorCode === 303;\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n hideContentVideo();\n if (adsLoadedReject) {\n adsLoadedReject(new Error(isNoFill ? \"No ads available\" : \"Ads loader error\"));\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n }\n emit(\"ad_error\", {\n code: errorCode,\n vastErrorCode,\n message: errorMessage,\n isNoFill,\n cause: innerError\n });\n },\n false\n );\n }\n makeAdsRequest(google, vastTagUrl);\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n currentReject?.(error);\n adsLoadedReject = void 0;\n adsLoadedResolve = void 0;\n return Promise.reject(error);\n }\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n if (!adsManager) {\n return Promise.reject(new Error(\"No ads manager\"));\n }\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 480;\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n adPlaying = true;\n const adVolume = originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n }\n try {\n adsManager.setVolume(originalMutedState ? 0 : adVolume);\n } catch {\n }\n adsManager.start();\n return Promise.resolve();\n } catch (error) {\n adPlaying = false;\n setAdPlayingFlag(false);\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {\n });\n }\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adsManager || !adPlaying) {\n return;\n }\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n if (adsManager && typeof adsManager.pause === \"function\") {\n adsManager.pause();\n }\n } catch (error) {\n console.warn(\"[IMA] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adsManager || !adPlaying) {\n return;\n }\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {\n });\n }\n if (adsManager && typeof adsManager.resume === \"function\") {\n adsManager.resume();\n }\n } catch (error) {\n console.warn(\"[IMA] Error resuming ad:\", error);\n }\n },\n async stop() {\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n showContentVideo();\n if (options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\"[IMA] Content video paused in live mode on stop, resuming playback\");\n video.play().catch(() => {\n });\n }\n } else if (video.paused) {\n video.play().catch(() => {\n });\n }\n try {\n adsManager?.stop?.();\n } catch {\n }\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"none\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n if (adContainerEl.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n adVideoElement = void 0;\n }\n }, 500);\n }\n showContentVideo();\n try {\n adsLoader?.destroy?.();\n } catch {\n }\n adDisplayContainer = void 0;\n adsLoader = void 0;\n contentVideoHidden = false;\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = clampedVolume;\n adVideoElement.muted = clampedVolume === 0;\n }\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(clampedVolume);\n } catch {\n }\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n showPlaceholder() {\n ensurePlaceholderContainer();\n hideContentVideo();\n if (adContainerEl) {\n const wasHidden = adContainerEl.style.display === \"none\" || adContainerEl.style.opacity === \"0\";\n if (wasHidden) {\n adContainerEl.style.transition = \"none\";\n } else {\n adContainerEl.style.transition = \"opacity 0.3s ease-in-out\";\n }\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n if (wasHidden) {\n requestAnimationFrame(() => {\n if (adContainerEl) {\n adContainerEl.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.backgroundColor = \"#000\";\n }\n }, 300);\n }\n }\n };\n}\n\n// src/sdk/vastParser.ts\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\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 `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\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 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} 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 `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\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 console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\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 xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nfunction fireTrackingPixels(urls, sessionId, licenseKey, logPrefix = \"[VastParser]\") {\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(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n\n// src/sdk/hlsAdPlayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nfunction createHlsAdPlayer(contentVideo, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n const preloadedAds = /* @__PURE__ */ new Map();\n const preloadingAds = /* @__PURE__ */ new Map();\n let destroyed = false;\n let pendingTimeouts = [];\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels2(urls) {\n fireTrackingPixels(urls, sessionId, licenseKey, \"[HlsAdPlayer]\");\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 async function fetchAndParseVastAdLocal(vastTagUrl) {\n return fetchAndParseVastAd(vastTagUrl, \"hls-only\", \"[HlsAdPlayer]\");\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels2(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels2(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels2(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels2(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 fireTrackingPixels2(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels2(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels2(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels2(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels2(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels2(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {\n });\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n emit(\"content_resume\");\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(vastTagUrl) {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n sessionId = generateSessionId();\n let ad;\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAdLocal(vastTagUrl);\n }\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels2(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (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 (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 {\n throw new Error(\"HLS not supported\");\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {\n });\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {\n });\n }\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n preloadedAds.clear();\n preloadingAds.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\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 };\n}\n\n// src/sdk/prebid.ts\nvar DEFAULT_TIMEOUT_MS = 3e3;\nvar AUCTION_PATH = \"/openrtb2/auction\";\nfunction createPrebidManager(config) {\n let initialized = false;\n let serverUrl = \"\";\n const debug = config.debug ?? false;\n function log(...args) {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n function warn(...args) {\n console.warn(\"[Prebid]\", ...args);\n }\n function resolveServerUrl() {\n if (config.serverUrl) {\n return config.serverUrl.replace(/\\/$/, \"\");\n }\n const extUrl = config.ortbRequest?.ext?.prebid?.server?.externalurl;\n if (typeof extUrl === \"string\" && extUrl.length > 0) {\n return extUrl.replace(/\\/$/, \"\");\n }\n throw new Error(\n \"Prebid Server URL not configured. Provide serverUrl in PrebidConfig or ext.prebid.server.externalurl in the OpenRTB request.\"\n );\n }\n function buildRequest() {\n const req = JSON.parse(JSON.stringify(config.ortbRequest));\n req.id = `${req.id || \"prebid\"}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n if (!req.ext) req.ext = {};\n if (!req.ext.prebid) req.ext.prebid = {};\n if (!req.ext.prebid.cache) req.ext.prebid.cache = {};\n if (!req.ext.prebid.cache.vastxml) req.ext.prebid.cache.vastxml = {};\n if (!req.ext.prebid.targeting) {\n req.ext.prebid.targeting = {\n includewinners: true,\n includebidderkeys: false\n };\n }\n if (!req.device) req.device = {};\n if (typeof navigator !== \"undefined\") {\n if (!req.device.ua) req.device.ua = navigator.userAgent;\n if (!req.device.language) {\n req.device.language = (navigator.language || \"\").split(\"-\")[0] || \"en\";\n }\n }\n if (typeof window !== \"undefined\") {\n if (!req.device.w) req.device.w = window.screen?.width || window.innerWidth;\n if (!req.device.h) req.device.h = window.screen?.height || window.innerHeight;\n }\n if (!req.site) req.site = {};\n if (typeof window !== \"undefined\") {\n if (!req.site.page) req.site.page = window.location.href;\n if (!req.site.domain) req.site.domain = window.location.hostname;\n }\n return req;\n }\n function parseResponse(data) {\n const bids = [];\n const seatbids = data?.seatbid || [];\n const currency = data?.cur || \"USD\";\n for (const seatbid of seatbids) {\n const seat = seatbid.seat || \"unknown\";\n const bidArray = seatbid.bid || [];\n for (const bid of bidArray) {\n const cacheUrl = bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml = bid.adm || void 0;\n const bidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n bids.push(bidResponse);\n }\n }\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n function extractVastUrl(bids) {\n if (bids.length === 0) return null;\n const winner = bids[0];\n const cpmFloor = config.cpmFloor ?? 0;\n if (cpmFloor > 0 && winner.cpm < cpmFloor) {\n log(\n `Winning bid $${winner.cpm.toFixed(2)} below CPM floor $${cpmFloor.toFixed(2)}, rejecting`\n );\n return null;\n }\n if (winner.vastUrl) {\n log(\n `Using cached VAST URL from ${winner.bidder} ($${winner.cpm.toFixed(2)} ${winner.currency})`\n );\n return winner.vastUrl;\n }\n if (winner.vastXml) {\n log(\n `Creating blob URL from VAST XML (${winner.bidder}, $${winner.cpm.toFixed(2)})`\n );\n try {\n const blob = new Blob([winner.vastXml], { type: \"text/xml\" });\n return URL.createObjectURL(blob);\n } catch (error) {\n warn(\"Failed to create blob URL from VAST XML:\", error);\n }\n }\n return null;\n }\n async function initialize() {\n if (initialized) return;\n serverUrl = resolveServerUrl();\n if (!config.ortbRequest?.imp || config.ortbRequest.imp.length === 0) {\n throw new Error(\"No impressions (imp) defined in the OpenRTB request.\");\n }\n initialized = true;\n log(\"Initialized with server:\", serverUrl);\n log(\n \"Bidders:\",\n config.ortbRequest.imp.map((imp) => {\n const bidders = imp.ext?.prebid?.bidder;\n return bidders ? Object.keys(bidders).join(\", \") : \"none\";\n }).join(\"; \")\n );\n }\n async function requestBids() {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n const auctionUrl = `${serverUrl}${AUCTION_PATH}`;\n const request = buildRequest();\n const timeout = config.timeout ?? config.ortbRequest.tmax ?? DEFAULT_TIMEOUT_MS;\n log(\"Sending auction request to:\", auctionUrl);\n const controller = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2e3);\n try {\n const fetchOptions = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request)\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n const response = await fetch(auctionUrl, fetchOptions);\n clearTimeout(timeoutId);\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n const data = await response.json();\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency} ${b.width}x${b.height}` + (b.vastUrl ? \" [cached VAST]\" : \"\") + (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n return bids;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2e3}ms`);\n return [];\n }\n throw error;\n }\n }\n async function getVastUrl() {\n try {\n const bids = await requestBids();\n return extractVastUrl(bids);\n } catch (error) {\n warn(\"Failed to get VAST URL:\", error);\n return null;\n }\n }\n function destroy() {\n initialized = false;\n serverUrl = \"\";\n log(\"Destroyed\");\n }\n return {\n initialize,\n requestBids,\n getVastUrl,\n destroy,\n get isInitialized() {\n return initialized;\n }\n };\n}\n\n// src/sdk/prebidController.ts\nvar import_hls2 = __toESM(require(\"hls.js\"), 1);\nvar LOG = \"[PrebidController]\";\nfunction createPrebidController(contentVideo, prebidConfig, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n let destroyed = false;\n let trackingFired = createEmptyTrackingState();\n const prebidDebug = prebidConfig.debug ?? false;\n const prebidManager = createPrebidManager({\n ...prebidConfig,\n debug: prebidDebug\n });\n let prebidInitialized = false;\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(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels2(urls) {\n fireTrackingPixels(urls, sessionId, licenseKey, LOG);\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(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n console.log(`${LOG} 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(`${LOG} No best match found, using first media file`);\n return firstFile;\n }\n console.log(`${LOG} 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 });\n return bestMatch.file;\n }\n function isHlsMediaFile(file) {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\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(`${LOG} Created ad video element with volume ${video.volume}`);\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels2(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels2(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels2(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels2(currentAd.trackingUrls.start);\n console.log(`${LOG} Ad started playing`);\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels2(currentAd.trackingUrls.complete);\n console.log(`${LOG} Ad completed`);\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) {\n fireTrackingPixels2(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels2(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels2(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels2(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels2(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\n `${LOG} Content video paused in live mode, resuming playback`\n );\n contentVideo.play().catch(() => {\n });\n } else {\n console.log(`${LOG} Content video already playing in live mode`);\n }\n }\n emit(\"content_resume\");\n }\n function handleAdError() {\n console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function ensurePrebidInitialized() {\n if (prebidInitialized) return;\n if (prebidConfig.enabled === false) {\n throw new Error(\"Prebid is disabled in config\");\n }\n if (!prebidConfig.ortbRequest?.imp?.length) {\n throw new Error(\"No impressions configured in ortbRequest\");\n }\n await prebidManager.initialize();\n prebidInitialized = true;\n console.log(`${LOG} Prebid Server manager initialized`);\n }\n async function runPrebidAuction() {\n await ensurePrebidInitialized();\n const bids = await prebidManager.requestBids();\n if (bids.length === 0) {\n console.warn(`${LOG} No bids received from Prebid Server`);\n return null;\n }\n const cpmFloor = prebidConfig.cpmFloor ?? 0;\n const winner = bids[0];\n if (cpmFloor > 0 && winner.cpm < cpmFloor) {\n console.log(\n `${LOG} Winning bid $${winner.cpm.toFixed(2)} below CPM floor $${cpmFloor.toFixed(2)}, rejecting`\n );\n return null;\n }\n console.log(\n `${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`\n );\n if (winner.vastXml) {\n console.log(`${LOG} Parsing VAST XML from bid response (inline)`);\n return parseVastXml(winner.vastXml, \"mp4-first\", LOG);\n }\n if (winner.vastUrl) {\n console.log(`${LOG} Fetching VAST from cached URL: ${winner.vastUrl}`);\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", LOG);\n }\n console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n return null;\n }\n function startPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n function startNativePlayback(mediaFile) {\n if (!adVideoElement) return;\n console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n function startHlsPlayback(mediaFile) {\n if (!adVideoElement) return;\n console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n if (import_hls2.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new import_hls2.default({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls2.default.Events.MANIFEST_PARSED, () => {\n console.log(`${LOG} HLS manifest parsed, starting playback`);\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n adHls.on(import_hls2.default.Events.ERROR, (_event, data) => {\n console.error(`${LOG} HLS error:`, data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n return {\n initialize() {\n console.log(`${LOG} 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 = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(vastTagUrl) {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n console.log(`${LOG} requestAds called:`, vastTagUrl || \"(empty - will run Prebid auction)\");\n if (adPlaying) {\n console.warn(`${LOG} Cannot request new ads while an ad is playing`);\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n sessionId = generateSessionId();\n let ad;\n if (vastTagUrl && vastTagUrl.length > 0) {\n console.log(`${LOG} Fetching VAST from provided URL`);\n ad = await fetchAndParseVastAd(vastTagUrl, \"mp4-first\", LOG);\n } else {\n console.log(`${LOG} Running Prebid Server auction`);\n ad = await runPrebidAuction();\n }\n if (!ad) {\n console.warn(`${LOG} No ads available`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available\"));\n }\n currentAd = ad;\n console.log(\n `${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`\n );\n fireTrackingPixels2(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(`${LOG} Error requesting ads:`, error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n if (!currentAd) {\n console.warn(`${LOG} Cannot play: No ad loaded`);\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(`${LOG} Starting ad playback`);\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n ...createEmptyTrackingState(),\n impression: trackingFired.impression\n };\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(`${LOG} Content paused (VOD mode)`);\n } else {\n console.log(`${LOG} Content continues (Live mode)`);\n }\n console.log(`${LOG} FORCE MUTING main video`);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `${LOG} Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}`\n );\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n return Promise.resolve();\n } catch (error) {\n console.error(`${LOG} Error playing ad:`, error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {\n });\n }\n } catch (error) {\n console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n async stop() {\n console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `${LOG} Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\n `${LOG} Content video paused in live mode, resuming playback on stop`\n );\n contentVideo.play().catch(() => {\n });\n }\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n prebidManager.destroy();\n prebidInitialized = false;\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`${LOG} 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 `${LOG} updateOriginalMutedState: { 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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\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 };\n}\n\n// src/utils/tracking.ts\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && 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(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\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 const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.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 cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\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/player/StormcloudVideoPlayer.ts\nvar StormcloudVideoPlayer = class {\n constructor(config) {\n this.attached = false;\n this.inAdBreak = false;\n this.ptsDriftEmaMs = 0;\n this.adPodQueue = [];\n this.lastHeartbeatTime = 0;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.showAds = false;\n this.isLiveStream = false;\n this.nativeHlsMode = false;\n this.videoSrcProtection = null;\n this.bufferedSegmentsCount = 0;\n this.shouldAutoplayAfterBuffering = false;\n this.hasInitialBufferCompleted = false;\n this.adRequestTokenCounter = 0;\n this.activeAdRequestToken = null;\n this.adRequestWatchdogToken = null;\n this.adFailsafeToken = null;\n this.failedVastUrls = /* @__PURE__ */ new Set();\n this.temporaryFailureUrls = /* @__PURE__ */ new Map();\n this.temporaryFailureCooldownMs = 3e4;\n this.continuousFetchingActive = false;\n this.adRequestQueue = [];\n this.maxPlaceholderDurationMs = 5e3;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n this.maxTotalAdRequestsPerBreak = 20;\n this.pendingAdBreak = null;\n this.consecutiveFailures = 0;\n this.maxConsecutiveFailures = 5;\n this.lastAdRequestTime = 0;\n this.minAdRequestIntervalMs = 2500;\n this.backoffBaseMs = 1e3;\n this.maxBackoffMs = 15e3;\n this.preloadPool = [];\n this.maxPreloadPoolSize = 3;\n this.preloadPoolActive = false;\n this.preloadPoolLoopRunning = false;\n this.continuousFetchLoopRunning = false;\n initializePolyfills();\n const browserOverrides = getBrowserConfigOverrides();\n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n logBrowserInfo(config.debugAdTiming);\n this.ima = this.createAdPlayer(false);\n }\n createAdPlayer(continueLiveStreamDuringAds) {\n const vastMode = this.config.vastMode || \"default\";\n let adPlayerType = this.config.adPlayerType || (vastMode === \"adstorm\" ? \"hls\" : \"ima\");\n if (adPlayerType === \"ima\" && !supportsGoogleIMA()) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Google IMA SDK not supported on this browser, falling back to HLS ad player\"\n );\n }\n adPlayerType = \"hls\";\n }\n if (adPlayerType === \"prebid\") {\n if (!this.config.prebid) {\n console.warn(\n \"[StormcloudVideoPlayer] adPlayerType is 'prebid' but no prebid config provided, falling back to HLS ad player\"\n );\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n ...this.hls ? { mainHlsInstance: this.hls } : {}\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Prebid ad controller (standalone, no IMA SDK)\"\n );\n }\n return createPrebidController(this.video, this.config.prebid, {\n continueLiveStreamDuringAds,\n ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n ...this.hls ? { mainHlsInstance: this.hls } : {}\n });\n }\n if (adPlayerType === \"hls\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)\"\n );\n }\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},\n ...this.hls ? { mainHlsInstance: this.hls } : {}\n });\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Google IMA ad player (IMA mode)\"\n );\n }\n return createImaController(this.video, {\n continueLiveStreamDuringAds\n });\n }\n }\n async load() {\n if (!this.attached) {\n this.attach();\n }\n try {\n await this.fetchAdConfiguration();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n error\n );\n }\n }\n this.initializeTracking();\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\"\n }\n );\n }\n this.ima.destroy();\n this.ima = this.createAdPlayer(false);\n this.ima.initialize();\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n return;\n }\n this.hls = new import_hls3.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_hls3.default.Events.MEDIA_ATTACHED, () => {\n this.hls?.loadSource(this.config.src);\n });\n this.hls.on(import_hls3.default.Events.MANIFEST_PARSED, async (_, data) => {\n if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream = this.hls?.levels?.some(\n (level) => level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n if (this.config.debugAdTiming) {\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: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior\n });\n }\n this.ima.destroy();\n this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n this.ima.initialize();\n this.bufferedSegmentsCount = 0;\n this.hasInitialBufferCompleted = false;\n this.shouldAutoplayAfterBuffering = !!this.config.autoplay;\n const minSegments = this.config.minSegmentsBeforePlay ?? 2;\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {\n });\n }\n }\n });\n this.hls.on(import_hls3.default.Events.LEVEL_LOADED, (_evt, data) => {\n if (this.inAdBreak || this.pendingAdBreak) {\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\") ? this.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 = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value, earlyDetection: true }\n };\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3AF} EARLY SCTE-35 DETECTION: Ad break marker found in fragment\", i, \"- starting pre-fetch (NOT playing yet)\");\n }\n this.startAdPrefetch(marker, frag?.sn);\n return;\n }\n }\n }\n }\n });\n this.hls.on(import_hls3.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.config.debugAdTiming) {\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.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Autoplay failed:\", err);\n }\n });\n }\n }\n });\n this.hls.on(import_hls3.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_hls3.default.Events.FRAG_CHANGED, (_evt, data) => {\n const frag = data?.frag;\n const tagList = frag?.tagList;\n if (!Array.isArray(tagList)) return;\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 = this.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.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { tag, value }\n };\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.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 = this.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.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\n });\n this.hls.on(import_hls3.default.Events.ERROR, (_evt, data) => {\n if (data?.fatal) {\n switch (data.type) {\n case import_hls3.default.ErrorTypes.NETWORK_ERROR:\n this.hls?.startLoad();\n break;\n case import_hls3.default.ErrorTypes.MEDIA_ERROR:\n this.hls?.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n this.hls.attachMedia(this.video);\n }\n attachImaEventListeners() {\n this.ima.on(\"all_ads_completed\", () => {\n const remaining = this.getRemainingAdMs();\n this.consecutiveFailures = 0;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] IMA 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 (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n this.handleAdPodComplete();\n }\n }\n });\n this.ima.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 this.ima.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n if (this.inAdBreak && this.expectedAdBreakDurationMs != null) {\n if (this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.ima.on(\"content_resume\", () => {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n }\n }\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n if (!this.inAdBreak) {\n return;\n }\n this.consecutiveFailures = 0;\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\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 (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n this.handleAdPodComplete();\n }\n });\n }\n recreateImaController() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Recreating ImaController for new ad\");\n }\n const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n if (shouldShowPlaceholder && this.ima) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old ImaController\");\n }\n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n this.isShowingPlaceholder = true;\n }\n if (this.ima) {\n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Error destroying old ImaController:\", error);\n }\n }\n }\n const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n this.ima = this.createAdPlayer(continueLiveStreamDuringAds);\n this.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachImaEventListeners();\n if (shouldShowPlaceholder) {\n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n this.isShowingPlaceholder = true;\n }\n }\n ensurePlaceholderContainer() {\n if (this.placeholderContainer) {\n return;\n }\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n showPlaceholderLayer() {\n this.ensurePlaceholderContainer();\n if (!this.placeholderContainer) {\n return;\n }\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and IMA)\");\n }\n }\n hidePlaceholderLayer() {\n if (!this.placeholderContainer) {\n return;\n }\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\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.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachImaEventListeners();\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n this.emptiedHandler = () => {\n if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.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 shouldUseNativeHls() {\n const streamType = this.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 onId3Tag(tag) {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n parseScte35FromId3(tag) {\n const text = this.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 = this.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 = this.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 = this.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 = this.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 = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n return void 0;\n }\n 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 }\n onScte35Marker(marker) {\n if (this.config.debugAdTiming) {\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.pendingAdBreak\n });\n }\n if (marker.type === \"start\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n const hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;\n this.inAdBreak = true;\n const durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : this.pendingAdBreak?.marker.durationSeconds != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\",\n hasPrefetchedAds\n });\n }\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\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.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;\n }\n if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {\n this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.ima.isAdPlaying();\n const hasQueuedAds = this.adRequestQueue.length > 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null\n });\n }\n if (adPlaying || remaining > 1e3 && hasQueuedAds) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active\");\n }\n return;\n }\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n if (adPlaying) {\n this.ima.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n return;\n }\n }\n 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 }\n 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 }\n 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 }\n 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 }\n 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 }\n parseScte35Binary(data) {\n class BitReader {\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 }\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 r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return void 0;\n }\n 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 if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\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 timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds = void 0;\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 if (outOfNetwork) {\n const marker = {\n type: \"start\",\n ...durationSeconds !== void 0 ? { durationSeconds } : {},\n raw: { splice_command_type: 5 }\n };\n return marker;\n }\n return void 0;\n }\n initializeTracking() {\n sendInitialTracking(this.config.licenseKey).then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n }).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5e3);\n });\n }\n sendHeartbeatIfNeeded() {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n async fetchAdConfiguration() {\n if (this.config.adPlayerType === \"prebid\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Prebid mode: VAST URLs sourced from Prebid Server auctions\"\n );\n }\n return;\n }\n const vastMode = this.config.vastMode || \"default\";\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n }\n if (vastMode === \"adstorm\") {\n if (!this.config.licenseKey) {\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\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 = this.config.vastTagUrl;\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n );\n }\n return;\n }\n const data = await response.json();\n const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n if (imaPayload) {\n this.apiVastTagUrl = decodeURIComponent(imaPayload);\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:\",\n this.apiVastTagUrl\n );\n }\n } else {\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n this.apiNumberAds\n );\n }\n }\n }\n isPrebidMode() {\n return this.config.adPlayerType === \"prebid\";\n }\n getCurrentAdIndex() {\n return this.currentAdIndex;\n }\n getTotalAdsInBreak() {\n return this.totalAdsInBreak;\n }\n generateVastUrlsWithCorrelators(baseUrl, count) {\n const urls = [];\n const baseTimestamp = Date.now();\n for (let i = 0; i < count; i++) {\n const timestamp = baseTimestamp + i;\n const random = Math.floor(Math.random() * 1e12);\n const uniqueCorrelator = `${timestamp}_${random}_${i}`;\n let urlWithCorrelator;\n const correlatorRegex = /([?&])correlator=([^&]*)/;\n if (correlatorRegex.test(baseUrl)) {\n urlWithCorrelator = baseUrl.replace(correlatorRegex, `$1correlator=${uniqueCorrelator}`);\n } else if (baseUrl.includes(\"?\")) {\n urlWithCorrelator = `${baseUrl}&correlator=${uniqueCorrelator}`;\n } else {\n urlWithCorrelator = `${baseUrl}?correlator=${uniqueCorrelator}`;\n }\n urls.push(urlWithCorrelator);\n }\n return urls;\n }\n isAdPlaying() {\n return this.inAdBreak && this.ima.isAdPlaying();\n }\n isShowingAds() {\n return this.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 shouldContinueLiveStreamDuringAds() {\n if (this.config.allowNativeHls) {\n return false;\n }\n if (!this.isLiveStream) {\n return false;\n }\n return true;\n }\n startAdPrefetch(marker, fragmentSn) {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n if (this.isPrebidMode()) {\n this.pendingAdBreak = {\n marker,\n ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n vastUrls: [],\n isFetching: false,\n fetchStartTime: Date.now()\n };\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid mode: ad break marker registered, auction runs at playback time via controller\");\n }\n return;\n }\n const scheduled = this.findCurrentOrNextBreak(this.video.currentTime * 1e3);\n const tags = this.selectVastTagsForBreak(scheduled);\n let baseVastUrl;\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n } else {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n }\n return;\n }\n const urlsToPregenerate = 5;\n const generatedUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, urlsToPregenerate);\n this.pendingAdBreak = {\n marker,\n ...fragmentSn !== void 0 ? { detectedAtFragmentSn: fragmentSn } : {},\n vastUrls: generatedUrls,\n isFetching: false,\n fetchStartTime: Date.now()\n };\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] \\u{1F504} Starting ad prefetch for upcoming ad break\");\n console.log(`[PREFETCH] \\u{1F4CB} Pre-generated ${generatedUrls.length} VAST URLs`);\n }\n this.startPreloadPool(baseVastUrl, generatedUrls.slice(0, this.maxPreloadPoolSize));\n }\n clearPendingAdBreak() {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = void 0;\n }\n this.pendingAdBreak = null;\n }\n startPreloadPool(baseVastUrl, initialUrls) {\n if (this.preloadPoolActive) {\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n }\n return;\n }\n this.preloadPoolActive = true;\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u{1F3CA} Starting preload pool EARLY (target size: ${this.maxPreloadPoolSize})`);\n console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n }\n for (const url of initialUrls) {\n if (this.preloadPool.length < this.maxPreloadPoolSize) {\n this.preloadAdIntoPool(url);\n }\n }\n this.preloadPoolLoop(baseVastUrl);\n }\n async preloadAdIntoPool(vastUrl) {\n if (this.preloadPool.some((entry) => entry.vastUrl === vastUrl) || this.failedVastUrls.has(vastUrl) || this.isUrlInCooldown(vastUrl)) {\n return;\n }\n if (this.preloadPool.length >= this.maxPreloadPoolSize) {\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u{1F4E5} Preloading ad into pool: ${vastUrl}`);\n }\n const loadPromise = (async () => {\n let hasAdError = false;\n let adErrorPayload = null;\n let errorListenerCleanup = null;\n try {\n const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n const preloadIma = this.createAdPlayer(continueLiveStreamDuringAds);\n preloadIma.initialize();\n const errorListener = (payload) => {\n hasAdError = true;\n adErrorPayload = payload;\n };\n preloadIma.on(\"ad_error\", errorListener);\n errorListenerCleanup = () => preloadIma.off(\"ad_error\", errorListener);\n await preloadIma.requestAds(vastUrl);\n preloadIma.pause();\n await new Promise((resolve) => setTimeout(resolve, 1500));\n preloadIma.pause();\n if (hasAdError) {\n const isNoFill = adErrorPayload?.isNoFill || adErrorPayload?.code === 303 || adErrorPayload?.vastErrorCode === 303;\n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n preloadIma.destroy();\n if (isNoFill) {\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u26A0\\uFE0F Ad preload returned no-fill: ${vastUrl}`);\n }\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n } else {\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u26A0\\uFE0F Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n }\n if (adErrorPayload && !this.isTemporaryAdError(adErrorPayload)) {\n this.failedVastUrls.add(vastUrl);\n } else {\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n }\n }\n return;\n }\n const poolEntry = {\n vastUrl,\n imaController: preloadIma,\n loadedAt: Date.now(),\n isReady: true,\n loadPromise: Promise.resolve()\n };\n const lateErrorListener = (payload) => {\n const index = this.preloadPool.findIndex((entry) => entry.vastUrl === vastUrl);\n if (index >= 0) {\n this.preloadPool.splice(index, 1);\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u26A0\\uFE0F Late error detected, removed from pool: ${vastUrl}`, payload);\n }\n try {\n preloadIma.destroy();\n } catch {\n }\n }\n };\n preloadIma.on(\"ad_error\", lateErrorListener);\n this.preloadPool.push(poolEntry);\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u2705 Ad preloaded (no errors detected within timeout) (pool size: ${this.preloadPool.length}/${this.maxPreloadPoolSize})`);\n }\n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n } catch (error) {\n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n if (this.config.debugAdTiming) {\n console.warn(`[PRELOAD-POOL] \\u26A0\\uFE0F Failed to preload ad: ${vastUrl}`, error);\n }\n if (error instanceof Error && !this.isTemporaryAdError(error)) {\n this.failedVastUrls.add(vastUrl);\n } else if (error instanceof Error && this.isTemporaryAdError(error)) {\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n }\n }\n })();\n loadPromise.catch(() => {\n });\n }\n async preloadPoolLoop(baseVastUrl) {\n if (this.preloadPoolLoopRunning) {\n return;\n }\n this.preloadPoolLoopRunning = true;\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] \\u{1F504} Starting continuous preload loop\");\n }\n while (this.preloadPoolActive) {\n if (!this.inAdBreak && this.preloadPool.length >= this.maxPreloadPoolSize) {\n await new Promise((resolve) => setTimeout(resolve, 2e3));\n continue;\n }\n if (!this.inAdBreak && this.pendingAdBreak === null) {\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n }\n break;\n }\n while (this.preloadPool.length < this.maxPreloadPoolSize) {\n if (!this.preloadPoolActive) {\n break;\n }\n if (this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 0) {\n break;\n }\n }\n const newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n const newUrl = newUrls[0];\n if (newUrl && !this.failedVastUrls.has(newUrl) && !this.isUrlInCooldown(newUrl)) {\n await this.preloadAdIntoPool(newUrl);\n }\n await new Promise((resolve) => setTimeout(resolve, 1e3));\n }\n await new Promise((resolve) => setTimeout(resolve, 2e3));\n }\n this.preloadPoolLoopRunning = false;\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] \\u{1F6D1} Preload loop ended\");\n }\n }\n getPreloadedAd() {\n if (this.preloadPool.length === 0) {\n return null;\n }\n const entry = this.preloadPool.shift();\n if (!entry || !entry.isReady) {\n return null;\n }\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] \\u{1F3AF} Using preloaded ad from pool (${this.preloadPool.length} remaining)`);\n }\n return {\n vastUrl: entry.vastUrl,\n imaController: entry.imaController\n };\n }\n stopPreloadPool() {\n this.preloadPoolActive = false;\n this.preloadPoolLoopRunning = false;\n for (const entry of this.preloadPool) {\n try {\n entry.imaController.destroy();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n }\n }\n }\n this.preloadPool = [];\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] \\u{1F6D1} Preload pool stopped and cleaned up\");\n }\n }\n async handleAdStart(_marker) {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1e3\n );\n const tags = this.selectVastTagsForBreak(scheduled);\n const isPrebid = this.isPrebidMode();\n let baseVastUrl;\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n }\n if (!isPrebid && !baseVastUrl) {\n this.clearPendingAdBreak();\n return;\n }\n const adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : scheduled?.durationMs;\n if (this.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F4FA} ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n this.failedVastUrls.clear();\n this.temporaryFailureUrls.clear();\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n this.showAds = true;\n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n let firstAdUrl;\n let usePreloadedAd = false;\n let preloadedController;\n if (isPrebid) {\n firstAdUrl = \"\";\n this.clearPendingAdBreak();\n if (this.config.debugAdTiming) {\n console.log(\"[Prebid] Controller will run auction internally via requestAds()\");\n }\n } else {\n const preloaded = this.getPreloadedAd();\n if (preloaded) {\n firstAdUrl = preloaded.vastUrl;\n preloadedController = preloaded.imaController;\n usePreloadedAd = true;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F680} Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n console.log(`[CONTINUOUS-FETCH] Pool still has ${this.preloadPool.length} preloaded ads ready`);\n }\n } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n firstAdUrl = this.adRequestQueue.shift();\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u26A0\\uFE0F Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n }\n this.clearPendingAdBreak();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F680} Generating new ad URLs...\");\n }\n const firstAdUrlArray = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n firstAdUrl = firstAdUrlArray[0];\n this.adRequestQueue = [];\n }\n }\n if (firstAdUrl == null) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F Failed to get first ad URL\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F4CB} First VAST URL:\", firstAdUrl || \"(Prebid auction)\");\n }\n try {\n if (usePreloadedAd && preloadedController) {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedController;\n this.attachImaEventListeners();\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n }\n this.ima.resume();\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n if (!isPrebid && baseVastUrl && !this.preloadPoolActive) {\n this.preloadPoolActive = true;\n this.preloadPoolLoop(baseVastUrl);\n }\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n } else {\n this.lastAdRequestTime = Date.now();\n await this.ima.requestAds(firstAdUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 First ad request successful, starting playback\");\n }\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n if (!isPrebid && baseVastUrl && !this.preloadPoolActive) {\n this.startPreloadPool(baseVastUrl, []);\n }\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F First ad request failed:\", error);\n }\n if (!isPrebid && !usePreloadedAd) {\n const fallbackPreloaded = this.getPreloadedAd();\n if (fallbackPreloaded) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F504} First ad failed, using preloaded fallback\");\n }\n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = fallbackPreloaded.imaController;\n this.attachImaEventListeners();\n this.ima.resume();\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n if (baseVastUrl && !this.preloadPoolActive) {\n this.preloadPoolActive = true;\n this.preloadPoolLoop(baseVastUrl);\n }\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n return;\n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n }\n if (this.isTemporaryAdError(error)) {\n this.temporaryFailureUrls.set(firstAdUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n }\n } else {\n this.failedVastUrls.add(firstAdUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n }\n }\n this.consecutiveFailures++;\n this.startContinuousFetching(baseVastUrl);\n await this.tryNextAvailableAdWithRateLimit();\n }\n }\n startContinuousFetching(baseVastUrl) {\n if (!this.continuousFetchingActive) {\n return;\n }\n if (this.continuousFetchLoopRunning) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23ED\\uFE0F Fetch loop already running, skipping duplicate start\");\n }\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F504} Starting continuous ad fetching loop\");\n }\n this.continuousFetchLoopRunning = true;\n this.continuousFetchLoop(baseVastUrl);\n }\n async continuousFetchLoop(baseVastUrl) {\n while (this.continuousFetchingActive && this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F Ad break time expired, stopping URL generation\");\n }\n break;\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), stopping URL generation`);\n }\n break;\n }\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Maximum ad requests reached (${this.maxTotalAdRequestsPerBreak}), stopping`);\n }\n break;\n }\n const maxQueueSize = 5;\n if (this.adRequestQueue.length >= maxQueueSize) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F8\\uFE0F URL queue full (${this.adRequestQueue.length}), waiting...`);\n }\n await new Promise((resolve) => setTimeout(resolve, 1e3));\n continue;\n }\n if (this.isPrebidMode()) {\n this.adRequestQueue.push(\"\");\n this.totalAdsInBreak++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Prebid auction slot queued (queue: ${this.adRequestQueue.length})`\n );\n }\n } else if (baseVastUrl) {\n const newAdUrl = this.generateVastUrlsWithCorrelators(baseVastUrl, 1)[0];\n if (!newAdUrl || this.failedVastUrls.has(newAdUrl) || this.isUrlInCooldown(newAdUrl)) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n continue;\n }\n if (this.config.debugAdTiming) {\n const queuedUrlsPreview = [...this.adRequestQueue, newAdUrl];\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F4DD} Queued VAST URL (queue size: ${queuedUrlsPreview.length})`,\n { queuedUrls: queuedUrlsPreview }\n );\n }\n this.adRequestQueue.push(newAdUrl);\n this.totalAdsInBreak++;\n }\n const generationDelay = this.consecutiveFailures > 0 ? Math.min(1e3 * Math.pow(2, this.consecutiveFailures), 5e3) : 500;\n await new Promise((resolve) => setTimeout(resolve, generationDelay));\n }\n this.continuousFetchLoopRunning = false;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] \\u{1F6D1} 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.hidePlaceholderLayer();\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Stopping continuous ad fetching\");\n }\n }\n async tryNextAvailableAdWithRateLimit() {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F3 Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n }\n return this.tryNextAvailableAd(0);\n }\n async tryNextAvailableAd(retryCount = 0) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n this.cleanupTemporaryFailures();\n const preloaded = this.getPreloadedAd();\n if (preloaded) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F3AF} Using preloaded ad from pool (${this.preloadPool.length} remaining in pool)`);\n }\n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloaded.imaController;\n this.attachImaEventListeners();\n this.ima.resume();\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n this.consecutiveFailures = 0;\n return;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] \\u26A0\\uFE0F Preloaded ad failed to play:\", error);\n }\n }\n }\n while (this.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n if (!nextAdUrl) {\n continue;\n }\n if (this.failedVastUrls.has(nextAdUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23ED\\uFE0F Skipping permanently-failed URL, trying next...\");\n }\n continue;\n }\n if (this.isUrlInCooldown(nextAdUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23ED\\uFE0F Skipping URL in cooldown (recent no-fill), trying next...\");\n }\n continue;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F3AC} Requesting next ad via IMA SDK (${this.currentAdIndex + 1}/${this.totalAdsInBreak}, ${this.adRequestQueue.length} remaining in queue)`);\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n try {\n await this.playSingleAd(nextAdUrl);\n this.consecutiveFailures = 0;\n } catch (error) {\n const errorMessage = error.message;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u274C Ad request failed:\", errorMessage);\n }\n if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n this.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.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u23F3 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.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F9\\uFE0F No more ads available, ending ad break\");\n }\n this.handleAdPodComplete();\n }\n }\n async showPlaceholderAndWaitForAds() {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n if (waitTime < 1e3) {\n this.handleAdPodComplete();\n return;\n }\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u2B1B Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n }\n this.isShowingPlaceholder = true;\n this.ima.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) {\n return;\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u{1F6D1} Too many failures during placeholder wait\");\n }\n break;\n }\n while (this.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n if (!nextAdUrl) {\n continue;\n }\n if (this.failedVastUrls.has(nextAdUrl)) {\n continue;\n }\n if (this.isUrlInCooldown(nextAdUrl)) {\n continue;\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u2705 Ad URL available, requesting via IMA SDK\");\n }\n this.isShowingPlaceholder = false;\n this.ima.hidePlaceholder();\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n try {\n await this.playSingleAd(nextAdUrl);\n this.consecutiveFailures = 0;\n } catch (error) {\n const errorMessage = error.message;\n if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n this.consecutiveFailures++;\n }\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n }\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] \\u23F0 Placeholder timeout, ending ad break\");\n }\n this.isShowingPlaceholder = false;\n this.ima.hidePlaceholder();\n this.handleAdPodComplete();\n }\n findCurrentOrNextBreak(nowMs) {\n const schedule = [];\n let candidate;\n for (const b of schedule) {\n const tol = this.config.driftToleranceMs ?? 1e3;\n if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {\n candidate = b;\n }\n }\n return candidate;\n }\n onTimeUpdate(currentTimeSec) {\n if (this.ima.isAdPlaying()) return;\n const nowMs = currentTimeSec * 1e3;\n const breakToPlay = this.findBreakForTime(nowMs);\n if (breakToPlay) {\n this.handleMidAdJoin(breakToPlay, nowMs);\n }\n }\n async handleMidAdJoin(adBreak, nowMs) {\n const durationMs = adBreak.durationMs ?? 0;\n const endMs = adBreak.startTimeMs + durationMs;\n if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {\n const remainingMs = endMs - nowMs;\n const tags = this.selectVastTagsForBreak(adBreak) || (this.apiVastTagUrl ? [this.apiVastTagUrl] : void 0);\n if (tags && tags.length > 0) {\n const first = tags[0];\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n await this.playSingleAd(first);\n this.inAdBreak = true;\n this.expectedAdBreakDurationMs = remainingMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(remainingMs);\n }\n }\n }\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 if (!this.inAdBreak) return;\n this.adStopTimerId = void 0;\n const adPlaying = this.ima.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\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 : 6e4;\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n if (adPlaying) {\n this.ima.stop().catch(() => {\n });\n }\n this.handleAdPodComplete();\n }\n scheduleAdStartIn(delayMs) {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" }).catch(() => {\n });\n }, ms);\n }\n clearAdStartTimer() {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = void 0;\n }\n }\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 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 async playSingleAd(vastTagUrl) {\n if (this.ima.isAdPlaying()) {\n return;\n }\n if (this.failedVastUrls.has(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n }\n throw new Error(\"VAST URL permanently failed\");\n }\n if (this.isUrlInCooldown(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n }\n throw new Error(\"VAST URL in cooldown after no-fill\");\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n }\n throw new Error(\"Too many consecutive failures\");\n }\n this.recreateImaController();\n const requestToken = ++this.adRequestTokenCounter;\n this.activeAdRequestToken = requestToken;\n this.startAdRequestWatchdog(requestToken);\n try {\n this.lastAdRequestTime = Date.now();\n await this.ima.requestAds(vastTagUrl);\n this.clearAdRequestWatchdog();\n if (this.activeAdRequestToken !== requestToken) {\n return;\n }\n try {\n this.startAdFailsafeTimer(requestToken);\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n this.consecutiveFailures = 0;\n this.temporaryFailureUrls.delete(vastTagUrl);\n } catch (playError) {\n if (this.config.debugAdTiming) {\n console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n }\n const preloadedFallback = this.getPreloadedAd();\n if (preloadedFallback) {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n }\n try {\n this.clearAdFailsafeTimer();\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedFallback.imaController;\n this.attachImaEventListeners();\n this.ima.resume();\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n await this.ima.play();\n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n return;\n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n if (this.isTemporaryAdError(playError)) {\n this.temporaryFailureUrls.set(vastTagUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n }\n } else {\n this.failedVastUrls.add(vastTagUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n }\n }\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n throw playError;\n }\n } catch (error) {\n const errorMessage = error?.message || \"\";\n if (this.config.debugAdTiming) {\n console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n }\n const preloadedFallback = this.getPreloadedAd();\n if (preloadedFallback) {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n }\n try {\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedFallback.imaController;\n this.attachImaEventListeners();\n this.ima.resume();\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n await this.ima.play();\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n return;\n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n if (this.isTemporaryAdError(error)) {\n this.temporaryFailureUrls.set(vastTagUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n }\n } else {\n this.failedVastUrls.add(vastTagUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n }\n }\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n throw error;\n }\n }\n handleAdPodComplete() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] \\u{1F3C1} Ad pod complete - cleaning up\");\n }\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n this.stopContinuousFetching();\n this.stopPreloadPool();\n this.clearPendingAdBreak();\n if (this.isShowingPlaceholder) {\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n this.adRequestQueue = [];\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = void 0;\n this.currentAdBreakStartWallClockMs = void 0;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.consecutiveFailures = 0;\n this.ima.stop().catch(() => {\n });\n const restoredMuted = this.ima.getOriginalMutedState();\n const restoredVolume = this.ima.getOriginalVolume();\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.video.paused) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n }\n this.video.play()?.catch(() => {\n });\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {\n });\n }\n }\n handleAdFailure() {\n this.consecutiveFailures++;\n const remaining = this.getRemainingAdMs();\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.consecutiveFailures}`,\n this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n );\n }\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] \\u{1F6D1} Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n if (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Ad failed and no time remaining. Failed URLs:\", this.failedVastUrls.size);\n }\n this.handleAdPodComplete();\n }\n }\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.handleAdFailure();\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 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 imaAdPlaying: this.ima.isAdPlaying()\n });\n this.handleAdFailure();\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 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 logAdState(event, extra = {}) {\n if (!this.config.debugAdTiming) {\n return;\n }\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n showAds: this.showAds,\n adPlaying: this.ima.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra\n });\n }\n getRemainingAdMs() {\n if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)\n return 0;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n findBreakForTime(nowMs) {\n const schedule = [];\n for (const b of schedule) {\n const end = (b.startTimeMs || 0) + (b.durationMs || 0);\n if (nowMs >= (b.startTimeMs || 0) && (b.durationMs ? nowMs < end : true)) {\n return b;\n }\n }\n return void 0;\n }\n toggleMute() {\n if (this.ima.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n this.ima.updateOriginalMutedState(newMutedState, this.video.volume);\n this.ima.setAdVolume(newMutedState ? 0 : 1);\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n toggleFullscreen() {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.video.parentElement;\n if (!container) {\n reject(new Error(\"No parent container found for fullscreen\"));\n return;\n }\n container.requestFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document.exitFullscreen().then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n }).catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n isMuted() {\n if (this.ima.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n setMuted(muted) {\n const adPlaying = this.ima.isAdPlaying();\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n this.video.muted = muted;\n if (adPlaying) {\n this.ima.updateOriginalMutedState(muted, this.video.volume);\n this.ima.setAdVolume(muted ? 0 : 1);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted\n });\n }\n return;\n }\n this.ima.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n setVolume(volume) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.ima.isAdPlaying();\n if (adPlaying) {\n this.ima.setAdVolume(clampedVolume);\n this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n getVolume() {\n const adPlaying = this.ima.isAdPlaying();\n if (adPlaying) {\n return this.ima.getAdVolume();\n }\n return this.video.volume;\n }\n isFullscreen() {\n return !!document.fullscreenElement;\n }\n isLive() {\n return this.isLiveStream;\n }\n get videoElement() {\n return this.video;\n }\n resize() {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n if (this.ima && this.ima.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n this.ima.resize(width, height);\n }\n }\n destroy() {\n this.stopContinuousFetching();\n this.stopPreloadPool();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = void 0;\n }\n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = void 0;\n }\n this.hls?.destroy();\n this.ima?.destroy();\n this.adRequestQueue = [];\n this.consecutiveFailures = 0;\n }\n};\n\n// src/ui/StormcloudVideoPlayer.tsx\nvar import_fa = require(\"react-icons/fa\");\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nvar CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n \"vastMode\"\n];\nvar StormcloudVideoPlayerComponent = import_react.default.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n vastMode,\n vastTagUrl,\n adPlayerType,\n prebid,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n const videoRef = (0, import_react.useRef)(null);\n const playerRef = (0, import_react.useRef)(null);\n const bufferingTimeoutRef = (0, import_react.useRef)(null);\n const [adStatus, setAdStatus] = import_react.default.useState({ showAds: false, currentIndex: 0, totalAds: 0 });\n const [shouldShowNativeControls, setShouldShowNativeControls] = import_react.default.useState(true);\n const [isMuted, setIsMuted] = import_react.default.useState(false);\n const [isFullscreen, setIsFullscreen] = import_react.default.useState(false);\n const [isPlaying, setIsPlaying] = import_react.default.useState(false);\n const [currentTime, setCurrentTime] = import_react.default.useState(0);\n const [duration, setDuration] = import_react.default.useState(0);\n const [volume, setVolume] = import_react.default.useState(1);\n const [playbackRate, setPlaybackRate] = import_react.default.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = import_react.default.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = import_react.default.useState(false);\n const [isLoading, setIsLoading] = import_react.default.useState(true);\n const [isBuffering, setIsBuffering] = import_react.default.useState(false);\n const [showCenterPlay, setShowCenterPlay] = import_react.default.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = import_react.default.useState(false);\n const [viewportWidth, setViewportWidth] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = import_react.default.useState(\n typeof window !== \"undefined\" ? window.innerHeight > window.innerWidth : false\n );\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n const responsiveScale = getResponsiveScale();\n const formatTime = (seconds) => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor(seconds % 3600 / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== \"\" || videoRef.current.readyState >= 1;\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n const handleTimelineSeek = (e) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n const handleVolumeChange = (newVolume) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n const handlePlaybackRateChange = (rate) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n const isHlsStream = src?.toLowerCase().includes(\".m3u8\") || src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);\n const criticalPropsKey = (0, import_react.useMemo)(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n vastMode\n ]);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n setShowLicenseWarning(false);\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {\n }\n playerRef.current = null;\n }\n const cfg = {\n src,\n videoElement: el\n };\n if (autoplay !== void 0) cfg.autoplay = autoplay;\n if (muted !== void 0) cfg.muted = muted;\n if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== void 0)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== void 0)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== void 0)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== void 0) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== void 0)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== void 0) cfg.onControlClick = onControlClick;\n if (licenseKey !== void 0) cfg.licenseKey = licenseKey;\n if (vastMode !== void 0) cfg.vastMode = vastMode;\n if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;\n if (adPlayerType !== void 0) cfg.adPlayerType = adPlayerType;\n if (prebid !== void 0) cfg.prebid = prebid;\n if (minSegmentsBeforePlay !== void 0)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player.load().then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n }).catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n return () => {\n try {\n player.destroy();\n } catch {\n }\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n try {\n if (autoplay !== void 0 && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== void 0 && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current) return;\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n setAdStatus((prev) => {\n if (prev.showAds !== showAds || prev.currentIndex !== currentIndex || prev.totalAds !== totalAds) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n (0, import_react.useEffect)(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n (0, import_react.useEffect)(() => {\n if (!playerRef.current || !videoRef.current) return;\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n const interval = setInterval(updateStates, 200);\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n (0, import_react.useEffect)(() => {\n if (!videoRef.current) return;\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video2 = videoRef.current;\n void video2.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n if (video.paused) {\n setShowCenterPlay(true);\n }\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: `\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n ` }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n className: `stormcloud-video-wrapper ${wrapperClassName || \"\"}`,\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : void 0,\n left: isFullscreen ? 0 : void 0,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : void 0,\n backgroundColor: isFullscreen ? \"#000\" : void 0,\n borderRadius: isFullscreen ? 0 : void 0,\n boxShadow: isFullscreen ? \"none\" : void 0,\n ...wrapperStyle\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"video\",\n {\n ref: videoRef,\n className,\n style: {\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : void 0,\n ...style\n },\n controls: shouldShowNativeControls && controls && !showCustomControls,\n playsInline,\n preload,\n poster,\n ...restVideoAttrs,\n children\n }\n ),\n (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaSpinner,\n {\n className: \"stormcloud-loading-indicator\",\n size: 42,\n color: \"white\",\n style: {\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\"\n }\n }\n ),\n showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background: \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow: \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\"\n },\n children: \"License Key Required\"\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\"\n },\n children: [\n \"Please provide a valid license key to use the Stormcloud Video Player.\",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"br\", {}),\n \"Contact your administrator for licensing information.\"\n ]\n }\n )\n ]\n }\n ),\n showCenterPlay && !isLoading && !isBuffering && !showLicenseWarning && !adStatus.showAds && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: handleCenterPlayClick,\n style: {\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\"\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n },\n title: \"Play\",\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: 36,\n color: \"white\",\n style: {\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\"\n }\n }\n )\n }\n ),\n shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background: \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"8px\",\n background: \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\"\n },\n onClick: handleTimelineSeek,\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n height: \"100%\",\n background: \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${duration > 0 ? currentTime / duration * 100 : 0}%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n top: \"-6px\",\n right: `${duration > 0 ? 100 - currentTime / duration * 100 : 100}%`,\n width: \"20px\",\n height: \"20px\",\n background: \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow: \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\"\n }\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: handlePlayPause,\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow = \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow = \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n },\n title: isPlaying ? \"Pause\" : \"Play\",\n children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPause,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaPlay,\n {\n size: Math.max(16, 20 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 0 0 transparent)\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor = \"rgba(59, 130, 246, 0.4)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.15)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n },\n onMouseLeave: (e) => {\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow: \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\"\n },\n children: [\n formatTime(currentTime),\n \" / \",\n formatTime(duration)\n ]\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\"\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => setShowSpeedMenu(!showSpeedMenu),\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${14 * responsiveScale}px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: \"Playback Speed\",\n children: [\n playbackRate,\n \"x\"\n ]\n }\n ),\n showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow: \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\"\n },\n children: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"button\",\n {\n onClick: () => handlePlaybackRateChange(speed),\n style: {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background: playbackRate === speed ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\" : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom: speed !== 2 ? \"1px solid rgba(255, 255, 255, 0.05)\" : \"none\"\n },\n onMouseEnter: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n },\n onMouseLeave: (e) => {\n if (playbackRate !== speed) {\n e.target.style.background = \"transparent\";\n }\n },\n children: [\n speed,\n \"x\"\n ]\n },\n speed\n )\n )\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${2 * responsiveScale}px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`\n },\n onMouseEnter: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n },\n onMouseLeave: (e) => {\n const target = e.target;\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow = \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: { filter: \"drop-shadow(0 0 0 transparent)\" }\n }\n )\n }\n )\n ]\n }\n )\n ]\n }\n )\n ]\n }\n ) }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\"\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isMuted ? \"Unmute\" : \"Mute\",\n children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeMute,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeDown,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaVolumeUp,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n ),\n showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9\n },\n onMouseEnter: () => setShowVolumeSlider(true),\n onMouseLeave: () => setShowVolumeSlider(false)\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow: \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition: \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\"\n },\n onMouseEnter: (e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow = \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor = \"rgba(96, 165, 250, 0.8)\";\n },\n onMouseLeave: (e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow = \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor = \"rgba(255, 255, 255, 0.7)\";\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\"\n },\n onMouseDown: (e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n const handleMouseMove = (moveEvent) => {\n if (!sliderElement) return;\n const rect2 = sliderElement.getBoundingClientRect();\n const y2 = moveEvent.clientY - rect2.top;\n const percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));\n handleVolumeChange(percentage2);\n };\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n const rect = sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n onClick: (e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage = 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n },\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background: \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition: \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow: \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\"\n }\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n bottom: `calc(${(isMuted ? 0 : volume) * 100}% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background: \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow: \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition: \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\"\n },\n onMouseEnter: (e) => {\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n },\n onMouseLeave: (e) => {\n e.currentTarget.style.boxShadow = \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n },\n onMouseDown: (e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n },\n onMouseUp: (e) => {\n e.currentTarget.style.cursor = \"grab\";\n }\n }\n )\n ]\n }\n )\n }\n )\n ] })\n ]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"button\",\n {\n onClick: () => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n },\n onMouseEnter: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n },\n onMouseLeave: (e) => {\n const target = e.currentTarget;\n target.style.boxShadow = \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background = \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n },\n style: {\n background: \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow: \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`\n },\n title: isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\",\n children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaCompress,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_fa.FaExpand,\n {\n size: Math.max(14, 16 * responsiveScale),\n style: {\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\"\n }\n }\n )\n }\n )\n ]\n }\n ),\n onControlClick && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n onClick: onControlClick,\n style: {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\"\n }\n }\n )\n ]\n }\n )\n ] });\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\"\n ];\n for (const prop of uiProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\"\n ];\n for (const prop of callbackProps) {\n if (prevProps[prop] !== nextProps[prop]) {\n return false;\n }\n }\n return true;\n }\n);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n StormcloudVideoPlayerComponent\n});\n","import React, { useEffect, useRef, useMemo } from \"react\";\nimport { StormcloudVideoPlayer } from \"../player/StormcloudVideoPlayer\";\nimport type { StormcloudVideoPlayerConfig } from \"../types\";\nimport {\n FaPlay,\n FaPause,\n FaVolumeUp,\n FaVolumeMute,\n FaVolumeDown,\n FaExpand,\n FaCompress,\n FaSpinner,\n} from \"react-icons/fa\";\n\nexport type StormcloudVideoPlayerProps = Omit<\n StormcloudVideoPlayerConfig,\n \"videoElement\"\n> &\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n onReady?: (player: StormcloudVideoPlayer) => void;\n wrapperClassName?: string;\n wrapperStyle?: React.CSSProperties;\n licenseKey?: string;\n };\n\nconst CRITICAL_PROPS = [\n \"src\",\n \"allowNativeHls\",\n \"licenseKey\",\n \"lowLatencyMode\",\n \"driftToleranceMs\",\n \"vastMode\",\n] as const;\n\nexport const StormcloudVideoPlayerComponent: React.FC<StormcloudVideoPlayerProps> =\n React.memo(\n (props) => {\n const {\n src,\n autoplay,\n muted,\n lowLatencyMode,\n allowNativeHls,\n driftToleranceMs,\n immediateManifestAds,\n debugAdTiming,\n showCustomControls,\n hideLoadingIndicator,\n onVolumeToggle,\n onFullscreenToggle,\n onControlClick,\n onReady,\n wrapperClassName,\n wrapperStyle,\n className,\n style,\n controls,\n playsInline,\n preload,\n poster,\n children,\n licenseKey,\n vastMode,\n vastTagUrl,\n adPlayerType,\n prebid,\n minSegmentsBeforePlay,\n ...restVideoAttrs\n } = props;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playerRef = useRef<StormcloudVideoPlayer | null>(null);\n const bufferingTimeoutRef = useRef<number | null>(null);\n const [adStatus, setAdStatus] = React.useState<{\n showAds: boolean;\n currentIndex: number;\n totalAds: number;\n }>({ showAds: false, currentIndex: 0, totalAds: 0 });\n\n const [shouldShowNativeControls, setShouldShowNativeControls] =\n React.useState(true);\n\n const [isMuted, setIsMuted] = React.useState(false);\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [showVolumeSlider, setShowVolumeSlider] = React.useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isBuffering, setIsBuffering] = React.useState(false);\n const [showCenterPlay, setShowCenterPlay] = React.useState(false);\n const [showLicenseWarning, setShowLicenseWarning] = React.useState(false);\n const [viewportWidth, setViewportWidth] = React.useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1920\n );\n const [isPortrait, setIsPortrait] = React.useState(\n typeof window !== \"undefined\"\n ? window.innerHeight > window.innerWidth\n : false\n );\n\n const getResponsiveScale = () => {\n if (viewportWidth < 480) return 0.7;\n if (viewportWidth < 768) return 0.8;\n if (viewportWidth < 1024) return 0.9;\n return 1;\n };\n\n const responsiveScale = getResponsiveScale();\n\n const formatTime = (seconds: number): string => {\n if (!isFinite(seconds)) return \"0:00:00\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return `${hours}:${minutes\n .toString()\n .padStart(2, \"0\")}:${remainingSeconds.toString().padStart(2, \"0\")}`;\n };\n\n const handlePlayPause = () => {\n if (videoRef.current) {\n if (videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n } else {\n videoRef.current.pause();\n setShowCenterPlay(true);\n }\n }\n };\n\n const handleCenterPlayClick = () => {\n if (videoRef.current && videoRef.current.paused) {\n const hasValidSource =\n videoRef.current.src ||\n (videoRef.current.currentSrc &&\n videoRef.current.currentSrc !== \"\") ||\n videoRef.current.readyState >= 1;\n\n if (hasValidSource) {\n videoRef.current.play()?.catch((error) => {\n console.error(\"[StormcloudVideoPlayer] Failed to play:\", error);\n });\n setShowCenterPlay(false);\n } else {\n console.warn(\n \"[StormcloudVideoPlayer] Cannot play: video has no valid source\"\n );\n }\n }\n };\n\n const handleTimelineSeek = (e: React.MouseEvent<HTMLDivElement>) => {\n if (videoRef.current && duration > 0 && isFinite(duration)) {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const progress = Math.max(0, Math.min(1, clickX / rect.width));\n const newTime = progress * duration;\n\n if (isFinite(newTime) && newTime >= 0 && newTime <= duration) {\n videoRef.current.currentTime = newTime;\n }\n }\n };\n\n const handleVolumeChange = (newVolume: number) => {\n if (playerRef.current && isFinite(newVolume)) {\n const clampedVolume = Math.max(0, Math.min(1, newVolume));\n playerRef.current.setVolume(clampedVolume);\n }\n };\n\n const handlePlaybackRateChange = (rate: number) => {\n if (videoRef.current && isFinite(rate) && rate > 0) {\n videoRef.current.playbackRate = rate;\n }\n setShowSpeedMenu(false);\n };\n\n const isHlsStream =\n src?.toLowerCase().includes(\".m3u8\") ||\n src?.toLowerCase().includes(\"/hls/\");\n const shouldShowEnhancedControls =\n showCustomControls && (isHlsStream ? allowNativeHls : true);\n\n const criticalPropsKey = useMemo(() => {\n return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join(\"|\");\n }, [\n src,\n allowNativeHls,\n licenseKey,\n lowLatencyMode,\n driftToleranceMs,\n vastMode,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = videoRef.current;\n if (!el || !src) return;\n\n if (!licenseKey) {\n setShowLicenseWarning(true);\n setIsLoading(false);\n console.warn(\n \"StormcloudVideoPlayer: License key is required but not provided. Please set the licenseKey prop to use the player.\"\n );\n return;\n }\n\n setShowLicenseWarning(false);\n\n if (debugAdTiming) {\n console.log(\"[StormcloudUI] Initializing player, isLoading=true\");\n }\n\n if (playerRef.current) {\n try {\n playerRef.current.destroy();\n } catch {}\n playerRef.current = null;\n }\n\n const cfg: StormcloudVideoPlayerConfig = {\n src,\n videoElement: el,\n } as StormcloudVideoPlayerConfig;\n if (autoplay !== undefined) cfg.autoplay = autoplay;\n if (muted !== undefined) cfg.muted = muted;\n if (lowLatencyMode !== undefined) cfg.lowLatencyMode = lowLatencyMode;\n if (allowNativeHls !== undefined) cfg.allowNativeHls = allowNativeHls;\n if (driftToleranceMs !== undefined)\n cfg.driftToleranceMs = driftToleranceMs;\n if (immediateManifestAds !== undefined)\n cfg.immediateManifestAds = immediateManifestAds;\n if (debugAdTiming !== undefined) cfg.debugAdTiming = debugAdTiming;\n if (showCustomControls !== undefined)\n cfg.showCustomControls = showCustomControls;\n if (onVolumeToggle !== undefined) cfg.onVolumeToggle = onVolumeToggle;\n if (onFullscreenToggle !== undefined)\n cfg.onFullscreenToggle = onFullscreenToggle;\n if (onControlClick !== undefined) cfg.onControlClick = onControlClick;\n if (licenseKey !== undefined) cfg.licenseKey = licenseKey;\n if (vastMode !== undefined) cfg.vastMode = vastMode;\n if (vastTagUrl !== undefined) cfg.vastTagUrl = vastTagUrl;\n if (adPlayerType !== undefined) cfg.adPlayerType = adPlayerType;\n if (prebid !== undefined) cfg.prebid = prebid;\n if (minSegmentsBeforePlay !== undefined)\n cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;\n\n const player = new StormcloudVideoPlayer(cfg);\n playerRef.current = player;\n player\n .load()\n .then(() => {\n const showNative = player.shouldShowNativeControls();\n setShouldShowNativeControls(showNative);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Player loaded successfully, waiting for video ready\"\n );\n }\n onReady?.(player);\n })\n .catch((error) => {\n console.error(\n \"StormcloudVideoPlayer: Failed to load player:\",\n error\n );\n setIsLoading(false);\n onReady?.(player);\n });\n\n return () => {\n try {\n player.destroy();\n } catch {}\n playerRef.current = null;\n };\n }, [criticalPropsKey]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n try {\n if (autoplay !== undefined && playerRef.current.videoElement) {\n playerRef.current.videoElement.autoplay = autoplay;\n }\n if (muted !== undefined && !playerRef.current.isShowingAds()) {\n playerRef.current.setMuted(muted);\n }\n } catch (error) {\n console.warn(\"Failed to update player properties:\", error);\n }\n }, [autoplay, muted]);\n\n useEffect(() => {\n if (!playerRef.current) return;\n\n const checkAdStatus = () => {\n if (playerRef.current) {\n const showAdsFromMethod = playerRef.current.isShowingAds();\n const showAdsFromAttribute = videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n const showAds = showAdsFromMethod || showAdsFromAttribute;\n const currentIndex = playerRef.current.getCurrentAdIndex();\n const totalAds = playerRef.current.getTotalAdsInBreak();\n\n setAdStatus((prev) => {\n if (\n prev.showAds !== showAds ||\n prev.currentIndex !== currentIndex ||\n prev.totalAds !== totalAds\n ) {\n if (showAds && !prev.showAds) {\n setShowCenterPlay(false);\n }\n return { showAds, currentIndex, totalAds };\n }\n return prev;\n });\n }\n };\n\n const interval = setInterval(checkAdStatus, 50);\n return () => clearInterval(interval);\n }, []);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !playerRef.current) return;\n\n const handleResize = () => {\n if (playerRef.current && videoRef.current) {\n if (typeof playerRef.current.resize === \"function\") {\n playerRef.current.resize();\n }\n }\n setViewportWidth(window.innerWidth);\n setIsPortrait(window.innerHeight > window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (!playerRef.current || !videoRef.current) return;\n\n const updateStates = () => {\n if (playerRef.current && videoRef.current) {\n setIsMuted(playerRef.current.isMuted());\n setIsPlaying(!videoRef.current.paused);\n\n const currentTimeValue = videoRef.current.currentTime;\n setCurrentTime(isFinite(currentTimeValue) ? currentTimeValue : 0);\n\n const durationValue = videoRef.current.duration;\n setDuration(isFinite(durationValue) ? durationValue : 0);\n\n const volumeValue = playerRef.current.getVolume();\n setVolume(\n isFinite(volumeValue) ? Math.max(0, Math.min(1, volumeValue)) : 1\n );\n\n const rateValue = videoRef.current.playbackRate;\n setPlaybackRate(\n isFinite(rateValue) && rateValue > 0 ? rateValue : 1\n );\n }\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n const interval = setInterval(updateStates, 200);\n\n const handleFullscreenChange = () => {\n setIsFullscreen(\n document.fullscreenElement === videoRef.current?.parentElement\n );\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\n return () => {\n clearInterval(interval);\n document.removeEventListener(\n \"fullscreenchange\",\n handleFullscreenChange\n );\n };\n }, []);\n\n useEffect(() => {\n if (!videoRef.current) return;\n\n const handleLoadedMetadata = () => {\n if (videoRef.current) {\n const video = videoRef.current;\n void video.offsetHeight;\n }\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadedmetadata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadedData = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadeddata, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleLoadStart = () => {\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: loadstart, readyState:\",\n videoRef.current?.readyState\n );\n }\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplay, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: canplaythrough, readyState:\",\n videoRef.current?.readyState,\n \"- clearing loading state, isLoading=false\"\n );\n }\n };\n\n const handleWaiting = () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n }\n\n bufferingTimeoutRef.current = window.setTimeout(() => {\n setIsBuffering(true);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video buffering detected (after 300ms delay), readyState:\",\n videoRef.current?.readyState,\n \"- showing spinner, isBuffering=true\"\n );\n }\n }, 300);\n\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: waiting, readyState:\",\n videoRef.current?.readyState,\n \"- buffering delay started (300ms)\"\n );\n }\n };\n\n const handlePlaying = () => {\n setIsLoading(false);\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n setIsBuffering(false);\n setShowCenterPlay(false);\n if (debugAdTiming) {\n console.log(\n \"[StormcloudUI] Video event: playing, readyState:\",\n videoRef.current?.readyState,\n \"- playback started, isLoading=false, isBuffering=false\"\n );\n }\n };\n\n const handlePause = () => {\n const isAdActive = playerRef.current?.isShowingAds() || \n videoRef.current?.dataset?.stormcloudAdPlaying === \"true\";\n \n if (playerRef.current && !isAdActive) {\n setShowCenterPlay(true);\n } else {\n setShowCenterPlay(false);\n }\n };\n\n const handleEnded = () => {\n setShowCenterPlay(true);\n };\n\n const video = videoRef.current;\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n\n if (video.paused) {\n setShowCenterPlay(true);\n }\n\n return () => {\n if (bufferingTimeoutRef.current) {\n clearTimeout(bufferingTimeoutRef.current);\n bufferingTimeoutRef.current = null;\n }\n\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n };\n }, [debugAdTiming]);\n\n return (\n <>\n <style>\n {`\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n `}\n </style>\n <div\n className={`stormcloud-video-wrapper ${wrapperClassName || \"\"}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: isFullscreen ? \"fixed\" : \"relative\",\n top: isFullscreen ? 0 : undefined,\n left: isFullscreen ? 0 : undefined,\n overflow: \"hidden\",\n width: isFullscreen ? \"100vw\" : \"100%\",\n height: isFullscreen ? \"100vh\" : \"auto\",\n minHeight: isFullscreen ? \"100vh\" : \"auto\",\n maxWidth: isFullscreen ? \"100vw\" : \"100%\",\n maxHeight: isFullscreen ? \"100vh\" : \"none\",\n zIndex: isFullscreen ? 999999 : undefined,\n backgroundColor: isFullscreen ? \"#000\" : undefined,\n borderRadius: isFullscreen ? 0 : undefined,\n boxShadow: isFullscreen ? \"none\" : undefined,\n ...wrapperStyle,\n }}\n >\n <video\n ref={videoRef}\n className={className}\n style={{\n display: \"block\",\n width: \"100%\",\n height: isFullscreen ? \"100%\" : \"auto\",\n maxWidth: \"100%\",\n maxHeight: isFullscreen ? \"100%\" : \"none\",\n objectFit: isFullscreen ? \"cover\" : \"contain\",\n backgroundColor: \"#000\",\n aspectRatio: isFullscreen ? \"unset\" : undefined,\n ...style,\n }}\n controls={\n shouldShowNativeControls && controls && !showCustomControls\n }\n playsInline={playsInline}\n preload={preload}\n poster={poster}\n {...restVideoAttrs}\n >\n {children}\n </video>\n\n {(isLoading || isBuffering) && !hideLoadingIndicator && (\n <FaSpinner\n className=\"stormcloud-loading-indicator\"\n size={42}\n color=\"white\"\n style={{\n position: \"absolute\",\n top: \"calc(50% - 21px)\",\n left: \"calc(50% - 21px)\",\n zIndex: 20,\n animation: \"spin 1s linear infinite\",\n filter: \"drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))\",\n }}\n />\n )}\n\n {showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 25,\n background:\n \"linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)\",\n color: \"white\",\n padding: \"24px 32px\",\n borderRadius: \"16px\",\n backdropFilter: \"blur(20px)\",\n border: \"2px solid rgba(255, 255, 255, 0.2)\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n margin: \"0 16px\",\n }}\n >\n <div\n style={{\n fontSize: \"20px\",\n fontWeight: \"bold\",\n marginBottom: \"12px\",\n color: \"#ffffff\",\n textShadow: \"0 2px 4px rgba(0, 0, 0, 0.5)\",\n }}\n >\n License Key Required\n </div>\n <div\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n color: \"rgba(255, 255, 255, 0.9)\",\n textShadow: \"0 1px 2px rgba(0, 0, 0, 0.3)\",\n }}\n >\n Please provide a valid license key to use the Stormcloud Video\n Player.\n <br />\n Contact your administrator for licensing information.\n </div>\n </div>\n )}\n\n {showCenterPlay &&\n !isLoading &&\n !isBuffering &&\n !showLicenseWarning &&\n !adStatus.showAds && (\n <div\n onClick={handleCenterPlayClick}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 15,\n cursor: \"pointer\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\",\n borderRadius: \"50%\",\n width: \"100px\",\n height: \"100px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n border: \"3px solid rgba(255, 255, 255, 0.8)\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)\";\n target.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.9)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLElement;\n target.style.transform = \"translate(-50%, -50%)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)\";\n target.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)\";\n target.style.borderColor = \"rgba(255, 255, 255, 0.8)\";\n }}\n title=\"Play\"\n >\n <FaPlay\n size={36}\n color=\"white\"\n style={{\n marginLeft: \"6px\",\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n }}\n />\n </div>\n )}\n\n {shouldShowEnhancedControls && !showLicenseWarning ? (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: 0,\n left: 0,\n right: 0,\n background:\n \"linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)\",\n padding: \"20px 16px 16px\",\n zIndex: 10,\n }}\n >\n <div\n style={{\n width: \"100%\",\n height: \"8px\",\n background:\n \"linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)\",\n borderRadius: \"8px\",\n marginBottom: \"16px\",\n cursor: \"pointer\",\n position: \"relative\",\n backdropFilter: \"blur(5px)\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n boxShadow: \"inset 0 2px 4px rgba(0, 0, 0, 0.2)\",\n }}\n onClick={handleTimelineSeek}\n >\n <div\n style={{\n height: \"100%\",\n background:\n \"linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)\",\n borderRadius: \"8px\",\n width: `${\n duration > 0 ? (currentTime / duration) * 100 : 0\n }%`,\n transition: \"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow: \"0 2px 8px rgba(139, 92, 246, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n top: \"-6px\",\n right: `${\n duration > 0\n ? 100 - (currentTime / duration) * 100\n : 100\n }%`,\n width: \"20px\",\n height: \"20px\",\n background:\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)\",\n borderRadius: \"50%\",\n border: \"3px solid rgba(139, 92, 246, 0.8)\",\n boxShadow:\n \"0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)\",\n transform: \"translateX(50%)\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n color: \"white\",\n flexWrap: viewportWidth < 768 ? \"wrap\" : \"nowrap\",\n gap: `${8 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n flexWrap: viewportWidth < 480 ? \"wrap\" : \"nowrap\",\n }}\n >\n <button\n onClick={handlePlayPause}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n backdropFilter: \"blur(12px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${10 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n minWidth: `${48 * responsiveScale}px`,\n minHeight: `${48 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n target.style.boxShadow =\n \"0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n target.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n }}\n title={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <FaPause\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaPlay\n size={Math.max(16, 20 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 0 0 transparent)\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(15px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"1px solid rgba(255, 255, 255, 0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)\";\n e.currentTarget.style.borderColor =\n \"rgba(59, 130, 246, 0.4)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.15)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n // Hover effect removed\n }}\n onMouseLeave={(e) => {\n // Hover effect removed\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 -\n Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)\",\n borderRadius: \"4px\",\n boxShadow:\n \"inset 0 1px 3px rgba(0, 0, 0, 0.2)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 7px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"14px\",\n height: \"14px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n boxShadow:\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <div\n style={{\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n color: \"rgba(255, 255, 255, 0.9)\",\n display: viewportWidth < 480 ? \"none\" : \"block\",\n }}\n >\n {formatTime(currentTime)} / {formatTime(duration)}\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: `${12 * responsiveScale}px`,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: viewportWidth < 600 ? \"none\" : \"block\",\n }}\n >\n <button\n onClick={() => setShowSpeedMenu(!showSpeedMenu)}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px ${\n 14 * responsiveScale\n }px`,\n borderRadius: `${14 * responsiveScale}px`,\n fontSize: `${14 * responsiveScale}px`,\n fontFamily: \"monospace\",\n fontWeight: \"700\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${56 * responsiveScale}px`,\n minHeight: `${40 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title=\"Playback Speed\"\n >\n {playbackRate}x\n </button>\n\n {showSpeedMenu && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n right: 0,\n marginBottom: \"12px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)\",\n backdropFilter: \"blur(20px)\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(255, 255, 255, 0.1)\",\n overflow: \"hidden\",\n minWidth: \"90px\",\n boxShadow:\n \"0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)\",\n }}\n >\n {[0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n (speed) => (\n <button\n key={speed}\n onClick={() =>\n handlePlaybackRateChange(speed)\n }\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n background:\n playbackRate === speed\n ? \"linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)\"\n : \"transparent\",\n border: \"none\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n fontWeight: \"600\",\n textAlign: \"center\",\n transition:\n \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n borderBottom:\n speed !== 2\n ? \"1px solid rgba(255, 255, 255, 0.05)\"\n : \"none\",\n }}\n onMouseEnter={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background =\n \"linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)\";\n }\n }}\n onMouseLeave={(e) => {\n if (playbackRate !== speed) {\n (\n e.target as HTMLElement\n ).style.background = \"transparent\";\n }\n }}\n >\n {speed}x\n </button>\n )\n )}\n </div>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current\n .toggleFullscreen()\n .catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\",\n backdropFilter: \"blur(10px)\",\n border: `${\n 2 * responsiveScale\n }px solid rgba(255, 255, 255, 0.3)`,\n color: \"#ffffff\",\n cursor: \"pointer\",\n padding: `${8 * responsiveScale}px`,\n borderRadius: `${16 * responsiveScale}px`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n boxShadow:\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\",\n minWidth: `${44 * responsiveScale}px`,\n minHeight: `${44 * responsiveScale}px`,\n }}\n onMouseEnter={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)\";\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)\";\n }}\n onMouseLeave={(e) => {\n const target = e.target as HTMLElement;\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)\";\n target.style.boxShadow =\n \"0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)\";\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{ filter: \"drop-shadow(0 0 0 transparent)\" }}\n />\n )}\n </button>\n </div>\n </div>\n </div>\n </>\n ) : (\n showCustomControls &&\n !showLicenseWarning && (\n <div\n style={{\n position: \"absolute\",\n bottom: `${10 * responsiveScale}px`,\n right: `${10 * responsiveScale}px`,\n transform: \"none\",\n display: \"flex\",\n flexDirection: isPortrait ? \"column\" : \"row\",\n gap: `${10 * responsiveScale}px`,\n zIndex: 10,\n }}\n >\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px\",\n margin: \"-8px\",\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n >\n <button\n onClick={() => {\n if (playerRef.current) {\n playerRef.current.toggleMute();\n }\n if (onVolumeToggle) {\n onVolumeToggle();\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <FaVolumeMute\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : volume < 0.5 ? (\n <FaVolumeDown\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaVolumeUp\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n\n {showVolumeSlider && (\n <>\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"60px\",\n height: \"20px\",\n marginBottom: \"-16px\",\n zIndex: 9,\n }}\n onMouseEnter={() => setShowVolumeSlider(true)}\n onMouseLeave={() => setShowVolumeSlider(false)}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: \"4px\",\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)\",\n backdropFilter: \"blur(20px)\",\n padding: \"10px 14px\",\n borderRadius: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.7)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"128px\",\n boxShadow:\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\",\n zIndex: 10,\n transition:\n \"transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out\",\n }}\n onMouseEnter={(e) => {\n setShowVolumeSlider(true);\n e.currentTarget.style.boxShadow =\n \"0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)\";\n e.currentTarget.style.borderColor =\n \"rgba(96, 165, 250, 0.8)\";\n }}\n onMouseLeave={(e) => {\n setShowVolumeSlider(false);\n e.currentTarget.style.boxShadow =\n \"0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)\";\n e.currentTarget.style.borderColor =\n \"rgba(255, 255, 255, 0.7)\";\n }}\n >\n <div\n style={{\n position: \"relative\",\n width: \"8px\",\n height: \"104px\",\n cursor: \"pointer\",\n transition: \"transform 0.2s ease-in-out\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n const sliderElement = e.currentTarget;\n\n const handleMouseMove = (\n moveEvent: MouseEvent\n ) => {\n if (!sliderElement) return;\n const rect =\n sliderElement.getBoundingClientRect();\n const y = moveEvent.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n };\n\n const handleMouseUp = () => {\n document.removeEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.removeEventListener(\n \"mouseup\",\n handleMouseUp\n );\n };\n\n document.addEventListener(\n \"mousemove\",\n handleMouseMove\n );\n document.addEventListener(\n \"mouseup\",\n handleMouseUp\n );\n\n const rect =\n sliderElement.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n onClick={(e) => {\n e.stopPropagation();\n const rect =\n e.currentTarget.getBoundingClientRect();\n const y = e.clientY - rect.top;\n const percentage =\n 1 - Math.max(0, Math.min(1, y / rect.height));\n handleVolumeChange(percentage);\n }}\n >\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"100%\",\n background:\n \"linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)\",\n borderRadius: \"4px\",\n border: \"1px solid rgba(255, 255, 255, 0.4)\",\n boxShadow: \"inset 0 1px 3px rgba(0, 0, 0, 0.3)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background:\n \"linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)\",\n borderRadius: \"4px\",\n transition:\n \"height 0.15s ease-out, box-shadow 0.2s ease-in-out\",\n boxShadow:\n \"0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n bottom: `calc(${\n (isMuted ? 0 : volume) * 100\n }% - 8px)`,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: \"16px\",\n height: \"16px\",\n background:\n \"linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)\",\n borderRadius: \"50%\",\n border: \"2px solid rgba(96, 165, 250, 0.9)\",\n boxShadow:\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\",\n transition:\n \"bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out\",\n cursor: \"grab\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)\";\n e.currentTarget.style.cursor = \"grab\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.boxShadow =\n \"0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.cursor = \"grabbing\";\n }}\n onMouseUp={(e) => {\n e.currentTarget.style.cursor = \"grab\";\n }}\n />\n </div>\n </div>\n </>\n )}\n </div>\n\n <button\n onClick={() => {\n if (onFullscreenToggle) {\n onFullscreenToggle();\n } else if (playerRef.current) {\n playerRef.current.toggleFullscreen().catch((err) => {\n console.error(\"Fullscreen error:\", err);\n });\n }\n }}\n onMouseEnter={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)\";\n }}\n onMouseLeave={(e) => {\n const target = e.currentTarget as HTMLButtonElement;\n target.style.boxShadow =\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\";\n target.style.background =\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\";\n }}\n style={{\n background:\n \"linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: `${18 * responsiveScale}px`,\n padding: `${8 * responsiveScale}px`,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backdropFilter: \"blur(20px)\",\n boxShadow:\n \"0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n minWidth: `${46 * responsiveScale}px`,\n minHeight: `${46 * responsiveScale}px`,\n }}\n title={\n isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"\n }\n >\n {isFullscreen ? (\n <FaCompress\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n ) : (\n <FaExpand\n size={Math.max(14, 16 * responsiveScale)}\n style={{\n filter: \"drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))\",\n color: \"#ffffff\",\n }}\n />\n )}\n </button>\n </div>\n )\n )}\n\n {onControlClick && (\n <div\n onClick={onControlClick}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 1,\n cursor: \"pointer\",\n }}\n />\n )}\n </div>\n </>\n );\n },\n (prevProps, nextProps) => {\n for (const prop of CRITICAL_PROPS) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const uiProps = [\n \"autoplay\",\n \"muted\",\n \"controls\",\n \"showCustomControls\",\n \"className\",\n \"style\",\n \"wrapperClassName\",\n \"wrapperStyle\",\n \"playsInline\",\n \"preload\",\n \"poster\",\n \"children\",\n ] as const;\n\n for (const prop of uiProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n const callbackProps = [\n \"onReady\",\n \"onVolumeToggle\",\n \"onFullscreenToggle\",\n \"onControlClick\",\n ] as const;\n for (const prop of callbackProps) {\n if ((prevProps as any)[prop] !== (nextProps as any)[prop]) {\n return false;\n }\n }\n\n return true;\n }\n );\n","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 supportsIMA: boolean;\n supportsModernJS: boolean;\n recommendedAdPlayer: 'ima' | 'hls';\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 supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer: 'ima' | 'hls' = 'ima';\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 if (webOSVersion !== undefined && webOSVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (webOSVersion !== undefined && webOSVersion >= 3) {\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\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 if (tizenVersion !== undefined && tizenVersion >= 4) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (tizenVersion !== undefined && tizenVersion >= 3 && chromeVersion >= 47) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n isLegacyTV = false;\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n if (chromeVersion >= 53) {\n supportsIMA = true;\n recommendedAdPlayer = 'ima';\n } else {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n isLegacyTV = true;\n }\n } else {\n if (chromeVersion > 0) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (chromeVersion < 50) {\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\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 supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n webOSVersion,\n tizenVersion,\n chromeVersion: chromeVersionNum,\n };\n}\n\nexport function supportsGoogleIMA(): boolean {\n const browser = detectBrowser();\n\n if (browser.isLegacyTV) {\n return false;\n }\n\n if (typeof document === 'undefined' ||\n typeof document.createElement !== 'function') {\n return false;\n }\n\n try {\n const video = document.createElement('video');\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n if (typeof Promise === 'undefined') {\n return false;\n }\n\n return browser.supportsIMA;\n}\n\nexport function getRecommendedAdPlayer(): 'ima' | 'hls' {\n const browser = detectBrowser();\n return browser.recommendedAdPlayer;\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 const imaSupport = supportsGoogleIMA();\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 supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\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 getBrowserConfigOverrides(): {\n adPlayerType?: 'ima' | 'hls';\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: { adPlayerType?: 'ima' | 'hls'; allowNativeHls?: boolean } = {};\n\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = 'hls';\n }\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'ima':\n return supportsGoogleIMA();\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\n","import Hls from \"hls.js\";\nimport type {\n StormcloudVideoPlayerConfig,\n Scte35Marker,\n Id3TagInfo,\n ImaController,\n AdBreak,\n StormcloudApiResponse,\n} from \"../types\";\nimport { createImaController } from \"../sdk/ima\";\nimport { createHlsAdPlayer } from \"../sdk/hlsAdPlayer\";\nimport { createPrebidController } from \"../sdk/prebidController\";\nimport { sendInitialTracking, sendHeartbeat } from \"../utils/tracking\";\nimport { initializePolyfills } from \"../utils/polyfills\";\nimport {\n supportsGoogleIMA,\n logBrowserInfo,\n getBrowserConfigOverrides,\n} from \"../utils/browserCompat\";\n\nexport class StormcloudVideoPlayer {\n private readonly video: HTMLVideoElement;\n private readonly config: StormcloudVideoPlayerConfig;\n private hls?: Hls;\n private ima: ImaController;\n private attached = false;\n private inAdBreak = false;\n private currentAdBreakStartWallClockMs: number | undefined;\n private expectedAdBreakDurationMs: number | undefined;\n private adStopTimerId: number | undefined;\n private adStartTimerId: number | undefined;\n private adFailsafeTimerId: number | undefined;\n private ptsDriftEmaMs = 0;\n private adPodQueue: string[] = [];\n private apiVastTagUrl: string | undefined;\n private apiNumberAds: number | undefined;\n private lastHeartbeatTime: number = 0;\n private heartbeatInterval: number | undefined;\n private currentAdIndex: number = 0;\n private totalAdsInBreak: number = 0;\n private showAds: boolean = false;\n private isLiveStream: boolean = false;\n private nativeHlsMode: boolean = false;\n private videoSrcProtection: string | null = null;\n private bufferedSegmentsCount: number = 0;\n private shouldAutoplayAfterBuffering: boolean = false;\n private hasInitialBufferCompleted: boolean = false;\n private adRequestTokenCounter = 0;\n private activeAdRequestToken: number | null = null;\n private adRequestWatchdogId: number | undefined;\n private adRequestWatchdogToken: number | null = null;\n private adFailsafeToken: number | null = null;\n private failedVastUrls: Set<string> = new Set();\n private temporaryFailureUrls: Map<string, number> = new Map();\n private readonly temporaryFailureCooldownMs: number = 30000;\n private continuousFetchingActive: boolean = false;\n private adRequestQueue: string[] = [];\n private maxPlaceholderDurationMs: number = 5000;\n private isShowingPlaceholder: boolean = false;\n private timeUpdateHandler?: (event: Event) => void;\n private emptiedHandler?: (event: Event) => void;\n \n private totalAdRequestsInBreak: number = 0;\n private readonly maxTotalAdRequestsPerBreak: number = 20;\n \n private pendingAdBreak: {\n marker: Scte35Marker;\n detectedAtFragmentSn?: number;\n vastUrls: string[];\n isFetching: boolean;\n fetchStartTime?: number;\n } | null = null;\n private prefetchTimerId: number | undefined;\n \n private consecutiveFailures: number = 0;\n private readonly maxConsecutiveFailures: number = 5;\n private lastAdRequestTime: number = 0;\n private readonly minAdRequestIntervalMs: number = 2500;\n private readonly backoffBaseMs: number = 1000;\n private readonly maxBackoffMs: number = 15000;\n private placeholderContainer: HTMLDivElement | undefined;\n\n private preloadPool: Array<{\n vastUrl: string;\n imaController: ImaController;\n loadedAt: number;\n isReady: boolean;\n loadPromise: Promise<void>;\n }> = [];\n private readonly maxPreloadPoolSize: number = 3;\n private preloadPoolActive: boolean = false;\n private preloadPoolLoopRunning: boolean = false;\n\n constructor(config: StormcloudVideoPlayerConfig) {\n initializePolyfills();\n\n const browserOverrides = getBrowserConfigOverrides();\n \n this.config = { ...browserOverrides, ...config };\n this.video = config.videoElement;\n\n logBrowserInfo(config.debugAdTiming);\n\n this.ima = this.createAdPlayer(false);\n }\n\n private createAdPlayer(continueLiveStreamDuringAds: boolean): ImaController {\n const vastMode = this.config.vastMode || \"default\";\n let adPlayerType =\n this.config.adPlayerType || (vastMode === \"adstorm\" ? \"hls\" : \"ima\");\n\n if (adPlayerType === \"ima\" && !supportsGoogleIMA()) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Google IMA SDK not supported on this browser, falling back to HLS ad player\"\n );\n }\n adPlayerType = \"hls\";\n }\n\n if (adPlayerType === \"prebid\") {\n if (!this.config.prebid) {\n console.warn(\n \"[StormcloudVideoPlayer] adPlayerType is 'prebid' but no prebid config provided, falling back to HLS ad player\"\n );\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...(this.config.licenseKey\n ? { licenseKey: this.config.licenseKey }\n : {}),\n ...(this.hls ? { mainHlsInstance: this.hls } : {}),\n });\n }\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Prebid ad controller (standalone, no IMA SDK)\"\n );\n }\n return createPrebidController(this.video, this.config.prebid, {\n continueLiveStreamDuringAds,\n ...(this.config.licenseKey\n ? { licenseKey: this.config.licenseKey }\n : {}),\n ...(this.hls ? { mainHlsInstance: this.hls } : {}),\n });\n }\n\n if (adPlayerType === \"hls\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)\"\n );\n }\n return createHlsAdPlayer(this.video, {\n continueLiveStreamDuringAds,\n ...(this.config.licenseKey\n ? { licenseKey: this.config.licenseKey }\n : {}),\n ...(this.hls ? { mainHlsInstance: this.hls } : {}),\n });\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Creating Google IMA ad player (IMA mode)\"\n );\n }\n return createImaController(this.video, {\n continueLiveStreamDuringAds,\n });\n }\n }\n\n async load(): Promise<void> {\n if (!this.attached) {\n this.attach();\n }\n\n try {\n await this.fetchAdConfiguration();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to fetch ad configuration:\",\n error\n );\n }\n }\n\n this.initializeTracking();\n\n if (this.shouldUseNativeHls()) {\n this.nativeHlsMode = true;\n this.videoSrcProtection = this.config.src;\n this.video.src = this.config.src;\n\n this.isLiveStream = this.config.lowLatencyMode ?? false;\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:\",\n {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior: \"vod (main video pauses during ads)\",\n }\n );\n }\n\n this.ima.destroy();\n this.ima = this.createAdPlayer(false);\n this.ima.initialize();\n\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n return;\n }\n\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 if (this.config.allowNativeHls === false) {\n this.isLiveStream = true;\n } else {\n this.isLiveStream =\n this.hls?.levels?.some(\n (level) =>\n level?.details?.live === true || level?.details?.type === \"LIVE\"\n ) ?? false;\n }\n\n if (this.config.debugAdTiming) {\n const adBehavior = this.shouldContinueLiveStreamDuringAds()\n ? \"live (main video continues muted during ads)\"\n : \"vod (main video pauses during ads)\";\n console.log(\"[StormcloudVideoPlayer] Stream type detected:\", {\n isLive: this.isLiveStream,\n allowNativeHls: this.config.allowNativeHls,\n adBehavior,\n });\n }\n\n this.ima.destroy();\n this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());\n this.ima.initialize();\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.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Waiting for\",\n minSegments,\n \"segments to buffer before playback\"\n );\n }\n\n if (minSegments === 0 || !this.config.autoplay) {\n this.hasInitialBufferCompleted = true;\n if (this.config.autoplay) {\n await this.video.play()?.catch(() => {});\n }\n }\n });\n\n this.hls.on(Hls.Events.LEVEL_LOADED, (_evt, data: any) => {\n if (this.inAdBreak || this.pendingAdBreak) {\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 ? this.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 = this.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.config.debugAdTiming) {\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.startAdPrefetch(marker, frag?.sn);\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.config.debugAdTiming) {\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.config.debugAdTiming) {\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.config.debugAdTiming) {\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_CHANGED, (_evt, data: any) => {\n const frag = data?.frag;\n const tagList: any[] | undefined = frag?.tagList;\n if (!Array.isArray(tagList)) 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\n if (!tag) continue;\n if (tag.includes(\"EXT-X-CUE-OUT-CONT\")) {\n const prog = this.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.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-OUT\")) {\n const durationSeconds = this.parseCueOutDuration(value);\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { tag, value },\n } as Scte35Marker;\n this.onScte35Marker(marker);\n } else if (tag.includes(\"EXT-X-CUE-IN\")) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value } });\n } else if (tag.includes(\"EXT-X-DATERANGE\")) {\n const attrs = this.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 = this.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.onScte35Marker(marker);\n }\n if (hasScteIn) {\n this.onScte35Marker({ type: \"end\", raw: { tag, value, attrs } });\n }\n }\n }\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.destroy();\n break;\n }\n }\n });\n\n this.hls.attachMedia(this.video);\n }\n\n private attachImaEventListeners(): void {\n this.ima.on(\"all_ads_completed\", () => {\n const remaining = this.getRemainingAdMs();\n \n this.consecutiveFailures = 0;\n \n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] IMA 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 (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n this.handleAdPodComplete();\n }\n }\n });\n this.ima.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 this.ima.on(\"content_pause\", () => {\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = true;\n \n if (this.inAdBreak && this.expectedAdBreakDurationMs != null) {\n if (this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Starting ad break timer on content_pause (first ad starting)\");\n }\n }\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n if (this.isShowingPlaceholder) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder - new ads starting\");\n }\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n });\n this.ima.on(\"content_resume\", () => {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on content_resume (ad ended, gap between ads)\");\n }\n }\n\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.activeAdRequestToken = null;\n this.showAds = false;\n\n if (!this.inAdBreak) {\n return;\n }\n\n this.consecutiveFailures = 0;\n\n const remaining = this.getRemainingAdMs();\n \n if (this.config.debugAdTiming) {\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 (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n this.handleAdPodComplete();\n }\n });\n }\n\n private recreateImaController(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Recreating ImaController for new ad\");\n }\n\n const shouldShowPlaceholder = this.inAdBreak && this.showAds;\n if (shouldShowPlaceholder && this.ima) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder before destroying old ImaController\");\n }\n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n this.isShowingPlaceholder = true;\n }\n\n if (this.ima) {\n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Error destroying old ImaController:\", error);\n }\n }\n }\n\n const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n this.ima = this.createAdPlayer(continueLiveStreamDuringAds);\n \n this.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachImaEventListeners();\n\n if (shouldShowPlaceholder) {\n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n this.isShowingPlaceholder = true;\n }\n }\n\n private ensurePlaceholderContainer(): void {\n if (this.placeholderContainer) {\n return;\n }\n\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 = \"5\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n if (!this.video.parentElement) {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] Video element has no parent for placeholder container\");\n }\n return;\n }\n\n this.video.parentElement.appendChild(container);\n this.placeholderContainer = container;\n }\n\n private showPlaceholderLayer(): void {\n this.ensurePlaceholderContainer();\n \n if (!this.placeholderContainer) {\n return;\n }\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video when showing placeholder\");\n }\n }\n\n const wasHidden = this.placeholderContainer.style.display === \"none\" || this.placeholderContainer.style.opacity === \"0\";\n if (wasHidden) {\n this.placeholderContainer.style.transition = \"none\";\n } else {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n \n this.placeholderContainer.style.backgroundColor = \"#000\";\n this.placeholderContainer.style.display = \"flex\";\n this.placeholderContainer.offsetHeight;\n this.placeholderContainer.style.opacity = \"1\";\n this.placeholderContainer.style.pointerEvents = \"auto\";\n \n if (wasHidden) {\n requestAnimationFrame(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Showing placeholder layer (between content and IMA)\");\n }\n }\n\n private hidePlaceholderLayer(): void {\n if (!this.placeholderContainer) {\n return;\n }\n\n this.placeholderContainer.style.opacity = \"0\";\n setTimeout(() => {\n if (this.placeholderContainer) {\n this.placeholderContainer.style.display = \"none\";\n this.placeholderContainer.style.pointerEvents = \"none\";\n this.placeholderContainer.style.backgroundColor = \"#000\";\n }\n }, 300);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Hiding placeholder layer\");\n }\n }\n\n private attach(): void {\n if (this.attached) return;\n this.attached = true;\n this.video.autoplay = !!this.config.autoplay;\n this.video.muted = !!this.config.muted;\n\n this.ima.initialize();\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n this.attachImaEventListeners();\n\n this.timeUpdateHandler = () => {\n this.onTimeUpdate(this.video.currentTime);\n };\n this.video.addEventListener(\"timeupdate\", this.timeUpdateHandler);\n\n this.emptiedHandler = () => {\n if (\n this.nativeHlsMode &&\n this.videoSrcProtection &&\n !this.ima.isAdPlaying()\n ) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Video src was cleared, restoring:\",\n this.videoSrcProtection\n );\n }\n const currentTime = this.video.currentTime;\n const wasPaused = this.video.paused;\n this.video.src = this.videoSrcProtection;\n this.video.currentTime = currentTime;\n if (!wasPaused) {\n this.video.play().catch(() => {});\n }\n }\n };\n this.video.addEventListener(\"emptied\", this.emptiedHandler);\n }\n\n private shouldUseNativeHls(): boolean {\n const streamType = this.getStreamType();\n\n if (streamType === \"other\") {\n return true;\n }\n\n const canNative = this.video.canPlayType(\"application/vnd.apple.mpegurl\");\n return !!(this.config.allowNativeHls && canNative);\n }\n\n private onId3Tag(tag: Id3TagInfo): void {\n if (typeof tag.ptsSeconds === \"number\") {\n this.updatePtsDrift(tag.ptsSeconds);\n }\n const marker = this.parseScte35FromId3(tag);\n if (marker) {\n this.onScte35Marker(marker);\n }\n }\n\n private parseScte35FromId3(tag: Id3TagInfo): Scte35Marker | undefined {\n const text = this.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 = this.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 = this.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 = this.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 = this.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 = this.parseScte35Binary(tag.value);\n if (bin) return bin;\n }\n\n return undefined;\n }\n\n private 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\n private onScte35Marker(marker: Scte35Marker): void {\n if (this.config.debugAdTiming) {\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.pendingAdBreak,\n });\n }\n\n if (marker.type === \"start\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE start marker\");\n }\n }\n\n if (this.inAdBreak) {\n if (this.expectedAdBreakDurationMs == null && marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n if (this.config.debugAdTiming) {\n console.log(`[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ${this.expectedAdBreakDurationMs}ms`);\n }\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n\n const hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;\n\n this.inAdBreak = true;\n const durationMs =\n marker.durationSeconds != null\n ? marker.durationSeconds * 1000\n : (this.pendingAdBreak?.marker.durationSeconds != null \n ? this.pendingAdBreak.marker.durationSeconds * 1000 \n : undefined);\n this.expectedAdBreakDurationMs = durationMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n\n const isManifestMarker = this.isManifestBasedMarker(marker);\n const forceImmediate = this.config.immediateManifestAds ?? true;\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ad start decision:\", {\n isManifestMarker,\n forceImmediate,\n hasPts: typeof marker.ptsSeconds === \"number\",\n hasPrefetchedAds,\n });\n }\n\n if (isManifestMarker && forceImmediate) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Starting ad immediately (manifest-based)${hasPrefetchedAds ? \" with prefetched ads\" : \"\"}`\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n } else if (typeof marker.ptsSeconds === \"number\") {\n const tol = this.config.driftToleranceMs ?? 1000;\n const nowMs = this.video.currentTime * 1000;\n const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;\n const deltaMs = Math.floor(marker.ptsSeconds * 1000 - estCurrentPtsMs);\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] PTS-based timing calculation:\", {\n nowMs,\n estCurrentPtsMs,\n markerPtsMs: marker.ptsSeconds * 1000,\n deltaMs,\n tolerance: tol,\n });\n }\n\n if (deltaMs > tol) {\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Scheduling ad start in ${deltaMs}ms`\n );\n }\n this.scheduleAdStartIn(deltaMs);\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (within tolerance)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n } else {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Starting ad immediately (fallback)\"\n );\n }\n this.clearAdStartTimer();\n this.handleAdStart(marker);\n }\n if (this.expectedAdBreakDurationMs != null) {\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n return;\n }\n if (marker.type === \"progress\" && this.inAdBreak) {\n if (marker.durationSeconds != null) {\n this.expectedAdBreakDurationMs = marker.durationSeconds * 1000;\n }\n if (\n this.expectedAdBreakDurationMs != null &&\n this.currentAdBreakStartWallClockMs != null\n ) {\n const elapsedMs = Date.now() - this.currentAdBreakStartWallClockMs;\n const remainingMs = Math.max(\n 0,\n this.expectedAdBreakDurationMs - elapsedMs\n );\n this.scheduleAdStopCountdown(remainingMs);\n }\n \n if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null && this.adRequestQueue.length > 0) {\n this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n if (marker.type === \"end\") {\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video on SCTE end marker\");\n }\n }\n\n const remaining = this.getRemainingAdMs();\n const adPlaying = this.ima.isAdPlaying();\n const hasQueuedAds = this.adRequestQueue.length > 0;\n \n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] SCTE-35 end marker received:\", {\n remaining,\n adPlaying,\n hasQueuedAds,\n activeAdRequest: this.activeAdRequestToken !== null,\n });\n }\n \n if (adPlaying || (remaining > 1000 && hasQueuedAds)) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active\");\n }\n return;\n }\n \n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n \n if (adPlaying) {\n this.ima.stop().catch(() => {});\n }\n \n this.handleAdPodComplete();\n return;\n }\n }\n\n private 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\n private 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\n private 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\n private 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\n private 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\n private parseScte35Binary(data: Uint8Array): Scte35Marker | undefined {\n class 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 }\n\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 r.readBits(8);\n r.readBits(1);\n r.readBits(6);\n const ptsAdjHigh = r.readBits(1);\n const ptsAdjLow = r.readBits(32);\n void ptsAdjHigh;\n void ptsAdjLow;\n r.readBits(8);\n r.readBits(12);\n const spliceCommandLength = r.readBits(12);\n const spliceCommandType = r.readBits(8);\n if (spliceCommandType !== 5) {\n return undefined;\n }\n 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 if (programSpliceFlag && !spliceImmediateFlag) {\n const timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\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 timeSpecifiedFlag = r.readBits(1) === 1;\n if (timeSpecifiedFlag) {\n r.readBits(6);\n r.readBits(33);\n } else {\n r.readBits(7);\n }\n }\n }\n }\n let durationSeconds: number | undefined = undefined;\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\n if (outOfNetwork) {\n const marker: Scte35Marker = {\n type: \"start\",\n ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n raw: { splice_command_type: 5 },\n } as Scte35Marker;\n return marker;\n }\n return undefined;\n }\n\n private initializeTracking(): void {\n sendInitialTracking(this.config.licenseKey)\n .then(() => {\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n })\n .catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send initial tracking:\",\n error\n );\n }\n this.heartbeatInterval = window.setInterval(() => {\n this.sendHeartbeatIfNeeded();\n }, 5000);\n });\n }\n\n private sendHeartbeatIfNeeded(): void {\n const now = Date.now();\n if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 30000) {\n this.lastHeartbeatTime = now;\n sendHeartbeat(this.config.licenseKey).catch((error) => {\n if (this.config.debugAdTiming) {\n console.warn(\n \"[StormcloudVideoPlayer] Failed to send heartbeat:\",\n error\n );\n }\n });\n }\n }\n\n private async fetchAdConfiguration(): Promise<void> {\n if (this.config.adPlayerType === \"prebid\") {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Prebid mode: VAST URLs sourced from Prebid Server auctions\"\n );\n }\n return;\n }\n\n const vastMode = this.config.vastMode || \"default\";\n\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] VAST mode:\", vastMode);\n }\n\n if (vastMode === \"adstorm\") {\n if (!this.config.licenseKey) {\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\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 = this.config.vastTagUrl;\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.warn(\n `[StormcloudVideoPlayer] Failed to fetch ad configuration: ${response.status}`\n );\n }\n return;\n }\n\n const data: StormcloudApiResponse = await response.json();\n\n const imaPayload = data.response?.ima?.[\"publisherdesk.ima\"]?.payload;\n if (imaPayload) {\n this.apiVastTagUrl = decodeURIComponent(imaPayload);\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Extracted VAST tag URL from /ads/web:\",\n this.apiVastTagUrl\n );\n }\n } else {\n if (this.config.debugAdTiming) {\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.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Number of ads per break from API:\",\n this.apiNumberAds\n );\n }\n }\n }\n\n private isPrebidMode(): boolean {\n return this.config.adPlayerType === \"prebid\";\n }\n\n getCurrentAdIndex(): number {\n return this.currentAdIndex;\n }\n\n getTotalAdsInBreak(): number {\n return this.totalAdsInBreak;\n }\n\n private generateVastUrlsWithCorrelators(\n baseUrl: string,\n count: number\n ): string[] {\n const urls: string[] = [];\n const baseTimestamp = Date.now();\n \n for (let i = 0; i < count; i++) {\n const timestamp = baseTimestamp + i;\n const random = Math.floor(Math.random() * 1000000000000);\n const uniqueCorrelator = `${timestamp}_${random}_${i}`;\n \n let urlWithCorrelator: string;\n \n const correlatorRegex = /([?&])correlator=([^&]*)/;\n if (correlatorRegex.test(baseUrl)) {\n urlWithCorrelator = baseUrl.replace(correlatorRegex, `$1correlator=${uniqueCorrelator}`);\n } else if (baseUrl.includes(\"?\")) {\n urlWithCorrelator = `${baseUrl}&correlator=${uniqueCorrelator}`;\n } else {\n urlWithCorrelator = `${baseUrl}?correlator=${uniqueCorrelator}`;\n }\n \n urls.push(urlWithCorrelator);\n }\n \n return urls;\n }\n\n isAdPlaying(): boolean {\n return this.inAdBreak && this.ima.isAdPlaying();\n }\n\n isShowingAds(): boolean {\n return this.showAds;\n }\n\n getStreamType(): \"hls\" | \"other\" {\n const url = this.config.src.toLowerCase();\n if (\n url.includes(\".m3u8\") ||\n url.includes(\"/hls/\") ||\n url.includes(\"application/vnd.apple.mpegurl\")\n ) {\n return \"hls\";\n }\n return \"other\";\n }\n\n shouldShowNativeControls(): boolean {\n const streamType = this.getStreamType();\n if (streamType === \"other\") {\n return !(this.config.showCustomControls ?? false);\n }\n return !!(\n this.config.allowNativeHls && !(this.config.showCustomControls ?? false)\n );\n }\n\n private shouldContinueLiveStreamDuringAds(): boolean {\n if (this.config.allowNativeHls) {\n return false;\n }\n\n if (!this.isLiveStream) {\n return false;\n }\n\n return true;\n }\n\n private startAdPrefetch(marker: Scte35Marker, fragmentSn?: number): void {\n if (this.pendingAdBreak || this.inAdBreak) {\n return;\n }\n\n if (this.isPrebidMode()) {\n this.pendingAdBreak = {\n marker,\n ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n vastUrls: [],\n isFetching: false,\n fetchStartTime: Date.now(),\n };\n\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] Prebid mode: ad break marker registered, auction runs at playback time via controller\");\n }\n return;\n }\n\n const scheduled = this.findCurrentOrNextBreak(this.video.currentTime * 1000);\n const tags = this.selectVastTagsForBreak(scheduled);\n\n let baseVastUrl: string;\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n } else {\n if (this.config.debugAdTiming) {\n console.warn(\"[StormcloudVideoPlayer] No VAST URL available for prefetch\");\n }\n return;\n }\n\n const urlsToPregenerate = 5;\n const generatedUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, urlsToPregenerate);\n\n this.pendingAdBreak = {\n marker,\n ...(fragmentSn !== undefined ? { detectedAtFragmentSn: fragmentSn } : {}),\n vastUrls: generatedUrls,\n isFetching: false,\n fetchStartTime: Date.now(),\n };\n\n if (this.config.debugAdTiming) {\n console.log(\"[PREFETCH] 🔄 Starting ad prefetch for upcoming ad break\");\n console.log(`[PREFETCH] 📋 Pre-generated ${generatedUrls.length} VAST URLs`);\n }\n\n this.startPreloadPool(baseVastUrl, generatedUrls.slice(0, this.maxPreloadPoolSize));\n }\n\n private clearPendingAdBreak(): void {\n if (this.prefetchTimerId != null) {\n clearTimeout(this.prefetchTimerId);\n this.prefetchTimerId = undefined;\n }\n this.pendingAdBreak = null;\n }\n\n private startPreloadPool(baseVastUrl: string, initialUrls: string[]): void {\n if (this.preloadPoolActive) {\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] Already active, skipping duplicate start\");\n }\n return;\n }\n\n this.preloadPoolActive = true;\n \n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] 🏊 Starting preload pool EARLY (target size: ${this.maxPreloadPoolSize})`);\n console.log(`[PRELOAD-POOL] Ad break hasn't started yet, but preloading ads in advance`);\n }\n\n for (const url of initialUrls) {\n if (this.preloadPool.length < this.maxPreloadPoolSize) {\n this.preloadAdIntoPool(url);\n }\n }\n\n this.preloadPoolLoop(baseVastUrl);\n }\n\n private async preloadAdIntoPool(vastUrl: string): Promise<void> {\n if (\n this.preloadPool.some(entry => entry.vastUrl === vastUrl) ||\n this.failedVastUrls.has(vastUrl) ||\n this.isUrlInCooldown(vastUrl)\n ) {\n return;\n }\n\n if (this.preloadPool.length >= this.maxPreloadPoolSize) {\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] 📥 Preloading ad into pool: ${vastUrl}`);\n }\n\n const loadPromise = (async () => {\n let hasAdError = false;\n let adErrorPayload: any = null;\n let errorListenerCleanup: (() => void) | null = null;\n \n try {\n const continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();\n const preloadIma = this.createAdPlayer(continueLiveStreamDuringAds);\n preloadIma.initialize();\n \n const errorListener = (payload?: any) => {\n hasAdError = true;\n adErrorPayload = payload;\n };\n preloadIma.on(\"ad_error\", errorListener);\n errorListenerCleanup = () => preloadIma.off(\"ad_error\", errorListener);\n \n await preloadIma.requestAds(vastUrl);\n \n preloadIma.pause();\n \n await new Promise(resolve => setTimeout(resolve, 1500));\n \n preloadIma.pause();\n \n if (hasAdError) {\n const isNoFill = adErrorPayload?.isNoFill || \n adErrorPayload?.code === 303 || \n adErrorPayload?.vastErrorCode === 303;\n \n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n preloadIma.destroy();\n \n if (isNoFill) {\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] ⚠️ Ad preload returned no-fill: ${vastUrl}`);\n }\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n } else {\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] ⚠️ Ad preload failed with error: ${vastUrl}`, adErrorPayload);\n }\n if (adErrorPayload && !this.isTemporaryAdError(adErrorPayload as Error)) {\n this.failedVastUrls.add(vastUrl);\n } else {\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n }\n }\n return;\n }\n \n const poolEntry = {\n vastUrl,\n imaController: preloadIma,\n loadedAt: Date.now(),\n isReady: true,\n loadPromise: Promise.resolve(),\n };\n \n const lateErrorListener = (payload?: any) => {\n const index = this.preloadPool.findIndex(entry => entry.vastUrl === vastUrl);\n if (index >= 0) {\n this.preloadPool.splice(index, 1);\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] ⚠️ Late error detected, removed from pool: ${vastUrl}`, payload);\n }\n try {\n preloadIma.destroy();\n } catch {}\n }\n };\n preloadIma.on(\"ad_error\", lateErrorListener);\n \n this.preloadPool.push(poolEntry);\n \n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] ✅ Ad preloaded (no errors detected within timeout) (pool size: ${this.preloadPool.length}/${this.maxPreloadPoolSize})`);\n }\n \n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n } catch (error) {\n if (errorListenerCleanup) {\n errorListenerCleanup();\n }\n \n if (this.config.debugAdTiming) {\n console.warn(`[PRELOAD-POOL] ⚠️ Failed to preload ad: ${vastUrl}`, error);\n }\n \n if (error instanceof Error && !this.isTemporaryAdError(error)) {\n this.failedVastUrls.add(vastUrl);\n } else if (error instanceof Error && this.isTemporaryAdError(error)) {\n this.temporaryFailureUrls.set(vastUrl, Date.now());\n }\n }\n })();\n\n loadPromise.catch(() => {});\n }\n\n private async preloadPoolLoop(baseVastUrl: string): Promise<void> {\n if (this.preloadPoolLoopRunning) {\n return;\n }\n\n this.preloadPoolLoopRunning = true;\n\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] 🔄 Starting continuous preload loop\");\n }\n\n while (this.preloadPoolActive) {\n if (!this.inAdBreak && this.preloadPool.length >= this.maxPreloadPoolSize) {\n await new Promise(resolve => setTimeout(resolve, 2000));\n continue;\n }\n\n if (!this.inAdBreak && this.pendingAdBreak === null) {\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] Ad break cancelled, stopping preload pool\");\n }\n break;\n }\n\n while (this.preloadPool.length < this.maxPreloadPoolSize) {\n if (!this.preloadPoolActive) {\n break;\n }\n\n if (this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n if (remaining <= 0) {\n break;\n }\n }\n\n const newUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, 1);\n const newUrl = newUrls[0];\n \n if (newUrl && !this.failedVastUrls.has(newUrl) && !this.isUrlInCooldown(newUrl)) {\n await this.preloadAdIntoPool(newUrl);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n\n this.preloadPoolLoopRunning = false;\n\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] 🛑 Preload loop ended\");\n }\n }\n\n private getPreloadedAd(): { vastUrl: string; imaController: ImaController } | null {\n if (this.preloadPool.length === 0) {\n return null;\n }\n\n const entry = this.preloadPool.shift();\n if (!entry || !entry.isReady) {\n return null;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[PRELOAD-POOL] 🎯 Using preloaded ad from pool (${this.preloadPool.length} remaining)`);\n }\n\n return {\n vastUrl: entry.vastUrl,\n imaController: entry.imaController,\n };\n }\n\n private stopPreloadPool(): void {\n this.preloadPoolActive = false;\n this.preloadPoolLoopRunning = false;\n\n for (const entry of this.preloadPool) {\n try {\n entry.imaController.destroy();\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[PRELOAD-POOL] Error destroying preloaded controller:\", error);\n }\n }\n }\n\n this.preloadPool = [];\n\n if (this.config.debugAdTiming) {\n console.log(\"[PRELOAD-POOL] 🛑 Preload pool stopped and cleaned up\");\n }\n }\n\n private async handleAdStart(_marker: Scte35Marker): Promise<void> {\n const scheduled = this.findCurrentOrNextBreak(\n this.video.currentTime * 1000\n );\n const tags = this.selectVastTagsForBreak(scheduled);\n const isPrebid = this.isPrebidMode();\n\n let baseVastUrl: string | undefined;\n if (this.apiVastTagUrl) {\n baseVastUrl = this.apiVastTagUrl;\n } else if (tags && tags.length > 0 && tags[0]) {\n baseVastUrl = tags[0];\n }\n\n if (!isPrebid && !baseVastUrl) {\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.config.debugAdTiming) {\n const mode = this.isLiveStream ? \"LIVE\" : \"VOD\";\n console.log(\n `[CONTINUOUS-FETCH] 📺 ${mode} MODE: Target duration=${adBreakDurationMs}ms`\n );\n }\n\n this.failedVastUrls.clear();\n this.temporaryFailureUrls.clear();\n this.consecutiveFailures = 0;\n this.continuousFetchingActive = true;\n this.isShowingPlaceholder = false;\n this.totalAdRequestsInBreak = 0;\n\n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n\n if (!this.video.muted) {\n this.video.muted = true;\n this.video.volume = 0;\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted video in handleAdStart\");\n }\n }\n\n this.inAdBreak = true;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 1;\n this.adPodQueue = [];\n \n this.showAds = true;\n \n this.showPlaceholderLayer();\n this.ima.showPlaceholder();\n\n if (\n this.expectedAdBreakDurationMs == null &&\n adBreakDurationMs != null\n ) {\n this.expectedAdBreakDurationMs = adBreakDurationMs;\n }\n\n let firstAdUrl: string | undefined;\n let usePreloadedAd = false;\n let preloadedController: ImaController | undefined;\n\n if (isPrebid) {\n firstAdUrl = \"\";\n this.clearPendingAdBreak();\n\n if (this.config.debugAdTiming) {\n console.log(\"[Prebid] Controller will run auction internally via requestAds()\");\n }\n } else {\n const preloaded = this.getPreloadedAd();\n if (preloaded) {\n firstAdUrl = preloaded.vastUrl;\n preloadedController = preloaded.imaController;\n usePreloadedAd = true;\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🚀 Using preloaded ad from pool (preloaded in advance, ready immediately!)\");\n console.log(`[CONTINUOUS-FETCH] Pool still has ${this.preloadPool.length} preloaded ads ready`);\n }\n } else if (this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0) {\n this.adRequestQueue = [...this.pendingAdBreak.vastUrls];\n firstAdUrl = this.adRequestQueue.shift();\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⚠️ Pool empty, using prefetched URLs (${this.adRequestQueue.length + 1} available)`);\n }\n\n this.clearPendingAdBreak();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🚀 Generating new ad URLs...\");\n }\n\n const firstAdUrlArray = this.generateVastUrlsWithCorrelators(baseVastUrl!, 1);\n firstAdUrl = firstAdUrlArray[0];\n this.adRequestQueue = [];\n }\n }\n \n if (firstAdUrl == null) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ Failed to get first ad URL\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 📋 First VAST URL:\", firstAdUrl || \"(Prebid auction)\");\n }\n\n try {\n if (usePreloadedAd && preloadedController) {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedController;\n \n this.attachImaEventListeners();\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ Using preloaded ad, resuming and starting playback immediately (no request delay!)\");\n }\n \n this.ima.resume();\n \n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n \n if (!isPrebid && baseVastUrl && !this.preloadPoolActive) {\n this.preloadPoolActive = true;\n this.preloadPoolLoop(baseVastUrl);\n }\n \n await this.ima.play();\n\n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n } else {\n this.lastAdRequestTime = Date.now();\n await this.ima.requestAds(firstAdUrl);\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ First ad request successful, starting playback\");\n }\n\n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n \n if (!isPrebid && baseVastUrl && !this.preloadPoolActive) {\n this.startPreloadPool(baseVastUrl, []);\n }\n \n await this.ima.play();\n \n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n \n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n }\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ First ad request failed:\", error);\n }\n \n if (!isPrebid && !usePreloadedAd) {\n const fallbackPreloaded = this.getPreloadedAd();\n if (fallbackPreloaded) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🔄 First ad failed, using preloaded fallback\");\n }\n \n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = fallbackPreloaded.imaController;\n this.attachImaEventListeners();\n \n this.ima.resume();\n \n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.startContinuousFetching(baseVastUrl);\n \n if (baseVastUrl && !this.preloadPoolActive) {\n this.preloadPoolActive = true;\n this.preloadPoolLoop(baseVastUrl);\n }\n \n await this.ima.play();\n \n if (this.expectedAdBreakDurationMs != null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n \n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n return; \n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n }\n \n if (this.isTemporaryAdError(error as Error)) {\n this.temporaryFailureUrls.set(firstAdUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] First ad had temporary error (no-fill) - will try alternatives\");\n }\n } else {\n this.failedVastUrls.add(firstAdUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] First ad had permanent error - URL blacklisted\");\n }\n }\n this.consecutiveFailures++;\n \n this.startContinuousFetching(baseVastUrl);\n await this.tryNextAvailableAdWithRateLimit();\n }\n }\n\n private continuousFetchLoopRunning = false;\n\n private startContinuousFetching(baseVastUrl?: string): void {\n if (!this.continuousFetchingActive) {\n return;\n }\n\n if (this.continuousFetchLoopRunning) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏭️ Fetch loop already running, skipping duplicate start\");\n }\n return;\n }\n\n if (this.config.debugAdTiming) {\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 while (this.continuousFetchingActive && this.inAdBreak) {\n const remaining = this.getRemainingAdMs();\n \n if (remaining <= 0) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ Ad break time expired, stopping URL generation\");\n }\n break;\n }\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), stopping URL generation`);\n }\n break;\n }\n\n if (this.totalAdRequestsInBreak >= this.maxTotalAdRequestsPerBreak) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Maximum ad requests reached (${this.maxTotalAdRequestsPerBreak}), stopping`);\n }\n break;\n }\n\n const maxQueueSize = 5;\n if (this.adRequestQueue.length >= maxQueueSize) {\n if (this.config.debugAdTiming) {\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 if (this.isPrebidMode()) {\n this.adRequestQueue.push(\"\");\n this.totalAdsInBreak++;\n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Prebid auction slot queued (queue: ${this.adRequestQueue.length})`\n );\n }\n } else if (baseVastUrl) {\n const newAdUrl = this.generateVastUrlsWithCorrelators(baseVastUrl, 1)[0];\n\n if (!newAdUrl || this.failedVastUrls.has(newAdUrl) || this.isUrlInCooldown(newAdUrl)) {\n await new Promise(resolve => setTimeout(resolve, 500));\n continue;\n }\n\n if (this.config.debugAdTiming) {\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 this.totalAdsInBreak++;\n }\n \n const generationDelay = this.consecutiveFailures > 0 \n ? Math.min(1000 * Math.pow(2, this.consecutiveFailures), 5000)\n : 500;\n await new Promise(resolve => setTimeout(resolve, generationDelay));\n }\n\n this.continuousFetchLoopRunning = false;\n\n if (this.config.debugAdTiming) {\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 private stopContinuousFetching(): void {\n this.continuousFetchingActive = false;\n this.continuousFetchLoopRunning = false;\n \n this.hidePlaceholderLayer();\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Stopping continuous ad fetching\");\n }\n }\n\n private async tryNextAvailableAdWithRateLimit(): Promise<void> {\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n const backoffMultiplier = Math.pow(2, this.consecutiveFailures);\n const backoffDelay = Math.min(this.backoffBaseMs * backoffMultiplier, this.maxBackoffMs);\n const effectiveMinInterval = this.minAdRequestIntervalMs + (this.consecutiveFailures > 0 ? backoffDelay : 0);\n \n const timeSinceLastRequest = Date.now() - this.lastAdRequestTime;\n if (timeSinceLastRequest < effectiveMinInterval) {\n const waitTime = effectiveMinInterval - timeSinceLastRequest;\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏳ Rate limiting: waiting ${waitTime}ms before next request (backoff: ${this.consecutiveFailures} failures)`);\n }\n await new Promise(resolve => setTimeout(resolve, waitTime));\n }\n\n return this.tryNextAvailableAd(0);\n }\n\n private async tryNextAvailableAd(retryCount: number = 0): Promise<void> {\n const remaining = this.getRemainingAdMs();\n \n if (remaining <= 500) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ No time remaining, ending ad break\");\n }\n this.handleAdPodComplete();\n return;\n }\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Too many consecutive failures (${this.consecutiveFailures}), ending ad break`);\n }\n this.handleAdPodComplete();\n return;\n }\n\n this.cleanupTemporaryFailures();\n\n const preloaded = this.getPreloadedAd();\n if (preloaded) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🎯 Using preloaded ad from pool (${this.preloadPool.length} remaining in pool)`);\n }\n \n try {\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloaded.imaController;\n this.attachImaEventListeners();\n \n this.ima.resume();\n \n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n \n await this.ima.play();\n \n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n this.consecutiveFailures = 0;\n return;\n } catch (error) {\n if (this.config.debugAdTiming) {\n console.warn(\"[CONTINUOUS-FETCH] ⚠️ Preloaded ad failed to play:\", error);\n }\n }\n }\n\n while (this.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n \n if (!nextAdUrl) {\n continue;\n }\n \n if (this.failedVastUrls.has(nextAdUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏭️ Skipping permanently-failed URL, trying next...\");\n }\n continue;\n }\n \n if (this.isUrlInCooldown(nextAdUrl)) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏭️ Skipping URL in cooldown (recent no-fill), trying next...\");\n }\n continue;\n }\n \n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🎬 Requesting next ad via IMA SDK (${this.currentAdIndex + 1}/${this.totalAdsInBreak}, ${this.adRequestQueue.length} remaining in queue)`);\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n \n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n \n try {\n await this.playSingleAd(nextAdUrl);\n this.consecutiveFailures = 0;\n } catch (error) {\n const errorMessage = (error as Error).message;\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ❌ Ad request failed:\", errorMessage);\n }\n \n if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n this.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.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⏳ Queue empty, waiting for URLs... (${retryCount + 1}/${maxRetries})`);\n }\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.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏹️ No more ads available, ending ad break\");\n }\n this.handleAdPodComplete();\n }\n }\n\n private async showPlaceholderAndWaitForAds(): Promise<void> {\n const remaining = this.getRemainingAdMs();\n const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);\n \n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Skipping placeholder - too many consecutive failures\");\n }\n this.handleAdPodComplete();\n return;\n }\n \n if (waitTime < 1000) {\n this.handleAdPodComplete();\n return;\n }\n\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] ⬛ Showing placeholder for ${waitTime}ms while waiting for ad URLs`);\n }\n\n this.isShowingPlaceholder = true;\n \n this.ima.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) {\n return;\n }\n \n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] 🛑 Too many failures during placeholder wait\");\n }\n break;\n }\n\n while (this.adRequestQueue.length > 0) {\n const nextAdUrl = this.adRequestQueue.shift();\n \n if (!nextAdUrl) {\n continue;\n }\n \n if (this.failedVastUrls.has(nextAdUrl)) {\n continue;\n }\n \n if (this.isUrlInCooldown(nextAdUrl)) {\n continue;\n }\n \n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ✅ Ad URL available, requesting via IMA SDK\");\n }\n \n this.isShowingPlaceholder = false;\n this.ima.hidePlaceholder();\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n this.ima.updateOriginalMutedState(currentMuted, currentVolume);\n \n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n this.lastAdRequestTime = Date.now();\n \n try {\n await this.playSingleAd(nextAdUrl);\n this.consecutiveFailures = 0;\n } catch (error) {\n const errorMessage = (error as Error).message;\n if (!errorMessage.includes(\"permanently failed\") && !errorMessage.includes(\"in cooldown\")) {\n this.consecutiveFailures++;\n }\n await this.tryNextAvailableAdWithRateLimit();\n }\n return;\n }\n }\n\n if (this.config.debugAdTiming) {\n console.log(\"[CONTINUOUS-FETCH] ⏰ Placeholder timeout, ending ad break\");\n }\n \n this.isShowingPlaceholder = false;\n this.ima.hidePlaceholder();\n this.handleAdPodComplete();\n }\n\n private findCurrentOrNextBreak(nowMs: number): AdBreak | undefined {\n const schedule: AdBreak[] = [];\n let candidate: AdBreak | undefined;\n for (const b of schedule) {\n const tol = this.config.driftToleranceMs ?? 1000;\n if (\n b.startTimeMs <= nowMs + tol &&\n (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))\n ) {\n candidate = b;\n }\n }\n return candidate;\n }\n\n private onTimeUpdate(currentTimeSec: number): void {\n if (this.ima.isAdPlaying()) return;\n const nowMs = currentTimeSec * 1000;\n const breakToPlay = this.findBreakForTime(nowMs);\n if (breakToPlay) {\n this.handleMidAdJoin(breakToPlay, nowMs);\n }\n }\n\n private async handleMidAdJoin(\n adBreak: AdBreak,\n nowMs: number\n ): Promise<void> {\n const durationMs = adBreak.durationMs ?? 0;\n const endMs = adBreak.startTimeMs + durationMs;\n if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {\n const remainingMs = endMs - nowMs;\n const tags =\n this.selectVastTagsForBreak(adBreak) ||\n (this.apiVastTagUrl ? [this.apiVastTagUrl] : undefined);\n if (tags && tags.length > 0) {\n const first = tags[0] as string;\n const rest = tags.slice(1);\n this.adPodQueue = rest;\n \n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n \n await this.playSingleAd(first);\n this.inAdBreak = true;\n this.expectedAdBreakDurationMs = remainingMs;\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(remainingMs);\n }\n }\n }\n\n private 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 private clearAdStopTimer(): void {\n if (this.adStopTimerId != null) {\n clearTimeout(this.adStopTimerId);\n this.adStopTimerId = undefined;\n }\n }\n\n private ensureAdStoppedByTimer(): void {\n if (!this.inAdBreak) return;\n\n this.adStopTimerId = undefined;\n\n const adPlaying = this.ima.isAdPlaying();\n const pendingAds = this.adPodQueue.length > 0;\n const checkIntervalMs = Math.max(\n 250,\n Math.floor(this.config.adBreakCheckIntervalMs ?? 1000)\n );\n const maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;\n const maxExtensionMs =\n typeof maxExtensionMsConfig === \"number\" && maxExtensionMsConfig > 0\n ? maxExtensionMsConfig\n : 60000;\n\n let elapsedSinceStartMs = 0;\n if (this.currentAdBreakStartWallClockMs != null) {\n elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;\n }\n const expectedDurationMs = this.expectedAdBreakDurationMs ?? 0;\n const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);\n\n const shouldExtendAdBreak =\n (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;\n\n if (shouldExtendAdBreak) {\n this.scheduleAdStopCountdown(checkIntervalMs);\n return;\n }\n\n if (adPlaying) {\n this.ima.stop().catch(() => {});\n }\n\n this.handleAdPodComplete();\n }\n\n private scheduleAdStartIn(delayMs: number): void {\n this.clearAdStartTimer();\n const ms = Math.max(0, Math.floor(delayMs));\n if (ms === 0) {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n return;\n }\n this.adStartTimerId = window.setTimeout(() => {\n this.handleAdStart({ type: \"start\" } as Scte35Marker).catch(() => {});\n }, ms) as unknown as number;\n }\n\n private clearAdStartTimer(): void {\n if (this.adStartTimerId != null) {\n clearTimeout(this.adStartTimerId);\n this.adStartTimerId = undefined;\n }\n }\n\n private 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 private 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 \n if (message.includes(\"timeout\")) {\n return true;\n }\n \n if (message.includes(\"rate limit\") || message.includes(\"too many requests\")) {\n return true;\n }\n \n if (message.includes(\"ad playback error\")) {\n return true;\n }\n \n return false;\n }\n\n private 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 private 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 private async playSingleAd(vastTagUrl: string): Promise<void> {\n if (this.ima.isAdPlaying()) {\n return;\n }\n\n if (this.failedVastUrls.has(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Skipping permanently-failed VAST URL:\", vastTagUrl);\n }\n throw new Error(\"VAST URL permanently failed\");\n }\n\n if (this.isUrlInCooldown(vastTagUrl)) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Skipping URL in cooldown (recent no-fill):\", vastTagUrl);\n }\n throw new Error(\"VAST URL in cooldown after no-fill\");\n }\n\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Too many consecutive failures, not requesting more ads\");\n }\n throw new Error(\"Too many consecutive failures\");\n }\n\n this.recreateImaController();\n\n const requestToken = ++this.adRequestTokenCounter;\n this.activeAdRequestToken = requestToken;\n \n this.startAdRequestWatchdog(requestToken);\n\n try {\n this.lastAdRequestTime = Date.now();\n await this.ima.requestAds(vastTagUrl);\n\n this.clearAdRequestWatchdog();\n\n if (this.activeAdRequestToken !== requestToken) {\n return;\n }\n\n try {\n this.startAdFailsafeTimer(requestToken);\n await this.ima.play();\n \n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n this.consecutiveFailures = 0;\n this.temporaryFailureUrls.delete(vastTagUrl);\n } catch (playError) {\n if (this.config.debugAdTiming) {\n console.error(\"[AD-ERROR] Failed to play ad:\", playError);\n }\n \n const preloadedFallback = this.getPreloadedAd();\n if (preloadedFallback) {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Play failed, trying preloaded fallback ad\");\n }\n \n try {\n this.clearAdFailsafeTimer();\n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedFallback.imaController;\n this.attachImaEventListeners();\n \n this.ima.resume();\n \n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n \n await this.ima.play();\n \n if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {\n this.currentAdBreakStartWallClockMs = Date.now();\n this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);\n }\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n return; \n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n \n if (this.isTemporaryAdError(playError as Error)) {\n this.temporaryFailureUrls.set(vastTagUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Temporary play error - URL can be retried after cooldown\");\n }\n } else {\n this.failedVastUrls.add(vastTagUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Permanent play error - URL blacklisted\");\n }\n }\n \n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n throw playError;\n }\n } catch (error) {\n const errorMessage = (error as Error)?.message || \"\";\n if (this.config.debugAdTiming) {\n console.error(\"[AD-ERROR] Ad request failed:\", errorMessage);\n }\n \n const preloadedFallback = this.getPreloadedAd();\n if (preloadedFallback) {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Request failed, trying preloaded fallback ad\");\n }\n \n try {\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n \n this.ima.destroy();\n this.video.muted = true;\n this.video.volume = 0;\n this.ima = preloadedFallback.imaController;\n this.attachImaEventListeners();\n \n this.ima.resume();\n \n this.consecutiveFailures = 0;\n this.currentAdIndex++;\n this.totalAdRequestsInBreak++;\n \n await this.ima.play();\n \n const currentMuted = this.video.muted;\n const currentVolume = this.video.volume;\n const adVolume = currentMuted ? 0 : currentVolume;\n this.ima.setAdVolume(adVolume);\n \n return;\n } catch (fallbackError) {\n if (this.config.debugAdTiming) {\n console.warn(\"[AD-ERROR] Preloaded fallback also failed:\", fallbackError);\n }\n }\n }\n \n if (this.isTemporaryAdError(error as Error)) {\n this.temporaryFailureUrls.set(vastTagUrl, Date.now());\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Temporary error (no-fill/timeout) - URL can be retried after cooldown\");\n }\n } else {\n this.failedVastUrls.add(vastTagUrl);\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Permanent error - URL blacklisted:\", errorMessage);\n }\n }\n\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n if (this.activeAdRequestToken === requestToken) {\n this.activeAdRequestToken = null;\n }\n\n throw error;\n }\n }\n\n private handleAdPodComplete(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] 🏁 Ad pod complete - cleaning up\");\n }\n\n this.clearAdRequestWatchdog();\n this.clearAdFailsafeTimer();\n this.activeAdRequestToken = null;\n\n this.stopContinuousFetching();\n this.stopPreloadPool();\n this.clearPendingAdBreak();\n \n if (this.isShowingPlaceholder) {\n this.ima.hidePlaceholder();\n this.isShowingPlaceholder = false;\n }\n\n this.adRequestQueue = [];\n\n this.inAdBreak = false;\n this.expectedAdBreakDurationMs = undefined;\n this.currentAdBreakStartWallClockMs = undefined;\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.adPodQueue = [];\n this.showAds = false;\n this.currentAdIndex = 0;\n this.totalAdsInBreak = 0;\n this.consecutiveFailures = 0;\n\n this.ima.stop().catch(() => {});\n\n const restoredMuted = this.ima.getOriginalMutedState();\n const restoredVolume = this.ima.getOriginalVolume();\n\n if (this.video.muted !== restoredMuted) {\n this.video.muted = restoredMuted;\n }\n if (Math.abs(this.video.volume - restoredVolume) > 0.01) {\n this.video.volume = restoredVolume;\n }\n\n if (this.shouldContinueLiveStreamDuringAds()) {\n if (this.video.paused) {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback\");\n }\n this.video.play()?.catch(() => {});\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Content video already playing in live mode after ads\");\n }\n }\n } else if (this.video.paused) {\n this.video.play()?.catch(() => {});\n }\n }\n\n private handleAdFailure(): void {\n this.consecutiveFailures++;\n const remaining = this.getRemainingAdMs();\n \n if (this.config.debugAdTiming) {\n console.log(\n `[CONTINUOUS-FETCH] Ad failure: remaining=${remaining}ms, queued ads=${this.adRequestQueue.length}, consecutiveFailures=${this.consecutiveFailures}`,\n this.adRequestQueue.length > 0 ? { queuedUrls: [...this.adRequestQueue] } : {}\n );\n }\n \n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n if (this.config.debugAdTiming) {\n console.log(`[CONTINUOUS-FETCH] 🛑 Max consecutive failures reached (${this.consecutiveFailures}), ending ad break gracefully`);\n }\n this.handleAdPodComplete();\n return;\n }\n \n if (remaining > 500) {\n this.tryNextAvailableAdWithRateLimit();\n } else {\n if (this.config.debugAdTiming) {\n console.log(\"[AD-ERROR] Ad failed and no time remaining. Failed URLs:\", this.failedVastUrls.size);\n }\n this.handleAdPodComplete();\n }\n }\n\n private 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.handleAdFailure();\n }, timeoutMs) as unknown as number;\n\n this.logAdState(\"ad_request_watchdog_started\", { token, timeoutMs });\n }\n\n private 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 private 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 imaAdPlaying: this.ima.isAdPlaying(),\n });\n\n this.handleAdFailure();\n }, failsafeMs) as unknown as number;\n\n this.logAdState(\"ad_failsafe_started\", { token, failsafeMs });\n }\n\n private 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 private 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 private logAdState(event: string, extra: Record<string, unknown> = {}): void {\n if (!this.config.debugAdTiming) {\n return;\n }\n\n console.log(\"[StormcloudVideoPlayer][AdState]\", {\n event,\n timestamp: new Date().toISOString(),\n showAds: this.showAds,\n adPlaying: this.ima.isAdPlaying(),\n inAdBreak: this.inAdBreak,\n activeAdRequestToken: this.activeAdRequestToken,\n ...extra,\n });\n }\n\n private getRemainingAdMs(): number {\n if (\n this.expectedAdBreakDurationMs == null ||\n this.currentAdBreakStartWallClockMs == null\n )\n return 0;\n const elapsed = Date.now() - this.currentAdBreakStartWallClockMs;\n return Math.max(0, this.expectedAdBreakDurationMs - elapsed);\n }\n\n private findBreakForTime(nowMs: number): AdBreak | undefined {\n const schedule: AdBreak[] = [];\n for (const b of schedule) {\n const end = (b.startTimeMs || 0) + (b.durationMs || 0);\n if (\n nowMs >= (b.startTimeMs || 0) &&\n (b.durationMs ? nowMs < end : true)\n ) {\n return b;\n }\n }\n return undefined;\n }\n\n toggleMute(): void {\n if (this.ima.isAdPlaying()) {\n const currentPerceptualState = this.isMuted();\n const newMutedState = !currentPerceptualState;\n\n this.ima.updateOriginalMutedState(newMutedState, this.video.volume);\n this.ima.setAdVolume(newMutedState ? 0 : 1);\n\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] Mute toggle during ad - immediately applied:\",\n newMutedState\n );\n }\n } else {\n this.video.muted = !this.video.muted;\n this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Muted:\", this.video.muted);\n }\n }\n }\n\n toggleFullscreen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!document.fullscreenElement) {\n const container = this.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 (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Entered fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\"[StormcloudVideoPlayer] Fullscreen error:\", err);\n }\n reject(err);\n });\n } else {\n document\n .exitFullscreen()\n .then(() => {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Exited fullscreen\");\n }\n resolve();\n })\n .catch((err) => {\n if (this.config.debugAdTiming) {\n console.error(\n \"[StormcloudVideoPlayer] Exit fullscreen error:\",\n err\n );\n }\n reject(err);\n });\n }\n });\n }\n\n isMuted(): boolean {\n if (this.ima.isAdPlaying()) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] isMuted() override during ad playback -> false\"\n );\n }\n return false;\n }\n return this.video.muted;\n }\n\n setMuted(muted: boolean): void {\n const adPlaying = this.ima.isAdPlaying();\n\n if (adPlaying && muted === this.video.muted) {\n if (this.config.debugAdTiming) {\n console.log(\n \"[StormcloudVideoPlayer] setMuted reflective update during ad ignored\",\n { muted }\n );\n }\n return;\n }\n\n this.video.muted = muted;\n\n if (adPlaying) {\n this.ima.updateOriginalMutedState(muted, this.video.volume);\n this.ima.setAdVolume(muted ? 0 : 1);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted applied during ad\", {\n muted,\n });\n }\n return;\n }\n\n this.ima.updateOriginalMutedState(muted, this.video.volume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setMuted called:\", muted);\n }\n }\n\n setVolume(volume: number): void {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n const adPlaying = this.ima.isAdPlaying();\n\n if (adPlaying) {\n this.ima.setAdVolume(clampedVolume);\n this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume applied during ad\", {\n volume: clampedVolume,\n });\n }\n } else {\n this.video.volume = clampedVolume;\n this.video.muted = clampedVolume === 0;\n this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] setVolume called:\", clampedVolume);\n }\n }\n }\n\n getVolume(): number {\n const adPlaying = this.ima.isAdPlaying();\n if (adPlaying) {\n return this.ima.getAdVolume();\n }\n return this.video.volume;\n }\n\n isFullscreen(): boolean {\n return !!document.fullscreenElement;\n }\n\n isLive(): boolean {\n return this.isLiveStream;\n }\n\n get videoElement(): HTMLVideoElement {\n return this.video;\n }\n\n resize(): void {\n if (this.config.debugAdTiming) {\n console.log(\"[StormcloudVideoPlayer] Resizing player\");\n }\n\n if (this.ima && this.ima.isAdPlaying()) {\n const width = this.video.clientWidth || 640;\n const height = this.video.clientHeight || 480;\n\n if (this.config.debugAdTiming) {\n console.log(\n `[StormcloudVideoPlayer] Resizing ads manager to ${width}x${height}`\n );\n }\n\n this.ima.resize(width, height);\n }\n }\n\n destroy(): void {\n this.stopContinuousFetching();\n this.stopPreloadPool();\n this.clearAdStartTimer();\n this.clearAdStopTimer();\n this.clearAdFailsafeTimer();\n this.clearAdRequestWatchdog();\n this.clearPendingAdBreak();\n \n if (this.placeholderContainer) {\n if (this.placeholderContainer.parentElement) {\n this.placeholderContainer.parentElement.removeChild(this.placeholderContainer);\n }\n this.placeholderContainer = undefined;\n }\n \n if (this.timeUpdateHandler) {\n this.video.removeEventListener(\"timeupdate\", this.timeUpdateHandler);\n delete this.timeUpdateHandler;\n }\n if (this.emptiedHandler) {\n this.video.removeEventListener(\"emptied\", this.emptiedHandler);\n delete this.emptiedHandler;\n }\n \n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n this.hls?.destroy();\n this.ima?.destroy();\n this.adRequestQueue = [];\n this.consecutiveFailures = 0;\n }\n}\n","import type { ImaController } from \"../types\";\nimport { supportsGoogleIMA } from \"../utils/browserCompat\";\n\ndeclare global {\n interface Window {\n google?: any;\n }\n}\n\nexport function createImaController(\n video: HTMLVideoElement,\n options?: { continueLiveStreamDuringAds?: boolean }\n): ImaController {\n let adPlaying = false;\n let contentVideoHidden = false;\n let originalMutedState = false;\n let originalVolume =\n typeof video.volume === \"number\" && !Number.isNaN(video.volume)\n ? Math.max(0, Math.min(1, video.volume))\n : 1;\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n let adVideoElement: HTMLVideoElement | undefined;\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n\n function hideContentVideo(): void {\n if (!contentVideoHidden) {\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.style.opacity = \"0\";\n setTimeout(() => {\n video.style.visibility = \"hidden\";\n }, 300);\n video.muted = true;\n video.volume = 0;\n contentVideoHidden = true;\n }\n }\n\n function showContentVideo(): void {\n if (contentVideoHidden) {\n video.style.visibility = \"visible\";\n video.style.transition = \"opacity 0.3s ease-in-out\";\n video.offsetHeight;\n video.style.opacity = \"1\";\n video.muted = originalMutedState;\n video.volume = originalVolume;\n contentVideoHidden = false;\n }\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const adVideo = document.createElement(\"video\");\n adVideo.style.position = \"absolute\";\n adVideo.style.top = \"0\";\n adVideo.style.left = \"0\";\n adVideo.style.width = \"100%\";\n adVideo.style.height = \"100%\";\n adVideo.style.objectFit = \"contain\";\n adVideo.style.backgroundColor = \"transparent\";\n adVideo.style.zIndex = \"15\";\n adVideo.playsInline = true;\n\n adVideo.volume = originalVolume;\n adVideo.muted = originalMutedState;\n\n adVideo.style.opacity = \"0\";\n adVideo.addEventListener(\n \"canplay\",\n () => {\n adVideo.style.opacity = \"1\";\n },\n { once: true }\n );\n\n return adVideo;\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 {}\n }\n }\n\n function ensureImaLoaded(): Promise<void> {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n\n try {\n const frameEl = window.frameElement as HTMLIFrameElement | null;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n // eslint-disable-next-line no-console\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {}\n\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n ) as HTMLScriptElement | null;\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 10000);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n\n let adsManager: any | undefined;\n let adsLoader: any | undefined;\n let adDisplayContainer: any | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let lastAdTagUrl: string | undefined;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise: Promise<void> | undefined;\n let adsLoadedResolve: (() => void) | undefined;\n let adsLoadedReject: ((error: Error) => void) | undefined;\n\n function makeAdsRequest(google: any, vastTagUrl: string) {\n const adsRequest = new google.ima.AdsRequest();\n \n const companionSizes = [\n { width: 728, height: 90 },\n { width: 300, height: 250 },\n { width: 180, height: 150 },\n { width: 120, height: 60 },\n { width: 88, height: 31 },\n { width: 300, height: 60 },\n { width: 300, height: 100 },\n { width: 320, height: 50 },\n { width: 468, height: 60 },\n { width: 300, height: 600 },\n { width: 160, height: 600 },\n ];\n\n const ciuSzsValue = companionSizes\n .map((size) => `fluid|${size.width}x${size.height}`)\n .join(\",\");\n\n const currentLocation = typeof window !== \"undefined\" ? window.location : null;\n const topLocation = typeof window !== \"undefined\" && window.top ? window.top.location : currentLocation;\n const currentUrl = currentLocation?.href || \"\";\n const topUrl = topLocation?.href || currentUrl;\n const currentDomain = currentLocation?.hostname || \"\";\n\n let modifiedVastTagUrl = vastTagUrl;\n try {\n const url = new URL(vastTagUrl);\n \n url.searchParams.set(\"ciu_szs\", ciuSzsValue);\n \n if (!url.searchParams.has(\"mpt\")) {\n url.searchParams.set(\"mpt\", \"h5_vsi\");\n }\n \n if (!url.searchParams.has(\"ctv\")) {\n url.searchParams.set(\"ctv\", \"0\");\n }\n \n if (!url.searchParams.has(\"gdpr\")) {\n url.searchParams.set(\"gdpr\", \"0\");\n }\n \n if (!url.searchParams.has(\"top\") && topUrl) {\n url.searchParams.set(\"top\", topUrl);\n }\n \n if (!url.searchParams.has(\"loc\") && currentUrl) {\n url.searchParams.set(\"loc\", currentUrl);\n }\n \n if (!url.searchParams.has(\"cdm\") && currentDomain) {\n url.searchParams.set(\"cdm\", currentDomain);\n }\n \n if (!url.searchParams.has(\"eoidce\")) {\n url.searchParams.set(\"eoidce\", \"1\");\n }\n \n if (!url.searchParams.has(\"fbidx\")) {\n url.searchParams.set(\"fbidx\", \"0\");\n }\n \n modifiedVastTagUrl = url.toString();\n } catch (e) {\n let baseUrl = vastTagUrl;\n \n const paramsToRemove = [\"ciu_szs\", \"mpt\", \"ctv\", \"gdpr\", \"top\", \"loc\", \"cdm\", \"eoidce\", \"fbidx\"];\n paramsToRemove.forEach((param) => {\n if (baseUrl.includes(`${param}=`)) {\n baseUrl = baseUrl.replace(new RegExp(`[?&]${param}=[^&]*`, \"g\"), \"\");\n }\n });\n baseUrl = baseUrl.replace(/[?&]$/, \"\");\n \n const params = new URLSearchParams();\n params.set(\"ciu_szs\", ciuSzsValue);\n params.set(\"mpt\", \"h5_vsi\");\n params.set(\"ctv\", \"0\");\n params.set(\"gdpr\", \"0\");\n if (topUrl) params.set(\"top\", topUrl);\n if (currentUrl) params.set(\"loc\", currentUrl);\n if (currentDomain) params.set(\"cdm\", currentDomain);\n params.set(\"eoidce\", \"1\");\n params.set(\"fbidx\", \"0\");\n \n const separator = baseUrl.includes(\"?\") ? \"&\" : \"?\";\n modifiedVastTagUrl = `${baseUrl}${separator}${params.toString()}`;\n }\n \n adsRequest.adTagUrl = modifiedVastTagUrl;\n\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 480;\n\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n\n if (typeof adsRequest.setCompanionSlots === \"function\") {\n try {\n const companionSlots: any[] = [];\n\n for (const size of companionSizes) {\n const slot = new google.ima.CompanionAdSlot();\n slot.width = size.width;\n slot.height = size.height;\n companionSlots.push(slot);\n }\n\n adsRequest.setCompanionSlots(companionSlots);\n } catch (error) {\n console.warn(\"[IMA] Failed to set companion slots:\", error);\n }\n }\n\n if (typeof adsRequest.setAdWillAutoPlay === \"function\") {\n try {\n const willAutoPlay = !video.paused || video.autoplay;\n adsRequest.setAdWillAutoPlay(willAutoPlay);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillAutoPlay:\", error);\n }\n }\n\n if (typeof adsRequest.setAdWillPlayMuted === \"function\") {\n try {\n const willPlayMuted = video.muted || video.volume === 0;\n adsRequest.setAdWillPlayMuted(willPlayMuted);\n } catch (error) {\n console.warn(\"[IMA] Failed to call setAdWillPlayMuted:\", error);\n }\n }\n\n adsRequest.vastLoadTimeout = 10000;\n\n adsLoader.requestAds(adsRequest);\n }\n\n function ensurePlaceholderContainer(): void {\n if (adContainerEl) {\n return;\n }\n\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 container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n video.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n function destroyAdsManager() {\n if (adsManager) {\n try {\n adsManager.destroy();\n } catch {}\n adsManager = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.style.opacity = \"0\";\n }\n }\n\n function destroyAdsLoader() {\n if (adsLoader) {\n try {\n adsLoader.destroy();\n } catch {}\n adsLoader = undefined;\n }\n }\n\n return {\n initialize() {\n ensureImaLoaded()\n .then(() => {\n const google = window.google;\n ensurePlaceholderContainer();\n\n if (!adDisplayContainer && adContainerEl) {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n\n adDisplayContainer = new google.ima.AdDisplayContainer(\n adContainerEl,\n adVideoElement\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {}\n }\n })\n .catch(() => {});\n },\n async requestAds(vastTagUrl: string) {\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n return Promise.reject(error);\n }\n\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n return Promise.reject(error);\n }\n\n if (adPlaying) {\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n\n destroyAdsManager();\n destroyAdsLoader();\n\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n\n let currentReject: ((error: Error) => void) | undefined;\n adsLoadedPromise = new Promise<void>((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n }, 10000);\n });\n\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n\n if (!adDisplayContainer) {\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 = \"transparent\";\n container.style.transition =\n \"opacity 0.3s ease-in-out, background-color 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n\n if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n\n video.parentElement.appendChild(container);\n adContainerEl = container;\n\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n }\n\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n adVideoElement\n );\n\n }\n\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n\n if (\n !videoWidth ||\n !videoHeight ||\n videoWidth === 0 ||\n videoHeight === 0\n ) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n currentReject?.(error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n\n if (!adsLoader) {\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt: any) => {\n try {\n const adsRenderingSettings =\n new google.ima.AdsRenderingSettings();\n adsRenderingSettings.enablePreloading = true;\n adsManager = evt.getAdsManager(video, adsRenderingSettings);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent: any) => {\n const error = errorEvent.getError();\n const errorCode = error.getErrorCode?.() || \"unknown\";\n const vastErrorCode = error.getVastErrorCode?.() || \"N/A\";\n const errorMessage = error.getMessage?.() || \"Unknown error\";\n \n let innerError: string | undefined;\n try {\n if (typeof error.getInnerError === \"function\") {\n const inner = error.getInnerError();\n if (inner) {\n innerError = typeof inner === \"string\" ? inner : (inner.message || String(inner));\n }\n }\n if (!innerError && error.cause) {\n innerError = typeof error.cause === \"string\" ? error.cause : (error.cause.message || String(error.cause));\n }\n if (!innerError && error.innerError) {\n innerError = typeof error.innerError === \"string\" ? error.innerError : (error.innerError.message || String(error.innerError));\n }\n } catch (e) {\n }\n \n const isNoFill = errorCode === 303 || vastErrorCode === 303;\n \n\n destroyAdsManager();\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n hideContentVideo();\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n\n if (lastAdTagUrl && retryAttempts < maxRetries && !isNoFill) {\n const delay =\n backoffBaseMs * Math.pow(2, retryAttempts++);\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl!);\n } catch {}\n }, delay);\n } else {\n emit(\"ad_error\", { \n code: errorCode, \n vastErrorCode, \n message: errorMessage,\n cause: innerError,\n isNoFill \n });\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n video.play()?.catch(() => {});\n }\n }\n }\n }\n );\n\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n }\n\n adPlaying = true;\n setAdPlayingFlag(true);\n \n const adVolume = originalMutedState ? 0 : originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adsManager) {\n try {\n adsManager.setVolume(adVolume);\n } catch {}\n }\n \n emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n setAdPlayingFlag(true);\n\n hideContentVideo();\n\n if (adVideoElement) {\n const adVolume = originalVolume;\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n \n if (adsManager) {\n try {\n adsManager.setVolume(originalMutedState ? 0 : adVolume);\n } catch {}\n }\n }\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n });\n\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n \n hideContentVideo();\n \n emit(\"content_resume\");\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n hideContentVideo();\n\n emit(\"all_ads_completed\");\n });\n\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = undefined;\n adsLoadedReject = undefined;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n hideContentVideo();\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent: any) => {\n const error = adErrorEvent.getError();\n const errorCode = error.getErrorCode?.() || \"unknown\";\n const vastErrorCode = error.getVastErrorCode?.() || \"N/A\";\n const errorMessage = error.getMessage?.() || \"Unknown error\";\n \n let innerError: string | undefined;\n try {\n if (typeof error.getInnerError === \"function\") {\n const inner = error.getInnerError();\n if (inner) {\n innerError = typeof inner === \"string\" ? inner : (inner.message || String(inner));\n }\n }\n if (!innerError && error.cause) {\n innerError = typeof error.cause === \"string\" ? error.cause : (error.cause.message || String(error.cause));\n }\n if (!innerError && error.innerError) {\n innerError = typeof error.innerError === \"string\" ? error.innerError : (error.innerError.message || String(error.innerError));\n }\n } catch (e) {\n }\n \n const isNoFill = errorCode === 303 || vastErrorCode === 303;\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n hideContentVideo();\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(isNoFill ? \"No ads available\" : \"Ads loader error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\", { \n code: errorCode, \n vastErrorCode, \n message: errorMessage,\n isNoFill,\n cause: innerError\n });\n },\n false\n );\n }\n\n makeAdsRequest(google, vastTagUrl);\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n\n currentReject?.(error as Error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n\n if (!adsManager) {\n return Promise.reject(new Error(\"No ads manager\"));\n }\n\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 480;\n\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n\n adPlaying = true;\n\n const adVolume = originalVolume;\n if (adVideoElement) {\n adVideoElement.volume = adVolume;\n adVideoElement.muted = originalMutedState;\n }\n\n try {\n adsManager.setVolume(originalMutedState ? 0 : adVolume);\n } catch {}\n\n adsManager.start();\n\n return Promise.resolve();\n } catch (error) {\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adsManager || !adPlaying) {\n return;\n }\n\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n\n if (adsManager && typeof adsManager.pause === \"function\") {\n adsManager.pause();\n }\n } catch (error) {\n console.warn(\"[IMA] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adsManager || !adPlaying) {\n return;\n }\n\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {});\n }\n\n if (adsManager && typeof adsManager.resume === \"function\") {\n adsManager.resume();\n }\n } catch (error) {\n console.warn(\"[IMA] Error resuming ad:\", error);\n }\n },\n async stop() {\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n adContainerEl.style.backgroundColor = \"transparent\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n }, 300);\n }\n\n showContentVideo();\n\n if (options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\"[IMA] Content video paused in live mode on stop, resuming playback\");\n video.play().catch(() => {});\n }\n } else if (video.paused) {\n video.play().catch(() => {});\n }\n\n try {\n adsManager?.stop?.();\n } catch {}\n\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"none\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n\n if (adContainerEl.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n adVideoElement = undefined;\n }\n }, 500);\n }\n\n showContentVideo();\n\n try {\n adsLoader?.destroy?.();\n } catch {}\n\n adDisplayContainer = undefined;\n adsLoader = undefined;\n contentVideoHidden = false;\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width: number, height: number) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\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 originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume: number) {\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = clampedVolume;\n adVideoElement.muted = clampedVolume === 0;\n }\n\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(clampedVolume);\n } catch {}\n }\n },\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n showPlaceholder() {\n ensurePlaceholderContainer();\n \n hideContentVideo();\n \n if (adContainerEl) {\n const wasHidden = adContainerEl.style.display === \"none\" || adContainerEl.style.opacity === \"0\";\n if (wasHidden) {\n adContainerEl.style.transition = \"none\";\n } else {\n adContainerEl.style.transition = \"opacity 0.3s ease-in-out\";\n }\n adContainerEl.style.backgroundColor = \"#000\";\n adContainerEl.style.display = \"flex\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n if (wasHidden) {\n requestAnimationFrame(() => {\n if (adContainerEl) {\n adContainerEl.style.transition = \"opacity 0.3s ease-in-out\";\n }\n });\n }\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.backgroundColor = \"#000\";\n }\n }, 300);\n }\n },\n };\n}\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface 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\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\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 `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\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 Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} 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 `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\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 console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\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 xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n licenseKey?: string,\n logPrefix = \"[VastParser]\"\n): 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(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n","import type { ImaController } from \"../types\";\nimport type { VastAd, VastMediaFile } from \"./vastParser\";\nimport {\n fetchAndParseVastAd,\n fireTrackingPixels as fireTrackingPixelsShared,\n} from \"./vastParser\";\nimport Hls from \"hls.js\";\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n const preloadedAds = new Map<string, VastAd>();\n const preloadingAds = new Map<string, Promise<void>>();\n let destroyed = false;\n let pendingTimeouts: number[] = [];\n\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n fireTrackingPixelsShared(urls, sessionId, licenseKey, \"[HlsAdPlayer]\");\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 async function fetchAndParseVastAdLocal(\n vastTagUrl: string\n ): Promise<VastAd | null> {\n return fetchAndParseVastAd(vastTagUrl, \"hls-only\", \"[HlsAdPlayer]\");\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {});\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] Initializing\");\n\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(vastTagUrl: string) {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n let ad: VastAd | null | undefined;\n\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAdLocal(vastTagUrl);\n }\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] Starting ad playback\");\n\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (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 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 {\n throw new Error(\"HLS not supported\");\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {});\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {});\n }\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n \n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n preloadedAds.clear();\n preloadingAds.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);\n\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\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 };\n}\n","import type {\n PrebidConfig,\n PrebidBidResponse,\n PrebidManager,\n} from \"../types\";\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst AUCTION_PATH = \"/openrtb2/auction\";\n\nexport function createPrebidManager(config: PrebidConfig): PrebidManager {\n let initialized = false;\n let serverUrl = \"\";\n const debug = config.debug ?? false;\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[Prebid]\", ...args);\n }\n }\n\n function warn(...args: any[]): void {\n console.warn(\"[Prebid]\", ...args);\n }\n\n function resolveServerUrl(): string {\n if (config.serverUrl) {\n return config.serverUrl.replace(/\\/$/, \"\");\n }\n\n const extUrl =\n config.ortbRequest?.ext?.prebid?.server?.externalurl;\n if (typeof extUrl === \"string\" && extUrl.length > 0) {\n return extUrl.replace(/\\/$/, \"\");\n }\n\n throw new Error(\n \"Prebid Server URL not configured. Provide serverUrl in PrebidConfig or ext.prebid.server.externalurl in the OpenRTB request.\"\n );\n }\n\n function buildRequest(): Record<string, any> {\n const req = JSON.parse(JSON.stringify(config.ortbRequest));\n\n req.id =\n `${req.id || \"prebid\"}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n if (!req.ext) req.ext = {};\n if (!req.ext.prebid) req.ext.prebid = {};\n if (!req.ext.prebid.cache) req.ext.prebid.cache = {};\n if (!req.ext.prebid.cache.vastxml) req.ext.prebid.cache.vastxml = {};\n if (!req.ext.prebid.targeting) {\n req.ext.prebid.targeting = {\n includewinners: true,\n includebidderkeys: false,\n };\n }\n\n if (!req.device) req.device = {};\n if (typeof navigator !== \"undefined\") {\n if (!req.device.ua) req.device.ua = navigator.userAgent;\n if (!req.device.language) {\n req.device.language =\n (navigator.language || \"\").split(\"-\")[0] || \"en\";\n }\n }\n if (typeof window !== \"undefined\") {\n if (!req.device.w) req.device.w = window.screen?.width || window.innerWidth;\n if (!req.device.h) req.device.h = window.screen?.height || window.innerHeight;\n }\n\n if (!req.site) req.site = {};\n if (typeof window !== \"undefined\") {\n if (!req.site.page) req.site.page = window.location.href;\n if (!req.site.domain) req.site.domain = window.location.hostname;\n }\n\n return req;\n }\n\n function parseResponse(data: any): PrebidBidResponse[] {\n const bids: PrebidBidResponse[] = [];\n const seatbids: any[] = data?.seatbid || [];\n const currency: string = data?.cur || \"USD\";\n\n for (const seatbid of seatbids) {\n const seat: string = seatbid.seat || \"unknown\";\n const bidArray: any[] = seatbid.bid || [];\n\n for (const bid of bidArray) {\n const cacheUrl: string | undefined =\n bid.ext?.prebid?.cache?.vastXml?.url;\n const vastXml: string | undefined = bid.adm || undefined;\n\n const bidResponse: PrebidBidResponse = {\n bidder: seat,\n cpm: bid.price || 0,\n width: bid.w || 0,\n height: bid.h || 0,\n adId: bid.id || \"\",\n impId: bid.impid || \"\",\n creativeId: bid.crid || \"\",\n currency,\n };\n if (cacheUrl) bidResponse.vastUrl = cacheUrl;\n if (vastXml) bidResponse.vastXml = vastXml;\n if (bid.adomain) bidResponse.adomain = bid.adomain;\n\n bids.push(bidResponse);\n }\n }\n\n bids.sort((a, b) => b.cpm - a.cpm);\n return bids;\n }\n\n function extractVastUrl(bids: PrebidBidResponse[]): string | null {\n if (bids.length === 0) return null;\n\n const winner = bids[0]!;\n\n const cpmFloor = config.cpmFloor ?? 0;\n if (cpmFloor > 0 && winner.cpm < cpmFloor) {\n log(\n `Winning bid $${winner.cpm.toFixed(2)} below CPM floor $${cpmFloor.toFixed(2)}, rejecting`\n );\n return null;\n }\n\n if (winner.vastUrl) {\n log(\n `Using cached VAST URL from ${winner.bidder} ($${winner.cpm.toFixed(2)} ${winner.currency})`\n );\n return winner.vastUrl;\n }\n\n if (winner.vastXml) {\n log(\n `Creating blob URL from VAST XML (${winner.bidder}, $${winner.cpm.toFixed(2)})`\n );\n try {\n const blob = new Blob([winner.vastXml], { type: \"text/xml\" });\n return URL.createObjectURL(blob);\n } catch (error) {\n warn(\"Failed to create blob URL from VAST XML:\", error);\n }\n }\n\n return null;\n }\n\n async function initialize(): Promise<void> {\n if (initialized) return;\n\n serverUrl = resolveServerUrl();\n\n if (\n !config.ortbRequest?.imp ||\n config.ortbRequest.imp.length === 0\n ) {\n throw new Error(\"No impressions (imp) defined in the OpenRTB request.\");\n }\n\n initialized = true;\n log(\"Initialized with server:\", serverUrl);\n log(\n \"Bidders:\",\n config.ortbRequest.imp\n .map((imp) => {\n const bidders = imp.ext?.prebid?.bidder;\n return bidders ? Object.keys(bidders).join(\", \") : \"none\";\n })\n .join(\"; \")\n );\n }\n\n async function requestBids(): Promise<PrebidBidResponse[]> {\n if (!initialized) {\n throw new Error(\"Prebid not initialized. Call initialize() first.\");\n }\n\n const auctionUrl = `${serverUrl}${AUCTION_PATH}`;\n const request = buildRequest();\n const timeout = config.timeout ?? config.ortbRequest.tmax ?? DEFAULT_TIMEOUT_MS;\n\n log(\"Sending auction request to:\", auctionUrl);\n\n const controller =\n typeof AbortController !== \"undefined\"\n ? new AbortController()\n : null;\n const timeoutId = setTimeout(() => {\n controller?.abort();\n }, timeout + 2000);\n\n try {\n const fetchOptions: RequestInit = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n };\n if (controller) {\n fetchOptions.signal = controller.signal;\n }\n\n const response = await fetch(auctionUrl, fetchOptions);\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new Error(\n `Prebid Server returned HTTP ${response.status}: ${body.slice(0, 200)}`\n );\n }\n\n const data = await response.json();\n\n if (debug && data?.ext?.responsetimemillis) {\n log(\"Bidder response times:\", data.ext.responsetimemillis);\n }\n if (debug && data?.ext?.errors) {\n warn(\"Auction errors:\", data.ext.errors);\n }\n\n const bids = parseResponse(data);\n log(`Received ${bids.length} bid(s)`);\n\n if (debug) {\n for (const b of bids) {\n log(\n ` ${b.bidder}: $${b.cpm.toFixed(2)} ${b.currency}` +\n ` ${b.width}x${b.height}` +\n (b.vastUrl ? \" [cached VAST]\" : \"\") +\n (b.vastXml && !b.vastUrl ? \" [VAST XML]\" : \"\")\n );\n }\n }\n\n return bids;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error?.name === \"AbortError\") {\n warn(`Auction request timed out after ${timeout + 2000}ms`);\n return [];\n }\n\n throw error;\n }\n }\n\n async function getVastUrl(): Promise<string | null> {\n try {\n const bids = await requestBids();\n return extractVastUrl(bids);\n } catch (error) {\n warn(\"Failed to get VAST URL:\", error);\n return null;\n }\n }\n\n function destroy(): void {\n initialized = false;\n serverUrl = \"\";\n log(\"Destroyed\");\n }\n\n return {\n initialize,\n requestBids,\n getVastUrl,\n destroy,\n get isInitialized() {\n return initialized;\n },\n };\n}\n","import type { ImaController, PrebidConfig } from \"../types\";\nimport type { VastAd, VastMediaFile } from \"./vastParser\";\nimport {\n parseVastXml,\n fetchAndParseVastAd,\n fireTrackingPixels as fireTrackingPixelsShared,\n createEmptyTrackingState,\n} from \"./vastParser\";\nimport { createPrebidManager } from \"./prebid\";\nimport Hls from \"hls.js\";\n\nconst LOG = \"[PrebidController]\";\n\nexport interface PrebidControllerOptions {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n}\n\nexport function createPrebidController(\n contentVideo: HTMLVideoElement,\n prebidConfig: PrebidConfig,\n options?: PrebidControllerOptions\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n let destroyed = false;\n let trackingFired = createEmptyTrackingState();\n\n const prebidDebug = prebidConfig.debug ?? false;\n const prebidManager = createPrebidManager({\n ...prebidConfig,\n debug: prebidDebug,\n });\n let prebidInitialized = false;\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(`${LOG} Error in event listener for ${event}:`, error);\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 fireTrackingPixelsShared(urls, sessionId, licenseKey, LOG);\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(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n\n console.log(`${LOG} 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(`${LOG} No best match found, using first media file`);\n return firstFile;\n }\n\n console.log(`${LOG} 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 });\n\n return bestMatch.file;\n }\n\n function isHlsMediaFile(file: VastMediaFile): boolean {\n return (\n file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\")\n );\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 video.volume = 1.0;\n console.log(`${LOG} Created ad video element with volume ${video.volume}`);\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(`${LOG} 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(`${LOG} Ad completed`);\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function handleAdComplete(): void {\n console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\n `${LOG} Content video paused in live mode, resuming playback`\n );\n contentVideo.play().catch(() => {});\n } else {\n console.log(`${LOG} Content video already playing in live mode`);\n }\n }\n\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n async function ensurePrebidInitialized(): Promise<void> {\n if (prebidInitialized) return;\n\n if (prebidConfig.enabled === false) {\n throw new Error(\"Prebid is disabled in config\");\n }\n\n if (!prebidConfig.ortbRequest?.imp?.length) {\n throw new Error(\"No impressions configured in ortbRequest\");\n }\n\n await prebidManager.initialize();\n prebidInitialized = true;\n console.log(`${LOG} Prebid Server manager initialized`);\n }\n\n async function runPrebidAuction(): Promise<VastAd | null> {\n await ensurePrebidInitialized();\n\n const bids = await prebidManager.requestBids();\n if (bids.length === 0) {\n console.warn(`${LOG} No bids received from Prebid Server`);\n return null;\n }\n\n const cpmFloor = prebidConfig.cpmFloor ?? 0;\n const winner = bids[0]!;\n\n if (cpmFloor > 0 && winner.cpm < cpmFloor) {\n console.log(\n `${LOG} Winning bid $${winner.cpm.toFixed(2)} below CPM floor $${cpmFloor.toFixed(2)}, rejecting`\n );\n return null;\n }\n\n console.log(\n `${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`\n );\n\n if (winner.vastXml) {\n console.log(`${LOG} Parsing VAST XML from bid response (inline)`);\n return parseVastXml(winner.vastXml, \"mp4-first\", LOG);\n }\n\n if (winner.vastUrl) {\n console.log(`${LOG} Fetching VAST from cached URL: ${winner.vastUrl}`);\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", LOG);\n }\n\n console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n return null;\n }\n\n function startPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n\n function startNativePlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n\n function startHlsPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n\n if (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(`${LOG} HLS manifest parsed, starting playback`);\n adVideoElement!.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (_event, data) => {\n console.error(`${LOG} HLS error:`, data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n ) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n\n return {\n initialize() {\n console.log(`${LOG} 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 = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(vastTagUrl: string) {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n\n console.log(`${LOG} requestAds called:`, vastTagUrl || \"(empty - will run Prebid auction)\");\n\n if (adPlaying) {\n console.warn(`${LOG} Cannot request new ads while an ad is playing`);\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n let ad: VastAd | null;\n\n if (vastTagUrl && vastTagUrl.length > 0) {\n console.log(`${LOG} Fetching VAST from provided URL`);\n ad = await fetchAndParseVastAd(vastTagUrl, \"mp4-first\", LOG);\n } else {\n console.log(`${LOG} Running Prebid Server auction`);\n ad = await runPrebidAuction();\n }\n\n if (!ad) {\n console.warn(`${LOG} No ads available`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available\"));\n }\n\n currentAd = ad;\n console.log(\n `${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(`${LOG} Error requesting ads:`, error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (destroyed) {\n return Promise.reject(new Error(\"Controller has been destroyed\"));\n }\n\n if (!currentAd) {\n console.warn(`${LOG} Cannot play: No ad loaded`);\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(`${LOG} Starting ad playback`);\n\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n\n trackingFired = {\n ...createEmptyTrackingState(),\n impression: trackingFired.impression,\n };\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(`${LOG} Content paused (VOD mode)`);\n } else {\n console.log(`${LOG} Content continues (Live mode)`);\n }\n\n console.log(`${LOG} FORCE MUTING main video`);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n console.log(\n `${LOG} Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}`\n );\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n\n return Promise.resolve();\n } catch (error) {\n console.error(`${LOG} Error playing ad:`, error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {});\n }\n } catch (error) {\n console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n\n async stop() {\n console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n console.log(\n `${LOG} Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\n `${LOG} Content video paused in live mode, resuming playback on stop`\n );\n contentVideo.play().catch(() => {});\n }\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(`${LOG} Destroying`);\n destroyed = true;\n\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n\n prebidManager.destroy();\n prebidInitialized = false;\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`${LOG} 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 `${LOG} updateOriginalMutedState: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\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\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 };\n}\n","import type { ClientInfo, TrackingData, HeartbeatData } from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && 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(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\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 const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.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 cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\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"]}