@trillboards/ads-sdk 2.3.0 → 2.3.1

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.
@@ -1,2 +1,2 @@
1
- "use strict";var TrillboardsLiteBundle=(()=>{var C=Object.defineProperty,re=Object.defineProperties,ae=Object.getOwnPropertyDescriptor,ne=Object.getOwnPropertyDescriptors,se=Object.getOwnPropertyNames,z=Object.getOwnPropertySymbols;var $=Object.prototype.hasOwnProperty,oe=Object.prototype.propertyIsEnumerable;var G=(r,e,t)=>e in r?C(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,I=(r,e)=>{for(var t in e||(e={}))$.call(e,t)&&G(r,t,e[t]);if(z)for(var t of z(e))oe.call(e,t)&&G(r,t,e[t]);return r},J=(r,e)=>re(r,ne(e));var de=(r,e)=>{for(var t in e)C(r,t,{get:e[t],enumerable:!0})},le=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of se(e))!$.call(r,a)&&a!==t&&C(r,a,{get:()=>e[a],enumerable:!(i=ae(e,a))||i.enumerable});return r};var ce=r=>le(C({},"__esModule",{value:!0}),r);var ue={};de(ue,{TrillboardsLite:()=>ee});var M="2.2.0",g={API_BASE:"https://api.trillboards.com/v1/partner",CDN_BASE:"https://cdn.trillboards.com",CACHE_NAME:"trillboards-lite-ads",CACHE_SIZE:10,REFRESH_INTERVAL:12e4,HEARTBEAT_INTERVAL:6e4,DEFAULT_IMAGE_DURATION:8e3,DEFAULT_AD_INTERVAL:6e4,PROGRAMMATIC_TIMEOUT_MS:12e3,PROGRAMMATIC_MIN_INTERVAL_MS:5e3,PROGRAMMATIC_RETRY_MS:5e3,PROGRAMMATIC_BACKOFF_MAX_MS:3e5,VERSION:M};function U(r){var t,i,a,n,s,c,o,d,p,f,v,h,m,l,y;let e=(t=r.deviceId)==null?void 0:t.trim();if(!e)throw new Error("TrillboardsConfig: deviceId must be a non-empty string");return{deviceId:e,apiBase:(i=r.apiBase)!=null?i:g.API_BASE,cdnBase:(a=r.cdnBase)!=null?a:g.CDN_BASE,waterfall:(n=r.waterfall)!=null?n:"programmatic_only",autoStart:(s=r.autoStart)!=null?s:!0,refreshInterval:Math.max((c=r.refreshInterval)!=null?c:g.REFRESH_INTERVAL,1e4),heartbeatInterval:Math.max((o=r.heartbeatInterval)!=null?o:g.HEARTBEAT_INTERVAL,5e3),defaultImageDuration:Math.max((d=r.defaultImageDuration)!=null?d:g.DEFAULT_IMAGE_DURATION,1e3),defaultAdInterval:Math.max((p=r.defaultAdInterval)!=null?p:g.DEFAULT_AD_INTERVAL,1e3),programmaticTimeout:Math.max((f=r.programmaticTimeout)!=null?f:g.PROGRAMMATIC_TIMEOUT_MS,1e3),programmaticMinInterval:Math.max((v=r.programmaticMinInterval)!=null?v:g.PROGRAMMATIC_MIN_INTERVAL_MS,1e3),programmaticRetry:Math.max((h=r.programmaticRetry)!=null?h:g.PROGRAMMATIC_RETRY_MS,1e3),programmaticBackoffMax:Math.max((m=r.programmaticBackoffMax)!=null?m:g.PROGRAMMATIC_BACKOFF_MAX_MS,5e3),cacheSize:Math.max((l=r.cacheSize)!=null?l:g.CACHE_SIZE,1),debug:(y=r.debug)!=null?y:!1}}var X={initialized:!1,isPlaying:!1,isPaused:!1,isOffline:!1,currentAd:null,adCount:0,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",adDeliveryProfileMode:null,screenId:null,deviceId:null};function K(){return{deviceId:null,partnerId:null,screenId:null,ads:[],currentAdIndex:0,isPlaying:!1,isPaused:!1,isOffline:!1,settings:{},programmatic:null,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",autoStart:!0,container:null,adTimer:null,refreshTimer:null,heartbeatTimer:null,programmaticRetryTimer:null,programmaticRetryActive:!1,programmaticRetryCount:0,programmaticLastError:null,adDeliveryProfile:null,initialized:!1,screenOrientation:null,screenDimensions:null,etag:null}}function Y(r){var e,t,i,a;return{initialized:r.initialized,isPlaying:r.isPlaying,isPaused:r.isPaused,isOffline:r.isOffline,currentAd:(e=r.ads[r.currentAdIndex])!=null?e:null,adCount:r.ads.length,programmaticPlaying:r.programmaticPlaying,prefetchedReady:(t=r.prefetchedReady)!=null?t:!1,waterfallMode:r.waterfallMode,adDeliveryProfileMode:(a=(i=r.adDeliveryProfile)==null?void 0:i.mode)!=null?a:null,screenId:r.screenId,deviceId:r.deviceId}}var L=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){var i;(i=this.handlers.get(e))==null||i.delete(t)}emit(e,t){let i=this.handlers.get(e);if(i)for(let a of[...i])try{a(t)}catch(n){console.error(`[TrillboardsAds] Event handler error for "${String(e)}":`,n)}}once(e,t){let i=a=>{this.off(e,i),t(a)};this.on(e,i)}removeAllListeners(){this.handlers.clear()}};var T={debug:0,info:1,warn:2,error:3,none:4},A="[Trillboards]",q=class{constructor(){this.level="none"}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){T[this.level]<=T.debug&&(t!==void 0?console.debug(A,e,t):console.debug(A,e))}info(e,t){T[this.level]<=T.info&&(t!==void 0?console.info(A,e,t):console.info(A,e))}warn(e,t){T[this.level]<=T.warn&&(t!==void 0?console.warn(A,e,t):console.warn(A,e))}error(e,t){T[this.level]<=T.error&&(t!==void 0?console.error(A,e,t):console.error(A,e))}},_=new q;function Z(r){_.setLevel(r)}function he(r){if(typeof window=="undefined")return{slotWidth:null,slotHeight:null,orientation:null,muted:!0,autoplayAllowed:!0,userAgent:null};let e=window.innerWidth,t=window.innerHeight;if(r){let i=r.getBoundingClientRect();i.width>0&&i.height>0&&(e=Math.round(i.width),t=Math.round(i.height))}return{slotWidth:e,slotHeight:t,orientation:t>e?"portrait":"landscape",muted:!0,autoplayAllowed:!0,userAgent:typeof navigator!="undefined"?navigator.userAgent:null}}var D=class{constructor(e){this.container=null;this.apiBase=e!=null?e:g.API_BASE}setContainer(e){this.container=e}async fetchAds(e,t=null){var s,c,o,d,p,f,v,h,m,l,y,b;_.debug("Fetching ads",{deviceId:e});let i={Accept:"application/json"};t&&(i["If-None-Match"]=t);let a=new AbortController,n=setTimeout(()=>a.abort(),1e4);try{let u=he(this.container),S=new URLSearchParams;u.slotWidth&&S.set("slot_w",String(u.slotWidth)),u.slotHeight&&S.set("slot_h",String(u.slotHeight)),u.orientation&&S.set("orientation",u.orientation),S.set("muted",u.muted?"1":"0"),S.set("autoplay",u.autoplayAllowed?"1":"0"),u.userAgent&&S.set("ua",u.userAgent);let W=S.toString(),te=W?`${this.apiBase}/device/${e}/ads?${W}`:`${this.apiBase}/device/${e}/ads`,P=await fetch(te,{headers:i,signal:a.signal});if(clearTimeout(n),P.status===304)return{ads:[],settings:{},programmatic:null,screenId:null,screenOrientation:null,screenDimensions:null,etag:t,notModified:!0};if(!P.ok)throw new Error(`HTTP ${P.status}`);let R=await P.json(),ie=P.headers.get("ETag"),j={ads:(c=(s=R.data)==null?void 0:s.ads)!=null?c:[],settings:(d=(o=R.data)==null?void 0:o.settings)!=null?d:{},programmatic:(f=(p=R.data)==null?void 0:p.header_bidding_settings)!=null?f:null,screenId:(h=(v=R.data)==null?void 0:v.screen_id)!=null?h:null,screenOrientation:(l=(m=R.data)==null?void 0:m.screen_orientation)!=null?l:null,screenDimensions:(b=(y=R.data)==null?void 0:y.screen_dimensions)!=null?b:null,etag:ie,notModified:!1};return _.debug("Ads fetched",{deviceId:e,count:j.ads.length,notModified:!1}),j}catch(u){throw clearTimeout(n),u}}async reportImpression(e){_.debug("Reporting impression",{adId:e.adid,impressionId:e.impid});try{let t=new URLSearchParams({adid:e.adid,impid:e.impid,did:e.did,aid:e.aid,duration:String(e.duration||0),completed:e.completed?"true":"false"});return(await fetch(`${this.apiBase}/impression?${t}`,{method:"GET",signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}async sendHeartbeat(e,t,i={}){var a;_.debug("Sending heartbeat",{deviceId:e});try{let n=await fetch(`${this.apiBase}/device/${e}/heartbeat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(I({device_id:e,screen_id:t,timestamp:new Date().toISOString(),status:"active"},i)),signal:AbortSignal.timeout(5e3)});if(!n.ok)return{ok:!1,data:null};let s=null;try{let c=await n.json();s=(a=c==null?void 0:c.data)!=null?a:null}catch(c){s=null}return{ok:!0,data:s}}catch(n){return{ok:!1,data:null}}}async reportProgrammaticEvent(e){_.debug("Reporting programmatic event",{eventType:e.eventType});try{return(await fetch(`${this.apiBase}/programmatic-event`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screen_id:e.screenId,device_id:e.deviceId,event_type:e.eventType,vast_source:e.vastSource,variant_name:e.variantName,error_code:e.errorCode,error_message:e.errorMessage,duration:e.duration,telemetry:e.telemetry,timestamp:new Date().toISOString()}),signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}};var k=class{constructor(e=10){this.db=null;this.DB_NAME="TrillboardsAdsCache";this.DB_VERSION=1;this.STORE_ADS="ads";this.STORE_IMPRESSIONS="pendingImpressions";this.maxCacheSize=e}async init(){if(!this.db)return new Promise((e,t)=>{if(typeof indexedDB=="undefined"){e();return}let i=indexedDB.open(this.DB_NAME,this.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>{this.db=i.result,e()},i.onupgradeneeded=a=>{let n=a.target.result;n.objectStoreNames.contains(this.STORE_ADS)||n.createObjectStore(this.STORE_ADS,{keyPath:"id"}).createIndex("cached_at","cached_at",{unique:!1}),n.objectStoreNames.contains(this.STORE_IMPRESSIONS)||n.createObjectStore(this.STORE_IMPRESSIONS,{keyPath:"impid"})}})}async cacheAds(e){if(!this.db)return;let t=this.db.transaction(this.STORE_ADS,"readwrite"),i=t.objectStore(this.STORE_ADS),a=Date.now();for(let n of e)i.put(J(I({},n),{cached_at:a}));await new Promise((n,s)=>{t.oncomplete=()=>n(),t.onerror=()=>s(t.error)}),await this.evictOldAds()}async getCachedAds(){return this.db?new Promise(e=>{let a=this.db.transaction(this.STORE_ADS,"readonly").objectStore(this.STORE_ADS).getAll();a.onsuccess=()=>e(a.result||[]),a.onerror=()=>e([])}):[]}async evictOldAds(){if(!this.db)return;let e=await this.getCachedAds();if(e.length<=this.maxCacheSize)return;let i=[...e].sort((s,c)=>{var o,d;return((o=c.cached_at)!=null?o:0)-((d=s.cached_at)!=null?d:0)}).slice(this.maxCacheSize),n=this.db.transaction(this.STORE_ADS,"readwrite").objectStore(this.STORE_ADS);for(let s of i)n.delete(s.id)}async savePendingImpression(e){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).put(e)}async getPendingImpressions(){return this.db?new Promise(e=>{let a=this.db.transaction(this.STORE_IMPRESSIONS,"readonly").objectStore(this.STORE_IMPRESSIONS).getAll();a.onsuccess=()=>e(a.result||[]),a.onerror=()=>e([])}):[]}async clearPendingImpressions(){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).clear()}destroy(){this.db&&(this.db.close(),this.db=null)}};var O=class{constructor(){this.VERSION="1.0";this.registered=null;this.detected=null;this.sessionId=`sess_${Date.now()}_${Math.random().toString(36).slice(2,9)}`;this.eventFilter=null;this.commandHandler=null;this.deviceId=null;this.screenId=null;this.messageListener=null;this.targetOrigin="*"}setContext(e,t){this.deviceId=e,this.screenId=t}register(e){var t,i;return typeof e.send!="function"?(console.error("[TrillboardsAds] Bridge requires send function"),!1):(this.registered={send:e.send,receive:(t=e.receive)!=null?t:null,name:(i=e.name)!=null?i:"CustomBridge"},Array.isArray(e.events)&&(this.eventFilter=new Set(e.events)),this.registered.receive&&this.commandHandler&&this.registered.receive(this.commandHandler),!0)}setCommandHandler(e){this.commandHandler=e}setTargetOrigin(e){this.targetOrigin=e}detect(){var t,i,a,n;if(typeof window=="undefined")return null;let e=null;if(window.TrillboardsBridge&&typeof window.TrillboardsBridge.onEvent=="function")e={type:"android",send:s=>window.TrillboardsBridge.onEvent(s)};else if(window.Android&&typeof window.Android.onTrillboardsEvent=="function")e={type:"android-alt",send:s=>window.Android.onTrillboardsEvent(s)};else if((a=(i=(t=window.webkit)==null?void 0:t.messageHandlers)==null?void 0:i.trillboards)!=null&&a.postMessage)e={type:"ios",send:s=>window.webkit.messageHandlers.trillboards.postMessage(JSON.parse(s))};else if(window.ReactNativeWebView&&typeof window.ReactNativeWebView.postMessage=="function")e={type:"react-native",send:s=>window.ReactNativeWebView.postMessage(s)};else if(window.Flutter&&typeof window.Flutter.postMessage=="function")e={type:"flutter",send:s=>window.Flutter.postMessage(s)};else if(window.__TRILL_CTV_BRIDGE__&&typeof window.__TRILL_CTV_BRIDGE__.postEvent=="function")e={type:"ctv",send:s=>window.__TRILL_CTV_BRIDGE__.postEvent(s)};else if(window.electronAPI&&typeof window.electronAPI.trillboardsEvent=="function")e={type:"electron",send:s=>window.electronAPI.trillboardsEvent(JSON.parse(s))};else if((n=window.__TAURI__)!=null&&n.event)e={type:"tauri",send:s=>{try{window.__TAURI__.event.emit("trillboards-event",JSON.parse(s))}catch(c){}}};else if(typeof window!="undefined"&&window.parent!==window&&typeof window.parent.postMessage=="function"){let s=this.targetOrigin;e={type:"postMessage",send:c=>window.parent.postMessage(JSON.parse(c),s)}}return this.detected=e,this.detected}buildPayload(e,t){let i={type:"trillboards",version:this.VERSION,event:e,data:t!=null?t:{},timestamp:Date.now(),deviceId:this.deviceId,screenId:this.screenId,sessionId:this.sessionId};return JSON.stringify(i)}send(e,t){var n;if(this.eventFilter&&!this.eventFilter.has(e))return!1;let i=this.buildPayload(e,t);if((n=this.registered)!=null&&n.send)try{return this.registered.send(e,JSON.parse(i)),!0}catch(s){}let a=this.detect();if(a!=null&&a.send)try{return a.send(i),!0}catch(s){}return!1}initCommandListener(){typeof window!="undefined"&&(this.messageListener&&window.removeEventListener("message",this.messageListener),this.messageListener=e=>{var t;((t=e.data)==null?void 0:t.type)==="trillboards-command"&&this.commandHandler&&this.commandHandler(e.data)},window.addEventListener("message",this.messageListener))}destroy(){typeof window!="undefined"&&this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.registered=null,this.detected=null,this.commandHandler=null,this.eventFilter=null}};var x=class{constructor(e=5,t=3e4){this.sources=new Map;this.maxFailures=e,this.openDurationMs=t}recordSuccess(e){e&&this.sources.set(e,{consecutiveFailures:0,openUntil:0})}recordFailure(e){var i;if(!e)return;let t=(i=this.sources.get(e))!=null?i:{consecutiveFailures:0,openUntil:0};t.consecutiveFailures+=1,t.consecutiveFailures>=this.maxFailures&&(t.openUntil=Date.now()+this.openDurationMs),this.sources.set(e,t)}isAvailable(e){if(!e)return!0;let t=this.sources.get(e);if(!t||t.consecutiveFailures<this.maxFailures)return!0;let i=Date.now();return i>=t.openUntil?(t.openUntil=i+this.openDurationMs,!0):!1}getState(e){var t;return(t=this.sources.get(e))!=null?t:{consecutiveFailures:0,openUntil:0}}reset(){this.sources.clear()}};var H=class{constructor(){this.totalRequests=0;this.fills=0;this.noFills=0;this.timeouts=0;this.errors=0}recordRequest(){this.totalRequests++}recordFill(){this.fills++}recordNoFill(){this.noFills++}recordTimeout(){this.timeouts++}recordError(){this.errors++}getFillRate(){return this.totalRequests>0?this.fills/this.totalRequests:0}getNoFillRate(){return this.totalRequests>0?this.noFills/this.totalRequests:0}getTimeoutRate(){return this.totalRequests>0?this.timeouts/this.totalRequests:0}getErrorRate(){return this.totalRequests>0?this.errors/this.totalRequests:0}getSnapshot(){return{fill_rate:Math.round(this.getFillRate()*1e4)/1e4,no_fill_rate:Math.round(this.getNoFillRate()*1e4)/1e4,timeout_rate:Math.round(this.getTimeoutRate()*1e4)/1e4,error_rate:Math.round(this.getErrorRate()*1e4)/1e4}}reset(){this.totalRequests=0,this.fills=0,this.noFills=0,this.timeouts=0,this.errors=0}};var N=class{constructor(e){this.circuitBreaker=e}getNextSource(e){if(!e||e.length===0)return null;let t=[...e].filter(i=>i.enabled).sort((i,a)=>i.priority-a.priority||Math.random()-.5);for(let i of t)if(this.circuitBreaker.isAvailable(i.name))return{source:i,vastUrl:i.vast_url};return null}getAvailableSources(e){return!e||e.length===0?[]:e.filter(t=>t.enabled&&this.circuitBreaker.isAvailable(t.name)).sort((t,i)=>t.priority-i.priority||Math.random()-.5).map(t=>({source:t,vastUrl:t.vast_url}))}recordSuccess(e){this.circuitBreaker.recordSuccess(e)}recordFailure(e){this.circuitBreaker.recordFailure(e)}};var w=class w{constructor(e,t=12e3){this.vastTagUrl=null;this.variantName=null;this.screenId=null;this.adContainer=null;this.contentVideo=null;this.ima={};this.currentSourceName=null;this.isPlaying=!1;this.isPrefetching=!1;this.prefetchedReady=!1;this.prefetchTimer=null;this.adStartTime=0;this.sources=[];this.circuitBreaker=new x(5,3e4),this.telemetry=new H,this.waterfallEngine=new N(this.circuitBreaker),this.events=e,this.timeoutMs=t}setSources(e){this.sources=e}getTelemetrySnapshot(){return this.telemetry.getSnapshot()}getIsPlaying(){return this.isPlaying}hasPrefetchedAd(){return this.prefetchedReady}createAdContainer(e){this.adContainer||(this.adContainer=document.createElement("div"),this.adContainer.id="trillboards-ad-container",this.adContainer.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;z-index:10000;display:none;",this.contentVideo=document.createElement("video"),this.contentVideo.id="trillboards-content-video",this.contentVideo.style.cssText="width:100%;height:100%;",this.contentVideo.setAttribute("playsinline",""),this.contentVideo.muted=!0,this.adContainer.appendChild(this.contentVideo),e.appendChild(this.adContainer))}async play(e,t){if(this.isPlaying)return;if(!this.adContainer||!this.contentVideo){t("Ad container not initialized");return}let i=this.vastTagUrl,a="default";if(this.sources.length>0){let o=this.waterfallEngine.getNextSource(this.sources);o&&(i=o.vastUrl,a=o.source.name)}if(!i){t("No VAST URL available");return}this.currentSourceName=a,this.telemetry.recordRequest();let n=Date.now(),s=i.includes("correlator=")?i.replace(/correlator=[^&]*/,`correlator=${n}`):`${i}${i.includes("?")?"&":"?"}correlator=${n}`;if(!await this.ensureImaSdk()){let o="Google IMA SDK not loaded";this.events.emit("programmatic_error",{error:o,code:void 0}),t(o),this.telemetry.recordError(),this.waterfallEngine.recordFailure(a);return}this.isPlaying=!0,this.adContainer.style.display="block";try{await this.requestAdsViaIMA(s,e,t)}catch(o){this.isPlaying=!1,this.adContainer.style.display="none",this.telemetry.recordError(),this.waterfallEngine.recordFailure(a),t(o instanceof Error?o.message:String(o))}}async ensureImaSdk(){return typeof google!="undefined"&&(google!=null&&google.ima)?!0:typeof document=="undefined"?!1:document.querySelector(`script[src="${w.IMA_SDK_URL}"]`)?new Promise(t=>{let i=Date.now(),a=()=>{typeof google!="undefined"&&(google!=null&&google.ima)?t(!0):Date.now()-i>5e3?t(!1):setTimeout(a,100)};a()}):(w.imaLoadPromise||(w.imaLoadPromise=new Promise(t=>{let i=document.createElement("script");i.src=w.IMA_SDK_URL,i.async=!0,i.onload=()=>{w.imaLoadPromise=null,t(!0)},i.onerror=()=>{w.imaLoadPromise=null,t(!1)},document.head.appendChild(i)})),w.imaLoadPromise)}async requestAdsViaIMA(e,t,i){return new Promise(a=>{let n=!1,s=()=>{n||(n=!0,t(),a())},c=v=>{n||(n=!0,i(v),a())};this.destroyIMA();let o=new google.ima.AdDisplayContainer(this.adContainer,this.contentVideo);o.initialize();let d=new google.ima.AdsLoader(o);this.ima.adDisplayContainer=o,this.ima.adsLoader=d;let p=setTimeout(()=>{this.telemetry.recordTimeout(),this.waterfallEngine.recordFailure(this.currentSourceName),this.stop({silent:!0}),this.events.emit("programmatic_timeout",{source:this.currentSourceName||"unknown"}),c("VAST request timeout")},this.timeoutMs);d.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,v=>{clearTimeout(p),this.telemetry.recordFill(),this.waterfallEngine.recordSuccess(this.currentSourceName);let h=v.getAdsManager(this.contentVideo);this.ima.adsManager=h,this.adStartTime=Date.now(),h.addEventListener(google.ima.AdEvent.Type.COMPLETE,()=>{let m=Math.round((Date.now()-this.adStartTime)/1e3);this.events.emit("programmatic_ended",{source:this.currentSourceName||"unknown",variant:this.variantName,duration:m}),this.stop({silent:!0}),s()}),h.addEventListener(google.ima.AdEvent.Type.STARTED,()=>{this.events.emit("programmatic_started",{source:this.currentSourceName||"unknown",variant:this.variantName})}),h.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,m=>{var y,b,u;let l=m.getError();this.events.emit("programmatic_error",{error:((y=l==null?void 0:l.getMessage)==null?void 0:y.call(l))||"Ad playback error",code:(b=l==null?void 0:l.getErrorCode)==null?void 0:b.call(l)}),this.stop({silent:!0}),c(((u=l==null?void 0:l.getMessage)==null?void 0:u.call(l))||"Ad error")});try{let m=this.adContainer.offsetWidth||window.innerWidth,l=this.adContainer.offsetHeight||window.innerHeight;h.init(m,l,google.ima.ViewMode.NORMAL),h.start()}catch(m){this.stop({silent:!0}),c("Failed to start ad")}}),d.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,v=>{var y,b;clearTimeout(p);let h=v.getError(),m=(y=h==null?void 0:h.getErrorCode)==null?void 0:y.call(h),l=((b=h==null?void 0:h.getMessage)==null?void 0:b.call(h))||"Ad load error";m===303?(this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_no_fill",{source:this.currentSourceName||"unknown"})):(this.telemetry.recordError(),this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_error",{error:l,code:m})),this.stop({silent:!0}),c(l)});let f=new google.ima.AdsRequest;f.adTagUrl=e,f.linearAdSlotWidth=this.adContainer.offsetWidth||window.innerWidth,f.linearAdSlotHeight=this.adContainer.offsetHeight||window.innerHeight,this.ima.adsRequest=f,d.requestAds(f)})}async prefetch(){return this.isPrefetching||this.prefetchedReady||!this.vastTagUrl&&this.sources.length===0?!1:(this.isPrefetching=!0,this.prefetchedReady=!0,this.isPrefetching=!1,this.events.emit("ad_ready",{type:"programmatic",source:this.currentSourceName||void 0}),!0)}destroyPrefetched(){this.prefetchedReady=!1,this.isPrefetching=!1,this.prefetchTimer&&(clearTimeout(this.prefetchTimer),this.prefetchTimer=null)}stop(e){this.isPlaying=!1,this.destroyIMA(),this.adContainer&&(this.adContainer.style.display="none")}destroyIMA(){if(this.ima.adsManager){try{this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.COMPLETE),this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.STARTED),this.ima.adsManager.removeEventListener(google.ima.AdErrorEvent.Type.AD_ERROR)}catch(e){}try{this.ima.adsManager.destroy()}catch(e){}this.ima.adsManager=null}if(this.ima.adsLoader){try{this.ima.adsLoader.destroy()}catch(e){}this.ima.adsLoader=null}this.ima.adDisplayContainer=null,this.ima.adsRequest=null}destroy(){this.stop({silent:!0}),this.destroyPrefetched(),this.adContainer&&(this.adContainer.remove(),this.adContainer=null,this.contentVideo=null),this.circuitBreaker.reset(),this.telemetry.reset()}};w.IMA_SDK_URL="https://imasdk.googleapis.com/js/sdkloader/ima3.js",w.imaLoadPromise=null;var B=w;var Q=300,F=class{constructor(e,t=8e3){this.container=null;this.currentAd=null;this.adTimer=null;this.videoElement=null;this.imageElement=null;this.videoEndedHandler=null;this.videoErrorHandler=null;this.events=e,this.defaultImageDuration=t}setContainer(e){this.container=e}play(e,t,i=0){this.container&&(this.stop(),this.currentAd=e,this.events.emit("ad_started",{id:e.id,type:e.type,index:i}),e.type==="video"?this.playVideo(e,t):this.playImage(e,t))}playVideo(e,t){for(this.videoElement=document.createElement("video"),this.videoElement.src=e.media_url,this.videoElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.videoElement.setAttribute("playsinline",""),this.videoElement.muted=!0,this.videoElement.autoplay=!0,this.videoEndedHandler=()=>{var a,n;let i=Math.min(Math.round((n=(a=this.videoElement)==null?void 0:a.duration)!=null?n:e.duration),Q);this.events.emit("ad_ended",{id:e.id,type:e.type,duration:i}),this.stop(),t()},this.videoErrorHandler=()=>{this.events.emit("ad_error",{error:"Video playback error"}),this.stop(),t()},this.videoElement.addEventListener("ended",this.videoEndedHandler),this.videoElement.addEventListener("error",this.videoErrorHandler);this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.videoElement)}playImage(e,t){var n;for(this.imageElement=document.createElement("img"),this.imageElement.src=e.media_url,this.imageElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.imageElement.alt=(n=e.title)!=null?n:"Advertisement";this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.imageElement);let i=Math.min(e.duration||this.defaultImageDuration/1e3,Q),a=i*1e3;this.adTimer=setTimeout(()=>{this.events.emit("ad_ended",{id:e.id,type:e.type,duration:Math.round(i)}),this.stop(),t()},a)}stop(){this.adTimer&&(clearTimeout(this.adTimer),this.adTimer=null),this.videoElement&&(this.videoEndedHandler&&(this.videoElement.removeEventListener("ended",this.videoEndedHandler),this.videoEndedHandler=null),this.videoErrorHandler&&(this.videoElement.removeEventListener("error",this.videoErrorHandler),this.videoErrorHandler=null),this.videoElement.pause(),this.videoElement.removeAttribute("src"),this.videoElement.load(),this.videoElement.remove(),this.videoElement=null),this.imageElement&&(this.imageElement.remove(),this.imageElement=null),this.currentAd=null}destroy(){this.stop(),this.container=null}};function me(r){if(!r)return null;let e=String(r).toLowerCase();return["programmatic_only","programmatic-only","programmatic"].includes(e)?"programmatic_only":["programmatic_then_direct","programmatic-direct","programmatic+direct","hybrid"].includes(e)?"programmatic_then_direct":["direct_only","direct-only","direct"].includes(e)?"direct_only":null}var E=class E{constructor(e){this.onlineHandler=null;this.offlineHandler=null;this.visibilityHandler=null;this.config=U(e),this.config.debug&&Z("debug"),this.state=K(),this.events=new L,this.api=new D(this.config.apiBase),this.cache=new k(this.config.cacheSize),this.bridge=new O,this.programmaticPlayer=new B(this.events,this.config.programmaticTimeout),this.directPlayer=new F(this.events,this.config.defaultImageDuration)}static async create(e){E._instance&&(E._instance.destroy(),E._instance=null);let t=new E(e);return await t.init(e),E._instance=t,t}async init(e){if(this.state.initialized)return;this.config=U(e),this.state.deviceId=this.config.deviceId,this.state.waterfallMode=this.config.waterfall,this.state.autoStart=this.config.autoStart;try{await this.cache.init()}catch(i){}this.bridge.setContext(this.state.deviceId,this.state.screenId),this.bridge.setCommandHandler(i=>this.handleBridgeCommand(i)),this.bridge.initCommandListener(),this.bridge.detect();let t=["initialized","ad_started","ad_ended","ad_ready","ad_error","programmatic_started","programmatic_ended","programmatic_error","programmatic_no_fill","state_changed"];for(let i of t)this.events.on(i,a=>{this.bridge.send(i,a)});this.createContainer(),typeof window!="undefined"&&(this.onlineHandler=()=>{this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.refreshAds().catch(()=>{})},this.offlineHandler=()=>{this.state.isOffline=!0,this.events.emit("offline",{}),this.emitStateChanged()},window.addEventListener("online",this.onlineHandler),window.addEventListener("offline",this.offlineHandler),this.visibilityHandler=()=>{let i=!document.hidden;this.events.emit("visibility_changed",{visible:i}),i&&this.refreshAds().catch(()=>{})},document.addEventListener("visibilitychange",this.visibilityHandler)),await this.refreshAds(),this.startRefreshTimer(),this.startHeartbeatTimer(),this.state.initialized=!0,this.events.emit("initialized",{deviceId:this.config.deviceId}),this.emitStateChanged(),this.state.autoStart&&this.prefetchNextAd().catch(()=>{})}destroy(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer),this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer),this.programmaticPlayer.destroy(),this.directPlayer.destroy(),this.bridge.destroy(),this.cache.destroy(),typeof window!="undefined"&&(this.onlineHandler&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null),this.offlineHandler&&(window.removeEventListener("offline",this.offlineHandler),this.offlineHandler=null),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null)),this.state.container&&this.state.container.remove(),this.events.removeAllListeners(),this.state=K(),E._instance===this&&(E._instance=null)}show(){this.state.container&&(this.state.container.style.display="block"),this.state.isPlaying=!0,this.state.isPaused=!1,this.playNextAd(),this.emitStateChanged()}hide(){this.state.container&&(this.state.container.style.display="none"),this.state.isPlaying=!1,this.state.isPaused=!0,this.programmaticPlayer.stop(),this.directPlayer.stop(),this.emitStateChanged()}skipAd(){this.programmaticPlayer.stop(),this.directPlayer.stop(),this.playNextAd()}async refresh(){this.programmaticPlayer.destroyPrefetched(),this.resetProgrammaticBackoff(),this.state.etag=null,await this.refreshAds(),this.prefetchNextAd()}async prefetchNextAd(){let e=this.state.waterfallMode;if(e==="programmatic_only"||e==="programmatic_then_direct"){let t=this.state.programmatic;(t!=null&&t.vast_tag_url||t!=null&&t.sources&&t.sources.length>0)&&await this.programmaticPlayer.prefetch()}}getState(){return Y(this.state)}getAds(){return[...this.state.ads]}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}registerBridge(e){return this.bridge.register(e)}createContainer(){if(typeof document=="undefined")return;let e=document.createElement("div");e.id="trillboards-ads-container",e.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;z-index:99999;display:none;background:#000;",document.body.appendChild(e),this.state.container=e,this.api.setContainer(e),this.directPlayer.setContainer(e),this.programmaticPlayer.createAdContainer(e)}async refreshAds(){var e,t,i,a,n,s,c,o;try{let d=await this.api.fetchAds(this.config.deviceId,this.state.etag);if(d.notModified)return;this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.state.ads=d.ads,this.state.settings=d.settings,this.state.etag=d.etag,this.state.screenId=(e=d.screenId)!=null?e:this.state.screenId,this.state.programmatic=d.programmatic,this.state.screenOrientation=(t=d.screenOrientation)!=null?t:this.state.screenOrientation,this.state.screenDimensions=(i=d.screenDimensions)!=null?i:this.state.screenDimensions,this.bridge.setContext(this.state.deviceId,this.state.screenId),this.programmaticPlayer.screenId=this.state.screenId,this.programmaticPlayer.vastTagUrl=(n=(a=this.state.programmatic)==null?void 0:a.vast_tag_url)!=null?n:null,this.programmaticPlayer.variantName=(c=(s=this.state.programmatic)==null?void 0:s.variant_name)!=null?c:null,(o=this.state.programmatic)!=null&&o.sources&&this.programmaticPlayer.setSources(this.state.programmatic.sources),this.state.ads.length>0&&await this.cache.cacheAds(this.state.ads),this.events.emit("ads_refreshed",{count:this.state.ads.length})}catch(d){this.state.isOffline=!0;let p=await this.cache.getCachedAds();p.length>0&&(this.state.ads=p,this.events.emit("ads_loaded_from_cache",{count:p.length}))}}startRefreshTimer(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.refreshTimer=setInterval(()=>{this.refreshAds().catch(()=>{})},this.config.refreshInterval)}startHeartbeatTimer(){this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer);let e=()=>{this.sendHeartbeatTick().catch(()=>{})};e(),this.state.heartbeatTimer=setInterval(()=>{e()},this.config.heartbeatInterval)}async sendHeartbeatTick(){var t;let e=await this.api.sendHeartbeat(this.config.deviceId,this.state.screenId,this.buildHeartbeatPayload());!e.ok||!e.data||((t=e.data.ad_delivery_profile)!=null&&t.mode&&this.applyAdDeliveryProfile(e.data.ad_delivery_profile),Array.isArray(e.data.commands)&&e.data.commands.length>0&&this.runHeartbeatCommands(e.data.commands))}buildHeartbeatPayload(){var d;let e=typeof navigator!="undefined"?navigator.userAgent:"",t=typeof navigator!="undefined"?navigator.platform:null,i=typeof navigator!="undefined"?navigator.connection:null,a=e.match(/(?:Chrome|Chromium)\/(\d+)/i),n=a?Number(a[1]):void 0,s=typeof window!="undefined"?!!((d=window==null?void 0:window.google)!=null&&d.ima):null,o={telemetry:{powerState:typeof document!="undefined"&&document.hidden?"standby":"on",agentStatus:typeof document!="undefined"&&document.hidden?"background":"foreground",os:t||void 0,agentVersion:M,ima_integration:"html5_webview",ima_supported:s,webview_chromium_major:Number.isFinite(n)?n:void 0},sdk:{version:M,ima_supported:s,ima_integration:"html5_webview",webview_chromium_major:Number.isFinite(n)?n:void 0},device:{os:t||void 0,model:e||void 0}};return i&&(o.network={connectionType:i.type||void 0,effectiveType:i.effectiveType||void 0,downlinkMbps:typeof i.downlink=="number"?i.downlink:void 0,bandwidthMbps:typeof i.downlink=="number"?i.downlink:void 0,rtt:typeof i.rtt=="number"?i.rtt:void 0,latencyRtt:typeof i.rtt=="number"?i.rtt:void 0,saveData:typeof i.saveData=="boolean"?i.saveData:void 0}),o}applyAdDeliveryProfile(e){var i,a;if(!(e!=null&&e.mode))return;let t=(a=(i=this.state.adDeliveryProfile)==null?void 0:i.mode)!=null?a:null;this.state.adDeliveryProfile=e,e.mode==="vast_fallback"&&this.state.programmaticPlaying&&(this.programmaticPlayer.stop({silent:!0}),this.state.programmaticPlaying=!1),t!==e.mode&&this.emitStateChanged()}runHeartbeatCommands(e){var t;for(let i of e){let a=String((i==null?void 0:i.command)||"").toLowerCase();if(a==="refresh_ads")this.refresh().catch(()=>{});else if(a==="restart"){if(typeof window!="undefined"&&typeof((t=window.location)==null?void 0:t.reload)=="function"){window.location.reload();return}this.refresh().catch(()=>{})}}}playNextAd(){var t;if(((t=this.state.adDeliveryProfile)==null?void 0:t.mode)==="vast_fallback"&&this.state.ads.length>0){this.playDirect();return}let e=this.state.waterfallMode;e==="programmatic_only"||e==="programmatic_then_direct"?this.playProgrammatic():e==="direct_only"&&this.playDirect()}playProgrammatic(){this.programmaticPlayer.getIsPlaying()||(this.state.programmaticPlaying=!0,this.emitStateChanged(),this.programmaticPlayer.play(()=>{this.state.programmaticPlaying=!1,this.resetProgrammaticBackoff(),this.emitStateChanged(),this.scheduleProgrammaticRetry()},e=>{this.state.programmaticPlaying=!1,this.state.programmaticLastError=e;let t=String(e||"").toLowerCase();t.includes("no fill")||t.includes("no ads vast response")||t.includes("waterfall_exhausted")||t==="throttled"||t==="busy"?this.state.programmaticRetryCount=0:this.state.programmaticRetryCount++,this.emitStateChanged(),this.state.waterfallMode==="programmatic_then_direct"&&this.state.ads.length>0?this.playDirect():this.scheduleProgrammaticRetry()}))}playDirect(){if(this.state.ads.length===0)return;let e=this.state.currentAdIndex%this.state.ads.length,t=this.state.ads[e];t&&this.directPlayer.play(t,()=>{var i;this.state.currentAdIndex=(e+1)%this.state.ads.length,this.api.reportImpression({adid:t.id,impid:t.impression_id,did:this.config.deviceId,aid:(i=t.allocation_id)!=null?i:"",duration:t.duration,completed:!0}),this.emitStateChanged(),this.scheduleNextDirect()},e)}scheduleNextDirect(){this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.adTimer=setTimeout(()=>{this.playNextAd()},this.config.defaultAdInterval)}scheduleProgrammaticRetry(){this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer);let e=this.state.programmaticRetryCount,t=this.config.programmaticRetry,i=this.config.programmaticBackoffMax,a=Math.min(t*Math.pow(2,e),i),n=a*.2*Math.random();this.state.programmaticRetryTimer=setTimeout(()=>{this.prefetchNextAd().catch(()=>{}).then(()=>{this.playNextAd()})},a+n)}resetProgrammaticBackoff(){this.state.programmaticRetryCount=0,this.state.programmaticLastError=null,this.state.programmaticRetryTimer&&(clearTimeout(this.state.programmaticRetryTimer),this.state.programmaticRetryTimer=null)}emitStateChanged(){this.events.emit("state_changed",this.getState())}handleBridgeCommand(e){let t;try{t=typeof e=="string"?JSON.parse(e):e}catch(n){console.warn("[TrillboardsAds] Failed to parse bridge command:",e);return}let i=t.action||t.command,a=t.params||t.data||{};switch(i){case"show":this.show();break;case"hide":this.hide();break;case"skip":this.skipAd();break;case"refresh":this.refresh();break;case"getState":this.bridge.send("state_changed",this.getState());break;case"configure":if(a.waterfall){let n=me(a.waterfall);n&&(this.state.waterfallMode=n)}typeof a.volume=="number"&&(this.state.settings.sound_enabled=a.volume>0);break}}};E._instance=null;var V=E;var ee={VERSION:M,_instance:null,async init(r){var t,i;let e={deviceId:r.deviceId,waterfall:(t=r.waterfall)!=null?t:"programmatic_only",autoStart:(i=r.autoStart)!=null?i:!0,apiBase:r.apiBase};this._instance=await V.create(e)},show(){var r;(r=this._instance)==null||r.show()},hide(){var r;(r=this._instance)==null||r.hide()},skipAd(){var r;(r=this._instance)==null||r.skipAd()},async refresh(){var r;await((r=this._instance)==null?void 0:r.refresh())},async prefetchNextAd(){var r;await((r=this._instance)==null?void 0:r.prefetchNextAd())},getState(){var r,e;return(e=(r=this._instance)==null?void 0:r.getState())!=null?e:I({},X)},getAds(){var r,e;return(e=(r=this._instance)==null?void 0:r.getAds())!=null?e:[]},on(r,e){var t;(t=this._instance)==null||t.on(r,e)},off(r,e){var t;(t=this._instance)==null||t.off(r,e)},registerBridge(r){var e,t;return(t=(e=this._instance)==null?void 0:e.registerBridge(r))!=null?t:!1},destroy(){var r;(r=this._instance)==null||r.destroy(),this._instance=null}};typeof window!="undefined"&&(window.TrillboardsLite=ee);return ce(ue);})();
1
+ "use strict";var TrillboardsLiteBundle=(()=>{var D=Object.defineProperty,se=Object.defineProperties,oe=Object.getOwnPropertyDescriptor,de=Object.getOwnPropertyDescriptors,le=Object.getOwnPropertyNames,X=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var Y=(r,e,t)=>e in r?D(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,T=(r,e)=>{for(var t in e||(e={}))Z.call(e,t)&&Y(r,t,e[t]);if(X)for(var t of X(e))ce.call(e,t)&&Y(r,t,e[t]);return r},L=(r,e)=>se(r,de(e));var he=(r,e)=>{for(var t in e)D(r,t,{get:e[t],enumerable:!0})},me=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of le(e))!Z.call(r,a)&&a!==t&&D(r,a,{get:()=>e[a],enumerable:!(i=oe(e,a))||i.enumerable});return r};var ue=r=>me(D({},"__esModule",{value:!0}),r);var fe={};he(fe,{TrillboardsLite:()=>re});var M="2.2.0",u={API_BASE:"https://api.trillboards.com/v1/partner",CDN_BASE:"https://cdn.trillboards.com",CACHE_NAME:"trillboards-lite-ads",CACHE_SIZE:10,REFRESH_INTERVAL:12e4,HEARTBEAT_INTERVAL:6e4,DEFAULT_IMAGE_DURATION:8e3,DEFAULT_AD_INTERVAL:6e4,PROGRAMMATIC_TIMEOUT_MS:12e3,PROGRAMMATIC_MIN_INTERVAL_MS:5e3,PROGRAMMATIC_RETRY_MS:5e3,PROGRAMMATIC_BACKOFF_MAX_MS:3e5,VERSION:M};function W(r){var t,i,a,n,s,c,o,d,g,f,v,h,m,l,y;let e=(t=r.deviceId)==null?void 0:t.trim();if(!e)throw new Error("TrillboardsConfig: deviceId must be a non-empty string");return{deviceId:e,apiBase:(i=r.apiBase)!=null?i:u.API_BASE,cdnBase:(a=r.cdnBase)!=null?a:u.CDN_BASE,waterfall:(n=r.waterfall)!=null?n:"programmatic_only",autoStart:(s=r.autoStart)!=null?s:!0,refreshInterval:Math.max((c=r.refreshInterval)!=null?c:u.REFRESH_INTERVAL,1e4),heartbeatInterval:Math.max((o=r.heartbeatInterval)!=null?o:u.HEARTBEAT_INTERVAL,5e3),defaultImageDuration:Math.max((d=r.defaultImageDuration)!=null?d:u.DEFAULT_IMAGE_DURATION,1e3),defaultAdInterval:Math.max((g=r.defaultAdInterval)!=null?g:u.DEFAULT_AD_INTERVAL,1e3),programmaticTimeout:Math.max((f=r.programmaticTimeout)!=null?f:u.PROGRAMMATIC_TIMEOUT_MS,1e3),programmaticMinInterval:Math.max((v=r.programmaticMinInterval)!=null?v:u.PROGRAMMATIC_MIN_INTERVAL_MS,1e3),programmaticRetry:Math.max((h=r.programmaticRetry)!=null?h:u.PROGRAMMATIC_RETRY_MS,1e3),programmaticBackoffMax:Math.max((m=r.programmaticBackoffMax)!=null?m:u.PROGRAMMATIC_BACKOFF_MAX_MS,5e3),cacheSize:Math.max((l=r.cacheSize)!=null?l:u.CACHE_SIZE,1),debug:(y=r.debug)!=null?y:!1}}var Q={initialized:!1,isPlaying:!1,isPaused:!1,isOffline:!1,currentAd:null,adCount:0,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",adDeliveryProfileMode:null,screenId:null,deviceId:null};function j(){return{deviceId:null,partnerId:null,screenId:null,ads:[],currentAdIndex:0,isPlaying:!1,isPaused:!1,isOffline:!1,settings:{},programmatic:null,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",autoStart:!0,container:null,adTimer:null,refreshTimer:null,heartbeatTimer:null,programmaticRetryTimer:null,programmaticRetryActive:!1,programmaticRetryCount:0,programmaticLastError:null,adDeliveryProfile:null,initialized:!1,screenOrientation:null,screenDimensions:null,etag:null}}function ee(r){var e,t,i,a;return{initialized:r.initialized,isPlaying:r.isPlaying,isPaused:r.isPaused,isOffline:r.isOffline,currentAd:(e=r.ads[r.currentAdIndex])!=null?e:null,adCount:r.ads.length,programmaticPlaying:r.programmaticPlaying,prefetchedReady:(t=r.prefetchedReady)!=null?t:!1,waterfallMode:r.waterfallMode,adDeliveryProfileMode:(a=(i=r.adDeliveryProfile)==null?void 0:i.mode)!=null?a:null,screenId:r.screenId,deviceId:r.deviceId}}var k=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){var i;(i=this.handlers.get(e))==null||i.delete(t)}emit(e,t){let i=this.handlers.get(e);if(i)for(let a of[...i])try{a(t)}catch(n){console.error(`[TrillboardsAds] Event handler error for "${String(e)}":`,n)}}once(e,t){let i=a=>{this.off(e,i),t(a)};this.on(e,i)}removeAllListeners(){this.handlers.clear()}};var A={debug:0,info:1,warn:2,error:3,none:4},S="[Trillboards]",z=class{constructor(){this.level="none"}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){A[this.level]<=A.debug&&(t!==void 0?console.debug(S,e,t):console.debug(S,e))}info(e,t){A[this.level]<=A.info&&(t!==void 0?console.info(S,e,t):console.info(S,e))}warn(e,t){A[this.level]<=A.warn&&(t!==void 0?console.warn(S,e,t):console.warn(S,e))}error(e,t){A[this.level]<=A.error&&(t!==void 0?console.error(S,e,t):console.error(S,e))}},R=new z;function te(r){R.setLevel(r)}function ge(r){if(typeof window=="undefined")return{slotWidth:null,slotHeight:null,orientation:null,muted:!0,autoplayAllowed:!0,userAgent:null};let e=window.innerWidth,t=window.innerHeight;if(r){let i=r.getBoundingClientRect();i.width>0&&i.height>0&&(e=Math.round(i.width),t=Math.round(i.height))}return{slotWidth:e,slotHeight:t,orientation:t>e?"portrait":"landscape",muted:!0,autoplayAllowed:!0,userAgent:typeof navigator!="undefined"?navigator.userAgent:null}}var O=class{constructor(e){this.container=null;this.apiBase=e!=null?e:u.API_BASE}setContainer(e){this.container=e}async fetchAds(e,t=null){var s,c,o,d,g,f,v,h,m,l,y,b,P;R.debug("Fetching ads",{deviceId:e});let i={Accept:"application/json"};t&&(i["If-None-Match"]=t);let a=new AbortController,n=setTimeout(()=>a.abort(),1e4);try{let p=ge(this.container),_=new URLSearchParams;p.slotWidth&&_.set("slot_w",String(p.slotWidth)),p.slotHeight&&_.set("slot_h",String(p.slotHeight)),p.orientation&&_.set("orientation",p.orientation),_.set("muted",p.muted?"1":"0"),_.set("autoplay",p.autoplayAllowed?"1":"0"),p.userAgent&&_.set("ua",p.userAgent);let G=_.toString(),ae=G?`${this.apiBase}/device/${e}/ads?${G}`:`${this.apiBase}/device/${e}/ads`,C=await fetch(ae,{headers:i,signal:a.signal});if(clearTimeout(n),C.status===304)return{ads:[],settings:{},programmatic:null,screenId:null,screenOrientation:null,screenDimensions:null,etag:t,notModified:!0};if(!C.ok)throw new Error(`HTTP ${C.status}`);let I=await C.json(),ne=C.headers.get("ETag"),q=(s=I.data)==null?void 0:s.header_bidding_settings,$={ads:(o=(c=I.data)==null?void 0:c.ads)!=null?o:[],settings:(g=(d=I.data)==null?void 0:d.settings)!=null?g:{},programmatic:q?L(T({},q),{sources:((v=(f=q.vast_waterfall)==null?void 0:f.sources)!=null?v:[]).map(J=>L(T({},J),{enabled:J.enabled!==!1}))}):null,screenId:(m=(h=I.data)==null?void 0:h.screen_id)!=null?m:null,screenOrientation:(y=(l=I.data)==null?void 0:l.screen_orientation)!=null?y:null,screenDimensions:(P=(b=I.data)==null?void 0:b.screen_dimensions)!=null?P:null,etag:ne,notModified:!1};return R.debug("Ads fetched",{deviceId:e,count:$.ads.length,notModified:!1}),$}catch(p){throw clearTimeout(n),p}}async reportImpression(e){R.debug("Reporting impression",{adId:e.adid,impressionId:e.impid});try{let t=new URLSearchParams({adid:e.adid,impid:e.impid,did:e.did,aid:e.aid,duration:String(e.duration||0),completed:e.completed?"true":"false"});return(await fetch(`${this.apiBase}/impression?${t}`,{method:"GET",signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}async sendHeartbeat(e,t,i={}){var a;R.debug("Sending heartbeat",{deviceId:e});try{let n=await fetch(`${this.apiBase}/device/${e}/heartbeat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(T({device_id:e,screen_id:t,timestamp:new Date().toISOString(),status:"active"},i)),signal:AbortSignal.timeout(5e3)});if(!n.ok)return{ok:!1,data:null};let s=null;try{let c=await n.json();s=(a=c==null?void 0:c.data)!=null?a:null}catch(c){s=null}return{ok:!0,data:s}}catch(n){return{ok:!1,data:null}}}async reportProgrammaticEvent(e){R.debug("Reporting programmatic event",{eventType:e.eventType});try{return(await fetch(`${this.apiBase}/programmatic-event`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screen_id:e.screenId,device_id:e.deviceId,event_type:e.eventType,vast_source:e.vastSource,variant_name:e.variantName,error_code:e.errorCode,error_message:e.errorMessage,duration:e.duration,telemetry:e.telemetry,timestamp:new Date().toISOString()}),signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}};var x=class{constructor(e=10){this.db=null;this.DB_NAME="TrillboardsAdsCache";this.DB_VERSION=1;this.STORE_ADS="ads";this.STORE_IMPRESSIONS="pendingImpressions";this.maxCacheSize=e}async init(){if(!this.db)return new Promise((e,t)=>{if(typeof indexedDB=="undefined"){e();return}let i=indexedDB.open(this.DB_NAME,this.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>{this.db=i.result,e()},i.onupgradeneeded=a=>{let n=a.target.result;n.objectStoreNames.contains(this.STORE_ADS)||n.createObjectStore(this.STORE_ADS,{keyPath:"id"}).createIndex("cached_at","cached_at",{unique:!1}),n.objectStoreNames.contains(this.STORE_IMPRESSIONS)||n.createObjectStore(this.STORE_IMPRESSIONS,{keyPath:"impid"})}})}async cacheAds(e){if(!this.db)return;let t=this.db.transaction(this.STORE_ADS,"readwrite"),i=t.objectStore(this.STORE_ADS),a=Date.now();for(let n of e)i.put(L(T({},n),{cached_at:a}));await new Promise((n,s)=>{t.oncomplete=()=>n(),t.onerror=()=>s(t.error)}),await this.evictOldAds()}async getCachedAds(){return this.db?new Promise(e=>{let a=this.db.transaction(this.STORE_ADS,"readonly").objectStore(this.STORE_ADS).getAll();a.onsuccess=()=>e(a.result||[]),a.onerror=()=>e([])}):[]}async evictOldAds(){if(!this.db)return;let e=await this.getCachedAds();if(e.length<=this.maxCacheSize)return;let i=[...e].sort((s,c)=>{var o,d;return((o=c.cached_at)!=null?o:0)-((d=s.cached_at)!=null?d:0)}).slice(this.maxCacheSize),n=this.db.transaction(this.STORE_ADS,"readwrite").objectStore(this.STORE_ADS);for(let s of i)n.delete(s.id)}async savePendingImpression(e){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).put(e)}async getPendingImpressions(){return this.db?new Promise(e=>{let a=this.db.transaction(this.STORE_IMPRESSIONS,"readonly").objectStore(this.STORE_IMPRESSIONS).getAll();a.onsuccess=()=>e(a.result||[]),a.onerror=()=>e([])}):[]}async clearPendingImpressions(){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).clear()}destroy(){this.db&&(this.db.close(),this.db=null)}};var H=class{constructor(){this.VERSION="1.0";this.registered=null;this.detected=null;this.sessionId=`sess_${Date.now()}_${Math.random().toString(36).slice(2,9)}`;this.eventFilter=null;this.commandHandler=null;this.deviceId=null;this.screenId=null;this.messageListener=null;this.targetOrigin="*"}setContext(e,t){this.deviceId=e,this.screenId=t}register(e){var t,i;return typeof e.send!="function"?(console.error("[TrillboardsAds] Bridge requires send function"),!1):(this.registered={send:e.send,receive:(t=e.receive)!=null?t:null,name:(i=e.name)!=null?i:"CustomBridge"},Array.isArray(e.events)&&(this.eventFilter=new Set(e.events)),this.registered.receive&&this.commandHandler&&this.registered.receive(this.commandHandler),!0)}setCommandHandler(e){this.commandHandler=e}setTargetOrigin(e){this.targetOrigin=e}detect(){var t,i,a,n;if(typeof window=="undefined")return null;let e=null;if(window.TrillboardsBridge&&typeof window.TrillboardsBridge.onEvent=="function")e={type:"android",send:s=>window.TrillboardsBridge.onEvent(s)};else if(window.Android&&typeof window.Android.onTrillboardsEvent=="function")e={type:"android-alt",send:s=>window.Android.onTrillboardsEvent(s)};else if((a=(i=(t=window.webkit)==null?void 0:t.messageHandlers)==null?void 0:i.trillboards)!=null&&a.postMessage)e={type:"ios",send:s=>window.webkit.messageHandlers.trillboards.postMessage(JSON.parse(s))};else if(window.ReactNativeWebView&&typeof window.ReactNativeWebView.postMessage=="function")e={type:"react-native",send:s=>window.ReactNativeWebView.postMessage(s)};else if(window.Flutter&&typeof window.Flutter.postMessage=="function")e={type:"flutter",send:s=>window.Flutter.postMessage(s)};else if(window.__TRILL_CTV_BRIDGE__&&typeof window.__TRILL_CTV_BRIDGE__.postEvent=="function")e={type:"ctv",send:s=>window.__TRILL_CTV_BRIDGE__.postEvent(s)};else if(window.electronAPI&&typeof window.electronAPI.trillboardsEvent=="function")e={type:"electron",send:s=>window.electronAPI.trillboardsEvent(JSON.parse(s))};else if((n=window.__TAURI__)!=null&&n.event)e={type:"tauri",send:s=>{try{window.__TAURI__.event.emit("trillboards-event",JSON.parse(s))}catch(c){}}};else if(typeof window!="undefined"&&window.parent!==window&&typeof window.parent.postMessage=="function"){let s=this.targetOrigin;e={type:"postMessage",send:c=>window.parent.postMessage(JSON.parse(c),s)}}return this.detected=e,this.detected}buildPayload(e,t){let i={type:"trillboards",version:this.VERSION,event:e,data:t!=null?t:{},timestamp:Date.now(),deviceId:this.deviceId,screenId:this.screenId,sessionId:this.sessionId};return JSON.stringify(i)}send(e,t){var n;if(this.eventFilter&&!this.eventFilter.has(e))return!1;let i=this.buildPayload(e,t);if((n=this.registered)!=null&&n.send)try{return this.registered.send(e,JSON.parse(i)),!0}catch(s){}let a=this.detect();if(a!=null&&a.send)try{return a.send(i),!0}catch(s){}return!1}initCommandListener(){typeof window!="undefined"&&(this.messageListener&&window.removeEventListener("message",this.messageListener),this.messageListener=e=>{var t;((t=e.data)==null?void 0:t.type)==="trillboards-command"&&this.commandHandler&&this.commandHandler(e.data)},window.addEventListener("message",this.messageListener))}destroy(){typeof window!="undefined"&&this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.registered=null,this.detected=null,this.commandHandler=null,this.eventFilter=null}};var N=class{constructor(e=5,t=3e4){this.sources=new Map;this.maxFailures=e,this.openDurationMs=t}recordSuccess(e){e&&this.sources.set(e,{consecutiveFailures:0,openUntil:0})}recordFailure(e){var i;if(!e)return;let t=(i=this.sources.get(e))!=null?i:{consecutiveFailures:0,openUntil:0};t.consecutiveFailures+=1,t.consecutiveFailures>=this.maxFailures&&(t.openUntil=Date.now()+this.openDurationMs),this.sources.set(e,t)}isAvailable(e){if(!e)return!0;let t=this.sources.get(e);if(!t||t.consecutiveFailures<this.maxFailures)return!0;let i=Date.now();return i>=t.openUntil?(t.openUntil=i+this.openDurationMs,!0):!1}getState(e){var t;return(t=this.sources.get(e))!=null?t:{consecutiveFailures:0,openUntil:0}}reset(){this.sources.clear()}};var B=class{constructor(){this.totalRequests=0;this.fills=0;this.noFills=0;this.timeouts=0;this.errors=0}recordRequest(){this.totalRequests++}recordFill(){this.fills++}recordNoFill(){this.noFills++}recordTimeout(){this.timeouts++}recordError(){this.errors++}getFillRate(){return this.totalRequests>0?this.fills/this.totalRequests:0}getNoFillRate(){return this.totalRequests>0?this.noFills/this.totalRequests:0}getTimeoutRate(){return this.totalRequests>0?this.timeouts/this.totalRequests:0}getErrorRate(){return this.totalRequests>0?this.errors/this.totalRequests:0}getSnapshot(){return{fill_rate:Math.round(this.getFillRate()*1e4)/1e4,no_fill_rate:Math.round(this.getNoFillRate()*1e4)/1e4,timeout_rate:Math.round(this.getTimeoutRate()*1e4)/1e4,error_rate:Math.round(this.getErrorRate()*1e4)/1e4}}reset(){this.totalRequests=0,this.fills=0,this.noFills=0,this.timeouts=0,this.errors=0}};var F=class{constructor(e){this.circuitBreaker=e}getNextSource(e){if(!e||e.length===0)return null;let t=[...e].filter(i=>i.enabled!==!1).sort((i,a)=>i.priority-a.priority||Math.random()-.5);for(let i of t)if(this.circuitBreaker.isAvailable(i.name))return{source:i,vastUrl:i.vast_url};return null}getAvailableSources(e){return!e||e.length===0?[]:e.filter(t=>t.enabled!==!1&&this.circuitBreaker.isAvailable(t.name)).sort((t,i)=>t.priority-i.priority||Math.random()-.5).map(t=>({source:t,vastUrl:t.vast_url}))}recordSuccess(e){this.circuitBreaker.recordSuccess(e)}recordFailure(e){this.circuitBreaker.recordFailure(e)}};var w=class w{constructor(e,t=12e3){this.vastTagUrl=null;this.variantName=null;this.screenId=null;this.adContainer=null;this.contentVideo=null;this.ima={};this.currentSourceName=null;this.isPlaying=!1;this.isPrefetching=!1;this.prefetchedReady=!1;this.prefetchTimer=null;this.adStartTime=0;this.sources=[];this.circuitBreaker=new N(5,3e4),this.telemetry=new B,this.waterfallEngine=new F(this.circuitBreaker),this.events=e,this.timeoutMs=t}setSources(e){this.sources=e}getTelemetrySnapshot(){return this.telemetry.getSnapshot()}getIsPlaying(){return this.isPlaying}hasPrefetchedAd(){return this.prefetchedReady}createAdContainer(e){this.adContainer||(this.adContainer=document.createElement("div"),this.adContainer.id="trillboards-ad-container",this.adContainer.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;z-index:10000;display:none;",this.contentVideo=document.createElement("video"),this.contentVideo.id="trillboards-content-video",this.contentVideo.style.cssText="width:100%;height:100%;",this.contentVideo.setAttribute("playsinline",""),this.contentVideo.muted=!0,this.adContainer.appendChild(this.contentVideo),e.appendChild(this.adContainer))}async play(e,t){if(this.isPlaying)return;if(!this.adContainer||!this.contentVideo){t("Ad container not initialized");return}let i=this.vastTagUrl,a="default";if(this.sources.length>0){let o=this.waterfallEngine.getNextSource(this.sources);o&&(i=o.vastUrl,a=o.source.name)}if(!i){t("No VAST URL available");return}this.currentSourceName=a,this.telemetry.recordRequest();let n=Date.now(),s=i.includes("correlator=")?i.replace(/correlator=[^&]*/,`correlator=${n}`):`${i}${i.includes("?")?"&":"?"}correlator=${n}`;if(!await this.ensureImaSdk()){let o="Google IMA SDK not loaded";this.events.emit("programmatic_error",{error:o,code:void 0}),t(o),this.telemetry.recordError(),this.waterfallEngine.recordFailure(a);return}this.isPlaying=!0,this.adContainer.style.display="block";try{await this.requestAdsViaIMA(s,e,t)}catch(o){this.isPlaying=!1,this.adContainer.style.display="none",this.telemetry.recordError(),this.waterfallEngine.recordFailure(a),t(o instanceof Error?o.message:String(o))}}async ensureImaSdk(){return typeof google!="undefined"&&(google!=null&&google.ima)?!0:typeof document=="undefined"?!1:document.querySelector(`script[src="${w.IMA_SDK_URL}"]`)?new Promise(t=>{let i=Date.now(),a=()=>{typeof google!="undefined"&&(google!=null&&google.ima)?t(!0):Date.now()-i>5e3?t(!1):setTimeout(a,100)};a()}):(w.imaLoadPromise||(w.imaLoadPromise=new Promise(t=>{let i=document.createElement("script");i.src=w.IMA_SDK_URL,i.async=!0,i.onload=()=>{w.imaLoadPromise=null,t(!0)},i.onerror=()=>{w.imaLoadPromise=null,t(!1)},document.head.appendChild(i)})),w.imaLoadPromise)}async requestAdsViaIMA(e,t,i){return new Promise(a=>{let n=!1,s=()=>{n||(n=!0,t(),a())},c=v=>{n||(n=!0,i(v),a())};this.destroyIMA();let o=new google.ima.AdDisplayContainer(this.adContainer,this.contentVideo);o.initialize();let d=new google.ima.AdsLoader(o);this.ima.adDisplayContainer=o,this.ima.adsLoader=d;let g=setTimeout(()=>{this.telemetry.recordTimeout(),this.waterfallEngine.recordFailure(this.currentSourceName),this.stop({silent:!0}),this.events.emit("programmatic_timeout",{source:this.currentSourceName||"unknown"}),c("VAST request timeout")},this.timeoutMs);d.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,v=>{clearTimeout(g),this.telemetry.recordFill(),this.waterfallEngine.recordSuccess(this.currentSourceName);let h=v.getAdsManager(this.contentVideo);this.ima.adsManager=h,this.adStartTime=Date.now(),h.addEventListener(google.ima.AdEvent.Type.COMPLETE,()=>{let m=Math.round((Date.now()-this.adStartTime)/1e3);this.events.emit("programmatic_ended",{source:this.currentSourceName||"unknown",variant:this.variantName,duration:m}),this.stop({silent:!0}),s()}),h.addEventListener(google.ima.AdEvent.Type.STARTED,()=>{this.events.emit("programmatic_started",{source:this.currentSourceName||"unknown",variant:this.variantName})}),h.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,m=>{var y,b,P;let l=m.getError();this.events.emit("programmatic_error",{error:((y=l==null?void 0:l.getMessage)==null?void 0:y.call(l))||"Ad playback error",code:(b=l==null?void 0:l.getErrorCode)==null?void 0:b.call(l)}),this.stop({silent:!0}),c(((P=l==null?void 0:l.getMessage)==null?void 0:P.call(l))||"Ad error")});try{let m=this.adContainer.offsetWidth||window.innerWidth,l=this.adContainer.offsetHeight||window.innerHeight;h.init(m,l,google.ima.ViewMode.NORMAL),h.start()}catch(m){this.stop({silent:!0}),c("Failed to start ad")}}),d.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,v=>{var y,b;clearTimeout(g);let h=v.getError(),m=(y=h==null?void 0:h.getErrorCode)==null?void 0:y.call(h),l=((b=h==null?void 0:h.getMessage)==null?void 0:b.call(h))||"Ad load error";m===303?(this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_no_fill",{source:this.currentSourceName||"unknown"})):(this.telemetry.recordError(),this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_error",{error:l,code:m})),this.stop({silent:!0}),c(l)});let f=new google.ima.AdsRequest;f.adTagUrl=e,f.linearAdSlotWidth=this.adContainer.offsetWidth||window.innerWidth,f.linearAdSlotHeight=this.adContainer.offsetHeight||window.innerHeight,this.ima.adsRequest=f,d.requestAds(f)})}async prefetch(){return this.isPrefetching||this.prefetchedReady||!this.vastTagUrl&&this.sources.length===0?!1:(this.isPrefetching=!0,this.prefetchedReady=!0,this.isPrefetching=!1,this.events.emit("ad_ready",{type:"programmatic",source:this.currentSourceName||void 0}),!0)}destroyPrefetched(){this.prefetchedReady=!1,this.isPrefetching=!1,this.prefetchTimer&&(clearTimeout(this.prefetchTimer),this.prefetchTimer=null)}stop(e){this.isPlaying=!1,this.destroyIMA(),this.adContainer&&(this.adContainer.style.display="none")}destroyIMA(){if(this.ima.adsManager){try{this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.COMPLETE),this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.STARTED),this.ima.adsManager.removeEventListener(google.ima.AdErrorEvent.Type.AD_ERROR)}catch(e){}try{this.ima.adsManager.destroy()}catch(e){}this.ima.adsManager=null}if(this.ima.adsLoader){try{this.ima.adsLoader.destroy()}catch(e){}this.ima.adsLoader=null}this.ima.adDisplayContainer=null,this.ima.adsRequest=null}destroy(){this.stop({silent:!0}),this.destroyPrefetched(),this.adContainer&&(this.adContainer.remove(),this.adContainer=null,this.contentVideo=null),this.circuitBreaker.reset(),this.telemetry.reset()}};w.IMA_SDK_URL="https://imasdk.googleapis.com/js/sdkloader/ima3.js",w.imaLoadPromise=null;var V=w;var ie=300,U=class{constructor(e,t=8e3){this.container=null;this.currentAd=null;this.adTimer=null;this.videoElement=null;this.imageElement=null;this.videoEndedHandler=null;this.videoErrorHandler=null;this.events=e,this.defaultImageDuration=t}setContainer(e){this.container=e}play(e,t,i=0){this.container&&(this.stop(),this.currentAd=e,this.events.emit("ad_started",{id:e.id,type:e.type,index:i}),e.type==="video"?this.playVideo(e,t):this.playImage(e,t))}playVideo(e,t){for(this.videoElement=document.createElement("video"),this.videoElement.src=e.media_url,this.videoElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.videoElement.setAttribute("playsinline",""),this.videoElement.muted=!0,this.videoElement.autoplay=!0,this.videoEndedHandler=()=>{var a,n;let i=Math.min(Math.round((n=(a=this.videoElement)==null?void 0:a.duration)!=null?n:e.duration),ie);this.events.emit("ad_ended",{id:e.id,type:e.type,duration:i}),this.stop(),t()},this.videoErrorHandler=()=>{this.events.emit("ad_error",{error:"Video playback error"}),this.stop(),t()},this.videoElement.addEventListener("ended",this.videoEndedHandler),this.videoElement.addEventListener("error",this.videoErrorHandler);this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.videoElement)}playImage(e,t){var n;for(this.imageElement=document.createElement("img"),this.imageElement.src=e.media_url,this.imageElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.imageElement.alt=(n=e.title)!=null?n:"Advertisement";this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.imageElement);let i=Math.min(e.duration||this.defaultImageDuration/1e3,ie),a=i*1e3;this.adTimer=setTimeout(()=>{this.events.emit("ad_ended",{id:e.id,type:e.type,duration:Math.round(i)}),this.stop(),t()},a)}stop(){this.adTimer&&(clearTimeout(this.adTimer),this.adTimer=null),this.videoElement&&(this.videoEndedHandler&&(this.videoElement.removeEventListener("ended",this.videoEndedHandler),this.videoEndedHandler=null),this.videoErrorHandler&&(this.videoElement.removeEventListener("error",this.videoErrorHandler),this.videoErrorHandler=null),this.videoElement.pause(),this.videoElement.removeAttribute("src"),this.videoElement.load(),this.videoElement.remove(),this.videoElement=null),this.imageElement&&(this.imageElement.remove(),this.imageElement=null),this.currentAd=null}destroy(){this.stop(),this.container=null}};function pe(r){if(!r)return null;let e=String(r).toLowerCase();return["programmatic_only","programmatic-only","programmatic"].includes(e)?"programmatic_only":["programmatic_then_direct","programmatic-direct","programmatic+direct","hybrid"].includes(e)?"programmatic_then_direct":["direct_only","direct-only","direct"].includes(e)?"direct_only":null}var E=class E{constructor(e){this.onlineHandler=null;this.offlineHandler=null;this.visibilityHandler=null;this.config=W(e),this.config.debug&&te("debug"),this.state=j(),this.events=new k,this.api=new O(this.config.apiBase),this.cache=new x(this.config.cacheSize),this.bridge=new H,this.programmaticPlayer=new V(this.events,this.config.programmaticTimeout),this.directPlayer=new U(this.events,this.config.defaultImageDuration)}static async create(e){E._instance&&(E._instance.destroy(),E._instance=null);let t=new E(e);return await t.init(e),E._instance=t,t}async init(e){if(this.state.initialized)return;this.config=W(e),this.state.deviceId=this.config.deviceId,this.state.waterfallMode=this.config.waterfall,this.state.autoStart=this.config.autoStart;try{await this.cache.init()}catch(i){}this.bridge.setContext(this.state.deviceId,this.state.screenId),this.bridge.setCommandHandler(i=>this.handleBridgeCommand(i)),this.bridge.initCommandListener(),this.bridge.detect();let t=["initialized","ad_started","ad_ended","ad_ready","ad_error","programmatic_started","programmatic_ended","programmatic_error","programmatic_no_fill","state_changed"];for(let i of t)this.events.on(i,a=>{this.bridge.send(i,a)});this.createContainer(),typeof window!="undefined"&&(this.onlineHandler=()=>{this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.refreshAds().catch(()=>{})},this.offlineHandler=()=>{this.state.isOffline=!0,this.events.emit("offline",{}),this.emitStateChanged()},window.addEventListener("online",this.onlineHandler),window.addEventListener("offline",this.offlineHandler),this.visibilityHandler=()=>{let i=!document.hidden;this.events.emit("visibility_changed",{visible:i}),i&&this.refreshAds().catch(()=>{})},document.addEventListener("visibilitychange",this.visibilityHandler)),await this.refreshAds(),this.startRefreshTimer(),this.startHeartbeatTimer(),this.state.initialized=!0,this.events.emit("initialized",{deviceId:this.config.deviceId}),this.emitStateChanged(),this.state.autoStart&&this.prefetchNextAd().catch(()=>{})}destroy(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer),this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer),this.programmaticPlayer.destroy(),this.directPlayer.destroy(),this.bridge.destroy(),this.cache.destroy(),typeof window!="undefined"&&(this.onlineHandler&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null),this.offlineHandler&&(window.removeEventListener("offline",this.offlineHandler),this.offlineHandler=null),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null)),this.state.container&&this.state.container.remove(),this.events.removeAllListeners(),this.state=j(),E._instance===this&&(E._instance=null)}show(){this.state.container&&(this.state.container.style.display="block"),this.state.isPlaying=!0,this.state.isPaused=!1,this.playNextAd(),this.emitStateChanged()}hide(){this.state.container&&(this.state.container.style.display="none"),this.state.isPlaying=!1,this.state.isPaused=!0,this.programmaticPlayer.stop(),this.directPlayer.stop(),this.emitStateChanged()}skipAd(){this.programmaticPlayer.stop(),this.directPlayer.stop(),this.playNextAd()}async refresh(){this.programmaticPlayer.destroyPrefetched(),this.resetProgrammaticBackoff(),this.state.etag=null,await this.refreshAds(),this.prefetchNextAd()}async prefetchNextAd(){let e=this.state.waterfallMode;if(e==="programmatic_only"||e==="programmatic_then_direct"){let t=this.state.programmatic;(t!=null&&t.vast_tag_url||t!=null&&t.sources&&t.sources.length>0)&&await this.programmaticPlayer.prefetch()}}getState(){return ee(this.state)}getAds(){return[...this.state.ads]}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}registerBridge(e){return this.bridge.register(e)}createContainer(){if(typeof document=="undefined")return;let e=document.createElement("div");e.id="trillboards-ads-container",e.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;z-index:99999;display:none;background:#000;",document.body.appendChild(e),this.state.container=e,this.api.setContainer(e),this.directPlayer.setContainer(e),this.programmaticPlayer.createAdContainer(e)}async refreshAds(){var e,t,i,a,n,s,c,o;try{let d=await this.api.fetchAds(this.config.deviceId,this.state.etag);if(d.notModified)return;this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.state.ads=d.ads,this.state.settings=d.settings,this.state.etag=d.etag,this.state.screenId=(e=d.screenId)!=null?e:this.state.screenId,this.state.programmatic=d.programmatic,this.state.screenOrientation=(t=d.screenOrientation)!=null?t:this.state.screenOrientation,this.state.screenDimensions=(i=d.screenDimensions)!=null?i:this.state.screenDimensions,this.bridge.setContext(this.state.deviceId,this.state.screenId),this.programmaticPlayer.screenId=this.state.screenId,this.programmaticPlayer.vastTagUrl=(n=(a=this.state.programmatic)==null?void 0:a.vast_tag_url)!=null?n:null,this.programmaticPlayer.variantName=(c=(s=this.state.programmatic)==null?void 0:s.variant_name)!=null?c:null,(o=this.state.programmatic)!=null&&o.sources&&this.programmaticPlayer.setSources(this.state.programmatic.sources),this.state.ads.length>0&&await this.cache.cacheAds(this.state.ads),this.events.emit("ads_refreshed",{count:this.state.ads.length})}catch(d){this.state.isOffline=!0;let g=await this.cache.getCachedAds();g.length>0&&(this.state.ads=g,this.events.emit("ads_loaded_from_cache",{count:g.length}))}}startRefreshTimer(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.refreshTimer=setInterval(()=>{this.refreshAds().catch(()=>{})},this.config.refreshInterval)}startHeartbeatTimer(){this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer);let e=()=>{this.sendHeartbeatTick().catch(()=>{})};e(),this.state.heartbeatTimer=setInterval(()=>{e()},this.config.heartbeatInterval)}async sendHeartbeatTick(){var t;let e=await this.api.sendHeartbeat(this.config.deviceId,this.state.screenId,this.buildHeartbeatPayload());!e.ok||!e.data||((t=e.data.ad_delivery_profile)!=null&&t.mode&&this.applyAdDeliveryProfile(e.data.ad_delivery_profile),Array.isArray(e.data.commands)&&e.data.commands.length>0&&this.runHeartbeatCommands(e.data.commands))}buildHeartbeatPayload(){var d;let e=typeof navigator!="undefined"?navigator.userAgent:"",t=typeof navigator!="undefined"?navigator.platform:null,i=typeof navigator!="undefined"?navigator.connection:null,a=e.match(/(?:Chrome|Chromium)\/(\d+)/i),n=a?Number(a[1]):void 0,s=typeof window!="undefined"?!!((d=window==null?void 0:window.google)!=null&&d.ima):null,o={telemetry:{powerState:typeof document!="undefined"&&document.hidden?"standby":"on",agentStatus:typeof document!="undefined"&&document.hidden?"background":"foreground",os:t||void 0,agentVersion:M,ima_integration:"html5_webview",ima_supported:s,webview_chromium_major:Number.isFinite(n)?n:void 0},sdk:{version:M,ima_supported:s,ima_integration:"html5_webview",webview_chromium_major:Number.isFinite(n)?n:void 0},device:{os:t||void 0,model:e||void 0}};return i&&(o.network={connectionType:i.type||void 0,effectiveType:i.effectiveType||void 0,downlinkMbps:typeof i.downlink=="number"?i.downlink:void 0,bandwidthMbps:typeof i.downlink=="number"?i.downlink:void 0,rtt:typeof i.rtt=="number"?i.rtt:void 0,latencyRtt:typeof i.rtt=="number"?i.rtt:void 0,saveData:typeof i.saveData=="boolean"?i.saveData:void 0}),o}applyAdDeliveryProfile(e){var i,a;if(!(e!=null&&e.mode))return;let t=(a=(i=this.state.adDeliveryProfile)==null?void 0:i.mode)!=null?a:null;this.state.adDeliveryProfile=e,e.mode==="vast_fallback"&&this.state.programmaticPlaying&&(this.programmaticPlayer.stop({silent:!0}),this.state.programmaticPlaying=!1),t!==e.mode&&this.emitStateChanged()}runHeartbeatCommands(e){var t;for(let i of e){let a=String((i==null?void 0:i.command)||"").toLowerCase();if(a==="refresh_ads")this.refresh().catch(()=>{});else if(a==="restart"){if(typeof window!="undefined"&&typeof((t=window.location)==null?void 0:t.reload)=="function"){window.location.reload();return}this.refresh().catch(()=>{})}}}playNextAd(){var t;if(((t=this.state.adDeliveryProfile)==null?void 0:t.mode)==="vast_fallback"&&this.state.ads.length>0){this.playDirect();return}let e=this.state.waterfallMode;e==="programmatic_only"||e==="programmatic_then_direct"?this.playProgrammatic():e==="direct_only"&&this.playDirect()}playProgrammatic(){this.programmaticPlayer.getIsPlaying()||(this.state.programmaticPlaying=!0,this.emitStateChanged(),this.programmaticPlayer.play(()=>{this.state.programmaticPlaying=!1,this.resetProgrammaticBackoff(),this.emitStateChanged(),this.scheduleProgrammaticRetry()},e=>{this.state.programmaticPlaying=!1,this.state.programmaticLastError=e;let t=String(e||"").toLowerCase();t.includes("no fill")||t.includes("no ads vast response")||t.includes("waterfall_exhausted")||t==="throttled"||t==="busy"?this.state.programmaticRetryCount=0:this.state.programmaticRetryCount++,this.emitStateChanged(),this.state.waterfallMode==="programmatic_then_direct"&&this.state.ads.length>0?this.playDirect():this.scheduleProgrammaticRetry()}))}playDirect(){if(this.state.ads.length===0)return;let e=this.state.currentAdIndex%this.state.ads.length,t=this.state.ads[e];t&&this.directPlayer.play(t,()=>{var i;this.state.currentAdIndex=(e+1)%this.state.ads.length,this.api.reportImpression({adid:t.id,impid:t.impression_id,did:this.config.deviceId,aid:(i=t.allocation_id)!=null?i:"",duration:t.duration,completed:!0}),this.emitStateChanged(),this.scheduleNextDirect()},e)}scheduleNextDirect(){this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.adTimer=setTimeout(()=>{this.playNextAd()},this.config.defaultAdInterval)}scheduleProgrammaticRetry(){this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer);let e=this.state.programmaticRetryCount,t=this.config.programmaticRetry,i=this.config.programmaticBackoffMax,a=Math.min(t*Math.pow(2,e),i),n=a*.2*Math.random();this.state.programmaticRetryTimer=setTimeout(()=>{this.prefetchNextAd().catch(()=>{}).then(()=>{this.playNextAd()})},a+n)}resetProgrammaticBackoff(){this.state.programmaticRetryCount=0,this.state.programmaticLastError=null,this.state.programmaticRetryTimer&&(clearTimeout(this.state.programmaticRetryTimer),this.state.programmaticRetryTimer=null)}emitStateChanged(){this.events.emit("state_changed",this.getState())}handleBridgeCommand(e){let t;try{t=typeof e=="string"?JSON.parse(e):e}catch(n){console.warn("[TrillboardsAds] Failed to parse bridge command:",e);return}let i=t.action||t.command,a=t.params||t.data||{};switch(i){case"show":this.show();break;case"hide":this.hide();break;case"skip":this.skipAd();break;case"refresh":this.refresh();break;case"getState":this.bridge.send("state_changed",this.getState());break;case"configure":if(a.waterfall){let n=pe(a.waterfall);n&&(this.state.waterfallMode=n)}typeof a.volume=="number"&&(this.state.settings.sound_enabled=a.volume>0);break}}};E._instance=null;var K=E;var re={VERSION:M,_instance:null,async init(r){var t,i;let e={deviceId:r.deviceId,waterfall:(t=r.waterfall)!=null?t:"programmatic_only",autoStart:(i=r.autoStart)!=null?i:!0,apiBase:r.apiBase};this._instance=await K.create(e)},show(){var r;(r=this._instance)==null||r.show()},hide(){var r;(r=this._instance)==null||r.hide()},skipAd(){var r;(r=this._instance)==null||r.skipAd()},async refresh(){var r;await((r=this._instance)==null?void 0:r.refresh())},async prefetchNextAd(){var r;await((r=this._instance)==null?void 0:r.prefetchNextAd())},getState(){var r,e;return(e=(r=this._instance)==null?void 0:r.getState())!=null?e:T({},Q)},getAds(){var r,e;return(e=(r=this._instance)==null?void 0:r.getAds())!=null?e:[]},on(r,e){var t;(t=this._instance)==null||t.on(r,e)},off(r,e){var t;(t=this._instance)==null||t.off(r,e)},registerBridge(r){var e,t;return(t=(e=this._instance)==null?void 0:e.registerBridge(r))!=null?t:!1},destroy(){var r;(r=this._instance)==null||r.destroy(),this._instance=null}};typeof window!="undefined"&&(window.TrillboardsLite=re);return ue(fe);})();
2
2
  //# sourceMappingURL=trillboards-lite.global.js.map