adgent-sdk 0.1.1 → 0.1.3

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,9 +1,9 @@
1
- (function(l,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("fast-xml-parser")):typeof define=="function"&&define.amd?define(["exports","fast-xml-parser"],u):(l=typeof globalThis<"u"?globalThis:l||self,u(l.AdgentSDK={},l.FastXMLParser))})(this,function(l,u){"use strict";var C=Object.defineProperty;var M=(l,u,c)=>u in l?C(l,u,{enumerable:!0,configurable:!0,writable:!0,value:c}):l[u]=c;var d=(l,u,c)=>M(l,typeof u!="symbol"?u+"":u,c);var c=(s=>(s.Idle="idle",s.Loading="loading",s.Ready="ready",s.Playing="playing",s.Paused="paused",s.Completed="completed",s.Error="error",s.WaitingForInteraction="waiting_for_interaction",s))(c||{}),h=(s=>(s[s.XML_PARSING_ERROR=100]="XML_PARSING_ERROR",s[s.VAST_SCHEMA_VALIDATION_ERROR=101]="VAST_SCHEMA_VALIDATION_ERROR",s[s.VAST_VERSION_NOT_SUPPORTED=102]="VAST_VERSION_NOT_SUPPORTED",s[s.GENERAL_WRAPPER_ERROR=300]="GENERAL_WRAPPER_ERROR",s[s.WRAPPER_TIMEOUT=301]="WRAPPER_TIMEOUT",s[s.WRAPPER_LIMIT_REACHED=302]="WRAPPER_LIMIT_REACHED",s[s.NO_VAST_RESPONSE=303]="NO_VAST_RESPONSE",s[s.GENERAL_LINEAR_ERROR=400]="GENERAL_LINEAR_ERROR",s[s.FILE_NOT_FOUND=401]="FILE_NOT_FOUND",s[s.MEDIA_TIMEOUT=402]="MEDIA_TIMEOUT",s[s.MEDIA_NOT_SUPPORTED=403]="MEDIA_NOT_SUPPORTED",s[s.GENERAL_COMPANION_ERROR=600]="GENERAL_COMPANION_ERROR",s[s.UNDEFINED_ERROR=900]="UNDEFINED_ERROR",s))(h||{});class k{constructor(e={}){d(this,"config");d(this,"xmlParser");this.config={maxWrapperDepth:e.maxWrapperDepth??5,timeout:e.timeout??1e4,debug:e.debug??!1,fetchFn:e.fetchFn??fetch.bind(globalThis)},this.xmlParser=new u.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}async parse(e){try{return{success:!0,response:await this.fetchAndParse(e,0)}}catch(r){const t=r instanceof Error?r.message:"Unknown error";return{success:!1,error:{code:h.GENERAL_WRAPPER_ERROR,message:t}}}}async fetchAndParse(e,r){if(r>=this.config.maxWrapperDepth)throw new Error(`Wrapper limit exceeded (max: ${this.config.maxWrapperDepth})`);this.log(`Fetching VAST (depth: ${r}): ${e}`);const t=await this.fetchWithTimeout(e),i=this.parseXml(t),a=await Promise.all(i.ads.map(async n=>{var f;return(f=n.wrapper)!=null&&f.vastAdTagURI?this.resolveWrapper(n,r+1):n}));return{...i,ads:a.flat()}}async resolveWrapper(e,r){var t;if(!((t=e.wrapper)!=null&&t.vastAdTagURI))return[e];try{return(await this.fetchAndParse(e.wrapper.vastAdTagURI,r)).ads.map(a=>this.mergeWrapperTracking(e,a))}catch(i){if(this.log(`Wrapper resolution failed: ${i}`),e.wrapper.fallbackOnNoAd)return[];throw i}}mergeWrapperTracking(e,r){return{...r,impressions:[...e.impressions,...r.impressions],errors:[...e.errors,...r.errors],creatives:r.creatives.map(t=>({...t,linear:t.linear?{...t.linear,trackingEvents:[...this.getWrapperTrackingEvents(e),...t.linear.trackingEvents]}:void 0}))}}getWrapperTrackingEvents(e){var t;const r=[];for(const i of e.creatives)(t=i.linear)!=null&&t.trackingEvents&&r.push(...i.linear.trackingEvents);return r}async fetchWithTimeout(e){const r=new AbortController,t=setTimeout(()=>r.abort(),this.config.timeout);try{const i=await this.config.fetchFn(e,{signal:r.signal});if(!i.ok)throw new Error(`HTTP ${i.status}: ${i.statusText}`);return i.text()}finally{clearTimeout(t)}}parseXml(e){const t=this.xmlParser.parse(e).VAST;if(!t)throw new Error("Invalid VAST: missing VAST element");const i=t["@_version"]||"4.0",a=this.parseAds(t.Ad);return{version:i,ads:a,errors:this.parseErrors(t.Error)}}parseAds(e){return e?(Array.isArray(e)?e:[e]).map(t=>this.parseAd(t)):[]}parseAd(e){var i,a,n;const r=!!e.Wrapper,t=e.InLine||e.Wrapper;return{id:e["@_id"]||"",sequence:e["@_sequence"],adSystem:t!=null&&t.AdSystem?{name:typeof t.AdSystem=="string"?t.AdSystem:t.AdSystem["#text"]||"",version:(i=t.AdSystem)==null?void 0:i["@_version"]}:void 0,adTitle:t==null?void 0:t.AdTitle,impressions:this.parseImpressions(t==null?void 0:t.Impression),errors:this.parseErrors(t==null?void 0:t.Error),creatives:this.parseCreatives((a=t==null?void 0:t.Creatives)==null?void 0:a.Creative),wrapper:r?{vastAdTagURI:t.VASTAdTagURI,followAdditionalWrappers:t["@_followAdditionalWrappers"]!==!1,allowMultipleAds:t["@_allowMultipleAds"],fallbackOnNoAd:t["@_fallbackOnNoAd"]}:void 0,inLine:r?void 0:{adTitle:(t==null?void 0:t.AdTitle)||"",description:t==null?void 0:t.Description,advertiser:t==null?void 0:t.Advertiser,creatives:this.parseCreatives((n=t==null?void 0:t.Creatives)==null?void 0:n.Creative)}}}parseImpressions(e){return e?(Array.isArray(e)?e:[e]).map(t=>({id:t["@_id"],url:typeof t=="string"?t:t["#text"]||""})):[]}parseCreatives(e){return e?(Array.isArray(e)?e:[e]).map(t=>({id:t["@_id"],sequence:t["@_sequence"],adId:t["@_adId"],linear:t.Linear?this.parseLinear(t.Linear):void 0})):[]}parseLinear(e){var r,t;return{duration:this.parseDuration(e.Duration),skipOffset:e["@_skipoffset"]?this.parseDuration(e["@_skipoffset"]):void 0,mediaFiles:this.parseMediaFiles((r=e.MediaFiles)==null?void 0:r.MediaFile),trackingEvents:this.parseTrackingEvents((t=e.TrackingEvents)==null?void 0:t.Tracking),videoClicks:e.VideoClicks?{clickThrough:e.VideoClicks.ClickThrough?{id:e.VideoClicks.ClickThrough["@_id"],url:typeof e.VideoClicks.ClickThrough=="string"?e.VideoClicks.ClickThrough:e.VideoClicks.ClickThrough["#text"]||""}:void 0}:void 0,adParameters:e.AdParameters}}parseMediaFiles(e){return e?(Array.isArray(e)?e:[e]).map(t=>({id:t["@_id"],url:typeof t=="string"?t:t["#text"]||"",delivery:t["@_delivery"]||"progressive",type:t["@_type"]||"video/mp4",width:parseInt(t["@_width"],10)||0,height:parseInt(t["@_height"],10)||0,bitrate:t["@_bitrate"]?parseInt(t["@_bitrate"],10):void 0,codec:t["@_codec"],scalable:t["@_scalable"],maintainAspectRatio:t["@_maintainAspectRatio"]})):[]}parseTrackingEvents(e){return e?(Array.isArray(e)?e:[e]).map(t=>({event:t["@_event"],url:typeof t=="string"?t:t["#text"]||"",offset:t["@_offset"]?this.parseDuration(t["@_offset"]):void 0})):[]}parseErrors(e){return e?(Array.isArray(e)?e:[e]).map(t=>typeof t=="string"?t:t["#text"]||""):[]}parseDuration(e){if(typeof e=="number")return e;if(typeof e!="string")return 0;if(e.endsWith("%"))return parseFloat(e)/100;const r=e.match(/(\d+):(\d+):(\d+(?:\.\d+)?)/);if(r){const[,t,i,a]=r;return parseInt(t,10)*3600+parseInt(i,10)*60+parseFloat(a)}return parseFloat(e)||0}selectBestMediaFile(e,r=2500){if(e.length===0)return null;const t=e.filter(n=>n.type.includes("mp4")||n.type.includes("video/mp4"));return[...t.length>0?t:e].sort((n,f)=>{const g=n.bitrate||0,v=f.bitrate||0,_=n.height>1080?1e4:0,O=f.height>1080?1e4:0,I=Math.abs(g-r)+_,x=Math.abs(v-r)+O;return I-x})[0]||null}aggregateTrackingEvents(e){var t;const r=[];for(const i of e)for(const a of i.creatives)(t=a.linear)!=null&&t.trackingEvents&&r.push(...a.linear.trackingEvents);return r}aggregateImpressions(e){const r=[];for(const t of e)for(const i of t.impressions)r.push(i.url);return r}log(e){this.config.debug&&console.log(`[VASTParser] ${e}`)}}function m(s,e={}){let r=s;return r=r.replace(/\[TIMESTAMP\]/g,Date.now().toString()),r=r.replace(/\[CACHEBUSTING\]/g,Math.random().toString(36).substring(2,15)),e.assetUri&&(r=r.replace(/\[ASSETURI\]/g,encodeURIComponent(e.assetUri))),e.contentPlayhead!==void 0&&(r=r.replace(/\[CONTENTPLAYHEAD\]/g,w(e.contentPlayhead))),e.adPlayhead!==void 0&&(r=r.replace(/\[ADPLAYHEAD\]/g,w(e.adPlayhead))),e.errorCode!==void 0&&(r=r.replace(/\[ERRORCODE\]/g,e.errorCode.toString())),e.breakPosition!==void 0&&(r=r.replace(/\[BREAKPOSITION\]/g,e.breakPosition.toString())),e.adType&&(r=r.replace(/\[ADTYPE\]/g,e.adType)),r}function w(s){const e=Math.floor(s/3600),r=Math.floor(s%3600/60),t=Math.floor(s%60),i=Math.floor(s%1*1e3);return e.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+"."+i.toString().padStart(3,"0")}var o=(s=>(s.WebOS="webos",s.Tizen="tizen",s.Vidaa="vidaa",s.WhaleOS="whaleos",s.FireTV="firetv",s.Roku="roku",s.Xbox="xbox",s.PlayStation="playstation",s.AndroidTV="androidtv",s.Vizio="vizio",s.Generic="generic",s))(o||{}),p=(s=>(s.Enter="enter",s.Back="back",s.Left="left",s.Right="right",s.Up="up",s.Down="down",s.Play="play",s.Pause="pause",s.PlayPause="playPause",s.Stop="stop",s.FastForward="fastForward",s.Rewind="rewind",s.Menu="menu",s.Info="info",s.Red="red",s.Green="green",s.Yellow="yellow",s.Blue="blue",s.ChannelUp="channelUp",s.ChannelDown="channelDown",s.VolumeUp="volumeUp",s.VolumeDown="volumeDown",s.Mute="mute",s))(p||{});const b={webos:{13:"enter",461:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",33:"channelUp",34:"channelDown"},tizen:{13:"enter",10009:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",10252:"playPause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",427:"channelUp",428:"channelDown",447:"volumeUp",448:"volumeDown",449:"mute"},vidaa:{13:"enter",8:"back",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind"},whaleos:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop"},firetv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},roku:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",179:"playPause",178:"stop",228:"fastForward",227:"rewind"},xbox:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",195:"menu",196:"menu"},playstation:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down"},androidtv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},vizio:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause"},generic:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",32:"playPause",80:"play",83:"stop",77:"mute"}},R={tizen:[/Tizen/i,/SMART-TV.*Samsung/i],webos:[/Web0S/i,/WebOS/i,/LG.*NetCast/i,/LGE.*TV/i],vidaa:[/Vidaa/i,/VIDAA/i,/Hisense/i],whaleos:[/WhaleTV/i,/Whale/i],firetv:[/AFT/i,/AFTS/i,/AFTM/i,/Amazon.*Fire/i],roku:[/Roku/i],xbox:[/Xbox/i,/Edge.*Xbox/i],playstation:[/PlayStation/i,/PS4/i,/PS5/i],androidtv:[/Android.*TV/i,/Chromecast/i,/BRAVIA/i,/SHIELD/i],vizio:[/VIZIO/i,/SmartCast/i],generic:[]};class T{constructor(){d(this,"platform");d(this,"capabilities");d(this,"deviceInfo");d(this,"keyMap");d(this,"reverseKeyMap");this.platform=this.detectPlatform(),this.keyMap=b[this.platform],this.reverseKeyMap=this.buildReverseKeyMap(),this.capabilities=this.detectCapabilities(),this.deviceInfo=this.detectDeviceInfo()}detectPlatform(){if(typeof window>"u"||typeof navigator>"u")return o.Generic;const e=navigator.userAgent,r=window;if(r.tizen)return o.Tizen;if(r.webOS||r.PalmSystem)return o.WebOS;for(const[t,i]of Object.entries(R))if(t!==o.Generic){for(const a of i)if(a.test(e))return t}return o.Generic}detectCapabilities(){const e=typeof navigator<"u",r=typeof document<"u",t=typeof window<"u",i={sendBeacon:e&&"sendBeacon"in navigator,fetchKeepalive:typeof fetch<"u",mutedAutoplayRequired:!0,fullscreen:r&&("fullscreenEnabled"in document||"webkitFullscreenEnabled"in document),hardwareDecodeInfo:!1,hdr:!1,hdr10Plus:!1,dolbyVision:!1,dolbyAtmos:!1,hevc:this.isCodecSupported('video/mp4; codecs="hvc1"'),vp9:this.isCodecSupported('video/webm; codecs="vp9"'),av1:this.isCodecSupported('video/mp4; codecs="av01.0.05M.08"'),maxResolution:this.detectMaxResolution(),touch:t&&"ontouchstart"in window,voice:!1};switch(this.platform){case o.Tizen:return{...i,hardwareDecodeInfo:!0,hdr:!0,hevc:!0,voice:!0};case o.WebOS:return{...i,hardwareDecodeInfo:!0,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,voice:!0};case o.FireTV:return{...i,hdr:!0,hdr10Plus:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Roku:return{...i,hdr:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Xbox:return{...i,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,av1:!0,voice:!0};case o.PlayStation:return{...i,hdr:!0,hevc:!0};case o.AndroidTV:return{...i,hdr:!0,dolbyVision:!0,hevc:!0,vp9:!0,voice:!0};default:return i}}detectDeviceInfo(){var t,i,a;const e={platform:this.platform};typeof window<"u"&&(e.screenWidth=(t=window.screen)==null?void 0:t.width,e.screenHeight=(i=window.screen)==null?void 0:i.height,e.devicePixelRatio=window.devicePixelRatio);const r=window;if(this.platform===o.Tizen&&((a=r.tizen)!=null&&a.systeminfo))try{r.tizen.systeminfo.getPropertyValue("BUILD",n=>{e.model=n.model,e.manufacturer=n.manufacturer||"Samsung"})}catch{e.manufacturer="Samsung"}if(this.platform===o.WebOS&&r.webOSSystem)try{const n=r.webOSSystem.deviceInfo;e.model=n==null?void 0:n.modelName,e.manufacturer="LG",e.osVersion=n==null?void 0:n.version}catch{e.manufacturer="LG"}return e}detectMaxResolution(){var i,a;if(typeof window>"u")return"unknown";const e=((i=window.screen)==null?void 0:i.width)||0,r=((a=window.screen)==null?void 0:a.height)||0,t=Math.max(e,r);return t>=3840?"4k":t>=1920?"1080p":t>=1280?"720p":"unknown"}buildReverseKeyMap(){const e=new Map;for(const[r,t]of Object.entries(this.keyMap)){const i=parseInt(r,10),a=e.get(t)||[];a.push(i),e.set(t,a)}return e}normalizeKeyCode(e){return this.keyMap[e]??null}getKeyCodesForAction(e){return this.reverseKeyMap.get(e)||[]}isCodecSupported(e){if(typeof document>"u")return!1;try{const t=document.createElement("video").canPlayType(e);return t==="probably"||t==="maybe"}catch{return!1}}registerTizenKeys(){if(this.platform!==o.Tizen)return;const e=window.tizen;e!=null&&e.tvinputdevice&&["MediaPlay","MediaPause","MediaStop","MediaFastForward","MediaRewind","MediaPlayPause","ColorF0Red","ColorF1Green","ColorF2Yellow","ColorF3Blue","Info"].forEach(t=>{try{e.tvinputdevice.registerKey(t)}catch{}})}registerWebOSKeys(){this.platform,o.WebOS}getVideoAttributes(){const e={muted:!0,playsinline:!0,autoplay:!0,"webkit-playsinline":!0};switch(this.platform){case o.Tizen:e["data-samsung-immersive"]="true";break;case o.WebOS:e["data-lg-immersive"]="true";break;case o.FireTV:case o.AndroidTV:e["x-webkit-airplay"]="allow";break}return e}getRecommendedVideoSettings(){switch(this.platform){case o.Tizen:case o.WebOS:return{maxBitrate:15e3,preferredCodec:"hevc",maxResolution:"4k"};case o.FireTV:return{maxBitrate:1e4,preferredCodec:"hevc",maxResolution:"4k"};case o.Roku:return{maxBitrate:8e3,preferredCodec:"h264",maxResolution:"4k"};case o.Xbox:case o.PlayStation:return{maxBitrate:2e4,preferredCodec:"hevc",maxResolution:"4k"};default:return{maxBitrate:5e3,preferredCodec:"h264",maxResolution:"1080p"}}}}let y=null;function E(){return y||(y=new T),y}class S{constructor(e=[],r={}){d(this,"config");d(this,"trackingEvents");d(this,"firedEvents");d(this,"macroContext");this.config={debug:r.debug??!1,retry:r.retry??!1,maxRetries:r.maxRetries??3},this.trackingEvents=this.groupEventsByType(e),this.firedEvents=new Set,this.macroContext={}}groupEventsByType(e){const r=new Map;for(const t of e){const i=r.get(t.event)||[];i.push(t),r.set(t.event,i)}return r}updateMacroContext(e){this.macroContext={...this.macroContext,...e}}track(e,r=!0){const t=this.trackingEvents.get(e);if(!t){this.log(`No tracking URLs for event: ${e}`);return}for(const i of t){const a=`${e}:${i.url}`;if(r&&this.firedEvents.has(a)){this.log(`Skipping duplicate event: ${e}`);continue}const n=m(i.url,this.macroContext);this.firePixel(n),r&&this.firedEvents.add(a)}}firePixel(e){const r=E();this.log(`Firing pixel: ${e}`);try{if(r.capabilities.sendBeacon&&navigator.sendBeacon(e))return;if(r.capabilities.fetchKeepalive){fetch(e,{method:"GET",keepalive:!0,mode:"no-cors",credentials:"omit"}).catch(()=>{});return}this.fireImageBeacon(e)}catch{this.log(`Failed to fire pixel: ${e}`)}}fireImageBeacon(e){const r=new Image(1,1);r.src=e}fireImpressions(e){for(const r of e){const t=m(r,this.macroContext);this.firePixel(t)}}fireError(e,r){const t={...this.macroContext,errorCode:r};for(const i of e){const a=m(i,t);this.firePixel(a)}}reset(){this.firedEvents.clear()}log(e){this.config.debug&&console.log(`[AdTracker] ${e}`)}}const P={targetBitrate:2500,maxWrapperDepth:5,timeout:1e4,debug:!1,skipButtonText:"Skip Ad"};class A{constructor(e){d(this,"config");d(this,"platform");d(this,"parser");d(this,"videoElement",null);d(this,"overlayElement",null);d(this,"skipButtonElement",null);d(this,"tracker",null);d(this,"state");d(this,"ads",[]);d(this,"listeners",new Set);d(this,"quartilesFired",new Set);d(this,"boundKeyHandler",null);d(this,"focusTrap",null);if(this.config={...P,...e},!this.config.container)throw new Error("Container element is required");this.platform=E(),this.parser=new k({maxWrapperDepth:this.config.maxWrapperDepth,timeout:this.config.timeout,debug:this.config.debug}),this.state={status:c.Idle,currentTime:0,duration:0,muted:!0,volume:1,canSkip:!1,skipCountdown:0,mediaFile:null,error:null},this.platform.platform==="tizen"&&this.platform.registerTizenKeys()}async init(){var e,r;if(!this.config.container)throw new Error("Container element not found");this.updateState({status:c.Loading});try{const t=await this.parser.parse(this.config.vastUrl);if(!t.success||!t.response)throw this.createError(((e=t.error)==null?void 0:e.code)||h.NO_VAST_RESPONSE,((r=t.error)==null?void 0:r.message)||"Failed to parse VAST");if(this.ads=t.response.ads,this.ads.length===0)throw this.createError(h.NO_VAST_RESPONSE,"No ads in VAST response");const i=this.getFirstLinearCreative();if(!i)throw this.createError(h.GENERAL_LINEAR_ERROR,"No linear creative found");const a=this.parser.selectBestMediaFile(i.mediaFiles,this.config.targetBitrate);if(!a)throw this.createError(h.FILE_NOT_FOUND,"No suitable media file found");this.updateState({mediaFile:a});const n=this.parser.aggregateTrackingEvents(this.ads);this.tracker=new S(n,{debug:this.config.debug}),this.tracker.updateMacroContext({assetUri:a.url}),this.createVideoElement(a),this.setupFocusManagement(),await this.attemptAutoplay()}catch(t){const i=t instanceof Error?this.createError(h.UNDEFINED_ERROR,t.message):t;this.handleError(i)}}getFirstLinearCreative(){for(const e of this.ads)for(const r of e.creatives)if(r.linear)return r.linear;return null}createVideoElement(e){const r=document.createElement("video"),t=this.platform.getVideoAttributes();Object.entries(t).forEach(([i,a])=>{typeof a=="boolean"?a&&r.setAttribute(i,""):r.setAttribute(i,a)}),r.src=e.url,r.style.cssText=`
1
+ (function(l,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("fast-xml-parser")):typeof define=="function"&&define.amd?define(["exports","fast-xml-parser"],f):(l=typeof globalThis<"u"?globalThis:l||self,f(l.AdgentSDK={},l.FastXMLParser))})(this,function(l,f){"use strict";var d=(r=>(r.Idle="idle",r.Loading="loading",r.Ready="ready",r.Playing="playing",r.Paused="paused",r.Completed="completed",r.Error="error",r.WaitingForInteraction="waiting_for_interaction",r))(d||{}),c=(r=>(r[r.XML_PARSING_ERROR=100]="XML_PARSING_ERROR",r[r.VAST_SCHEMA_VALIDATION_ERROR=101]="VAST_SCHEMA_VALIDATION_ERROR",r[r.VAST_VERSION_NOT_SUPPORTED=102]="VAST_VERSION_NOT_SUPPORTED",r[r.GENERAL_WRAPPER_ERROR=300]="GENERAL_WRAPPER_ERROR",r[r.WRAPPER_TIMEOUT=301]="WRAPPER_TIMEOUT",r[r.WRAPPER_LIMIT_REACHED=302]="WRAPPER_LIMIT_REACHED",r[r.NO_VAST_RESPONSE=303]="NO_VAST_RESPONSE",r[r.GENERAL_LINEAR_ERROR=400]="GENERAL_LINEAR_ERROR",r[r.FILE_NOT_FOUND=401]="FILE_NOT_FOUND",r[r.MEDIA_TIMEOUT=402]="MEDIA_TIMEOUT",r[r.MEDIA_NOT_SUPPORTED=403]="MEDIA_NOT_SUPPORTED",r[r.GENERAL_COMPANION_ERROR=600]="GENERAL_COMPANION_ERROR",r[r.UNDEFINED_ERROR=900]="UNDEFINED_ERROR",r))(c||{}),I=Object.defineProperty,x=(r,e,t)=>e in r?I(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,k=(r,e,t)=>x(r,typeof e!="symbol"?e+"":e,t);class w{constructor(e={}){k(this,"config"),k(this,"xmlParser");var t,i,s,a;this.config={maxWrapperDepth:(t=e.maxWrapperDepth)!=null?t:5,timeout:(i=e.timeout)!=null?i:1e4,debug:(s=e.debug)!=null?s:!1,fetchFn:(a=e.fetchFn)!=null?a:fetch.bind(globalThis)},this.xmlParser=new f.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}async parse(e){try{return{success:!0,response:await this.fetchAndParse(e,0)}}catch(t){const i=t instanceof Error?t.message:"Unknown error";return{success:!1,error:{code:c.GENERAL_WRAPPER_ERROR,message:i}}}}async fetchAndParse(e,t){if(t>=this.config.maxWrapperDepth)throw new Error(`Wrapper limit exceeded (max: ${this.config.maxWrapperDepth})`);this.log(`Fetching VAST (depth: ${t}): ${e}`);const i=await this.fetchWithTimeout(e),s=this.parseXml(i),a=await Promise.all(s.ads.map(async n=>{var p;return(p=n.wrapper)!=null&&p.vastAdTagURI?this.resolveWrapper(n,t+1):n}));return{...s,ads:a.flat()}}async resolveWrapper(e,t){var i;if(!((i=e.wrapper)!=null&&i.vastAdTagURI))return[e];try{return(await this.fetchAndParse(e.wrapper.vastAdTagURI,t)).ads.map(a=>this.mergeWrapperTracking(e,a))}catch(s){if(this.log(`Wrapper resolution failed: ${s}`),e.wrapper.fallbackOnNoAd)return[];throw s}}mergeWrapperTracking(e,t){return{...t,impressions:[...e.impressions,...t.impressions],errors:[...e.errors,...t.errors],creatives:t.creatives.map(i=>({...i,linear:i.linear?{...i.linear,trackingEvents:[...this.getWrapperTrackingEvents(e),...i.linear.trackingEvents]}:void 0}))}}getWrapperTrackingEvents(e){var t;const i=[];for(const s of e.creatives)(t=s.linear)!=null&&t.trackingEvents&&i.push(...s.linear.trackingEvents);return i}async fetchWithTimeout(e){const t=new AbortController,i=setTimeout(()=>t.abort(),this.config.timeout);try{const s=await this.config.fetchFn(e,{signal:t.signal});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);return s.text()}finally{clearTimeout(i)}}parseXml(e){const i=this.xmlParser.parse(e).VAST;if(!i)throw new Error("Invalid VAST: missing VAST element");const s=i["@_version"]||"4.0",a=this.parseAds(i.Ad);return{version:s,ads:a,errors:this.parseErrors(i.Error)}}parseAds(e){return e?(Array.isArray(e)?e:[e]).map(i=>this.parseAd(i)):[]}parseAd(e){var t,i,s;const a=!!e.Wrapper,n=e.InLine||e.Wrapper;return{id:e["@_id"]||"",sequence:e["@_sequence"],adSystem:n!=null&&n.AdSystem?{name:typeof n.AdSystem=="string"?n.AdSystem:n.AdSystem["#text"]||"",version:(t=n.AdSystem)==null?void 0:t["@_version"]}:void 0,adTitle:n==null?void 0:n.AdTitle,impressions:this.parseImpressions(n==null?void 0:n.Impression),errors:this.parseErrors(n==null?void 0:n.Error),creatives:this.parseCreatives((i=n==null?void 0:n.Creatives)==null?void 0:i.Creative),wrapper:a?{vastAdTagURI:n.VASTAdTagURI,followAdditionalWrappers:n["@_followAdditionalWrappers"]!==!1,allowMultipleAds:n["@_allowMultipleAds"],fallbackOnNoAd:n["@_fallbackOnNoAd"]}:void 0,inLine:a?void 0:{adTitle:(n==null?void 0:n.AdTitle)||"",description:n==null?void 0:n.Description,advertiser:n==null?void 0:n.Advertiser,creatives:this.parseCreatives((s=n==null?void 0:n.Creatives)==null?void 0:s.Creative)}}}parseImpressions(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||""})):[]}parseCreatives(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],sequence:i["@_sequence"],adId:i["@_adId"],linear:i.Linear?this.parseLinear(i.Linear):void 0})):[]}parseLinear(e){var t,i;return{duration:this.parseDuration(e.Duration),skipOffset:e["@_skipoffset"]?this.parseDuration(e["@_skipoffset"]):void 0,mediaFiles:this.parseMediaFiles((t=e.MediaFiles)==null?void 0:t.MediaFile),trackingEvents:this.parseTrackingEvents((i=e.TrackingEvents)==null?void 0:i.Tracking),videoClicks:e.VideoClicks?{clickThrough:e.VideoClicks.ClickThrough?{id:e.VideoClicks.ClickThrough["@_id"],url:typeof e.VideoClicks.ClickThrough=="string"?e.VideoClicks.ClickThrough:e.VideoClicks.ClickThrough["#text"]||""}:void 0}:void 0,adParameters:e.AdParameters}}parseMediaFiles(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||"",delivery:i["@_delivery"]||"progressive",type:i["@_type"]||"video/mp4",width:parseInt(i["@_width"],10)||0,height:parseInt(i["@_height"],10)||0,bitrate:i["@_bitrate"]?parseInt(i["@_bitrate"],10):void 0,codec:i["@_codec"],scalable:i["@_scalable"],maintainAspectRatio:i["@_maintainAspectRatio"]})):[]}parseTrackingEvents(e){return e?(Array.isArray(e)?e:[e]).map(i=>({event:i["@_event"],url:typeof i=="string"?i:i["#text"]||"",offset:i["@_offset"]?this.parseDuration(i["@_offset"]):void 0})):[]}parseErrors(e){return e?(Array.isArray(e)?e:[e]).map(i=>typeof i=="string"?i:i["#text"]||""):[]}parseDuration(e){if(typeof e=="number")return e;if(typeof e!="string")return 0;if(e.endsWith("%"))return parseFloat(e)/100;const t=e.match(/(\d+):(\d+):(\d+(?:\.\d+)?)/);if(t){const[,i,s,a]=t;return parseInt(i,10)*3600+parseInt(s,10)*60+parseFloat(a)}return parseFloat(e)||0}selectBestMediaFile(e,t=2500){if(e.length===0)return null;const i=e.filter(n=>n.type.includes("mp4")||n.type.includes("video/mp4"));return[...i.length>0?i:e].sort((n,p)=>{const _=n.bitrate||0,y=p.bitrate||0,W=n.height>1080?1e4:0,B=p.height>1080?1e4:0,V=Math.abs(_-t)+W,$=Math.abs(y-t)+B;return V-$})[0]||null}aggregateTrackingEvents(e){var t;const i=[];for(const s of e)for(const a of s.creatives)(t=a.linear)!=null&&t.trackingEvents&&i.push(...a.linear.trackingEvents);return i}aggregateImpressions(e){const t=[];for(const i of e)for(const s of i.impressions)t.push(s.url);return t}log(e){this.config.debug&&console.log(`[VASTParser] ${e}`)}}function m(r,e={}){let t=r;return t=t.replace(/\[TIMESTAMP\]/g,Date.now().toString()),t=t.replace(/\[CACHEBUSTING\]/g,Math.random().toString(36).substring(2,15)),e.assetUri&&(t=t.replace(/\[ASSETURI\]/g,encodeURIComponent(e.assetUri))),e.contentPlayhead!==void 0&&(t=t.replace(/\[CONTENTPLAYHEAD\]/g,R(e.contentPlayhead))),e.adPlayhead!==void 0&&(t=t.replace(/\[ADPLAYHEAD\]/g,R(e.adPlayhead))),e.errorCode!==void 0&&(t=t.replace(/\[ERRORCODE\]/g,e.errorCode.toString())),e.breakPosition!==void 0&&(t=t.replace(/\[BREAKPOSITION\]/g,e.breakPosition.toString())),e.adType&&(t=t.replace(/\[ADTYPE\]/g,e.adType)),t}function R(r){const e=Math.floor(r/3600),t=Math.floor(r%3600/60),i=Math.floor(r%60),s=Math.floor(r%1*1e3);return e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+":"+i.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")}var o=(r=>(r.WebOS="webos",r.Tizen="tizen",r.Vidaa="vidaa",r.WhaleOS="whaleos",r.FireTV="firetv",r.Roku="roku",r.Xbox="xbox",r.PlayStation="playstation",r.AndroidTV="androidtv",r.Vizio="vizio",r.Generic="generic",r))(o||{}),h=(r=>(r.Enter="enter",r.Back="back",r.Left="left",r.Right="right",r.Up="up",r.Down="down",r.Play="play",r.Pause="pause",r.PlayPause="playPause",r.Stop="stop",r.FastForward="fastForward",r.Rewind="rewind",r.Menu="menu",r.Info="info",r.Red="red",r.Green="green",r.Yellow="yellow",r.Blue="blue",r.ChannelUp="channelUp",r.ChannelDown="channelDown",r.VolumeUp="volumeUp",r.VolumeDown="volumeDown",r.Mute="mute",r))(h||{});const T={webos:{13:"enter",461:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",33:"channelUp",34:"channelDown"},tizen:{13:"enter",10009:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",10252:"playPause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",427:"channelUp",428:"channelDown",447:"volumeUp",448:"volumeDown",449:"mute"},vidaa:{13:"enter",8:"back",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind"},whaleos:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop"},firetv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},roku:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",179:"playPause",178:"stop",228:"fastForward",227:"rewind"},xbox:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",195:"menu",196:"menu"},playstation:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down"},androidtv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},vizio:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause"},generic:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",32:"playPause",80:"play",83:"stop",77:"mute"}},S={tizen:[/Tizen/i,/SMART-TV.*Samsung/i],webos:[/Web0S/i,/WebOS/i,/LG.*NetCast/i,/LGE.*TV/i],vidaa:[/Vidaa/i,/VIDAA/i,/Hisense/i],whaleos:[/WhaleTV/i,/Whale/i],firetv:[/AFT/i,/AFTS/i,/AFTM/i,/Amazon.*Fire/i],roku:[/Roku/i],xbox:[/Xbox/i,/Edge.*Xbox/i],playstation:[/PlayStation/i,/PS4/i,/PS5/i],androidtv:[/Android.*TV/i,/Chromecast/i,/BRAVIA/i,/SHIELD/i],vizio:[/VIZIO/i,/SmartCast/i],generic:[]};var C=Object.defineProperty,N=(r,e,t)=>e in r?C(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e,t)=>N(r,typeof e!="symbol"?e+"":e,t);class P{constructor(){v(this,"platform"),v(this,"capabilities"),v(this,"deviceInfo"),v(this,"keyMap"),v(this,"reverseKeyMap"),this.platform=this.detectPlatform(),this.keyMap=T[this.platform],this.reverseKeyMap=this.buildReverseKeyMap(),this.capabilities=this.detectCapabilities(),this.deviceInfo=this.detectDeviceInfo()}detectPlatform(){if(typeof window>"u"||typeof navigator>"u")return o.Generic;const e=navigator.userAgent,t=window;if(t.tizen)return o.Tizen;if(t.webOS||t.PalmSystem)return o.WebOS;for(const[i,s]of Object.entries(S))if(i!==o.Generic){for(const a of s)if(a.test(e))return i}return o.Generic}detectCapabilities(){const e=typeof navigator<"u",t=typeof document<"u",i=typeof window<"u",s={sendBeacon:e&&"sendBeacon"in navigator,fetchKeepalive:typeof fetch<"u",mutedAutoplayRequired:!0,fullscreen:t&&("fullscreenEnabled"in document||"webkitFullscreenEnabled"in document),hardwareDecodeInfo:!1,hdr:!1,hdr10Plus:!1,dolbyVision:!1,dolbyAtmos:!1,hevc:this.isCodecSupported('video/mp4; codecs="hvc1"'),vp9:this.isCodecSupported('video/webm; codecs="vp9"'),av1:this.isCodecSupported('video/mp4; codecs="av01.0.05M.08"'),maxResolution:this.detectMaxResolution(),touch:i&&"ontouchstart"in window,voice:!1};switch(this.platform){case o.Tizen:return{...s,hardwareDecodeInfo:!0,hdr:!0,hevc:!0,voice:!0};case o.WebOS:return{...s,hardwareDecodeInfo:!0,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,voice:!0};case o.FireTV:return{...s,hdr:!0,hdr10Plus:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Roku:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Xbox:return{...s,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,av1:!0,voice:!0};case o.PlayStation:return{...s,hdr:!0,hevc:!0};case o.AndroidTV:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,vp9:!0,voice:!0};default:return s}}detectDeviceInfo(){var e,t,i;const s={platform:this.platform};typeof window<"u"&&(s.screenWidth=(e=window.screen)==null?void 0:e.width,s.screenHeight=(t=window.screen)==null?void 0:t.height,s.devicePixelRatio=window.devicePixelRatio);const a=window;if(this.platform===o.Tizen&&((i=a.tizen)!=null&&i.systeminfo))try{a.tizen.systeminfo.getPropertyValue("BUILD",n=>{s.model=n.model,s.manufacturer=n.manufacturer||"Samsung"})}catch{s.manufacturer="Samsung"}if(this.platform===o.WebOS&&a.webOSSystem)try{const n=a.webOSSystem.deviceInfo;s.model=n==null?void 0:n.modelName,s.manufacturer="LG",s.osVersion=n==null?void 0:n.version}catch{s.manufacturer="LG"}return s}detectMaxResolution(){var e,t;if(typeof window>"u")return"unknown";const i=((e=window.screen)==null?void 0:e.width)||0,s=((t=window.screen)==null?void 0:t.height)||0,a=Math.max(i,s);return a>=3840?"4k":a>=1920?"1080p":a>=1280?"720p":"unknown"}buildReverseKeyMap(){const e=new Map;for(const[t,i]of Object.entries(this.keyMap)){const s=parseInt(t,10),a=e.get(i)||[];a.push(s),e.set(i,a)}return e}normalizeKeyCode(e){var t;return(t=this.keyMap[e])!=null?t:null}getKeyCodesForAction(e){return this.reverseKeyMap.get(e)||[]}isCodecSupported(e){if(typeof document>"u")return!1;try{const i=document.createElement("video").canPlayType(e);return i==="probably"||i==="maybe"}catch{return!1}}registerTizenKeys(){if(this.platform!==o.Tizen)return;const e=window.tizen;e!=null&&e.tvinputdevice&&["MediaPlay","MediaPause","MediaStop","MediaFastForward","MediaRewind","MediaPlayPause","ColorF0Red","ColorF1Green","ColorF2Yellow","ColorF3Blue","Info"].forEach(i=>{try{e.tvinputdevice.registerKey(i)}catch{}})}registerWebOSKeys(){this.platform,o.WebOS}getVideoAttributes(){const e={muted:!0,playsinline:!0,autoplay:!0,"webkit-playsinline":!0};switch(this.platform){case o.Tizen:e["data-samsung-immersive"]="true";break;case o.WebOS:e["data-lg-immersive"]="true";break;case o.FireTV:case o.AndroidTV:e["x-webkit-airplay"]="allow";break}return e}getRecommendedVideoSettings(){switch(this.platform){case o.Tizen:case o.WebOS:return{maxBitrate:15e3,preferredCodec:"hevc",maxResolution:"4k"};case o.FireTV:return{maxBitrate:1e4,preferredCodec:"hevc",maxResolution:"4k"};case o.Roku:return{maxBitrate:8e3,preferredCodec:"h264",maxResolution:"4k"};case o.Xbox:case o.PlayStation:return{maxBitrate:2e4,preferredCodec:"hevc",maxResolution:"4k"};default:return{maxBitrate:5e3,preferredCodec:"h264",maxResolution:"1080p"}}}}let E=null;function b(){return E||(E=new P),E}var M=Object.defineProperty,D=(r,e,t)=>e in r?M(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,g=(r,e,t)=>D(r,typeof e!="symbol"?e+"":e,t);class A{constructor(e=[],t={}){g(this,"config"),g(this,"trackingEvents"),g(this,"firedEvents"),g(this,"macroContext");var i,s,a;this.config={debug:(i=t.debug)!=null?i:!1,retry:(s=t.retry)!=null?s:!1,maxRetries:(a=t.maxRetries)!=null?a:3},this.trackingEvents=this.groupEventsByType(e),this.firedEvents=new Set,this.macroContext={}}groupEventsByType(e){const t=new Map;for(const i of e){const s=t.get(i.event)||[];s.push(i),t.set(i.event,s)}return t}updateMacroContext(e){this.macroContext={...this.macroContext,...e}}track(e,t=!0){const i=this.trackingEvents.get(e);if(!i){this.log(`No tracking URLs for event: ${e}`);return}for(const s of i){const a=`${e}:${s.url}`;if(t&&this.firedEvents.has(a)){this.log(`Skipping duplicate event: ${e}`);continue}const n=m(s.url,this.macroContext);this.firePixel(n),t&&this.firedEvents.add(a)}}firePixel(e){const t=b();this.log(`Firing pixel: ${e}`);try{if(t.capabilities.sendBeacon&&navigator.sendBeacon(e))return;if(t.capabilities.fetchKeepalive){fetch(e,{method:"GET",keepalive:!0,mode:"no-cors",credentials:"omit"}).catch(()=>{});return}this.fireImageBeacon(e)}catch{this.log(`Failed to fire pixel: ${e}`)}}fireImageBeacon(e){const t=new Image(1,1);t.src=e}fireImpressions(e){for(const t of e){const i=m(t,this.macroContext);this.firePixel(i)}}fireError(e,t){const i={...this.macroContext,errorCode:t};for(const s of e){const a=m(s,i);this.firePixel(a)}}reset(){this.firedEvents.clear()}log(e){this.config.debug&&console.log(`[AdTracker] ${e}`)}}var F=Object.defineProperty,L=(r,e,t)=>e in r?F(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,u=(r,e,t)=>L(r,typeof e!="symbol"?e+"":e,t);const U={targetBitrate:2500,maxWrapperDepth:5,timeout:1e4,debug:!1,skipButtonText:"Skip Ad"};class O{constructor(e){u(this,"config"),u(this,"platform"),u(this,"parser"),u(this,"videoElement",null),u(this,"overlayElement",null),u(this,"skipButtonElement",null),u(this,"tracker",null),u(this,"state"),u(this,"ads",[]),u(this,"listeners",new Set),u(this,"quartilesFired",new Set),u(this,"boundKeyHandler",null),u(this,"focusTrap",null),this.config={...U,...e},this.platform=b(),this.parser=new w({maxWrapperDepth:this.config.maxWrapperDepth,timeout:this.config.timeout,debug:this.config.debug}),this.state={status:d.Idle,currentTime:0,duration:0,muted:!0,volume:1,canSkip:!1,skipCountdown:0,mediaFile:null,error:null},this.platform.platform==="tizen"&&this.platform.registerTizenKeys()}async init(){var e,t;if(!this.config.container)throw new Error("Container element not found");this.updateState({status:d.Loading});try{const i=await this.parser.parse(this.config.vastUrl);if(!i.success||!i.response)throw this.createError(((e=i.error)==null?void 0:e.code)||c.NO_VAST_RESPONSE,((t=i.error)==null?void 0:t.message)||"Failed to parse VAST");if(this.ads=i.response.ads,this.ads.length===0)throw this.createError(c.NO_VAST_RESPONSE,"No ads in VAST response");const s=this.getFirstLinearCreative();if(!s)throw this.createError(c.GENERAL_LINEAR_ERROR,"No linear creative found");const a=this.parser.selectBestMediaFile(s.mediaFiles,this.config.targetBitrate);if(!a)throw this.createError(c.FILE_NOT_FOUND,"No suitable media file found");this.updateState({mediaFile:a});const n=this.parser.aggregateTrackingEvents(this.ads);this.tracker=new A(n,{debug:this.config.debug}),this.tracker.updateMacroContext({assetUri:a.url}),this.createVideoElement(a),this.setupFocusManagement(),await this.attemptAutoplay()}catch(i){const s=i instanceof Error?this.createError(c.UNDEFINED_ERROR,i.message):i;this.handleError(s)}}getFirstLinearCreative(){for(const e of this.ads)for(const t of e.creatives)if(t.linear)return t.linear;return null}createVideoElement(e){const t=document.createElement("video"),i=this.platform.getVideoAttributes();Object.entries(i).forEach(([s,a])=>{typeof a=="boolean"?a&&t.setAttribute(s,""):t.setAttribute(s,a)}),t.src=e.url,t.style.cssText=`
2
2
  width: 100%;
3
3
  height: 100%;
4
4
  object-fit: contain;
5
5
  background: #000;
6
- `,r.addEventListener("loadedmetadata",()=>{this.updateState({duration:r.duration,status:c.Ready}),this.emit({type:"loaded"})}),r.addEventListener("timeupdate",()=>{this.handleTimeUpdate(r)}),r.addEventListener("ended",()=>{this.handleComplete()}),r.addEventListener("error",()=>{const i=r.error;this.handleError(this.createError(h.MEDIA_NOT_SUPPORTED,(i==null?void 0:i.message)||"Video playback error"))}),r.addEventListener("play",()=>{this.updateState({status:c.Playing})}),r.addEventListener("pause",()=>{var i;this.state.status!==c.Completed&&(this.updateState({status:c.Paused}),this.emit({type:"pause"}),(i=this.tracker)==null||i.track("pause"))}),this.config.container.appendChild(r),this.videoElement=r,this.log(`Video element created with src: ${e.url}`)}async attemptAutoplay(){if(this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.log(`Autoplay failed: ${e}`),this.showStartOverlay()}}showStartOverlay(){if(this.updateState({status:c.WaitingForInteraction}),this.config.customStartOverlay){this.overlayElement=this.config.customStartOverlay,this.config.container.appendChild(this.overlayElement);return}const e=document.createElement("div");e.innerHTML=`
6
+ `,t.addEventListener("loadedmetadata",()=>{this.updateState({duration:t.duration,status:d.Ready}),this.emit({type:"loaded"})}),t.addEventListener("timeupdate",()=>{this.handleTimeUpdate(t)}),t.addEventListener("ended",()=>{this.handleComplete()}),t.addEventListener("error",()=>{const s=t.error;this.handleError(this.createError(c.MEDIA_NOT_SUPPORTED,(s==null?void 0:s.message)||"Video playback error"))}),t.addEventListener("play",()=>{this.updateState({status:d.Playing})}),t.addEventListener("pause",()=>{var s;this.state.status!==d.Completed&&(this.updateState({status:d.Paused}),this.emit({type:"pause"}),(s=this.tracker)==null||s.track("pause"))}),this.config.container.appendChild(t),this.videoElement=t,this.log(`Video element created with src: ${e.url}`)}async attemptAutoplay(){if(this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.log(`Autoplay failed: ${e}`),this.showStartOverlay()}}showStartOverlay(){if(this.updateState({status:d.WaitingForInteraction}),this.config.customStartOverlay){this.overlayElement=this.config.customStartOverlay,this.config.container.appendChild(this.overlayElement);return}const e=document.createElement("div");e.innerHTML=`
7
7
  <div style="
8
8
  position: absolute;
9
9
  top: 0;
@@ -29,7 +29,7 @@
29
29
  ▶ Start Ad
30
30
  </button>
31
31
  </div>
32
- `,e.style.cssText="position: absolute; top: 0; left: 0; width: 100%; height: 100%;";const r=e.querySelector("#adgent-start-btn");r==null||r.addEventListener("click",()=>this.onStartClick()),this.config.container.style.position="relative",this.config.container.appendChild(e),this.overlayElement=e,r==null||r.focus()}async onStartClick(){if(this.removeOverlay(),this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.handleError(this.createError(h.GENERAL_LINEAR_ERROR,`Playback failed: ${e}`))}}removeOverlay(){this.overlayElement&&(this.overlayElement.remove(),this.overlayElement=null)}handlePlaybackStart(){var r,t,i,a,n;this.updateState({status:c.Playing}),this.emit({type:"start"}),(t=(r=this.config).onStart)==null||t.call(r);const e=this.parser.aggregateImpressions(this.ads);(i=this.tracker)==null||i.fireImpressions(e),(a=this.tracker)==null||a.track("start"),(n=this.tracker)==null||n.track("creativeView"),this.setupSkipButton(),this.log("Playback started")}handleTimeUpdate(e){var f,g,v;const r=e.currentTime,t=e.duration;if(!t||isNaN(t))return;const i=r/t*100,a=this.calculateQuartile(i);this.updateState({currentTime:r,duration:t}),this.updateSkipCountdown(r),(f=this.tracker)==null||f.updateMacroContext({adPlayhead:r});const n={currentTime:r,duration:t,percentage:i,quartile:a};this.emit({type:"progress",data:n}),(v=(g=this.config).onProgress)==null||v.call(g,n),this.fireQuartileEvents(i)}calculateQuartile(e){return e>=100?4:e>=75?3:e>=50?2:e>=25?1:0}fireQuartileEvents(e){var t;const r=[{threshold:25,event:"firstQuartile"},{threshold:50,event:"midpoint"},{threshold:75,event:"thirdQuartile"}];for(const{threshold:i,event:a}of r)e>=i&&!this.quartilesFired.has(i)&&(this.quartilesFired.add(i),(t=this.tracker)==null||t.track(a),this.emit({type:"quartile",data:{quartile:a}}),this.log(`Quartile fired: ${a}`))}setupSkipButton(){const e=this.getFirstLinearCreative(),r=this.config.skipOffset??(e==null?void 0:e.skipOffset);if(!r||r<=0)return;this.updateState({skipCountdown:r,canSkip:!1});const t=document.createElement("button");t.id="adgent-skip-btn",t.style.cssText=`
32
+ `,e.style.cssText="position: absolute; top: 0; left: 0; width: 100%; height: 100%;";const t=e.querySelector("#adgent-start-btn");t==null||t.addEventListener("click",()=>this.onStartClick()),this.config.container.style.position="relative",this.config.container.appendChild(e),this.overlayElement=e,t==null||t.focus()}async onStartClick(){if(this.removeOverlay(),this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.handleError(this.createError(c.GENERAL_LINEAR_ERROR,`Playback failed: ${e}`))}}removeOverlay(){this.overlayElement&&(this.overlayElement.remove(),this.overlayElement=null)}handlePlaybackStart(){var e,t,i,s,a;this.updateState({status:d.Playing}),this.emit({type:"start"}),(t=(e=this.config).onStart)==null||t.call(e);const n=this.parser.aggregateImpressions(this.ads);(i=this.tracker)==null||i.fireImpressions(n),(s=this.tracker)==null||s.track("start"),(a=this.tracker)==null||a.track("creativeView"),this.setupSkipButton(),this.log("Playback started")}handleTimeUpdate(e){var t,i,s;const a=e.currentTime,n=e.duration;if(!n||isNaN(n))return;const p=a/n*100,_=this.calculateQuartile(p);this.updateState({currentTime:a,duration:n}),this.updateSkipCountdown(a),(t=this.tracker)==null||t.updateMacroContext({adPlayhead:a});const y={currentTime:a,duration:n,percentage:p,quartile:_};this.emit({type:"progress",data:y}),(s=(i=this.config).onProgress)==null||s.call(i,y),this.fireQuartileEvents(p)}calculateQuartile(e){return e>=100?4:e>=75?3:e>=50?2:e>=25?1:0}fireQuartileEvents(e){var t;const i=[{threshold:25,event:"firstQuartile"},{threshold:50,event:"midpoint"},{threshold:75,event:"thirdQuartile"}];for(const{threshold:s,event:a}of i)e>=s&&!this.quartilesFired.has(s)&&(this.quartilesFired.add(s),(t=this.tracker)==null||t.track(a),this.emit({type:"quartile",data:{quartile:a}}),this.log(`Quartile fired: ${a}`))}setupSkipButton(){var e;const t=this.getFirstLinearCreative(),i=(e=this.config.skipOffset)!=null?e:t==null?void 0:t.skipOffset;if(!i||i<=0)return;this.updateState({skipCountdown:i,canSkip:!1});const s=document.createElement("button");s.id="adgent-skip-btn",s.style.cssText=`
33
33
  position: absolute;
34
34
  bottom: 20px;
35
35
  right: 20px;
@@ -42,4 +42,4 @@
42
42
  cursor: pointer;
43
43
  z-index: 101;
44
44
  transition: opacity 0.3s;
45
- `,t.textContent=`Skip in ${r}s`,t.addEventListener("click",()=>this.skip()),this.config.container.appendChild(t),this.skipButtonElement=t}updateSkipCountdown(e){const r=this.getFirstLinearCreative(),t=this.config.skipOffset??(r==null?void 0:r.skipOffset);if(!t||!this.skipButtonElement)return;const i=Math.max(0,t-e);this.updateState({skipCountdown:i}),i<=0&&!this.state.canSkip?(this.updateState({canSkip:!0}),this.skipButtonElement.textContent=this.config.skipButtonText,this.skipButtonElement.style.opacity="1"):i>0&&(this.skipButtonElement.textContent=`Skip in ${Math.ceil(i)}s`,this.skipButtonElement.style.opacity="0.6")}skip(){var e,r,t;if(!this.state.canSkip){this.log("Skip not available yet");return}(e=this.tracker)==null||e.track("skip"),this.emit({type:"skip"}),(t=(r=this.config).onSkip)==null||t.call(r),this.destroy(),this.log("Ad skipped")}handleComplete(){var e,r,t;this.updateState({status:c.Completed}),(e=this.tracker)==null||e.track("complete"),this.emit({type:"complete"}),(t=(r=this.config).onComplete)==null||t.call(r),this.log("Ad completed")}handleError(e){var t,i,a;this.updateState({status:c.Error,error:e});const r=[];for(const n of this.ads)r.push(...n.errors);(t=this.tracker)==null||t.fireError(r,e.code),this.emit({type:"error",data:e}),(a=(i=this.config).onError)==null||a.call(i,e),this.log(`Error: ${e.message}`)}setupFocusManagement(){this.focusTrap=document.createElement("div"),this.focusTrap.tabIndex=0,this.focusTrap.style.cssText="position: absolute; opacity: 0; width: 0; height: 0;",this.config.container.appendChild(this.focusTrap),this.focusTrap.focus(),this.boundKeyHandler=e=>{const r=this.platform.normalizeKeyCode(e.keyCode);r&&(e.preventDefault(),e.stopPropagation(),this.handleKeyAction(r))},document.addEventListener("keydown",this.boundKeyHandler,!0)}handleKeyAction(e){var r,t;switch(this.log(`Key action: ${e}`),e){case p.Enter:this.state.status===c.WaitingForInteraction?this.onStartClick():this.state.canSkip&&this.skip();break;case p.Back:this.log("Back pressed - ignoring during ad");break;case p.Play:(r=this.videoElement)==null||r.play();break;case p.Pause:(t=this.videoElement)==null||t.pause();break;case p.Left:case p.Right:case p.Up:case p.Down:break}}unmute(){var e;this.videoElement&&(this.videoElement.muted=!1,this.updateState({muted:!1}),(e=this.tracker)==null||e.track("unmute"),this.emit({type:"unmute"}))}mute(){var e;this.videoElement&&(this.videoElement.muted=!0,this.updateState({muted:!0}),(e=this.tracker)==null||e.track("mute"),this.emit({type:"mute"}))}on(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return{...this.state}}destroy(){var e,r,t,i,a;this.boundKeyHandler&&(document.removeEventListener("keydown",this.boundKeyHandler,!0),this.boundKeyHandler=null),(e=this.videoElement)==null||e.remove(),(r=this.overlayElement)==null||r.remove(),(t=this.skipButtonElement)==null||t.remove(),(i=this.focusTrap)==null||i.remove(),this.videoElement=null,this.overlayElement=null,this.skipButtonElement=null,this.focusTrap=null,(a=this.tracker)==null||a.reset(),this.quartilesFired.clear(),this.listeners.clear(),this.ads=[],this.emit({type:"destroy"}),this.log("Player destroyed")}updateState(e){this.state={...this.state,...e}}emit(e){for(const r of this.listeners)try{r(e)}catch(t){this.log(`Listener error: ${t}`)}}createError(e,r,t=!1){return{code:e,message:r,recoverable:t}}log(e){this.config.debug&&console.log(`[AdPlayer] ${e}`)}}l.AdPlayer=A,l.AdTracker=S,l.AdgentSDK=A,l.DEFAULT_KEY_CODES=b,l.KeyAction=p,l.PLATFORM_DETECTION_PATTERNS=R,l.Platform=o,l.PlatformAdapter=T,l.PlaybackStatus=c,l.VASTErrorCode=h,l.VASTParser=k,l.getPlatformAdapter=E,l.replaceMacros=m,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
45
+ `,s.textContent=`Skip in ${i}s`,s.addEventListener("click",()=>this.skip()),this.config.container.appendChild(s),this.skipButtonElement=s}updateSkipCountdown(e){var t;const i=this.getFirstLinearCreative(),s=(t=this.config.skipOffset)!=null?t:i==null?void 0:i.skipOffset;if(!s||!this.skipButtonElement)return;const a=Math.max(0,s-e);this.updateState({skipCountdown:a}),a<=0&&!this.state.canSkip?(this.updateState({canSkip:!0}),this.skipButtonElement.textContent=this.config.skipButtonText,this.skipButtonElement.style.opacity="1"):a>0&&(this.skipButtonElement.textContent=`Skip in ${Math.ceil(a)}s`,this.skipButtonElement.style.opacity="0.6")}skip(){var e,t,i;if(!this.state.canSkip){this.log("Skip not available yet");return}(e=this.tracker)==null||e.track("skip"),this.emit({type:"skip"}),(i=(t=this.config).onSkip)==null||i.call(t),this.destroy(),this.log("Ad skipped")}handleComplete(){var e,t,i;this.updateState({status:d.Completed}),(e=this.tracker)==null||e.track("complete"),this.emit({type:"complete"}),(i=(t=this.config).onComplete)==null||i.call(t),this.log("Ad completed")}handleError(e){var t,i,s;this.updateState({status:d.Error,error:e});const a=[];for(const n of this.ads)a.push(...n.errors);(t=this.tracker)==null||t.fireError(a,e.code),this.emit({type:"error",data:e}),(s=(i=this.config).onError)==null||s.call(i,e),this.log(`Error: ${e.message}`)}setupFocusManagement(){this.focusTrap=document.createElement("div"),this.focusTrap.tabIndex=0,this.focusTrap.style.cssText="position: absolute; opacity: 0; width: 0; height: 0;",this.config.container.appendChild(this.focusTrap),this.focusTrap.focus(),this.boundKeyHandler=e=>{const t=this.platform.normalizeKeyCode(e.keyCode);t&&(e.preventDefault(),e.stopPropagation(),this.handleKeyAction(t))},document.addEventListener("keydown",this.boundKeyHandler,!0)}handleKeyAction(e){var t,i;switch(this.log(`Key action: ${e}`),e){case h.Enter:this.state.status===d.WaitingForInteraction?this.onStartClick():this.state.canSkip&&this.skip();break;case h.Back:this.log("Back pressed - ignoring during ad");break;case h.Play:(t=this.videoElement)==null||t.play();break;case h.Pause:(i=this.videoElement)==null||i.pause();break;case h.Left:case h.Right:case h.Up:case h.Down:break}}unmute(){var e;this.videoElement&&(this.videoElement.muted=!1,this.updateState({muted:!1}),(e=this.tracker)==null||e.track("unmute"),this.emit({type:"unmute"}))}mute(){var e;this.videoElement&&(this.videoElement.muted=!0,this.updateState({muted:!0}),(e=this.tracker)==null||e.track("mute"),this.emit({type:"mute"}))}on(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return{...this.state}}destroy(){var e,t,i,s,a;this.boundKeyHandler&&(document.removeEventListener("keydown",this.boundKeyHandler,!0),this.boundKeyHandler=null),(e=this.videoElement)==null||e.remove(),(t=this.overlayElement)==null||t.remove(),(i=this.skipButtonElement)==null||i.remove(),(s=this.focusTrap)==null||s.remove(),this.videoElement=null,this.overlayElement=null,this.skipButtonElement=null,this.focusTrap=null,(a=this.tracker)==null||a.reset(),this.quartilesFired.clear(),this.listeners.clear(),this.ads=[],this.emit({type:"destroy"}),this.log("Player destroyed")}updateState(e){this.state={...this.state,...e}}emit(e){for(const t of this.listeners)try{t(e)}catch(i){this.log(`Listener error: ${i}`)}}createError(e,t,i=!1){return{code:e,message:t,recoverable:i}}log(e){this.config.debug&&console.log(`[AdPlayer] ${e}`)}}l.AdPlayer=O,l.AdTracker=A,l.AdgentSDK=O,l.DEFAULT_KEY_CODES=T,l.KeyAction=h,l.PLATFORM_DETECTION_PATTERNS=S,l.Platform=o,l.PlatformAdapter=P,l.PlaybackStatus=d,l.VASTErrorCode=c,l.VASTParser=w,l.getPlatformAdapter=b,l.replaceMacros=m,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adgent-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Lightweight, framework-agnostic VAST Player SDK for Smart TV platforms",
5
5
  "type": "module",
6
6
  "main": "./dist/adgent-sdk.umd.js",