@openplayerjs/ads 3.1.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ function _mergeNamespaces(n, m) {
15
15
  return Object.freeze(n);
16
16
  }
17
17
 
18
- function e$1(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adId:e.adId||null,sequence:e.sequence||null,apiFramework:e.apiFramework||null,universalAdIds:[],creativeExtensions:[]}}const t$1=["ADCATEGORIES","ADCOUNT","ADPLAYHEAD","ADSERVINGID","ADTYPE","APIFRAMEWORKS","APPBUNDLE","ASSETURI","BLOCKEDADCATEGORIES","BREAKMAXADLENGTH","BREAKMAXADS","BREAKMAXDURATION","BREAKMINADLENGTH","BREAKMINDURATION","BREAKPOSITION","CLICKPOS","CLICKTYPE","CLIENTUA","CONTENTID","CONTENTPLAYHEAD","CONTENTURI","DEVICEIP","DEVICEUA","DOMAIN","EXTENSIONS","GDPRCONSENT","IFA","IFATYPE","INVENTORYSTATE","LATLONG","LIMITADTRACKING","MEDIAMIME","MEDIAPLAYHEAD","OMIDPARTNER","PAGEURL","PLACEMENTTYPE","PLAYERCAPABILITIES","PLAYERSIZE","PLAYERSTATE","PODSEQUENCE","REGULATIONS","SERVERSIDE","SERVERUA","TRANSACTIONID","UNIVERSALADID","VASTVERSIONS","VERIFICATIONVENDORS"];function r$1(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=[],n=s$1(e);!t.ERRORCODE||r.isCustomCode||/^[0-9]{3}$/.test(t.ERRORCODE)||(t.ERRORCODE=900),t.CACHEBUSTING=d(Math.round(1e8*Math.random())),t.TIMESTAMP=(new Date).toISOString(),t.RANDOM=t.random=t.CACHEBUSTING;for(const e in t)t[e]=c(t[e]);for(const e in n){const r=n[e];"string"==typeof r&&a.push(i$1(r,t));}return a}function i$1(e,r){const i=(e=a$1(e,r)).match(/[^[\]]+(?=])/g);if(!i)return e;let s=i.filter((e=>t$1.indexOf(e)>-1));return 0===s.length?e:(s=s.reduce(((e,t)=>(e[t]=-1,e)),{}),a$1(e,s))}function a$1(e,t){let r=e;for(const e in t){const i=t[e];r=r.replace(new RegExp("(?:\\[|%%)(".concat(e,")(?:\\]|%%)"),"g"),i);}return r}function s$1(e){return Array.isArray(e)?e.map((e=>e&&e.hasOwnProperty("url")?e.url:e)):e}function n$1(e){return /^(https?:\/\/|\/\/)/.test(e)}function o$1(e,t){for(let r=0;r<t.length;r++)if(l(t[r],e))return true;return false}function l(e,t){if(e&&t){const r=Object.getOwnPropertyNames(e),i=Object.getOwnPropertyNames(t);return r.length===i.length&&(e.id===t.id&&e.url===t.url)}return false}function c(e){return encodeURIComponent(e).replace(/[!'()*]/g,(e=>"%".concat(e.charCodeAt(0).toString(16))))}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e.toString().padStart(t,"0")}const u={track:function(e,t,i){r$1(e,t,i).forEach((e=>{if("undefined"!=typeof window&&null!==window){(new Image).src=e;}}));},resolveURLTemplates:r$1,extractURLsFromTemplates:s$1,filterUrlTemplates:function(e){return e.reduce(((e,t)=>{const r=t.url||t;return n$1(r)?e.validUrls.push(r):e.invalidUrls.push(r),e}),{validUrls:[],invalidUrls:[]})},containsTemplateObject:o$1,isTemplateObjectEqual:l,encodeURIComponentRFC3986:c,replaceUrlMacros:i$1,isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},flatten:function e(t){return t.reduce(((t,r)=>t.concat(Array.isArray(r)?e(r):r)),[])},joinArrayOfUniqueTemplateObjs:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];const r=Array.isArray(e)?e:[],i=Array.isArray(t)?t:[];return r.concat(i).reduce(((e,t)=>(o$1(t,e)||e.push(t),e)),[])},isValidTimeValue:function(e){return Number.isFinite(e)&&e>=-2},addLeadingZeros:d,isValidUrl:n$1,isBrowserEnvironment:function(){return "undefined"!=typeof window},formatMacrosValues:function(e){return "object"!=typeof e?e:JSON.stringify(e)}};function h(e){return ["true","TRUE","True","1"].includes(e)}function p(e){if(null==e)return -1;if(u.isNumeric(e))return parseInt(e);const t=e.split(":");if(3!==t.length)return -1;const r=t[2].split(".");let i=parseInt(r[0]);2===r.length&&(i+=parseFloat("0.".concat(r[1])));const a=parseInt(60*t[1]),s=parseInt(60*t[0]*60);return isNaN(s)||isNaN(a)||isNaN(i)||a>3600||i>60?-1:s+a+i}const m={childByName:function(e,t){return Array.from(e.childNodes).find((e=>e.nodeName===t))},childrenByName:function(e,t){return Array.from(e.childNodes).filter((e=>e.nodeName===t))},resolveVastAdTagURI:function(e,t){if(!t)return e;if(e.startsWith("//")){const{protocol:t}=location;return "".concat(t).concat(e)}if(!e.includes("://")){const r=t.slice(0,t.lastIndexOf("/"));return "".concat(r,"/").concat(e)}return e},parseBoolean:h,parseNodeText:function(e){return e&&(e.textContent||e.text||"").trim()},copyNodeAttribute:function(e,t,r){const i=t.getAttribute(e);i&&r.setAttribute(e,i);},parseAttributes:function(e){return Array.from(e.attributes).reduce(((e,t)=>(e[t.nodeName]=t.nodeValue,e)),{})},parseDuration:p,getStandAloneAds:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>!parseInt(e.sequence,10)))},getSortedAdPods:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>parseInt(e.sequence,10))).sort(((e,t)=>e.sequence-t.sequence))},assignAttributes:function(e,t){e&&Array.from(e).forEach((e=>{let{nodeName:r,nodeValue:i}=e;if(r&&i&&t.hasOwnProperty(r)){let e=i;"boolean"==typeof t[r]&&(e=h(e)),t[r]=e;}}));},mergeWrapperAdData:function(e,t){var r;e.errorURLTemplates=t.errorURLTemplates.concat(e.errorURLTemplates),e.impressionURLTemplates=t.impressionURLTemplates.concat(e.impressionURLTemplates),e.extensions=t.extensions.concat(e.extensions),t.viewableImpression.length>0&&(e.viewableImpression=[...e.viewableImpression,...t.viewableImpression]),e.followAdditionalWrappers=t.followAdditionalWrappers,e.allowMultipleAds=t.allowMultipleAds,e.fallbackOnNoAd=t.fallbackOnNoAd;const i=(t.creatives||[]).filter((e=>e&&"companion"===e.type)),a=i.reduce(((e,t)=>((t.variations||[]).forEach((t=>{(t.companionClickTrackingURLTemplates||[]).forEach((t=>{u.containsTemplateObject(t,e)||e.push(t);}));})),e)),[]);e.creatives=i.concat(e.creatives);const s=t.videoClickTrackingURLTemplates&&t.videoClickTrackingURLTemplates.length,n=t.videoCustomClickURLTemplates&&t.videoCustomClickURLTemplates.length;if(e.creatives.forEach((e=>{if(t.trackingEvents&&t.trackingEvents[e.type])for(const r in t.trackingEvents[e.type]){const i=t.trackingEvents[e.type][r];Array.isArray(e.trackingEvents[r])||(e.trackingEvents[r]=[]),e.trackingEvents[r]=e.trackingEvents[r].concat(i);}"linear"===e.type&&(s&&(e.videoClickTrackingURLTemplates=e.videoClickTrackingURLTemplates.concat(t.videoClickTrackingURLTemplates)),n&&(e.videoCustomClickURLTemplates=e.videoCustomClickURLTemplates.concat(t.videoCustomClickURLTemplates)),!t.videoClickThroughURLTemplate||null!==e.videoClickThroughURLTemplate&&void 0!==e.videoClickThroughURLTemplate||(e.videoClickThroughURLTemplate=t.videoClickThroughURLTemplate)),"companion"===e.type&&a.length&&(e.variations||[]).forEach((e=>{e.companionClickTrackingURLTemplates=u.joinArrayOfUniqueTemplateObjs(e.companionClickTrackingURLTemplates,a);}));})),t.adVerifications&&(e.adVerifications=e.adVerifications.concat(t.adVerifications)),t.blockedAdCategories&&(e.blockedAdCategories=e.blockedAdCategories.concat(t.blockedAdCategories)),null!==(r=t.creatives)&&void 0!==r&&r.length){const r=t.creatives.filter((e=>{var t;return (null===(t=e.icons)||void 0===t?void 0:t.length)&&!e.mediaFiles.length}));r.length&&(e.creatives=e.creatives.concat(r));}}};function g(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"companion",required:null,variations:[]}}(r);return i.required=t.getAttribute("required")||null,i.variations=m.childrenByName(t,"Companion").map((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adType:"companionAd",width:e.width||0,height:e.height||0,assetWidth:e.assetWidth||null,assetHeight:e.assetHeight||null,expandedWidth:e.expandedWidth||null,expandedHeight:e.expandedHeight||null,apiFramework:e.apiFramework||null,adSlotId:e.adSlotId||null,pxratio:e.pxratio||"1",renderingMode:e.renderingMode||"default",staticResources:[],htmlResources:[],iframeResources:[],adParameters:null,altText:null,companionClickThroughURLTemplate:null,companionClickTrackingURLTemplates:[],trackingEvents:{}}}(m.parseAttributes(e));t.htmlResources=m.childrenByName(e,"HTMLResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.iframeResources=m.childrenByName(e,"IFrameResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.staticResources=m.childrenByName(e,"StaticResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat({url:r,creativeType:t.getAttribute("creativeType")||null}):e}),[]),t.altText=m.parseNodeText(m.childByName(e,"AltText"))||null;const r=m.childByName(e,"TrackingEvents");r&&m.childrenByName(r,"Tracking").forEach((e=>{const r=e.getAttribute("event"),i=m.parseNodeText(e);r&&i&&(Array.isArray(t.trackingEvents[r])||(t.trackingEvents[r]=[]),t.trackingEvents[r].push(i));})),t.companionClickTrackingURLTemplates=m.childrenByName(e,"CompanionClickTracking").map((e=>({id:e.getAttribute("id")||null,url:m.parseNodeText(e)}))),t.companionClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"CompanionClickThrough"))||null;const i=m.childByName(e,"AdParameters");return i&&(t.adParameters={value:m.parseNodeText(i),xmlEncoded:i.getAttribute("xmlEncoded")||null}),t})),i}function v(t,r){let i;const a=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"linear",duration:0,skipDelay:null,mediaFiles:[],mezzanine:null,interactiveCreativeFile:null,closedCaptionFiles:[],videoClickThroughURLTemplate:null,videoClickTrackingURLTemplates:[],videoCustomClickURLTemplates:[],adParameters:null,icons:[],trackingEvents:{}}}(r);a.duration=m.parseDuration(m.parseNodeText(m.childByName(t,"Duration")));const s=t.getAttribute("skipoffset");if(null==s)a.skipDelay=null;else if("%"===s.charAt(s.length-1)&&-1!==a.duration){const e=parseInt(s,10);a.skipDelay=a.duration*(e/100);}else a.skipDelay=m.parseDuration(s);const n=m.childByName(t,"VideoClicks");if(n){const e=m.childByName(n,"ClickThrough");a.videoClickThroughURLTemplate=e?{id:e.getAttribute("id")||null,url:m.parseNodeText(e)}:null,m.childrenByName(n,"ClickTracking").forEach((e=>{a.videoClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),m.childrenByName(n,"CustomClick").forEach((e=>{a.videoCustomClickURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));}const o=m.childByName(t,"AdParameters");o&&(a.adParameters={value:m.parseNodeText(o),xmlEncoded:o.getAttribute("xmlEncoded")||null}),m.childrenByName(t,"TrackingEvents").forEach((e=>{m.childrenByName(e,"Tracking").forEach((e=>{let t=e.getAttribute("event");const r=m.parseNodeText(e);if(t&&r){if("progress"===t){if(i=e.getAttribute("offset"),!i)return;t="%"===i.charAt(i.length-1)?"progress-".concat(i):"progress-".concat(m.parseDuration(i));}Array.isArray(a.trackingEvents[t])||(a.trackingEvents[t]=[]),a.trackingEvents[t].push(r);}}));})),m.childrenByName(t,"MediaFiles").forEach((e=>{m.childrenByName(e,"MediaFile").forEach((e=>{a.mediaFiles.push(function(e){const t={id:null,fileURL:null,fileSize:0,deliveryType:"progressive",mimeType:null,mediaType:null,codec:null,bitrate:0,minBitrate:0,maxBitrate:0,width:0,height:0,apiFramework:null,scalable:null,maintainAspectRatio:null};t.id=e.getAttribute("id"),t.fileURL=m.parseNodeText(e),t.deliveryType=e.getAttribute("delivery"),t.codec=e.getAttribute("codec"),t.mimeType=e.getAttribute("type"),t.mediaType=e.getAttribute("mediaType")||"2D",t.apiFramework=e.getAttribute("apiFramework"),t.fileSize=parseInt(e.getAttribute("fileSize")||0),t.bitrate=parseInt(e.getAttribute("bitrate")||0),t.minBitrate=parseInt(e.getAttribute("minBitrate")||0),t.maxBitrate=parseInt(e.getAttribute("maxBitrate")||0),t.width=parseInt(e.getAttribute("width")||0),t.height=parseInt(e.getAttribute("height")||0);const r=e.getAttribute("scalable");r&&"string"==typeof r&&(t.scalable=m.parseBoolean(r));const i=e.getAttribute("maintainAspectRatio");i&&"string"==typeof i&&(t.maintainAspectRatio=m.parseBoolean(i));return t}(e));}));const t=m.childByName(e,"InteractiveCreativeFile");t&&(a.interactiveCreativeFile=function(e){const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,apiFramework:e.apiFramework||null,variableDuration:m.parseBoolean(e.variableDuration),fileURL:null}}(m.parseAttributes(e));return t.fileURL=m.parseNodeText(e),t}(t));const r=m.childByName(e,"ClosedCaptionFiles");r&&m.childrenByName(r,"ClosedCaptionFile").forEach((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,language:e.language||null,fileURL:null}}(m.parseAttributes(e));t.fileURL=m.parseNodeText(e),a.closedCaptionFiles.push(t);}));const i=m.childByName(e,"Mezzanine"),s=function(e,t){const r={};let i=false;return t.forEach((t=>{e&&e.getAttribute(t)?r[t]=e.getAttribute(t):i=true;})),i?null:r}(i,["delivery","type","width","height"]);if(s){const e={id:null,fileURL:null,delivery:null,codec:null,type:null,width:0,height:0,fileSize:0,mediaType:"2D"};e.id=i.getAttribute("id"),e.fileURL=m.parseNodeText(i),e.delivery=s.delivery,e.codec=i.getAttribute("codec"),e.type=s.type,e.width=parseInt(s.width,10),e.height=parseInt(s.height,10),e.fileSize=parseInt(i.getAttribute("fileSize"),10),e.mediaType=i.getAttribute("mediaType")||"2D",a.mezzanine=e;}}));const l=m.childByName(t,"Icons");return l&&m.childrenByName(l,"Icon").forEach((e=>{a.icons.push(function(e){const t={program:null,height:0,width:0,xPosition:0,yPosition:0,apiFramework:null,offset:null,duration:0,type:null,staticResource:null,htmlResource:null,iframeResource:null,pxratio:"1",iconClickThroughURLTemplate:null,iconClickTrackingURLTemplates:[],iconViewTrackingURLTemplate:null,iconClickFallbackImages:[],altText:null,hoverText:null};t.program=e.getAttribute("program"),t.height=parseInt(e.getAttribute("height")||0),t.width=parseInt(e.getAttribute("width")||0),t.xPosition=function(e){if(-1!==["left","right"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("xPosition")),t.yPosition=function(e){if(-1!==["top","bottom"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("yPosition")),t.apiFramework=e.getAttribute("apiFramework"),t.pxratio=e.getAttribute("pxratio")||"1",t.offset=m.parseDuration(e.getAttribute("offset")),t.duration=m.parseDuration(e.getAttribute("duration")),t.altText=e.getAttribute("altText"),t.hoverText=e.getAttribute("hoverText"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"IconClicks");if(r){t.iconClickThroughURLTemplate=m.parseNodeText(m.childByName(r,"IconClickThrough")),m.childrenByName(r,"IconClickTracking").forEach((e=>{t.iconClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));const e=m.childByName(r,"IconClickFallbackImages");e&&m.childrenByName(e,"IconClickFallbackImage").forEach((e=>{t.iconClickFallbackImages.push({url:m.parseNodeText(e)||null,width:e.getAttribute("width")||null,height:e.getAttribute("height")||null});}));}return t.iconViewTrackingURLTemplate=m.parseNodeText(m.childByName(e,"IconViewTracking")),t}(e));})),a}function f(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"nonlinear",variations:[],trackingEvents:{}}}(r);return m.childrenByName(t,"TrackingEvents").forEach((e=>{let t,r;m.childrenByName(e,"Tracking").forEach((e=>{t=e.getAttribute("event"),r=m.parseNodeText(e),t&&r&&(Array.isArray(i.trackingEvents[t])||(i.trackingEvents[t]=[]),i.trackingEvents[t].push(r));}));})),m.childrenByName(t,"NonLinear").forEach((e=>{const t={id:null,width:0,height:0,expandedWidth:0,expandedHeight:0,scalable:true,maintainAspectRatio:true,minSuggestedDuration:0,apiFramework:"static",adType:"nonLinearAd",type:null,staticResource:null,htmlResource:null,iframeResource:null,nonlinearClickThroughURLTemplate:null,nonlinearClickTrackingURLTemplates:[],adParameters:null};t.id=e.getAttribute("id")||null,t.width=e.getAttribute("width"),t.height=e.getAttribute("height"),t.expandedWidth=e.getAttribute("expandedWidth"),t.expandedHeight=e.getAttribute("expandedHeight"),t.scalable=m.parseBoolean(e.getAttribute("scalable")),t.maintainAspectRatio=m.parseBoolean(e.getAttribute("maintainAspectRatio")),t.minSuggestedDuration=m.parseDuration(e.getAttribute("minSuggestedDuration")),t.apiFramework=e.getAttribute("apiFramework"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"AdParameters");r&&(t.adParameters={value:m.parseNodeText(r),xmlEncoded:r.getAttribute("xmlEncoded")||null}),t.nonlinearClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"NonLinearClickThrough")),m.childrenByName(e,"NonLinearClickTracking").forEach((e=>{t.nonlinearClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),i.variations.push(t);})),i}function T(e){const t=[];return e.forEach((e=>{const r=A(e);r&&t.push(r);})),t}function A(e){if("#comment"===e.nodeName)return null;const t={name:null,value:null,attributes:{},children:[]},r=e.attributes,i=e.childNodes;if(t.name=e.nodeName,e.attributes)for(const e in r)if(r.hasOwnProperty(e)){const i=r[e];i.nodeName&&i.nodeValue&&(t.attributes[i.nodeName]=i.nodeValue);}for(const e in i)if(i.hasOwnProperty(e)){const r=A(i[e]);r&&t.children.push(r);}if(0===t.children.length||1===t.children.length&&["#cdata-section","#text"].indexOf(t.children[0].name)>=0){const r=m.parseNodeText(e);""!==r&&(t.value=r),t.children=[];}return null===(a=t).value&&0===Object.keys(a.attributes).length&&0===a.children.length?null:t;var a;}function R(e){return e.getAttribute("AdID")||e.getAttribute("adID")||e.getAttribute("adId")||null}const k={Wrapper:{subElements:["VASTAdTagURI","Impression"]},BlockedAdCategories:{attributes:["authority"]},InLine:{subElements:["AdSystem","AdTitle","Impression","AdServingId","Creatives"]},Category:{attributes:["authority"]},Pricing:{attributes:["model","currency"]},Verification:{oneOfinLineResources:["JavaScriptResource","ExecutableResource"],attributes:["vendor"]},UniversalAdId:{attributes:["idRegistry"]},JavaScriptResource:{attributes:["apiFramework","browserOptional"]},ExecutableResource:{attributes:["apiFramework","type"]},Tracking:{attributes:["event"]},Creatives:{subElements:["Creative"]},Creative:{subElements:["UniversalAdId"]},Linear:{subElements:["MediaFiles","Duration"]},MediaFiles:{subElements:["MediaFile"]},MediaFile:{attributes:["delivery","type","width","height"]},Mezzanine:{attributes:["delivery","type","width","height"]},NonLinear:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},Companion:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},StaticResource:{attributes:["creativeType"]},Icons:{subElements:["Icon"]},Icon:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"]}};function y(e,t){if(!k[e.nodeName]||!k[e.nodeName].attributes)return;const r=k[e.nodeName].attributes.filter((t=>!e.getAttribute(t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,attributes:r},t);}function E(e,t,r){const i=k[e.nodeName],a=!r&&"Wrapper"!==e.nodeName;if(!i||a)return;if(i.subElements){const r=i.subElements.filter((t=>!m.childByName(e,t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,subElements:r},t);}if(!r||!i.oneOfinLineResources)return;i.oneOfinLineResources.some((t=>m.childByName(e,t)))||N({name:e.nodeName,parentName:e.parentNode.nodeName,oneOfResources:i.oneOfinLineResources},t);}function b(e){return e.children&&0!==e.children.length}function N(e,t){let{name:r,parentName:i,attributes:a,subElements:s,oneOfResources:n}=e,o="Element '".concat(r,"'");o+=a?" missing required attribute(s) '".concat(a.join(", "),"' "):s?" missing required sub element(s) '".concat(s.join(", "),"' "):n?" must provide one of the following '".concat(n.join(", "),"' "):" is empty",t("VAST-warning",{message:o,parentElement:i,specVersion:4.1});}const w={verifyRequiredValues:function e(t,r,i){if(t&&t.nodeName)if("InLine"===t.nodeName&&(i=true),y(t,r),b(t)){E(t,r,i);for(let a=0;a<t.children.length;a++)e(t.children[a],r,i);}else 0===m.parseNodeText(t).length&&N({name:t.nodeName,parentName:t.parentNode.nodeName},r);},hasSubElements:b,emitMissingValueWarning:N,verifyRequiredAttributes:y,verifyRequiredSubElements:E};function L(e,t){let{allowMultipleAds:r,followAdditionalWrappers:i}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=Array.from(e.childNodes).filter((e=>{const t=e.nodeName.toLowerCase();return "inline"===t||false!==i&&"wrapper"===t}));for(const i of a){if(m.copyNodeAttribute("id",e,i),m.copyNodeAttribute("sequence",e,i),m.copyNodeAttribute("adType",e,i),"Wrapper"===i.nodeName)return {ad:I(i,t),type:"WRAPPER"};if("InLine"===i.nodeName)return {ad:C(i,t,{allowMultipleAds:r}),type:"INLINE"};const a=i.nodeName.toLowerCase();t("VAST-warning",{message:"<".concat(i.nodeName,"inline"===a?"> must be written <InLine>":"> must be written <Wrapper>"),wrongNode:i});}}function C(e,t){let{allowMultipleAds:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return false===r&&e.getAttribute("sequence")?null:U(e,t)}function U(e,t){let r=[];t&&w.verifyRequiredValues(e,t);const i=Array.from(e.childNodes),a=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,sequence:e.sequence||null,adType:e.adType||null,adServingId:null,categories:[],expires:null,viewableImpression:[],system:null,title:null,description:null,advertiser:null,pricing:null,survey:null,errorURLTemplates:[],impressionURLTemplates:[],creatives:[],extensions:[],adVerifications:[],blockedAdCategories:[],followAdditionalWrappers:true,allowMultipleAds:false,fallbackOnNoAd:null}}(m.parseAttributes(e));return i.forEach((e=>{switch(e.nodeName){case "Error":a.errorURLTemplates.push(m.parseNodeText(e));break;case "Impression":a.impressionURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});break;case "Creatives":a.creatives=function(e){const t=[];return e.forEach((e=>{const r={id:e.getAttribute("id")||null,adId:R(e),sequence:e.getAttribute("sequence")||null,apiFramework:e.getAttribute("apiFramework")||null},i=[];let a;m.childrenByName(e,"UniversalAdId").forEach((e=>{const t={idRegistry:e.getAttribute("idRegistry")||"unknown",value:m.parseNodeText(e)};i.push(t);}));const s=m.childByName(e,"CreativeExtensions");s&&(a=T(m.childrenByName(s,"CreativeExtension")));for(const s in e.childNodes){const n=e.childNodes[s];let o;switch(n.nodeName){case "Linear":o=v(n,r);break;case "NonLinearAds":o=f(n,r);break;case "CompanionAds":o=g(n,r);}o&&(i&&(o.universalAdIds=i),a&&(o.creativeExtensions=a),t.push(o));}})),t}(m.childrenByName(e,"Creative"));break;case "Extensions":{const t=m.childrenByName(e,"Extension");a.extensions=T(t),a.adVerifications.length||(r=function(e){let t=null,r=[];e.some((e=>t=m.childByName(e,"AdVerifications"))),t&&(r=x(m.childrenByName(t,"Verification")));return r}(t));break}case "AdVerifications":a.adVerifications=x(m.childrenByName(e,"Verification"));break;case "AdSystem":a.system={value:m.parseNodeText(e),version:e.getAttribute("version")||null};break;case "AdTitle":a.title=m.parseNodeText(e);break;case "AdServingId":a.adServingId=m.parseNodeText(e);break;case "Category":a.categories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});break;case "Expires":a.expires=parseInt(m.parseNodeText(e),10);break;case "ViewableImpression":a.viewableImpression.push(function(e){const t=(e,t)=>{const r=m.parseNodeText(t);return r&&e.push(r),e};return {id:e.getAttribute("id")||null,viewable:m.childrenByName(e,"Viewable").reduce(t,[]),notViewable:m.childrenByName(e,"NotViewable").reduce(t,[]),viewUndetermined:m.childrenByName(e,"ViewUndetermined").reduce(t,[])}}(e));break;case "Description":a.description=m.parseNodeText(e);break;case "Advertiser":a.advertiser={id:e.getAttribute("id")||null,value:m.parseNodeText(e)};break;case "Pricing":a.pricing={value:m.parseNodeText(e),model:e.getAttribute("model")||null,currency:e.getAttribute("currency")||null};break;case "Survey":a.survey={value:m.parseNodeText(e),type:e.getAttribute("type")||null};break;case "BlockedAdCategories":a.blockedAdCategories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});}})),r.length&&(a.adVerifications=a.adVerifications.concat(r)),a}function I(e,t){const r=U(e,t),i=e.getAttribute("followAdditionalWrappers"),a=e.getAttribute("allowMultipleAds"),s=e.getAttribute("fallbackOnNoAd");r.followAdditionalWrappers=!i||m.parseBoolean(i),r.allowMultipleAds=!!a&&m.parseBoolean(a),r.fallbackOnNoAd=s?m.parseBoolean(s):null;let n=m.childByName(e,"VASTAdTagURI");if(n?r.nextWrapperURL=m.parseNodeText(n):(n=m.childByName(e,"VASTAdTagURL"),n&&(r.nextWrapperURL=m.parseNodeText(m.childByName(n,"URL")))),r.creatives.forEach((e=>{if(["linear","nonlinear"].includes(e.type)){if(e.trackingEvents){r.trackingEvents||(r.trackingEvents={}),r.trackingEvents[e.type]||(r.trackingEvents[e.type]={});for(const t in e.trackingEvents){const i=e.trackingEvents[t];Array.isArray(r.trackingEvents[e.type][t])||(r.trackingEvents[e.type][t]=[]),i.forEach((i=>{r.trackingEvents[e.type][t].push(i);}));}}e.videoClickTrackingURLTemplates&&(Array.isArray(r.videoClickTrackingURLTemplates)||(r.videoClickTrackingURLTemplates=[]),e.videoClickTrackingURLTemplates.forEach((e=>{r.videoClickTrackingURLTemplates.push(e);}))),e.videoClickThroughURLTemplate&&(r.videoClickThroughURLTemplate=e.videoClickThroughURLTemplate),e.videoCustomClickURLTemplates&&(Array.isArray(r.videoCustomClickURLTemplates)||(r.videoCustomClickURLTemplates=[]),e.videoCustomClickURLTemplates.forEach((e=>{r.videoCustomClickURLTemplates.push(e);})));}})),r.nextWrapperURL)return r}function x(e){const t=[];return e.forEach((e=>{const r={resource:null,vendor:null,browserOptional:false,apiFramework:null,type:null,parameters:null,trackingEvents:{}},i=Array.from(e.childNodes);m.assignAttributes(e.attributes,r),i.forEach((e=>{let{nodeName:t,textContent:i,attributes:a}=e;switch(t){case "JavaScriptResource":case "ExecutableResource":r.resource=i.trim(),m.assignAttributes(a,r);break;case "VerificationParameters":r.parameters=i.trim();}}));const a=m.childByName(e,"TrackingEvents");a&&m.childrenByName(a,"Tracking").forEach((e=>{const t=e.getAttribute("event"),i=m.parseNodeText(e);t&&i&&(Array.isArray(r.trackingEvents[t])||(r.trackingEvents[t]=[]),r.trackingEvents[t].push(i));})),t.push(r);})),t}class S{constructor(){this._handlers=[];}on(e,t){if("function"!=typeof t)throw new TypeError("The handler argument must be of type Function. Received type ".concat(typeof t));if(!e)throw new TypeError("The event argument must be of type String. Received type ".concat(typeof e));return this._handlers.push({event:e,handler:t}),this}once(e,t){return this.on(e,function(e,t,r){const i={fired:false,wrapFn:void 0};function a(){i.fired||(e.off(t,i.wrapFn),i.fired=true,r.bind(e)(...arguments));}return i.wrapFn=a,a}(this,e,t))}off(e,t){return this._handlers=this._handlers.filter((r=>r.event!==e||r.handler!==t)),this}emit(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),i=1;i<t;i++)r[i-1]=arguments[i];let a=false;return this._handlers.forEach((t=>{"*"===t.event&&(a=true,t.handler(e,...r)),t.event===e&&(a=true,t.handler(...r));})),a}removeAllListeners(e){return e?(this._handlers=this._handlers.filter((t=>t.event!==e)),this):(this._handlers=[],this)}listenerCount(e){return this._handlers.filter((t=>t.event===e)).length}listeners(e){return this._handlers.reduce(((t,r)=>(r.event===e&&t.push(r.handler),t)),[])}eventNames(){return this._handlers.map((e=>e.event))}}let V=0,D=0;const O=(e,t)=>{if(!e||!t||e<=0||t<=0)return;D=(D*V+8*e/t)/++V;},F={ERRORCODE:900,extensions:[]},P="VAST response version not supported";class B extends S{constructor(){let{fetcher:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.maxWrapperDepth=null,this.rootErrorURLTemplates=[],this.errorURLTemplates=[],this.remainingAds=[],this.parsingOptions={},this.fetcher=e||null,this.keepFailedAdPod=false;}trackVastError(e,t){for(var r=arguments.length,i=new Array(r>2?r-2:0),a=2;a<r;a++)i[a-2]=arguments[a];this.emit("VAST-error",Object.assign({},F,t,...i)),u.track(e,t);}getErrorURLTemplates(){return this.rootErrorURLTemplates.concat(this.errorURLTemplates)}getEstimatedBitrate(){return D}initParsingStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.maxWrapperDepth=e.wrapperLimit||10,this.parsingOptions={allowMultipleAds:e.allowMultipleAds},this.keepFailedAdPod=e.keepFailedAdPod||false,this.rootURL="",this.resetParsingStatus(),O(e.byteLength,e.requestDuration);}resetParsingStatus(){this.errorURLTemplates=[],this.rootErrorURLTemplates=[],this.vastVersion=null;}getRemainingAds(e){if(0===this.remainingAds.length)return Promise.reject(new Error("No more ads are available for the given VAST"));const t=e?this.remainingAds:[this.remainingAds.shift()];return this.errorURLTemplates=[],this.resolveAds(t,{wrapperDepth:0,url:this.rootURL}).then((e=>this.buildVASTResponse(e)))}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.initParsingStatus(t),t.isRootVAST=true,this.parse(e,t).then((e=>this.buildVASTResponse(e)))}buildVASTResponse(e){const t=function(e){let{ads:t,errorURLTemplates:r,version:i}=e;return {ads:t||[],errorURLTemplates:r||[],version:i||null}}({ads:e,errorURLTemplates:this.getErrorURLTemplates(),version:this.vastVersion});return this.completeWrapperResolving(t),t}parseVastXml(e,t){let{isRootVAST:r=false,url:i=null,wrapperDepth:a=0,allowMultipleAds:s,followAdditionalWrappers:n}=t;if(!e||!e.documentElement||"VAST"!==e.documentElement.nodeName){var o;this.emit("VAST-ad-parsed",{type:"ERROR",url:i,wrapperDepth:a});const t="VideoAdServingTemplate"===(null==e||null===(o=e.documentElement)||void 0===o?void 0:o.nodeName);throw new Error(t?P:"Invalid VAST XMLDocument")}const l=[],c=e.documentElement.childNodes,d=e.documentElement.getAttribute("version");r&&d&&(this.vastVersion=d);for(const e in c){const t=c[e];if("Error"===t.nodeName){const e=m.parseNodeText(t);r?this.rootErrorURLTemplates.push(e):this.errorURLTemplates.push(e);}else if("Ad"===t.nodeName){if(this.vastVersion&&parseFloat(this.vastVersion)<3)s=true;else if(false===s&&l.length>1)break;const e=L(t,this.emit.bind(this),{allowMultipleAds:s,followAdditionalWrappers:n});e.ad?(l.push(e.ad),this.emit("VAST-ad-parsed",{type:e.type,url:i,wrapperDepth:a,adIndex:l.length-1,vastVersion:d})):this.trackVastError(this.getErrorURLTemplates(),{ERRORCODE:101});}}return l}parse(e){let{url:t=null,resolveAll:r=true,wrapperSequence:i=null,previousUrl:a=null,wrapperDepth:s=0,isRootVAST:n=false,followAdditionalWrappers:o,allowMultipleAds:l}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=[];this.vastVersion&&parseFloat(this.vastVersion)<3&&n&&(l=true);try{c=this.parseVastXml(e,{isRootVAST:n,url:t,wrapperDepth:s,allowMultipleAds:l,followAdditionalWrappers:o});}catch(e){return Promise.reject(e)}if(1===c.length&&null!=i&&(c[0].sequence=i),false===r){const e=m.getSortedAdPods(c),t=m.getStandAloneAds(c);e.length?c=e:t.length&&(c=[t.shift()]),this.remainingAds=t;}return this.resolveAds(c,{wrapperDepth:s,previousUrl:a,url:t})}resolveAds(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],{wrapperDepth:t,previousUrl:r,url:i}=arguments.length>1?arguments[1]:void 0;const a=[];return r=i,e.forEach((e=>{const i=this.resolveWrappers(e,t,r);a.push(i);})),Promise.all(a).then((e=>u.flatten(e)))}resolveWrappers(e,t,r){const i={...e};return new Promise((e=>{var a;if(t++,!i.nextWrapperURL)return delete i.nextWrapperURL,e(i);if(!this.fetcher)return i.VASTAdTagURI=i.nextWrapperURL,delete i.nextWrapperURL,e(i);if(t>=this.maxWrapperDepth)return i.errorCode=302,delete i.nextWrapperURL,e(i);i.nextWrapperURL=m.resolveVastAdTagURI(i.nextWrapperURL,r);const s=null!==(a=this.parsingOptions.allowMultipleAds)&&void 0!==a?a:i.allowMultipleAds,n=i.sequence;this.fetcher.fetchVAST({url:i.nextWrapperURL,emitter:this.emit.bind(this),maxWrapperDepth:this.maxWrapperDepth}).then((a=>this.parse(a,{url:i.nextWrapperURL,previousUrl:r,wrapperSequence:n,wrapperDepth:t,followAdditionalWrappers:i.followAdditionalWrappers,allowMultipleAds:s}).then((t=>{if(delete i.nextWrapperURL,0===t.length)return i.creatives=[],e(i);t.forEach((e=>{e&&m.mergeWrapperAdData(e,i);})),e(t);})))).catch((t=>{i.errorCode=t.message===P?102:301,i.errorMessage=t.message,e(i);}));}))}completeWrapperResolving(e){if(0===e.ads.length)this.trackVastError(e.errorURLTemplates,{ERRORCODE:303});else for(let t=e.ads.length-1;t>=0;t--){const r=e.ads[t],i=!r.creatives.some((e=>{var t,r;return (null===(t=e.mediaFiles)||void 0===t?void 0:t.length)>0||(null===(r=e.variations)||void 0===r?void 0:r.length)>0}));!r.errorCode&&!i||r.VASTAdTagURI||(this.trackVastError(r.errorURLTemplates.concat(e.errorURLTemplates),{ERRORCODE:r.errorCode||303},{ERRORMESSAGE:r.errorMessage||""},{extensions:r.extensions},{system:r.system}),this.keepFailedAdPod&&r.sequence?r.hasFailed=true:e.ads.splice(t,1));}}}let M=null;const W={data:{},length:0,getItem(e){return this.data[e]},setItem(e,t){this.data[e]=t,this.length=Object.keys(this.data).length;},removeItem(e){delete this.data[e],this.length=Object.keys(this.data).length;},clear(){this.data={},this.length=0;}};class j{constructor(){this.storage=this.initStorage();}initStorage(){if(M)return M;try{M="undefined"!=typeof window&&null!==window?window.localStorage||window.sessionStorage:null;}catch(e){M=null;}return M&&!this.isStorageDisabled(M)||(M=W,M.clear()),M}isStorageDisabled(e){const t="__VASTStorage__";try{if(e.setItem(t,t),e.getItem(t)!==t)return e.removeItem(t),!0}catch(e){return true}return e.removeItem(t),false}getItem(e){return this.storage.getItem(e)}setItem(e,t){return this.storage.setItem(e,t)}removeItem(e){return this.storage.removeItem(e)}clear(){return this.storage.clear()}}const q=12e4;const K={get:async function(e,t){try{const r=new AbortController,i=setTimeout((()=>{throw r.abort(),new Error("URLHandler: Request timed out after ".concat(t.timeout||q," ms (408)"))}),t.timeout||q),a=await fetch(e,{...t,signal:r.signal,credentials:t.withCredentials?"include":"omit"}).finally((()=>{clearTimeout(i);})),s=function(e){return u.isBrowserEnvironment()&&"https:"===window.location.protocol&&e.url.includes("http://")?"URLHandler: Cannot go from HTTPS to HTTP.":200===e.status&&e.ok?null:"URLHandler: ".concat(e.statusText," (").concat(e.status,")")}(a);return s?{error:new Error(s),statusCode:a.status}:async function(e){const t=await e.text();let r;r=u.isBrowserEnvironment()?new DOMParser:new((await Promise.resolve().then(function () { return index$1; })).DOMParser);return {xml:r.parseFromString(t,"text/xml"),details:{byteLength:t.length,statusCode:e.status,rawXml:t}}}(a)}catch(e){return {error:e,statusCode:"AbortError"===e.name?408:null}}}};class H{constructor(){this.URLTemplateFilters=[];}setOptions(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.urlHandler=e.urlHandler||e.urlhandler||K,this.fetchingOptions={...e.fetchOptions,timeout:e.timeout||q,withCredentials:Boolean(e.withCredentials)};}addURLTemplateFilter(e){"function"==typeof e&&this.URLTemplateFilters.push(e);}removeLastURLTemplateFilter(){this.URLTemplateFilters.pop();}countURLTemplateFilters(){return this.URLTemplateFilters.length}clearURLTemplateFilters(){this.URLTemplateFilters=[];}async fetchVAST(e){var t;let{url:r,maxWrapperDepth:i,emitter:a,wrapperDepth:s=0,previousUrl:n=null,wrapperAd:o=null}=e;const l=Date.now();this.URLTemplateFilters.forEach((e=>{r=e(r);})),a("VAST-resolving",{url:r,previousUrl:n,wrapperDepth:s,maxWrapperDepth:i,timeout:this.fetchingOptions.timeout,wrapperAd:o});const c=await this.urlHandler.get(r,this.fetchingOptions),d=Math.round(Date.now()-l);if(a("VAST-resolved",{url:r,previousUrl:n,wrapperDepth:s,error:(null==c?void 0:c.error)||null,duration:d,statusCode:(null==c?void 0:c.statusCode)||null,...null==c?void 0:c.details}),O(null==c||null===(t=c.details)||void 0===t?void 0:t.byteLength,d),c.error)throw new Error(c.error);return c.xml}}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new j;this.cappingFreeLunch=e,this.cappingMinimumTimeInterval=t,this.fetcher=new H,this.vastParser=new B({fetcher:this.fetcher}),this.storage=r,void 0===this.lastSuccessfulAd&&(this.lastSuccessfulAd=0),void 0===this.totalCalls&&(this.totalCalls=0),void 0===this.totalCallsTimeout&&(this.totalCallsTimeout=0);}addURLTemplateFilter(e){this.fetcher.addURLTemplateFilter(e);}removeLastURLTemplateFilter(){this.fetcher.removeLastURLTemplateFilter();}countURLTemplateFilters(){return this.fetcher.countURLTemplateFilters()}clearURLTemplateFilters(){this.fetcher.clearURLTemplateFilters();}getParser(){return this.vastParser}get lastSuccessfulAd(){return this.storage.getItem("vast-client-last-successful-ad")}set lastSuccessfulAd(e){this.storage.setItem("vast-client-last-successful-ad",e);}get totalCalls(){return this.storage.getItem("vast-client-total-calls")}set totalCalls(e){this.storage.setItem("vast-client-total-calls",e);}get totalCallsTimeout(){return this.storage.getItem("vast-client-total-calls-timeout")}set totalCallsTimeout(e){this.storage.setItem("vast-client-total-calls-timeout",e);}hasRemainingAds(){return this.vastParser.remainingAds.length>0}getNextAds(e){return this.vastParser.getRemainingAds(e)}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.fetcher.setOptions(t),this.vastParser.parseVAST(e,t)}get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=Date.now();return t.hasOwnProperty("resolveAll")||(t.resolveAll=false),this.totalCallsTimeout<r?(this.totalCalls=1,this.totalCallsTimeout=r+36e5):this.totalCalls++,new Promise(((i,a)=>{if(this.cappingFreeLunch>=this.totalCalls)return a(new Error("VAST call canceled – FreeLunch capping not reached yet ".concat(this.totalCalls,"/").concat(this.cappingFreeLunch)));const s=r-this.lastSuccessfulAd;if(s<0)this.lastSuccessfulAd=0;else if(s<this.cappingMinimumTimeInterval)return a(new Error("VAST call canceled – (".concat(this.cappingMinimumTimeInterval,")ms minimum interval reached")));this.vastParser.initParsingStatus(t),this.fetcher.setOptions(t),this.vastParser.rootURL=e,this.fetcher.fetchVAST({url:e,emitter:this.vastParser.emit.bind(this.vastParser),maxWrapperDepth:this.vastParser.maxWrapperDepth}).then((r=>(t.previousUrl=e,t.isRootVAST=true,t.url=e,this.vastParser.parse(r,t).then((e=>{const t=this.vastParser.buildVASTResponse(e);i(t);}))))).catch((e=>a(e)));}))}}class z extends S{constructor(e,t,r){var i;let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];super(),this.ad=t,this.creative=r,this.variation=a,this.muted=s,this.impressed=false,this.skippable=false,this.trackingEvents={},this.trackedProgressEvents=[],this.lastPercentage=0,this._alreadyTriggeredQuartiles={},this.emitAlwaysEvents=["creativeView","start","firstQuartile","midpoint","thirdQuartile","complete","resume","pause","rewind","skip","closeLinear","close"];for(const e in this.creative.trackingEvents){const t=this.creative.trackingEvents[e];this.trackingEvents[e]=t.slice(0);}this.viewableImpressionTrackers=(null===(i=this.ad.viewableImpression)||void 0===i?void 0:i.reduce(((e,t)=>(e.notViewable.push(...t.notViewable),e.viewUndetermined.push(...t.viewUndetermined),e.viewable.push(...t.viewable),e)),{notViewable:[],viewUndetermined:[],viewable:[]}))||{},Object.entries(this.viewableImpressionTrackers).forEach((e=>{let[t,r]=e;r.length&&(this.trackingEvents[t]=r);})),!function(e){return "linear"===e.type}(this.creative)?this._initVariationTracking():this._initLinearTracking(),e&&this.on("start",(()=>{e.lastSuccessfulAd=Date.now();}));}_initLinearTracking(){this.linear=true,this.skipDelay=this.creative.skipDelay,this.setDuration(this.creative.duration),this.clickThroughURLTemplate=this.creative.videoClickThroughURLTemplate,this.clickTrackingURLTemplates=this.creative.videoClickTrackingURLTemplates;}_initVariationTracking(){if(this.linear=false,this.skipDelay=-1,this.variation){for(const e in this.variation.trackingEvents){const t=this.variation.trackingEvents[e];this.trackingEvents[e]?this.trackingEvents[e]=this.trackingEvents[e].concat(t.slice(0)):this.trackingEvents[e]=t.slice(0);}"nonLinearAd"===this.variation.adType?(this.clickThroughURLTemplate=this.variation.nonlinearClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.nonlinearClickTrackingURLTemplates,this.setDuration(this.variation.minSuggestedDuration)):function(e){return "companionAd"===e.adType}(this.variation)&&(this.clickThroughURLTemplate=this.variation.companionClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.companionClickTrackingURLTemplates);}}setDuration(e){u.isValidTimeValue(e)?(this.assetDuration=e,this.quartiles={firstQuartile:Math.round(25*this.assetDuration)/100,midpoint:Math.round(50*this.assetDuration)/100,thirdQuartile:Math.round(75*this.assetDuration)/100}):this.emit("TRACKER-error",{message:"the duration provided is not valid. duration: ".concat(e)});}setProgress(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!u.isValidTimeValue(e)||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given setProgress parameter has the wrong type. progress: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});const i=this.skipDelay||-1;if(-1===i||this.skippable||(i>e?this.emit("skip-countdown",i-e):(this.skippable=true,this.emit("skip-countdown",0))),this.assetDuration>0){const i=Math.round(e/this.assetDuration*100),a=[];if(e>0){a.push("start");for(let e=this.lastPercentage;e<i;e++)a.push("progress-".concat(e+1,"%"));a.push("progress-".concat(e));for(const t in this.quartiles)this.isQuartileReached(t,this.quartiles[t],e)&&(a.push(t),this._alreadyTriggeredQuartiles[t]=true);this.lastPercentage=i;}a.forEach((e=>{this.track(e,{macros:t,once:r});})),e<this.progress&&(this.track("rewind",{macros:t}),this.trackedProgressEvents&&this.trackedProgressEvents.splice(0));}this.progress=e;}isQuartileReached(e,t,r){let i=false;return t<=r&&!this._alreadyTriggeredQuartiles[e]&&(i=true),i}setMuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.muted!==e&&this.track(e?"mute":"unmute",{macros:t}),this.muted=e):this.emit("TRACKER-error",{message:"One given setMuted parameter has the wrong type. muted: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setPaused(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.paused!==e&&this.track(e?"pause":"resume",{macros:t}),this.paused=e):this.emit("TRACKER-error",{message:"One given setPaused parameter has the wrong type. paused: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setFullscreen(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.fullscreen!==e&&this.track(e?"fullscreen":"exitFullscreen",{macros:t}),this.fullscreen=e):this.emit("TRACKER-error",{message:"One given setFullScreen parameter has the wrong type. fullscreen: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setExpand(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.expanded!==e&&(this.track(e?"expand":"collapse",{macros:t}),this.track(e?"playerExpand":"playerCollapse",{macros:t})),this.expanded=e):this.emit("TRACKER-error",{message:"One given setExpand parameter has the wrong type. expanded: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setSkipDelay(e){u.isValidTimeValue(e)?this.skipDelay=e:this.emit("TRACKER-error",{message:"setSkipDelay parameter does not have a valid value. duration: ".concat(e)});}trackImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.impressed||(this.impressed=true,this.trackURLs(this.ad.impressionURLTemplates,e),this.track("creativeView",{macros:e})):this.emit("TRACKER-error",{message:"trackImpression parameter has the wrong type. macros: ".concat(e)});}trackViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackNotViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("notViewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackNotViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackUndeterminedImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewUndetermined",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackUndeterminedImpression given macros has the wrong type. macros: ".concat(e)});}error(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e&&"boolean"==typeof t?this.trackURLs(this.ad.errorURLTemplates,e,{isCustomCode:t}):this.emit("TRACKER-error",{message:"One given error parameter has the wrong type. macros: ".concat(u.formatMacrosValues(e),", isCustomCode: ").concat(t)});}errorWithCode(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"string"==typeof e&&"boolean"==typeof t?(this.error({ERRORCODE:e},t),console.log("The method errorWithCode is deprecated, please use vast tracker error method instead")):this.emit("TRACKER-error",{message:"One given errorWithCode parameter has the wrong type. errorCode: ".concat(e,", isCustomCode: ").concat(t)});}complete(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("complete",{macros:e}):this.emit("TRACKER-error",{message:"complete given macros has the wrong type. macros: ".concat(e)});}notUsed(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?(this.track("notUsed",{macros:e}),this.trackingEvents=[]):this.emit("TRACKER-error",{message:"notUsed given macros has the wrong type. macros: ".concat(e)});}otherAdInteraction(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("otherAdInteraction",{macros:e}):this.emit("TRACKER-error",{message:"otherAdInteraction given macros has the wrong type. macros: ".concat(e)});}acceptInvitation(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("acceptInvitation",{macros:e}):this.emit("TRACKER-error",{message:"acceptInvitation given macros has the wrong type. macros: ".concat(e)});}adExpand(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adExpand",{macros:e}):this.emit("TRACKER-error",{message:"adExpand given macros has the wrong type. macros: ".concat(e)});}adCollapse(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adCollapse",{macros:e}):this.emit("TRACKER-error",{message:"adCollapse given macros has the wrong type. macros: ".concat(e)});}minimize(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("minimize",{macros:e}):this.emit("TRACKER-error",{message:"minimize given macros has the wrong type. macros: ".concat(e)});}verificationNotExecuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given verificationNotExecuted parameter has to wrong type. vendor: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});if(!this.ad||!this.ad.adVerifications||!this.ad.adVerifications.length)throw new Error("No adVerifications provided");if(!e)throw new Error("No vendor provided, unable to find associated verificationNotExecuted");const r=this.ad.adVerifications.find((t=>t.vendor===e));if(!r)throw new Error("No associated verification element found for vendor: ".concat(e));const i=r.trackingEvents;if(i&&i.verificationNotExecuted){const e=i.verificationNotExecuted;this.trackURLs(e,t),this.emit("verificationNotExecuted",{trackingURLTemplates:e});}}overlayViewDuration(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"string"==typeof e&&"object"==typeof t?(t.ADPLAYHEAD=e,this.track("overlayViewDuration",{macros:t})):this.emit("TRACKER-error",{message:"One given overlayViewDuration parameters has the wrong type. formattedDuration: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}close(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track(this.linear?"closeLinear":"close",{macros:e}):this.emit("TRACKER-error",{message:"close given macros has the wrong type. macros: ".concat(e)});}skip(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("skip",{macros:e}):this.emit("TRACKER-error",{message:"skip given macros has the wrong type. macros: ".concat(e)});}load(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("loaded",{macros:e}):this.emit("TRACKER-error",{message:"load given macros has the wrong type. macros: ".concat(e)});}click(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(null!==e&&"string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given click parameter has the wrong type. fallbackClickThroughURL: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});this.clickTrackingURLTemplates&&this.clickTrackingURLTemplates.length&&this.trackURLs(this.clickTrackingURLTemplates,t);const r=this.clickThroughURLTemplate||e,i={...t};if(r){this.progress&&(i.ADPLAYHEAD=this.progressFormatted());const e=u.resolveURLTemplates([r],i)[0];this.emit("clickthrough",e);}}trackProgressEvents(e,t,r){const i=parseFloat(e.split("-")[1]);Object.entries(this.trackingEvents).filter((e=>{let[t]=e;return t.startsWith("progress-")})).map((e=>{let[t,r]=e;return {name:t,time:parseFloat(t.split("-")[1]),urls:r}})).filter((e=>{let{time:t}=e;return t<=i&&t>this.progress})).forEach((e=>{let{name:i,urls:a}=e;!r&&this.trackedProgressEvents.includes(i)||(this.emit(i,{trackingURLTemplates:a}),this.trackURLs(a,t),r?delete this.trackingEvents[i]:this.trackedProgressEvents.push(i));}));}track(e){let{macros:t={},once:r=false}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("object"!=typeof t)return void this.emit("TRACKER-error",{message:"track given macros has the wrong type. macros: ".concat(t)});"closeLinear"===e&&!this.trackingEvents[e]&&this.trackingEvents.close&&(e="close"),e.startsWith("progress-")&&!e.endsWith("%")&&this.trackProgressEvents(e,t,r);const i=this.trackingEvents[e],a=this.emitAlwaysEvents.indexOf(e)>-1;i?(this.emit(e,{trackingURLTemplates:i}),this.trackURLs(i,t)):a&&this.emit(e,null),r&&(delete this.trackingEvents[e],a&&this.emitAlwaysEvents.splice(this.emitAlwaysEvents.indexOf(e),1));}trackURLs(e){var t;let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{validUrls:a,invalidUrls:s}=u.filterUrlTemplates(e);s.length&&this.emit("TRACKER-error",{message:"Provided urls are malformed. url: ".concat(s)});const n={...r};this.linear&&(this.creative&&this.creative.mediaFiles&&this.creative.mediaFiles[0]&&this.creative.mediaFiles[0].fileURL&&(n.ASSETURI=this.creative.mediaFiles[0].fileURL),this.progress&&(n.ADPLAYHEAD=this.progressFormatted())),null!==(t=this.creative)&&void 0!==t&&null!==(t=t.universalAdIds)&&void 0!==t&&t.length&&(n.UNIVERSALADID=this.creative.universalAdIds.map((e=>e.idRegistry.concat(" ",e.value))).join(",")),this.ad&&(this.ad.sequence&&(n.PODSEQUENCE=this.ad.sequence),this.ad.adType&&(n.ADTYPE=this.ad.adType),this.ad.adServingId&&(n.ADSERVINGID=this.ad.adServingId),this.ad.categories&&this.ad.categories.length&&(n.ADCATEGORIES=this.ad.categories.map((e=>e.value)).join(",")),this.ad.blockedAdCategories&&this.ad.blockedAdCategories.length&&(n.BLOCKEDADCATEGORIES=this.ad.blockedAdCategories.map((e=>e.value)).join(","))),u.track(a,n,i);}convertToTimecode(e){if(!u.isValidTimeValue(e))return "";const t=1e3*e,r=Math.floor(t/36e5),i=Math.floor(t/6e4%60),a=Math.floor(t/1e3%60),s=Math.floor(t%1e3);return "".concat(u.addLeadingZeros(r,2),":").concat(u.addLeadingZeros(i,2),":").concat(u.addLeadingZeros(a,2),".").concat(u.addLeadingZeros(s,3))}progressFormatted(){return this.convertToTimecode(this.progress)}}
18
+ function e$1(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adId:e.adId||null,sequence:e.sequence||null,apiFramework:e.apiFramework||null,universalAdIds:[],creativeExtensions:[]}}const t$1=["ADCATEGORIES","ADCOUNT","ADPLAYHEAD","ADSERVINGID","ADTYPE","APIFRAMEWORKS","APPBUNDLE","ASSETURI","BLOCKEDADCATEGORIES","BREAKMAXADLENGTH","BREAKMAXADS","BREAKMAXDURATION","BREAKMINADLENGTH","BREAKMINDURATION","BREAKPOSITION","CLICKPOS","CLICKTYPE","CLIENTUA","CONTENTID","CONTENTPLAYHEAD","CONTENTURI","DEVICEIP","DEVICEUA","DOMAIN","EXTENSIONS","GDPRCONSENT","IFA","IFATYPE","INVENTORYSTATE","LATLONG","LIMITADTRACKING","MEDIAMIME","MEDIAPLAYHEAD","OMIDPARTNER","PAGEURL","PLACEMENTTYPE","PLAYERCAPABILITIES","PLAYERSIZE","PLAYERSTATE","PODSEQUENCE","REGULATIONS","SERVERSIDE","SERVERUA","TRANSACTIONID","UNIVERSALADID","VASTVERSIONS","VERIFICATIONVENDORS"];function r$1(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=[],n=s$1(e);!t.ERRORCODE||r.isCustomCode||/^[0-9]{3}$/.test(t.ERRORCODE)||(t.ERRORCODE=900),t.CACHEBUSTING=d(Math.round(1e8*Math.random())),t.TIMESTAMP=(new Date).toISOString(),t.RANDOM=t.random=t.CACHEBUSTING;for(const e in t)t[e]=c(t[e]);for(const e in n){const r=n[e];"string"==typeof r&&a.push(i$1(r,t));}return a}function i$1(e,r){const i=(e=a$1(e,r)).match(/[^[\]]+(?=])/g);if(!i)return e;let s=i.filter((e=>t$1.indexOf(e)>-1));return 0===s.length?e:(s=s.reduce(((e,t)=>(e[t]=-1,e)),{}),a$1(e,s))}function a$1(e,t){let r=e;for(const e in t){const i=t[e];r=r.replace(new RegExp("(?:\\[|%%)(".concat(e,")(?:\\]|%%)"),"g"),i);}return r}function s$1(e){return Array.isArray(e)?e.map((e=>e&&e.hasOwnProperty("url")?e.url:e)):e}function n$1(e){return /^(https?:\/\/|\/\/)/.test(e)}function o$1(e,t){for(let r=0;r<t.length;r++)if(l(t[r],e))return true;return false}function l(e,t){if(e&&t){const r=Object.getOwnPropertyNames(e),i=Object.getOwnPropertyNames(t);return r.length===i.length&&(e.id===t.id&&e.url===t.url)}return false}function c(e){return encodeURIComponent(e).replace(/[!'()*]/g,(e=>"%".concat(e.charCodeAt(0).toString(16))))}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e.toString().padStart(t,"0")}const u={track:function(e,t,i){r$1(e,t,i).forEach((e=>{if("undefined"!=typeof window&&null!==window){(new Image).src=e;}}));},resolveURLTemplates:r$1,extractURLsFromTemplates:s$1,filterUrlTemplates:function(e){return e.reduce(((e,t)=>{const r=t.url||t;return n$1(r)?e.validUrls.push(r):e.invalidUrls.push(r),e}),{validUrls:[],invalidUrls:[]})},containsTemplateObject:o$1,isTemplateObjectEqual:l,encodeURIComponentRFC3986:c,replaceUrlMacros:i$1,isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},flatten:function e(t){return t.reduce(((t,r)=>t.concat(Array.isArray(r)?e(r):r)),[])},joinArrayOfUniqueTemplateObjs:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];const r=Array.isArray(e)?e:[],i=Array.isArray(t)?t:[];return r.concat(i).reduce(((e,t)=>(o$1(t,e)||e.push(t),e)),[])},isValidTimeValue:function(e){return Number.isFinite(e)&&e>=-2},addLeadingZeros:d,isValidUrl:n$1,isBrowserEnvironment:function(){return "undefined"!=typeof window},formatMacrosValues:function(e){return "object"!=typeof e?e:JSON.stringify(e)}};function h(e){return ["true","TRUE","True","1"].includes(e)}function p(e){if(null==e)return -1;if(u.isNumeric(e))return parseInt(e);const t=e.split(":");if(3!==t.length)return -1;const r=t[2].split(".");let i=parseInt(r[0]);2===r.length&&(i+=parseFloat("0.".concat(r[1])));const a=parseInt(60*t[1]),s=parseInt(60*t[0]*60);return isNaN(s)||isNaN(a)||isNaN(i)||a>3600||i>60?-1:s+a+i}const m={childByName:function(e,t){return Array.from(e.childNodes).find((e=>e.nodeName===t))},childrenByName:function(e,t){return Array.from(e.childNodes).filter((e=>e.nodeName===t))},resolveVastAdTagURI:function(e,t){if(!t)return e;if(e.startsWith("//")){const{protocol:t}=location;return "".concat(t).concat(e)}if(!e.includes("://")){const r=t.slice(0,t.lastIndexOf("/"));return "".concat(r,"/").concat(e)}return e},parseBoolean:h,parseNodeText:function(e){return e&&(e.textContent||e.text||"").trim()},copyNodeAttribute:function(e,t,r){const i=t.getAttribute(e);i&&r.setAttribute(e,i);},parseAttributes:function(e){return Array.from(e.attributes).reduce(((e,t)=>(e[t.nodeName]=t.nodeValue,e)),{})},parseDuration:p,getStandAloneAds:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>!parseInt(e.sequence,10)))},getSortedAdPods:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>parseInt(e.sequence,10))).sort(((e,t)=>e.sequence-t.sequence))},assignAttributes:function(e,t){e&&Array.from(e).forEach((e=>{let{nodeName:r,nodeValue:i}=e;if(r&&i&&t.hasOwnProperty(r)){let e=i;"boolean"==typeof t[r]&&(e=h(e)),t[r]=e;}}));},mergeWrapperAdData:function(e,t){var r;e.errorURLTemplates=t.errorURLTemplates.concat(e.errorURLTemplates),e.impressionURLTemplates=t.impressionURLTemplates.concat(e.impressionURLTemplates),e.extensions=t.extensions.concat(e.extensions),t.viewableImpression.length>0&&(e.viewableImpression=[...e.viewableImpression,...t.viewableImpression]),e.followAdditionalWrappers=t.followAdditionalWrappers,e.allowMultipleAds=t.allowMultipleAds,e.fallbackOnNoAd=t.fallbackOnNoAd;const i=(t.creatives||[]).filter((e=>e&&"companion"===e.type)),a=i.reduce(((e,t)=>((t.variations||[]).forEach((t=>{(t.companionClickTrackingURLTemplates||[]).forEach((t=>{u.containsTemplateObject(t,e)||e.push(t);}));})),e)),[]);e.creatives=i.concat(e.creatives);const s=t.videoClickTrackingURLTemplates&&t.videoClickTrackingURLTemplates.length,n=t.videoCustomClickURLTemplates&&t.videoCustomClickURLTemplates.length;if(e.creatives.forEach((e=>{if(t.trackingEvents&&t.trackingEvents[e.type])for(const r in t.trackingEvents[e.type]){const i=t.trackingEvents[e.type][r];Array.isArray(e.trackingEvents[r])||(e.trackingEvents[r]=[]),e.trackingEvents[r]=e.trackingEvents[r].concat(i);}"linear"===e.type&&(s&&(e.videoClickTrackingURLTemplates=e.videoClickTrackingURLTemplates.concat(t.videoClickTrackingURLTemplates)),n&&(e.videoCustomClickURLTemplates=e.videoCustomClickURLTemplates.concat(t.videoCustomClickURLTemplates)),!t.videoClickThroughURLTemplate||null!==e.videoClickThroughURLTemplate&&void 0!==e.videoClickThroughURLTemplate||(e.videoClickThroughURLTemplate=t.videoClickThroughURLTemplate)),"companion"===e.type&&a.length&&(e.variations||[]).forEach((e=>{e.companionClickTrackingURLTemplates=u.joinArrayOfUniqueTemplateObjs(e.companionClickTrackingURLTemplates,a);}));})),t.adVerifications&&(e.adVerifications=e.adVerifications.concat(t.adVerifications)),t.blockedAdCategories&&(e.blockedAdCategories=e.blockedAdCategories.concat(t.blockedAdCategories)),null!==(r=t.creatives)&&void 0!==r&&r.length){const r=t.creatives.filter((e=>{var t;return (null===(t=e.icons)||void 0===t?void 0:t.length)&&!e.mediaFiles.length}));r.length&&(e.creatives=e.creatives.concat(r));}}};function g(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"companion",required:null,variations:[]}}(r);return i.required=t.getAttribute("required")||null,i.variations=m.childrenByName(t,"Companion").map((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adType:"companionAd",width:e.width||0,height:e.height||0,assetWidth:e.assetWidth||null,assetHeight:e.assetHeight||null,expandedWidth:e.expandedWidth||null,expandedHeight:e.expandedHeight||null,apiFramework:e.apiFramework||null,adSlotId:e.adSlotId||null,pxratio:e.pxratio||"1",renderingMode:e.renderingMode||"default",staticResources:[],htmlResources:[],iframeResources:[],adParameters:null,altText:null,companionClickThroughURLTemplate:null,companionClickTrackingURLTemplates:[],trackingEvents:{}}}(m.parseAttributes(e));t.htmlResources=m.childrenByName(e,"HTMLResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.iframeResources=m.childrenByName(e,"IFrameResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.staticResources=m.childrenByName(e,"StaticResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat({url:r,creativeType:t.getAttribute("creativeType")||null}):e}),[]),t.altText=m.parseNodeText(m.childByName(e,"AltText"))||null;const r=m.childByName(e,"TrackingEvents");r&&m.childrenByName(r,"Tracking").forEach((e=>{const r=e.getAttribute("event"),i=m.parseNodeText(e);r&&i&&(Array.isArray(t.trackingEvents[r])||(t.trackingEvents[r]=[]),t.trackingEvents[r].push(i));})),t.companionClickTrackingURLTemplates=m.childrenByName(e,"CompanionClickTracking").map((e=>({id:e.getAttribute("id")||null,url:m.parseNodeText(e)}))),t.companionClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"CompanionClickThrough"))||null;const i=m.childByName(e,"AdParameters");return i&&(t.adParameters={value:m.parseNodeText(i),xmlEncoded:i.getAttribute("xmlEncoded")||null}),t})),i}function v(t,r){let i;const a=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"linear",duration:0,skipDelay:null,mediaFiles:[],mezzanine:null,interactiveCreativeFile:null,closedCaptionFiles:[],videoClickThroughURLTemplate:null,videoClickTrackingURLTemplates:[],videoCustomClickURLTemplates:[],adParameters:null,icons:[],trackingEvents:{}}}(r);a.duration=m.parseDuration(m.parseNodeText(m.childByName(t,"Duration")));const s=t.getAttribute("skipoffset");if(null==s)a.skipDelay=null;else if("%"===s.charAt(s.length-1)&&-1!==a.duration){const e=parseInt(s,10);a.skipDelay=a.duration*(e/100);}else a.skipDelay=m.parseDuration(s);const n=m.childByName(t,"VideoClicks");if(n){const e=m.childByName(n,"ClickThrough");a.videoClickThroughURLTemplate=e?{id:e.getAttribute("id")||null,url:m.parseNodeText(e)}:null,m.childrenByName(n,"ClickTracking").forEach((e=>{a.videoClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),m.childrenByName(n,"CustomClick").forEach((e=>{a.videoCustomClickURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));}const o=m.childByName(t,"AdParameters");o&&(a.adParameters={value:m.parseNodeText(o),xmlEncoded:o.getAttribute("xmlEncoded")||null}),m.childrenByName(t,"TrackingEvents").forEach((e=>{m.childrenByName(e,"Tracking").forEach((e=>{let t=e.getAttribute("event");const r=m.parseNodeText(e);if(t&&r){if("progress"===t){if(i=e.getAttribute("offset"),!i)return;t="%"===i.charAt(i.length-1)?"progress-".concat(i):"progress-".concat(m.parseDuration(i));}Array.isArray(a.trackingEvents[t])||(a.trackingEvents[t]=[]),a.trackingEvents[t].push(r);}}));})),m.childrenByName(t,"MediaFiles").forEach((e=>{m.childrenByName(e,"MediaFile").forEach((e=>{a.mediaFiles.push(function(e){const t={id:null,fileURL:null,fileSize:0,deliveryType:"progressive",mimeType:null,mediaType:null,codec:null,bitrate:0,minBitrate:0,maxBitrate:0,width:0,height:0,apiFramework:null,scalable:null,maintainAspectRatio:null};t.id=e.getAttribute("id"),t.fileURL=m.parseNodeText(e),t.deliveryType=e.getAttribute("delivery"),t.codec=e.getAttribute("codec"),t.mimeType=e.getAttribute("type"),t.mediaType=e.getAttribute("mediaType")||"2D",t.apiFramework=e.getAttribute("apiFramework"),t.fileSize=parseInt(e.getAttribute("fileSize")||0),t.bitrate=parseInt(e.getAttribute("bitrate")||0),t.minBitrate=parseInt(e.getAttribute("minBitrate")||0),t.maxBitrate=parseInt(e.getAttribute("maxBitrate")||0),t.width=parseInt(e.getAttribute("width")||0),t.height=parseInt(e.getAttribute("height")||0);const r=e.getAttribute("scalable");r&&"string"==typeof r&&(t.scalable=m.parseBoolean(r));const i=e.getAttribute("maintainAspectRatio");i&&"string"==typeof i&&(t.maintainAspectRatio=m.parseBoolean(i));return t}(e));}));const t=m.childByName(e,"InteractiveCreativeFile");t&&(a.interactiveCreativeFile=function(e){const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,apiFramework:e.apiFramework||null,variableDuration:m.parseBoolean(e.variableDuration),fileURL:null}}(m.parseAttributes(e));return t.fileURL=m.parseNodeText(e),t}(t));const r=m.childByName(e,"ClosedCaptionFiles");r&&m.childrenByName(r,"ClosedCaptionFile").forEach((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,language:e.language||null,fileURL:null}}(m.parseAttributes(e));t.fileURL=m.parseNodeText(e),a.closedCaptionFiles.push(t);}));const i=m.childByName(e,"Mezzanine"),s=function(e,t){const r={};let i=false;return t.forEach((t=>{e&&e.getAttribute(t)?r[t]=e.getAttribute(t):i=true;})),i?null:r}(i,["delivery","type","width","height"]);if(s){const e={id:null,fileURL:null,delivery:null,codec:null,type:null,width:0,height:0,fileSize:0,mediaType:"2D"};e.id=i.getAttribute("id"),e.fileURL=m.parseNodeText(i),e.delivery=s.delivery,e.codec=i.getAttribute("codec"),e.type=s.type,e.width=parseInt(s.width,10),e.height=parseInt(s.height,10),e.fileSize=parseInt(i.getAttribute("fileSize"),10),e.mediaType=i.getAttribute("mediaType")||"2D",a.mezzanine=e;}}));const l=m.childByName(t,"Icons");return l&&m.childrenByName(l,"Icon").forEach((e=>{a.icons.push(function(e){const t={program:null,height:0,width:0,xPosition:0,yPosition:0,apiFramework:null,offset:null,duration:0,type:null,staticResource:null,htmlResource:null,iframeResource:null,pxratio:"1",iconClickThroughURLTemplate:null,iconClickTrackingURLTemplates:[],iconViewTrackingURLTemplate:null,iconClickFallbackImages:[],altText:null,hoverText:null};t.program=e.getAttribute("program"),t.height=parseInt(e.getAttribute("height")||0),t.width=parseInt(e.getAttribute("width")||0),t.xPosition=function(e){if(-1!==["left","right"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("xPosition")),t.yPosition=function(e){if(-1!==["top","bottom"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("yPosition")),t.apiFramework=e.getAttribute("apiFramework"),t.pxratio=e.getAttribute("pxratio")||"1",t.offset=m.parseDuration(e.getAttribute("offset")),t.duration=m.parseDuration(e.getAttribute("duration")),t.altText=e.getAttribute("altText"),t.hoverText=e.getAttribute("hoverText"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"IconClicks");if(r){t.iconClickThroughURLTemplate=m.parseNodeText(m.childByName(r,"IconClickThrough")),m.childrenByName(r,"IconClickTracking").forEach((e=>{t.iconClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));const e=m.childByName(r,"IconClickFallbackImages");e&&m.childrenByName(e,"IconClickFallbackImage").forEach((e=>{t.iconClickFallbackImages.push({url:m.parseNodeText(e)||null,width:e.getAttribute("width")||null,height:e.getAttribute("height")||null});}));}return t.iconViewTrackingURLTemplate=m.parseNodeText(m.childByName(e,"IconViewTracking")),t}(e));})),a}function f(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"nonlinear",variations:[],trackingEvents:{}}}(r);return m.childrenByName(t,"TrackingEvents").forEach((e=>{let t,r;m.childrenByName(e,"Tracking").forEach((e=>{t=e.getAttribute("event"),r=m.parseNodeText(e),t&&r&&(Array.isArray(i.trackingEvents[t])||(i.trackingEvents[t]=[]),i.trackingEvents[t].push(r));}));})),m.childrenByName(t,"NonLinear").forEach((e=>{const t={id:null,width:0,height:0,expandedWidth:0,expandedHeight:0,scalable:true,maintainAspectRatio:true,minSuggestedDuration:0,apiFramework:"static",adType:"nonLinearAd",type:null,staticResource:null,htmlResource:null,iframeResource:null,nonlinearClickThroughURLTemplate:null,nonlinearClickTrackingURLTemplates:[],adParameters:null};t.id=e.getAttribute("id")||null,t.width=e.getAttribute("width"),t.height=e.getAttribute("height"),t.expandedWidth=e.getAttribute("expandedWidth"),t.expandedHeight=e.getAttribute("expandedHeight"),t.scalable=m.parseBoolean(e.getAttribute("scalable")),t.maintainAspectRatio=m.parseBoolean(e.getAttribute("maintainAspectRatio")),t.minSuggestedDuration=m.parseDuration(e.getAttribute("minSuggestedDuration")),t.apiFramework=e.getAttribute("apiFramework"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"AdParameters");r&&(t.adParameters={value:m.parseNodeText(r),xmlEncoded:r.getAttribute("xmlEncoded")||null}),t.nonlinearClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"NonLinearClickThrough")),m.childrenByName(e,"NonLinearClickTracking").forEach((e=>{t.nonlinearClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),i.variations.push(t);})),i}function T(e){const t=[];return e.forEach((e=>{const r=A(e);r&&t.push(r);})),t}function A(e){if("#comment"===e.nodeName)return null;const t={name:null,value:null,attributes:{},children:[]},r=e.attributes,i=e.childNodes;if(t.name=e.nodeName,e.attributes)for(const e in r)if(r.hasOwnProperty(e)){const i=r[e];i.nodeName&&i.nodeValue&&(t.attributes[i.nodeName]=i.nodeValue);}for(const e in i)if(i.hasOwnProperty(e)){const r=A(i[e]);r&&t.children.push(r);}if(0===t.children.length||1===t.children.length&&["#cdata-section","#text"].indexOf(t.children[0].name)>=0){const r=m.parseNodeText(e);""!==r&&(t.value=r),t.children=[];}return null===(a=t).value&&0===Object.keys(a.attributes).length&&0===a.children.length?null:t;var a;}function R(e){return e.getAttribute("AdID")||e.getAttribute("adID")||e.getAttribute("adId")||null}const k={Wrapper:{subElements:["VASTAdTagURI","Impression"]},BlockedAdCategories:{attributes:["authority"]},InLine:{subElements:["AdSystem","AdTitle","Impression","AdServingId","Creatives"]},Category:{attributes:["authority"]},Pricing:{attributes:["model","currency"]},Verification:{oneOfinLineResources:["JavaScriptResource","ExecutableResource"],attributes:["vendor"]},UniversalAdId:{attributes:["idRegistry"]},JavaScriptResource:{attributes:["apiFramework","browserOptional"]},ExecutableResource:{attributes:["apiFramework","type"]},Tracking:{attributes:["event"]},Creatives:{subElements:["Creative"]},Creative:{subElements:["UniversalAdId"]},Linear:{subElements:["MediaFiles","Duration"]},MediaFiles:{subElements:["MediaFile"]},MediaFile:{attributes:["delivery","type","width","height"]},Mezzanine:{attributes:["delivery","type","width","height"]},NonLinear:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},Companion:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},StaticResource:{attributes:["creativeType"]},Icons:{subElements:["Icon"]},Icon:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"]}};function y(e,t){if(!k[e.nodeName]||!k[e.nodeName].attributes)return;const r=k[e.nodeName].attributes.filter((t=>!e.getAttribute(t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,attributes:r},t);}function E(e,t,r){const i=k[e.nodeName],a=!r&&"Wrapper"!==e.nodeName;if(!i||a)return;if(i.subElements){const r=i.subElements.filter((t=>!m.childByName(e,t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,subElements:r},t);}if(!r||!i.oneOfinLineResources)return;i.oneOfinLineResources.some((t=>m.childByName(e,t)))||N({name:e.nodeName,parentName:e.parentNode.nodeName,oneOfResources:i.oneOfinLineResources},t);}function b(e){return e.children&&0!==e.children.length}function N(e,t){let{name:r,parentName:i,attributes:a,subElements:s,oneOfResources:n}=e,o="Element '".concat(r,"'");o+=a?" missing required attribute(s) '".concat(a.join(", "),"' "):s?" missing required sub element(s) '".concat(s.join(", "),"' "):n?" must provide one of the following '".concat(n.join(", "),"' "):" is empty",t("VAST-warning",{message:o,parentElement:i,specVersion:4.1});}const w={verifyRequiredValues:function e(t,r,i){if(t&&t.nodeName)if("InLine"===t.nodeName&&(i=true),y(t,r),b(t)){E(t,r,i);for(let a=0;a<t.children.length;a++)e(t.children[a],r,i);}else 0===m.parseNodeText(t).length&&N({name:t.nodeName,parentName:t.parentNode.nodeName},r);},hasSubElements:b,emitMissingValueWarning:N,verifyRequiredAttributes:y,verifyRequiredSubElements:E};function L(e,t){let{allowMultipleAds:r,followAdditionalWrappers:i}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=Array.from(e.childNodes).filter((e=>{const t=e.nodeName.toLowerCase();return "inline"===t||false!==i&&"wrapper"===t}));for(const i of a){if(m.copyNodeAttribute("id",e,i),m.copyNodeAttribute("sequence",e,i),m.copyNodeAttribute("adType",e,i),"Wrapper"===i.nodeName)return {ad:I(i,t),type:"WRAPPER"};if("InLine"===i.nodeName)return {ad:C(i,t,{allowMultipleAds:r}),type:"INLINE"};const a=i.nodeName.toLowerCase();t("VAST-warning",{message:"<".concat(i.nodeName,"inline"===a?"> must be written <InLine>":"> must be written <Wrapper>"),wrongNode:i});}}function C(e,t){let{allowMultipleAds:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return false===r&&e.getAttribute("sequence")?null:U(e,t)}function U(e,t){let r=[];t&&w.verifyRequiredValues(e,t);const i=Array.from(e.childNodes),a=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,sequence:e.sequence||null,adType:e.adType||null,adServingId:null,categories:[],expires:null,viewableImpression:[],system:null,title:null,description:null,advertiser:null,pricing:null,survey:null,errorURLTemplates:[],impressionURLTemplates:[],creatives:[],extensions:[],adVerifications:[],blockedAdCategories:[],followAdditionalWrappers:true,allowMultipleAds:false,fallbackOnNoAd:null}}(m.parseAttributes(e));return i.forEach((e=>{switch(e.nodeName){case "Error":a.errorURLTemplates.push(m.parseNodeText(e));break;case "Impression":a.impressionURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});break;case "Creatives":a.creatives=function(e){const t=[];return e.forEach((e=>{const r={id:e.getAttribute("id")||null,adId:R(e),sequence:e.getAttribute("sequence")||null,apiFramework:e.getAttribute("apiFramework")||null},i=[];let a;m.childrenByName(e,"UniversalAdId").forEach((e=>{const t={idRegistry:e.getAttribute("idRegistry")||"unknown",value:m.parseNodeText(e)};i.push(t);}));const s=m.childByName(e,"CreativeExtensions");s&&(a=T(m.childrenByName(s,"CreativeExtension")));for(const s in e.childNodes){const n=e.childNodes[s];let o;switch(n.nodeName){case "Linear":o=v(n,r);break;case "NonLinearAds":o=f(n,r);break;case "CompanionAds":o=g(n,r);}o&&(i&&(o.universalAdIds=i),a&&(o.creativeExtensions=a),t.push(o));}})),t}(m.childrenByName(e,"Creative"));break;case "Extensions":{const t=m.childrenByName(e,"Extension");a.extensions=T(t),a.adVerifications.length||(r=function(e){let t=null,r=[];e.some((e=>t=m.childByName(e,"AdVerifications"))),t&&(r=x(m.childrenByName(t,"Verification")));return r}(t));break}case "AdVerifications":a.adVerifications=x(m.childrenByName(e,"Verification"));break;case "AdSystem":a.system={value:m.parseNodeText(e),version:e.getAttribute("version")||null};break;case "AdTitle":a.title=m.parseNodeText(e);break;case "AdServingId":a.adServingId=m.parseNodeText(e);break;case "Category":a.categories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});break;case "Expires":a.expires=parseInt(m.parseNodeText(e),10);break;case "ViewableImpression":a.viewableImpression.push(function(e){const t=(e,t)=>{const r=m.parseNodeText(t);return r&&e.push(r),e};return {id:e.getAttribute("id")||null,viewable:m.childrenByName(e,"Viewable").reduce(t,[]),notViewable:m.childrenByName(e,"NotViewable").reduce(t,[]),viewUndetermined:m.childrenByName(e,"ViewUndetermined").reduce(t,[])}}(e));break;case "Description":a.description=m.parseNodeText(e);break;case "Advertiser":a.advertiser={id:e.getAttribute("id")||null,value:m.parseNodeText(e)};break;case "Pricing":a.pricing={value:m.parseNodeText(e),model:e.getAttribute("model")||null,currency:e.getAttribute("currency")||null};break;case "Survey":a.survey={value:m.parseNodeText(e),type:e.getAttribute("type")||null};break;case "BlockedAdCategories":a.blockedAdCategories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});}})),r.length&&(a.adVerifications=a.adVerifications.concat(r)),a}function I(e,t){const r=U(e,t),i=e.getAttribute("followAdditionalWrappers"),a=e.getAttribute("allowMultipleAds"),s=e.getAttribute("fallbackOnNoAd");r.followAdditionalWrappers=!i||m.parseBoolean(i),r.allowMultipleAds=!!a&&m.parseBoolean(a),r.fallbackOnNoAd=s?m.parseBoolean(s):null;let n=m.childByName(e,"VASTAdTagURI");if(n?r.nextWrapperURL=m.parseNodeText(n):(n=m.childByName(e,"VASTAdTagURL"),n&&(r.nextWrapperURL=m.parseNodeText(m.childByName(n,"URL")))),r.creatives.forEach((e=>{if(["linear","nonlinear"].includes(e.type)){if(e.trackingEvents){r.trackingEvents||(r.trackingEvents={}),r.trackingEvents[e.type]||(r.trackingEvents[e.type]={});for(const t in e.trackingEvents){const i=e.trackingEvents[t];Array.isArray(r.trackingEvents[e.type][t])||(r.trackingEvents[e.type][t]=[]),i.forEach((i=>{r.trackingEvents[e.type][t].push(i);}));}}e.videoClickTrackingURLTemplates&&(Array.isArray(r.videoClickTrackingURLTemplates)||(r.videoClickTrackingURLTemplates=[]),e.videoClickTrackingURLTemplates.forEach((e=>{r.videoClickTrackingURLTemplates.push(e);}))),e.videoClickThroughURLTemplate&&(r.videoClickThroughURLTemplate=e.videoClickThroughURLTemplate),e.videoCustomClickURLTemplates&&(Array.isArray(r.videoCustomClickURLTemplates)||(r.videoCustomClickURLTemplates=[]),e.videoCustomClickURLTemplates.forEach((e=>{r.videoCustomClickURLTemplates.push(e);})));}})),r.nextWrapperURL)return r}function x(e){const t=[];return e.forEach((e=>{const r={resource:null,vendor:null,browserOptional:false,apiFramework:null,type:null,parameters:null,trackingEvents:{}},i=Array.from(e.childNodes);m.assignAttributes(e.attributes,r),i.forEach((e=>{let{nodeName:t,textContent:i,attributes:a}=e;switch(t){case "JavaScriptResource":case "ExecutableResource":r.resource=i.trim(),m.assignAttributes(a,r);break;case "VerificationParameters":r.parameters=i.trim();}}));const a=m.childByName(e,"TrackingEvents");a&&m.childrenByName(a,"Tracking").forEach((e=>{const t=e.getAttribute("event"),i=m.parseNodeText(e);t&&i&&(Array.isArray(r.trackingEvents[t])||(r.trackingEvents[t]=[]),r.trackingEvents[t].push(i));})),t.push(r);})),t}class S{constructor(){this._handlers=[];}on(e,t){if("function"!=typeof t)throw new TypeError("The handler argument must be of type Function. Received type ".concat(typeof t));if(!e)throw new TypeError("The event argument must be of type String. Received type ".concat(typeof e));return this._handlers.push({event:e,handler:t}),this}once(e,t){return this.on(e,function(e,t,r){const i={fired:false,wrapFn:void 0};function a(){i.fired||(e.off(t,i.wrapFn),i.fired=true,r.bind(e)(...arguments));}return i.wrapFn=a,a}(this,e,t))}off(e,t){return this._handlers=this._handlers.filter((r=>r.event!==e||r.handler!==t)),this}emit(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),i=1;i<t;i++)r[i-1]=arguments[i];let a=false;return this._handlers.forEach((t=>{"*"===t.event&&(a=true,t.handler(e,...r)),t.event===e&&(a=true,t.handler(...r));})),a}removeAllListeners(e){return e?(this._handlers=this._handlers.filter((t=>t.event!==e)),this):(this._handlers=[],this)}listenerCount(e){return this._handlers.filter((t=>t.event===e)).length}listeners(e){return this._handlers.reduce(((t,r)=>(r.event===e&&t.push(r.handler),t)),[])}eventNames(){return this._handlers.map((e=>e.event))}}let D=0,V=0;const O=(e,t)=>{if(!e||!t||e<=0||t<=0)return;V=(V*D+8*e/t)/++D;},F={ERRORCODE:900,extensions:[]},P="VAST response version not supported";class B extends S{constructor(){let{fetcher:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.maxWrapperDepth=null,this.rootErrorURLTemplates=[],this.errorURLTemplates=[],this.remainingAds=[],this.parsingOptions={},this.fetcher=e||null,this.keepFailedAdPod=false;}trackVastError(e,t){for(var r=arguments.length,i=new Array(r>2?r-2:0),a=2;a<r;a++)i[a-2]=arguments[a];this.emit("VAST-error",Object.assign({},F,t,...i)),u.track(e,t);}getErrorURLTemplates(){return this.rootErrorURLTemplates.concat(this.errorURLTemplates)}getEstimatedBitrate(){return V}initParsingStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.maxWrapperDepth=e.wrapperLimit||10,this.parsingOptions={allowMultipleAds:e.allowMultipleAds},this.keepFailedAdPod=e.keepFailedAdPod||false,this.rootURL="",this.resetParsingStatus(),O(e.byteLength,e.requestDuration);}resetParsingStatus(){this.errorURLTemplates=[],this.rootErrorURLTemplates=[],this.vastVersion=null;}getRemainingAds(e){if(0===this.remainingAds.length)return Promise.reject(new Error("No more ads are available for the given VAST"));const t=e?this.remainingAds:[this.remainingAds.shift()];return this.errorURLTemplates=[],this.resolveAds(t,{wrapperDepth:0,url:this.rootURL}).then((e=>this.buildVASTResponse(e)))}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.initParsingStatus(t),t.isRootVAST=true,this.parse(e,t).then((e=>this.buildVASTResponse(e)))}buildVASTResponse(e){const t=function(e){let{ads:t,errorURLTemplates:r,version:i}=e;return {ads:t||[],errorURLTemplates:r||[],version:i||null}}({ads:e,errorURLTemplates:this.getErrorURLTemplates(),version:this.vastVersion});return this.completeWrapperResolving(t),t}parseVastXml(e,t){let{isRootVAST:r=false,url:i=null,wrapperDepth:a=0,allowMultipleAds:s,followAdditionalWrappers:n}=t;if(!e||!e.documentElement||"VAST"!==e.documentElement.nodeName){var o;this.emit("VAST-ad-parsed",{type:"ERROR",url:i,wrapperDepth:a});const t="VideoAdServingTemplate"===(null==e||null===(o=e.documentElement)||void 0===o?void 0:o.nodeName);throw new Error(t?P:"Invalid VAST XMLDocument")}const l=[],c=e.documentElement.childNodes,d=e.documentElement.getAttribute("version");r&&d&&(this.vastVersion=d);for(const e in c){const t=c[e];if("Error"===t.nodeName){const e=m.parseNodeText(t);r?this.rootErrorURLTemplates.push(e):this.errorURLTemplates.push(e);}else if("Ad"===t.nodeName){if(this.vastVersion&&parseFloat(this.vastVersion)<3)s=true;else if(false===s&&l.length>1)break;const e=L(t,this.emit.bind(this),{allowMultipleAds:s,followAdditionalWrappers:n});e.ad?(l.push(e.ad),this.emit("VAST-ad-parsed",{type:e.type,url:i,wrapperDepth:a,adIndex:l.length-1,vastVersion:d})):this.trackVastError(this.getErrorURLTemplates(),{ERRORCODE:101});}}return l}parse(e){let{url:t=null,resolveAll:r=true,wrapperSequence:i=null,previousUrl:a=null,wrapperDepth:s=0,isRootVAST:n=false,followAdditionalWrappers:o,allowMultipleAds:l}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=[];this.vastVersion&&parseFloat(this.vastVersion)<3&&n&&(l=true);try{c=this.parseVastXml(e,{isRootVAST:n,url:t,wrapperDepth:s,allowMultipleAds:l,followAdditionalWrappers:o});}catch(e){return Promise.reject(e)}if(1===c.length&&null!=i&&(c[0].sequence=i),false===r){const e=m.getSortedAdPods(c),t=m.getStandAloneAds(c);e.length?c=e:t.length&&(c=[t.shift()]),this.remainingAds=t;}return this.resolveAds(c,{wrapperDepth:s,previousUrl:a,url:t})}resolveAds(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],{wrapperDepth:t,previousUrl:r,url:i}=arguments.length>1?arguments[1]:void 0;const a=[];return r=i,e.forEach((e=>{const i=this.resolveWrappers(e,t,r);a.push(i);})),Promise.all(a).then((e=>u.flatten(e)))}resolveWrappers(e,t,r){const i={...e};return new Promise((e=>{var a;if(t++,!i.nextWrapperURL)return delete i.nextWrapperURL,e(i);if(!this.fetcher)return i.VASTAdTagURI=i.nextWrapperURL,delete i.nextWrapperURL,e(i);if(t>=this.maxWrapperDepth)return i.errorCode=302,delete i.nextWrapperURL,e(i);i.nextWrapperURL=m.resolveVastAdTagURI(i.nextWrapperURL,r);const s=null!==(a=this.parsingOptions.allowMultipleAds)&&void 0!==a?a:i.allowMultipleAds,n=i.sequence;this.fetcher.fetchVAST({url:i.nextWrapperURL,emitter:this.emit.bind(this),maxWrapperDepth:this.maxWrapperDepth,wrapperDepth:t,previousUrl:r,wrapperAd:i}).then((a=>this.parse(a,{url:i.nextWrapperURL,previousUrl:r,wrapperSequence:n,wrapperDepth:t,followAdditionalWrappers:i.followAdditionalWrappers,allowMultipleAds:s}).then((t=>{if(delete i.nextWrapperURL,0===t.length)return i.creatives=[],e(i);t.forEach((e=>{e&&m.mergeWrapperAdData(e,i);})),e(t);})))).catch((t=>{i.errorCode=t.message===P?102:301,i.errorMessage=t.message,e(i);}));}))}completeWrapperResolving(e){if(0===e.ads.length)this.trackVastError(e.errorURLTemplates,{ERRORCODE:303});else for(let t=e.ads.length-1;t>=0;t--){const r=e.ads[t],i=!r.creatives.some((e=>{var t,r;return (null===(t=e.mediaFiles)||void 0===t?void 0:t.length)>0||(null===(r=e.variations)||void 0===r?void 0:r.length)>0}));!r.errorCode&&!i||r.VASTAdTagURI||(this.trackVastError(r.errorURLTemplates.concat(e.errorURLTemplates),{ERRORCODE:r.errorCode||303},{ERRORMESSAGE:r.errorMessage||""},{extensions:r.extensions},{system:r.system}),this.keepFailedAdPod&&r.sequence?r.hasFailed=true:e.ads.splice(t,1));}}}let M=null;const W={data:{},length:0,getItem(e){return this.data[e]},setItem(e,t){this.data[e]=t,this.length=Object.keys(this.data).length;},removeItem(e){delete this.data[e],this.length=Object.keys(this.data).length;},clear(){this.data={},this.length=0;}};class j{constructor(){this.storage=this.initStorage();}initStorage(){if(M)return M;try{M="undefined"!=typeof window&&null!==window?window.localStorage||window.sessionStorage:null;}catch(e){M=null;}return M&&!this.isStorageDisabled(M)||(M=W,M.clear()),M}isStorageDisabled(e){const t="__VASTStorage__";try{if(e.setItem(t,t),e.getItem(t)!==t)return e.removeItem(t),!0}catch(e){return true}return e.removeItem(t),false}getItem(e){return this.storage.getItem(e)}setItem(e,t){return this.storage.setItem(e,t)}removeItem(e){return this.storage.removeItem(e)}clear(){return this.storage.clear()}}const q=12e4;const K={get:async function(e,t){try{const r=new AbortController,i=setTimeout((()=>{throw r.abort(),new Error("URLHandler: Request timed out after ".concat(t.timeout||q," ms (408)"))}),t.timeout||q),a=await fetch(e,{...t,signal:r.signal,credentials:t.withCredentials?"include":"omit"}).finally((()=>{clearTimeout(i);})),s=function(e){return u.isBrowserEnvironment()&&"https:"===window.location.protocol&&e.url.includes("http://")?"URLHandler: Cannot go from HTTPS to HTTP.":200===e.status&&e.ok?null:"URLHandler: ".concat(e.statusText," (").concat(e.status,")")}(a);return s?{error:new Error(s),statusCode:a.status}:async function(e){const t=await e.text();let r;r=u.isBrowserEnvironment()?new DOMParser:new((await Promise.resolve().then(function () { return index$1; })).DOMParser);return {xml:r.parseFromString(t,"text/xml"),details:{byteLength:t.length,statusCode:e.status,rawXml:t}}}(a)}catch(e){return {error:e,statusCode:"AbortError"===e.name?408:null}}}};class H{constructor(){this.URLTemplateFilters=[];}setOptions(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.urlHandler=e.urlHandler||e.urlhandler||K,this.fetchingOptions={...e.fetchOptions,timeout:e.timeout||q,withCredentials:Boolean(e.withCredentials)};}addURLTemplateFilter(e){"function"==typeof e&&this.URLTemplateFilters.push(e);}removeLastURLTemplateFilter(){this.URLTemplateFilters.pop();}countURLTemplateFilters(){return this.URLTemplateFilters.length}clearURLTemplateFilters(){this.URLTemplateFilters=[];}async fetchVAST(e){var t;let{url:r,maxWrapperDepth:i,emitter:a,wrapperDepth:s=0,previousUrl:n=null,wrapperAd:o=null}=e;const l=Date.now();this.URLTemplateFilters.forEach((e=>{r=e(r);})),a("VAST-resolving",{url:r,previousUrl:n,wrapperDepth:s,maxWrapperDepth:i,timeout:this.fetchingOptions.timeout,wrapperAd:o});const c=await this.urlHandler.get(r,this.fetchingOptions),d=Math.round(Date.now()-l);if(a("VAST-resolved",{url:r,previousUrl:n,wrapperDepth:s,error:(null==c?void 0:c.error)||null,duration:d,statusCode:(null==c?void 0:c.statusCode)||null,...null==c?void 0:c.details}),O(null==c||null===(t=c.details)||void 0===t?void 0:t.byteLength,d),c.error)throw new Error(c.error);return c.xml}}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new j;this.cappingFreeLunch=e,this.cappingMinimumTimeInterval=t,this.fetcher=new H,this.vastParser=new B({fetcher:this.fetcher}),this.storage=r,void 0===this.lastSuccessfulAd&&(this.lastSuccessfulAd=0),void 0===this.totalCalls&&(this.totalCalls=0),void 0===this.totalCallsTimeout&&(this.totalCallsTimeout=0);}addURLTemplateFilter(e){this.fetcher.addURLTemplateFilter(e);}removeLastURLTemplateFilter(){this.fetcher.removeLastURLTemplateFilter();}countURLTemplateFilters(){return this.fetcher.countURLTemplateFilters()}clearURLTemplateFilters(){this.fetcher.clearURLTemplateFilters();}getParser(){return this.vastParser}get lastSuccessfulAd(){return this.storage.getItem("vast-client-last-successful-ad")}set lastSuccessfulAd(e){this.storage.setItem("vast-client-last-successful-ad",e);}get totalCalls(){return this.storage.getItem("vast-client-total-calls")}set totalCalls(e){this.storage.setItem("vast-client-total-calls",e);}get totalCallsTimeout(){return this.storage.getItem("vast-client-total-calls-timeout")}set totalCallsTimeout(e){this.storage.setItem("vast-client-total-calls-timeout",e);}hasRemainingAds(){return this.vastParser.remainingAds.length>0}getNextAds(e){return this.vastParser.getRemainingAds(e)}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.fetcher.setOptions(t),this.vastParser.parseVAST(e,t)}get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=Date.now();return t.hasOwnProperty("resolveAll")||(t.resolveAll=false),this.totalCallsTimeout<r?(this.totalCalls=1,this.totalCallsTimeout=r+36e5):this.totalCalls++,new Promise(((i,a)=>{if(this.cappingFreeLunch>=this.totalCalls)return a(new Error("VAST call canceled – FreeLunch capping not reached yet ".concat(this.totalCalls,"/").concat(this.cappingFreeLunch)));const s=r-this.lastSuccessfulAd;if(s<0)this.lastSuccessfulAd=0;else if(s<this.cappingMinimumTimeInterval)return a(new Error("VAST call canceled – (".concat(this.cappingMinimumTimeInterval,")ms minimum interval reached")));this.vastParser.initParsingStatus(t),this.fetcher.setOptions(t),this.vastParser.rootURL=e,this.fetcher.fetchVAST({url:e,emitter:this.vastParser.emit.bind(this.vastParser),maxWrapperDepth:this.vastParser.maxWrapperDepth}).then((r=>(t.previousUrl=e,t.isRootVAST=true,t.url=e,this.vastParser.parse(r,t).then((e=>{const t=this.vastParser.buildVASTResponse(e);i(t);}))))).catch((e=>a(e)));}))}}class z extends S{constructor(e,t,r){var i;let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];super(),this.ad=t,this.creative=r,this.variation=a,this.muted=s,this.impressed=false,this.skippable=false,this.trackingEvents={},this.trackedProgressEvents=[],this.lastPercentage=0,this._alreadyTriggeredQuartiles={},this.emitAlwaysEvents=["creativeView","start","firstQuartile","midpoint","thirdQuartile","complete","resume","pause","rewind","skip","closeLinear","close"];for(const e in this.creative.trackingEvents){const t=this.creative.trackingEvents[e];this.trackingEvents[e]=t.slice(0);}this.viewableImpressionTrackers=(null===(i=this.ad.viewableImpression)||void 0===i?void 0:i.reduce(((e,t)=>(e.notViewable.push(...t.notViewable),e.viewUndetermined.push(...t.viewUndetermined),e.viewable.push(...t.viewable),e)),{notViewable:[],viewUndetermined:[],viewable:[]}))||{},Object.entries(this.viewableImpressionTrackers).forEach((e=>{let[t,r]=e;r.length&&(this.trackingEvents[t]=r);})),!function(e){return "linear"===e.type}(this.creative)?this._initVariationTracking():this._initLinearTracking(),e&&this.on("start",(()=>{e.lastSuccessfulAd=Date.now();}));}_initLinearTracking(){this.linear=true,this.skipDelay=this.creative.skipDelay,this.setDuration(this.creative.duration),this.clickThroughURLTemplate=this.creative.videoClickThroughURLTemplate,this.clickTrackingURLTemplates=this.creative.videoClickTrackingURLTemplates;}_initVariationTracking(){if(this.linear=false,this.skipDelay=-1,this.variation){for(const e in this.variation.trackingEvents){const t=this.variation.trackingEvents[e];this.trackingEvents[e]?this.trackingEvents[e]=this.trackingEvents[e].concat(t.slice(0)):this.trackingEvents[e]=t.slice(0);}"nonLinearAd"===this.variation.adType?(this.clickThroughURLTemplate=this.variation.nonlinearClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.nonlinearClickTrackingURLTemplates,this.setDuration(this.variation.minSuggestedDuration)):function(e){return "companionAd"===e.adType}(this.variation)&&(this.clickThroughURLTemplate=this.variation.companionClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.companionClickTrackingURLTemplates);}}setDuration(e){u.isValidTimeValue(e)?(this.assetDuration=e,this.quartiles={firstQuartile:Math.round(25*this.assetDuration)/100,midpoint:Math.round(50*this.assetDuration)/100,thirdQuartile:Math.round(75*this.assetDuration)/100}):this.emit("TRACKER-error",{message:"the duration provided is not valid. duration: ".concat(e)});}setProgress(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!u.isValidTimeValue(e)||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given setProgress parameter has the wrong type. progress: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});const i=this.skipDelay||-1;if(-1===i||this.skippable||(i>e?this.emit("skip-countdown",i-e):(this.skippable=true,this.emit("skip-countdown",0))),this.assetDuration>0){const i=Math.round(e/this.assetDuration*100),a=[];if(e>0){a.push("start");for(let e=this.lastPercentage;e<i;e++)a.push("progress-".concat(e+1,"%"));a.push("progress-".concat(e));for(const t in this.quartiles)this.isQuartileReached(t,this.quartiles[t],e)&&(a.push(t),this._alreadyTriggeredQuartiles[t]=true);this.lastPercentage=i;}a.forEach((e=>{this.track(e,{macros:t,once:r});})),e<this.progress&&(this.track("rewind",{macros:t}),this.trackedProgressEvents&&this.trackedProgressEvents.splice(0));}this.progress=e;}isQuartileReached(e,t,r){let i=false;return t<=r&&!this._alreadyTriggeredQuartiles[e]&&(i=true),i}setMuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.muted!==e&&this.track(e?"mute":"unmute",{macros:t}),this.muted=e):this.emit("TRACKER-error",{message:"One given setMuted parameter has the wrong type. muted: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setPaused(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.paused!==e&&this.track(e?"pause":"resume",{macros:t}),this.paused=e):this.emit("TRACKER-error",{message:"One given setPaused parameter has the wrong type. paused: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setFullscreen(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.fullscreen!==e&&this.track(e?"fullscreen":"exitFullscreen",{macros:t}),this.fullscreen=e):this.emit("TRACKER-error",{message:"One given setFullScreen parameter has the wrong type. fullscreen: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setExpand(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.expanded!==e&&(this.track(e?"expand":"collapse",{macros:t}),this.track(e?"playerExpand":"playerCollapse",{macros:t})),this.expanded=e):this.emit("TRACKER-error",{message:"One given setExpand parameter has the wrong type. expanded: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setSkipDelay(e){u.isValidTimeValue(e)?this.skipDelay=e:this.emit("TRACKER-error",{message:"setSkipDelay parameter does not have a valid value. duration: ".concat(e)});}trackImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.impressed||(this.impressed=true,this.trackURLs(this.ad.impressionURLTemplates,e),this.track("creativeView",{macros:e})):this.emit("TRACKER-error",{message:"trackImpression parameter has the wrong type. macros: ".concat(e)});}trackViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackNotViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("notViewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackNotViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackUndeterminedImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewUndetermined",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackUndeterminedImpression given macros has the wrong type. macros: ".concat(e)});}error(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e&&"boolean"==typeof t?this.trackURLs(this.ad.errorURLTemplates,e,{isCustomCode:t}):this.emit("TRACKER-error",{message:"One given error parameter has the wrong type. macros: ".concat(u.formatMacrosValues(e),", isCustomCode: ").concat(t)});}errorWithCode(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"string"==typeof e&&"boolean"==typeof t?(this.error({ERRORCODE:e},t),console.log("The method errorWithCode is deprecated, please use vast tracker error method instead")):this.emit("TRACKER-error",{message:"One given errorWithCode parameter has the wrong type. errorCode: ".concat(e,", isCustomCode: ").concat(t)});}complete(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("complete",{macros:e}):this.emit("TRACKER-error",{message:"complete given macros has the wrong type. macros: ".concat(e)});}notUsed(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?(this.track("notUsed",{macros:e}),this.trackingEvents=[]):this.emit("TRACKER-error",{message:"notUsed given macros has the wrong type. macros: ".concat(e)});}otherAdInteraction(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("otherAdInteraction",{macros:e}):this.emit("TRACKER-error",{message:"otherAdInteraction given macros has the wrong type. macros: ".concat(e)});}acceptInvitation(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("acceptInvitation",{macros:e}):this.emit("TRACKER-error",{message:"acceptInvitation given macros has the wrong type. macros: ".concat(e)});}adExpand(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adExpand",{macros:e}):this.emit("TRACKER-error",{message:"adExpand given macros has the wrong type. macros: ".concat(e)});}adCollapse(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adCollapse",{macros:e}):this.emit("TRACKER-error",{message:"adCollapse given macros has the wrong type. macros: ".concat(e)});}minimize(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("minimize",{macros:e}):this.emit("TRACKER-error",{message:"minimize given macros has the wrong type. macros: ".concat(e)});}verificationNotExecuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given verificationNotExecuted parameter has to wrong type. vendor: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});if(!this.ad||!this.ad.adVerifications||!this.ad.adVerifications.length)throw new Error("No adVerifications provided");if(!e)throw new Error("No vendor provided, unable to find associated verificationNotExecuted");const r=this.ad.adVerifications.find((t=>t.vendor===e));if(!r)throw new Error("No associated verification element found for vendor: ".concat(e));const i=r.trackingEvents;if(i&&i.verificationNotExecuted){const e=i.verificationNotExecuted;this.trackURLs(e,t),this.emit("verificationNotExecuted",{trackingURLTemplates:e});}}overlayViewDuration(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"string"==typeof e&&"object"==typeof t?(t.ADPLAYHEAD=e,this.track("overlayViewDuration",{macros:t})):this.emit("TRACKER-error",{message:"One given overlayViewDuration parameters has the wrong type. formattedDuration: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}close(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track(this.linear?"closeLinear":"close",{macros:e}):this.emit("TRACKER-error",{message:"close given macros has the wrong type. macros: ".concat(e)});}skip(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("skip",{macros:e}):this.emit("TRACKER-error",{message:"skip given macros has the wrong type. macros: ".concat(e)});}load(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("loaded",{macros:e}):this.emit("TRACKER-error",{message:"load given macros has the wrong type. macros: ".concat(e)});}click(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(null!==e&&"string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given click parameter has the wrong type. fallbackClickThroughURL: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});this.clickTrackingURLTemplates&&this.clickTrackingURLTemplates.length&&this.trackURLs(this.clickTrackingURLTemplates,t);const r=this.clickThroughURLTemplate||e,i={...t};if(r){this.progress&&(i.ADPLAYHEAD=this.progressFormatted());const e=u.resolveURLTemplates([r],i)[0];this.emit("clickthrough",e);}}trackProgressEvents(e,t,r){const i=parseFloat(e.split("-")[1]);Object.entries(this.trackingEvents).filter((e=>{let[t]=e;return t.startsWith("progress-")})).map((e=>{let[t,r]=e;return {name:t,time:parseFloat(t.split("-")[1]),urls:r}})).filter((e=>{let{time:t}=e;return t<=i&&t>this.progress})).forEach((e=>{let{name:i,urls:a}=e;!r&&this.trackedProgressEvents.includes(i)||(this.emit(i,{trackingURLTemplates:a}),this.trackURLs(a,t),r?delete this.trackingEvents[i]:this.trackedProgressEvents.push(i));}));}track(e){let{macros:t={},once:r=false}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("object"!=typeof t)return void this.emit("TRACKER-error",{message:"track given macros has the wrong type. macros: ".concat(t)});"closeLinear"===e&&!this.trackingEvents[e]&&this.trackingEvents.close&&(e="close"),e.startsWith("progress-")&&!e.endsWith("%")&&this.trackProgressEvents(e,t,r);const i=this.trackingEvents[e],a=this.emitAlwaysEvents.indexOf(e)>-1;i?(this.emit(e,{trackingURLTemplates:i}),this.trackURLs(i,t)):a&&this.emit(e,null),r&&(delete this.trackingEvents[e],a&&this.emitAlwaysEvents.splice(this.emitAlwaysEvents.indexOf(e),1));}trackURLs(e){var t;let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{validUrls:a,invalidUrls:s}=u.filterUrlTemplates(e);s.length&&this.emit("TRACKER-error",{message:"Provided urls are malformed. url: ".concat(s)});const n={...r};this.linear&&(this.creative&&this.creative.mediaFiles&&this.creative.mediaFiles[0]&&this.creative.mediaFiles[0].fileURL&&(n.ASSETURI=this.creative.mediaFiles[0].fileURL),this.progress&&(n.ADPLAYHEAD=this.progressFormatted())),null!==(t=this.creative)&&void 0!==t&&null!==(t=t.universalAdIds)&&void 0!==t&&t.length&&(n.UNIVERSALADID=this.creative.universalAdIds.map((e=>e.idRegistry.concat(" ",e.value))).join(",")),this.ad&&(this.ad.sequence&&(n.PODSEQUENCE=this.ad.sequence),this.ad.adType&&(n.ADTYPE=this.ad.adType),this.ad.adServingId&&(n.ADSERVINGID=this.ad.adServingId),this.ad.categories&&this.ad.categories.length&&(n.ADCATEGORIES=this.ad.categories.map((e=>e.value)).join(",")),this.ad.blockedAdCategories&&this.ad.blockedAdCategories.length&&(n.BLOCKEDADCATEGORIES=this.ad.blockedAdCategories.map((e=>e.value)).join(","))),u.track(a,n,i);}convertToTimecode(e){if(!u.isValidTimeValue(e))return "";const t=1e3*e,r=Math.floor(t/36e5),i=Math.floor(t/6e4%60),a=Math.floor(t/1e3%60),s=Math.floor(t%1e3);return "".concat(u.addLeadingZeros(r,2),":").concat(u.addLeadingZeros(i,2),":").concat(u.addLeadingZeros(a,2),".").concat(u.addLeadingZeros(s,3))}progressFormatted(){return this.convertToTimecode(this.progress)}}
19
19
 
20
20
  // ─── Utility ─────────────────────────────────────────────────────────────────
21
21
  function toXmlDocument(xml) {
@@ -147,8 +147,17 @@ function extractSimidUrl(creative, rawDoc) {
147
147
  // Path 1: parsed library object
148
148
  // vast-client may expose InteractiveCreativeFile as interactiveCreativeFiles[] or inside mediaFiles[]
149
149
  const mediaFiles = [
150
- ...(creative?.mediaFiles || creative?.MediaFiles || creative?.linear?.mediaFiles || creative?.linear?.MediaFiles || []),
151
- ...(creative?.interactiveCreativeFiles || creative?.linear?.interactiveCreativeFiles || []),
150
+ ...(creative?.mediaFiles ||
151
+ creative?.MediaFiles ||
152
+ creative?.linear?.mediaFiles ||
153
+ creative?.linear?.MediaFiles ||
154
+ []),
155
+ ...(creative?.interactiveCreativeFiles ||
156
+ creative?.linear?.interactiveCreativeFiles ||
157
+ creative?.linear?.InteractiveCreativeFiles || [creative?.interactiveCreativeFile] || [
158
+ creative?.InteractiveCreativeFile,
159
+ ] ||
160
+ []),
152
161
  ];
153
162
  for (const mf of mediaFiles) {
154
163
  const framework = String(mf?.apiFramework || mf?.APIFramework || '').toLowerCase();
@@ -189,7 +198,11 @@ function extractAdVerifications(parsed, rawDoc) {
189
198
  const verifications = ad?.adVerifications || ad?.AdVerifications || [];
190
199
  for (const v of verifications) {
191
200
  const vendor = String(v?.vendor || v?.Vendor || '');
192
- const resources = v?.resource || v?.resources || v?.JavaScriptResource || v?.javaScriptResource || (v?.javascriptResource ? [v.javascriptResource] : []);
201
+ const resources = v?.resource ||
202
+ v?.resources ||
203
+ v?.JavaScriptResource ||
204
+ v?.javaScriptResource ||
205
+ (v?.javascriptResource ? [v.javascriptResource] : []);
193
206
  const resArr = Array.isArray(resources) ? resources : [resources];
194
207
  for (const r of resArr) {
195
208
  const scriptUrl = String(r?.uri || r?.url || r?.browserOptional?.value || r?.value || r || '').trim();
@@ -208,7 +221,9 @@ function extractAdVerifications(parsed, rawDoc) {
208
221
  try {
209
222
  return Array.from(root.getElementsByTagNameNS('*', tag));
210
223
  }
211
- catch { /* ignore */ }
224
+ catch {
225
+ /* ignore */
226
+ }
212
227
  try {
213
228
  return Array.from(root.getElementsByTagName(tag));
214
229
  }
@@ -395,7 +410,9 @@ function collectNonLinearFromXml(doc) {
395
410
  return arr;
396
411
  }
397
412
  }
398
- catch { /* ignore */ }
413
+ catch {
414
+ /* ignore */
415
+ }
399
416
  try {
400
417
  return Array.from(root.getElementsByTagName(localName));
401
418
  }
@@ -425,7 +442,9 @@ function collectNonLinearFromXml(doc) {
425
442
  });
426
443
  }
427
444
  }
428
- catch { /* ignore */ }
445
+ catch {
446
+ /* ignore */
447
+ }
429
448
  const nlEls = byLocalName(doc, 'NonLinear');
430
449
  for (const nl of nlEls) {
431
450
  const w = Number(nl.getAttribute('width') || 0);
@@ -496,8 +515,21 @@ function setSafeHTMLFn(el, html) {
496
515
  const tpl = document.createElement('template');
497
516
  tpl.innerHTML = String(html || '');
498
517
  const blockedTags = new Set([
499
- 'SCRIPT', 'IFRAME', 'OBJECT', 'EMBED', 'LINK', 'STYLE', 'SVG', 'MATH',
500
- 'FORM', 'INPUT', 'TEXTAREA', 'SELECT', 'OPTION', 'META', 'BASE',
518
+ 'SCRIPT',
519
+ 'IFRAME',
520
+ 'OBJECT',
521
+ 'EMBED',
522
+ 'LINK',
523
+ 'STYLE',
524
+ 'SVG',
525
+ 'MATH',
526
+ 'FORM',
527
+ 'INPUT',
528
+ 'TEXTAREA',
529
+ 'SELECT',
530
+ 'OPTION',
531
+ 'META',
532
+ 'BASE',
501
533
  ]);
502
534
  const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_ELEMENT);
503
535
  const toRemove = [];
@@ -681,8 +713,21 @@ class AdDomManager {
681
713
  const tpl = document.createElement('template');
682
714
  tpl.innerHTML = String(html || '');
683
715
  const blockedTags = new Set([
684
- 'SCRIPT', 'IFRAME', 'OBJECT', 'EMBED', 'LINK', 'STYLE', 'SVG', 'MATH',
685
- 'FORM', 'INPUT', 'TEXTAREA', 'SELECT', 'OPTION', 'META', 'BASE',
716
+ 'SCRIPT',
717
+ 'IFRAME',
718
+ 'OBJECT',
719
+ 'EMBED',
720
+ 'LINK',
721
+ 'STYLE',
722
+ 'SVG',
723
+ 'MATH',
724
+ 'FORM',
725
+ 'INPUT',
726
+ 'TEXTAREA',
727
+ 'SELECT',
728
+ 'OPTION',
729
+ 'META',
730
+ 'BASE',
686
731
  ]);
687
732
  const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_ELEMENT);
688
733
  const toRemove = [];
@@ -722,7 +767,9 @@ class AdDomManager {
722
767
  return;
723
768
  window.open(url.toString(), '_blank', 'noopener,noreferrer');
724
769
  }
725
- catch { /* ignore */ }
770
+ catch {
771
+ /* ignore */
772
+ }
726
773
  }
727
774
  // ─── Skip UI ─────────────────────────────────────────────────────────────────
728
775
  ensureSkipDom() {
@@ -733,7 +780,7 @@ class AdDomManager {
733
780
  const btn = document.createElement('button');
734
781
  btn.type = 'button';
735
782
  btn.className = 'op-ads__skip-btn';
736
- btn.textContent = 'Skip Ad';
783
+ btn.textContent = this.cfg.labels?.skip || 'Skip Ad';
737
784
  wrap.appendChild(btn);
738
785
  this.overlay.appendChild(wrap);
739
786
  const onClick = (e) => {
@@ -777,7 +824,8 @@ class AdDomManager {
777
824
  if (this.skipWrap)
778
825
  this.skipWrap.style.display = 'block';
779
826
  if (this.skipBtn) {
780
- this.skipBtn.textContent = remaining <= 0.05 ? 'Skip Ad' : Math.ceil(remaining).toString();
827
+ this.skipBtn.textContent =
828
+ remaining <= 0.05 ? this.cfg.labels?.skip || 'Skip Ad' : Math.ceil(remaining).toString();
781
829
  this.skipBtn.style.pointerEvents = remaining <= 0.05 ? 'auto' : 'none';
782
830
  }
783
831
  };
@@ -798,7 +846,9 @@ class AdDomManager {
798
846
  try {
799
847
  this.getTracker()?.trackSkip?.();
800
848
  }
801
- catch { /* ignore */ }
849
+ catch {
850
+ /* ignore */
851
+ }
802
852
  const brk = currentBreakMeta ? { kind: currentBreakMeta.kind, id: currentBreakMeta.breakId } : null;
803
853
  emitSkip({ break: brk, reason });
804
854
  const v = adVideo;
@@ -808,7 +858,9 @@ class AdDomManager {
808
858
  v.currentTime = Math.max(0, v.duration - 0.001);
809
859
  v.dispatchEvent(new Event('ended'));
810
860
  }
811
- catch { /* ignore */ }
861
+ catch {
862
+ /* ignore */
863
+ }
812
864
  }
813
865
  }
814
866
  // ─── Overlay cleanup ──────────────────────────────────────────────────────────
@@ -860,9 +912,18 @@ class AdDomManager {
860
912
  wrap.className = 'op-ads__companion';
861
913
  wrap.style.position = 'relative';
862
914
  wrap.style.cursor = click ? 'pointer' : 'default';
863
- const staticRes = companion?.staticResource || companion?.StaticResource || companion?.staticResources?.[0] || companion?.StaticResources?.[0];
864
- const iframeRes = companion?.iFrameResource || companion?.IFrameResource || companion?.iFrameResources?.[0] || companion?.IFrameResources?.[0];
865
- const htmlRes = companion?.htmlResource || companion?.HTMLResource || companion?.htmlResources?.[0] || companion?.HTMLResources?.[0];
915
+ const staticRes = companion?.staticResource ||
916
+ companion?.StaticResource ||
917
+ companion?.staticResources?.[0] ||
918
+ companion?.StaticResources?.[0];
919
+ const iframeRes = companion?.iFrameResource ||
920
+ companion?.IFrameResource ||
921
+ companion?.iFrameResources?.[0] ||
922
+ companion?.IFrameResources?.[0];
923
+ const htmlRes = companion?.htmlResource ||
924
+ companion?.HTMLResource ||
925
+ companion?.htmlResources?.[0] ||
926
+ companion?.HTMLResources?.[0];
866
927
  let node = null;
867
928
  if (staticRes) {
868
929
  const img = document.createElement('img');
@@ -895,7 +956,9 @@ class AdDomManager {
895
956
  this.getTracker()?.trackClick?.();
896
957
  this.getTracker()?.trackClickThrough?.();
897
958
  }
898
- catch { /* ignore */ }
959
+ catch {
960
+ /* ignore */
961
+ }
899
962
  e.preventDefault();
900
963
  e.stopPropagation();
901
964
  };
@@ -989,7 +1052,9 @@ class AdDomManager {
989
1052
  this.getTracker()?.trackClick?.();
990
1053
  this.getTracker()?.trackClickThrough?.();
991
1054
  }
992
- catch { /* ignore */ }
1055
+ catch {
1056
+ /* ignore */
1057
+ }
993
1058
  e.preventDefault();
994
1059
  e.stopPropagation();
995
1060
  };
@@ -1941,32 +2006,66 @@ class AdScheduler {
1941
2006
  }
1942
2007
 
1943
2008
  /**
1944
- * SimidSession — Full IAB SIMID (Secure Interactive Media Interface Definition) implementation.
2009
+ * SimidSession — IAB SIMID 1.2 (Secure Interactive Media Interface Definition) implementation.
1945
2010
  *
1946
- * Protocol overview:
1947
- * - Player sends messages to the creative iframe via postMessage.
1948
- * - Creative sends messages back, handled by the player's message listener.
1949
- * - Each playercreative message carries a unique msgId. The creative responds
1950
- * with SIMID:Creative:resolve or SIMID:Creative:reject referencing that msgId.
2011
+ * SIMID 1.2 session initialization sequence:
2012
+ * 1. Creative Player : createSession (with sessionId)
2013
+ * 2. Player → Creative: resolve (acks createSession)
2014
+ * 3. Player Creative: SIMID:Player:init (environmentData + creativeData)
2015
+ * 4. Creative Player : resolve (acks init)
2016
+ * 5. Creative → Player : SIMID:Creative:ready
2017
+ * 6. Player → Creative: SIMID:Player:startCreative
2018
+ * 7. Creative → Player : resolve (acks startCreative)
2019
+ *
2020
+ * Message format notes:
2021
+ * - Some SIMID creatives post messages as JSON-encoded strings rather than plain objects.
2022
+ * handleMessage() handles both via parseMessageData().
2023
+ * - The outgoing format mirrors the incoming format: if the creative sends JSON strings
2024
+ * (i.e. JSON.parse(event.data) is used on the creative side), the player also sends
2025
+ * JSON strings so they parse correctly. Format is auto-detected on the first message.
2026
+ * - Older creatives may skip createSession and go straight to SIMID:Creative:ready.
2027
+ * onCreativeReady() falls back to sending init + startCreative in that case.
1951
2028
  *
1952
2029
  * Spec: https://iabtechlab.com/standards/simid/
1953
2030
  */
1954
2031
  // ─── Message type constants ───────────────────────────────────────────────────
1955
2032
  const SIMID_PLAYER = {
1956
2033
  INIT: 'SIMID:Player:init',
1957
- START_AD: 'SIMID:Player:startAd',
2034
+ START_CREATIVE: 'SIMID:Player:startCreative',
1958
2035
  AD_PROGRESS: 'SIMID:Player:adProgress',
1959
2036
  AD_PAUSED: 'SIMID:Player:adPaused',
1960
2037
  AD_PLAYING: 'SIMID:Player:adPlaying',
1961
2038
  AD_STOPPED: 'SIMID:Player:adStopped',
1962
2039
  AD_SKIPPED: 'SIMID:Player:adSkipped',
1963
2040
  AD_VOLUME: 'SIMID:Player:adVolume',
2041
+ AD_DURATION_CHANGE: 'SIMID:Player:adDurationChange',
1964
2042
  RESIZE: 'SIMID:Player:resize',
1965
2043
  FATAL: 'SIMID:Player:fatal',
1966
2044
  LOG: 'SIMID:Player:log',
2045
+ APP_BACKGROUNDED: 'SIMID:Player:appBackgrounded',
2046
+ APP_FOREGROUNDED: 'SIMID:Player:appForegrounded',
2047
+ /** Player resolves a creative request (spec type: "resolve") */
2048
+ RESOLVE: 'resolve',
2049
+ /** Player rejects a creative request (spec type: "reject") */
2050
+ REJECT: 'reject',
2051
+ };
2052
+ /** SIMID 1.2 media event types — player bridges ad video DOM events to these postMessages. */
2053
+ const SIMID_MEDIA = {
2054
+ DURATION_CHANGE: 'SIMID:Media:durationchange',
2055
+ ENDED: 'SIMID:Media:ended',
2056
+ ERROR: 'SIMID:Media:error',
2057
+ PAUSE: 'SIMID:Media:pause',
2058
+ PLAY: 'SIMID:Media:play',
2059
+ PLAYING: 'SIMID:Media:playing',
2060
+ SEEKED: 'SIMID:Media:seeked',
2061
+ SEEKING: 'SIMID:Media:seeking',
2062
+ STALLED: 'SIMID:Media:stalled',
2063
+ TIME_UPDATE: 'SIMID:Media:timeupdate',
2064
+ VOLUME_CHANGE: 'SIMID:Media:volumechange',
1967
2065
  };
1968
2066
  const SIMID_CREATIVE = {
1969
2067
  READY: 'SIMID:Creative:ready',
2068
+ GET_MEDIA_STATE: 'SIMID:Creative:getMediaState',
1970
2069
  RESOLVE: 'SIMID:Creative:resolve',
1971
2070
  REJECT: 'SIMID:Creative:reject',
1972
2071
  REQUEST_FULLSCREEN: 'SIMID:Creative:requestFullscreen',
@@ -1977,11 +2076,13 @@ const SIMID_CREATIVE = {
1977
2076
  REQUEST_STOP: 'SIMID:Creative:requestStop',
1978
2077
  REQUEST_PAUSE: 'SIMID:Creative:requestPause',
1979
2078
  REQUEST_PLAY: 'SIMID:Creative:requestPlay',
2079
+ REQUEST_CHANGE_AD_DURATION: 'SIMID:Creative:requestChangeAdDuration',
1980
2080
  FATAL: 'SIMID:Creative:fatal',
1981
2081
  LOG: 'SIMID:Creative:log',
1982
2082
  };
2083
+ // ─── SimidSession ─────────────────────────────────────────────────────────────
1983
2084
  class SimidSession {
1984
- constructor(iframe, adVideo, callbacks) {
2085
+ constructor(iframe, adVideo, callbacks, creativeInfo) {
1985
2086
  Object.defineProperty(this, "iframe", {
1986
2087
  enumerable: true,
1987
2088
  configurable: true,
@@ -2000,7 +2101,13 @@ class SimidSession {
2000
2101
  writable: true,
2001
2102
  value: callbacks
2002
2103
  });
2003
- Object.defineProperty(this, "msgId", {
2104
+ Object.defineProperty(this, "creativeInfo", {
2105
+ enumerable: true,
2106
+ configurable: true,
2107
+ writable: true,
2108
+ value: creativeInfo
2109
+ });
2110
+ Object.defineProperty(this, "msgCounter", {
2004
2111
  enumerable: true,
2005
2112
  configurable: true,
2006
2113
  writable: true,
@@ -2018,6 +2125,24 @@ class SimidSession {
2018
2125
  writable: true,
2019
2126
  value: void 0
2020
2127
  });
2128
+ Object.defineProperty(this, "sessionId", {
2129
+ enumerable: true,
2130
+ configurable: true,
2131
+ writable: true,
2132
+ value: ''
2133
+ });
2134
+ Object.defineProperty(this, "initSent", {
2135
+ enumerable: true,
2136
+ configurable: true,
2137
+ writable: true,
2138
+ value: false
2139
+ });
2140
+ Object.defineProperty(this, "initPromise", {
2141
+ enumerable: true,
2142
+ configurable: true,
2143
+ writable: true,
2144
+ value: null
2145
+ });
2021
2146
  Object.defineProperty(this, "started", {
2022
2147
  enumerable: true,
2023
2148
  configurable: true,
@@ -2030,53 +2155,210 @@ class SimidSession {
2030
2155
  writable: true,
2031
2156
  value: false
2032
2157
  });
2158
+ Object.defineProperty(this, "mediaListeners", {
2159
+ enumerable: true,
2160
+ configurable: true,
2161
+ writable: true,
2162
+ value: []
2163
+ });
2164
+ Object.defineProperty(this, "visibilityHandler", {
2165
+ enumerable: true,
2166
+ configurable: true,
2167
+ writable: true,
2168
+ value: null
2169
+ });
2170
+ /**
2171
+ * Detected outgoing message format.
2172
+ * 'plain' — post plain JS objects (spec default, works with most creatives)
2173
+ * 'json-string' — post JSON.stringify(payload) as the message value; used when the
2174
+ * creative calls JSON.parse(event.data) to deserialise incoming messages
2175
+ * (e.g. Google's compiled SIMID sample creative)
2176
+ */
2177
+ Object.defineProperty(this, "outgoingFormat", {
2178
+ enumerable: true,
2179
+ configurable: true,
2180
+ writable: true,
2181
+ value: 'plain'
2182
+ });
2183
+ Object.defineProperty(this, "_targetOrigin", {
2184
+ enumerable: true,
2185
+ configurable: true,
2186
+ writable: true,
2187
+ value: null
2188
+ });
2033
2189
  this.messageListener = this.handleMessage.bind(this);
2034
2190
  window.addEventListener('message', this.messageListener);
2191
+ this.bindMediaEvents();
2035
2192
  }
2036
- // ─── Internal send/receive ────────────────────────────────────────────────
2193
+ // ─── Internal messaging helpers ───────────────────────────────────────────
2037
2194
  nextMsgId() {
2038
- return ++this.msgId;
2195
+ return ++this.msgCounter;
2039
2196
  }
2040
- send(type, args, id) {
2041
- const msgId = id ?? this.nextMsgId();
2042
- const msg = { type, msgId, args: args ?? {} };
2197
+ /**
2198
+ * Returns the target origin for postMessage calls to the creative iframe.
2199
+ * Lazily derived from iframe.src so we don't need a constructor argument.
2200
+ * Falls back to '*' only when the src is not an absolute URL (e.g. data: URIs
2201
+ * used in tests), which is an acceptable edge case.
2202
+ */
2203
+ getTargetOrigin() {
2204
+ if (this._targetOrigin !== null)
2205
+ return this._targetOrigin;
2206
+ try {
2207
+ const origin = new URL(this.iframe.src, window.location.href).origin;
2208
+ // data: and blob: URLs produce the string "null" as their origin — treat as wildcard.
2209
+ this._targetOrigin = origin === 'null' ? '*' : origin;
2210
+ }
2211
+ catch {
2212
+ this._targetOrigin = '*';
2213
+ }
2214
+ return this._targetOrigin;
2215
+ }
2216
+ /**
2217
+ * Post a payload to the creative's iframe using the detected outgoing format.
2218
+ * - 'plain': postMessage(payload, origin)
2219
+ * - 'json-string': postMessage(JSON.stringify(payload), origin)
2220
+ */
2221
+ postMsg(payload) {
2222
+ const data = this.outgoingFormat === 'json-string' ? JSON.stringify(payload) : payload;
2223
+ this.iframe.contentWindow?.postMessage(data, this.getTargetOrigin());
2224
+ }
2225
+ /**
2226
+ * Send a player→creative message that expects a resolve/reject response.
2227
+ * Returns a promise that resolves/rejects when the creative responds.
2228
+ */
2229
+ send(type, args) {
2230
+ const messageId = this.nextMsgId();
2231
+ const payload = {
2232
+ type,
2233
+ messageId,
2234
+ sessionId: this.sessionId || undefined,
2235
+ timestamp: Date.now(),
2236
+ args: args ?? {},
2237
+ };
2043
2238
  return new Promise((resolve, reject) => {
2044
- this.pending.set(msgId, { resolve, reject });
2239
+ this.pending.set(messageId, { resolve, reject });
2045
2240
  try {
2046
- this.iframe.contentWindow?.postMessage(msg, '*');
2241
+ this.postMsg(payload);
2047
2242
  }
2048
2243
  catch (e) {
2049
- this.pending.delete(msgId);
2244
+ this.pending.delete(messageId);
2050
2245
  reject(e);
2051
2246
  }
2052
2247
  });
2053
2248
  }
2249
+ /**
2250
+ * Send a resolve response to the creative for a message it sent us.
2251
+ * Per spec: type="resolve", args={ messageId: <original>, value: <payload> }
2252
+ */
2253
+ sendResolve(resolvedMessageId, value) {
2254
+ try {
2255
+ this.postMsg({
2256
+ type: SIMID_PLAYER.RESOLVE,
2257
+ messageId: this.nextMsgId(),
2258
+ sessionId: this.sessionId || undefined,
2259
+ timestamp: Date.now(),
2260
+ args: { messageId: resolvedMessageId, value: value ?? {} },
2261
+ });
2262
+ }
2263
+ catch {
2264
+ /* ignore */
2265
+ }
2266
+ }
2267
+ /**
2268
+ * Send a reject response to the creative for a message it sent us.
2269
+ */
2270
+ sendReject(resolvedMessageId, errorCode, message) {
2271
+ try {
2272
+ this.postMsg({
2273
+ type: SIMID_PLAYER.REJECT,
2274
+ messageId: this.nextMsgId(),
2275
+ sessionId: this.sessionId || undefined,
2276
+ timestamp: Date.now(),
2277
+ args: { messageId: resolvedMessageId, value: { errorCode, message } },
2278
+ });
2279
+ }
2280
+ catch {
2281
+ /* ignore */
2282
+ }
2283
+ }
2284
+ // ─── Message parsing ──────────────────────────────────────────────────────
2285
+ /**
2286
+ * Parse a raw postMessage payload into a SimidMessage.
2287
+ * Handles both plain objects and JSON-encoded strings.
2288
+ * Auto-detects the outgoing format from the first valid message received.
2289
+ */
2290
+ parseMessageData(raw) {
2291
+ if (typeof raw === 'string') {
2292
+ let parsed;
2293
+ try {
2294
+ parsed = JSON.parse(raw);
2295
+ }
2296
+ catch {
2297
+ return null;
2298
+ }
2299
+ if (!parsed?.type)
2300
+ return null;
2301
+ // Creative sends JSON strings → it expects JSON strings back.
2302
+ if (this.outgoingFormat === 'plain')
2303
+ this.outgoingFormat = 'json-string';
2304
+ return parsed;
2305
+ }
2306
+ if (raw && typeof raw === 'object')
2307
+ return raw;
2308
+ return null;
2309
+ }
2310
+ // ─── Message dispatch ─────────────────────────────────────────────────────
2054
2311
  handleMessage(event) {
2055
2312
  if (this.destroyed)
2056
2313
  return;
2057
- const data = event.data;
2058
- if (!data || typeof data.type !== 'string')
2314
+ const data = this.parseMessageData(event.data);
2315
+ if (!data || !data.type)
2059
2316
  return;
2317
+ // Support both SIMID 1.2 (messageId) and legacy (msgId) fields.
2318
+ const incomingId = data.messageId ?? data.msgId ?? 0;
2060
2319
  switch (data.type) {
2320
+ // ── SIMID 1.2 session init ───────────────────────────────────────────
2321
+ case 'createSession':
2322
+ this.onCreateSession(incomingId, data.sessionId || '');
2323
+ break;
2324
+ case SIMID_CREATIVE.GET_MEDIA_STATE:
2325
+ this.sendResolve(incomingId, this.getMediaState());
2326
+ break;
2061
2327
  case SIMID_CREATIVE.READY:
2062
- this.onCreativeReady(data);
2328
+ void this.onCreativeReady();
2063
2329
  break;
2330
+ // ── Promise resolution ───────────────────────────────────────────────
2331
+ // IAB reference creatives (simid_protocol.js) and Google's compiled sample send
2332
+ // type="resolve" / type="reject" when acknowledging player messages.
2333
+ // Some third-party implementations send type="SIMID:Creative:resolve" / "SIMID:Creative:reject".
2334
+ // Both forms are handled here.
2335
+ case 'resolve': // IAB reference implementation pattern
2336
+ // falls through
2064
2337
  case SIMID_CREATIVE.RESOLVE: {
2065
- const pending = data.resolves != null ? this.pending.get(data.resolves) : undefined;
2338
+ // `resolves` (top-level) or args.messageId both point to our outgoing messageId.
2339
+ const resolvedId = data.resolves ?? data.args?.messageId;
2340
+ const pending = resolvedId != null ? this.pending.get(resolvedId) : undefined;
2066
2341
  if (pending) {
2067
- this.pending.delete(data.resolves);
2068
- pending.resolve(data.args);
2342
+ this.pending.delete(resolvedId);
2343
+ pending.resolve(data.args?.value ?? data.args);
2069
2344
  }
2070
2345
  break;
2071
2346
  }
2347
+ case 'reject': // IAB reference implementation pattern
2348
+ // falls through
2072
2349
  case SIMID_CREATIVE.REJECT: {
2073
- const pending = data.rejects != null ? this.pending.get(data.rejects) : undefined;
2350
+ const rejectedId = data.rejects ?? data.args?.messageId;
2351
+ const pending = rejectedId != null ? this.pending.get(rejectedId) : undefined;
2074
2352
  if (pending) {
2075
- this.pending.delete(data.rejects);
2076
- pending.reject({ errorCode: data.errorCode, reason: data.reason });
2353
+ this.pending.delete(rejectedId);
2354
+ pending.reject({
2355
+ errorCode: data.errorCode ?? data.args?.value?.errorCode,
2356
+ reason: data.reason ?? data.args?.value?.message,
2357
+ });
2077
2358
  }
2078
2359
  break;
2079
2360
  }
2361
+ // ── Creative → Player commands ───────────────────────────────────────
2080
2362
  case SIMID_CREATIVE.REQUEST_SKIP:
2081
2363
  this.callbacks.onSkip();
2082
2364
  break;
@@ -2100,17 +2382,29 @@ class SimidSession {
2100
2382
  this.callbacks.onTrackingEvent(trackingEvent, data.args);
2101
2383
  break;
2102
2384
  }
2103
- case SIMID_CREATIVE.REQUEST_FULLSCREEN:
2104
- try {
2105
- const container = this.iframe.closest('.op-ads') ?? this.iframe.parentElement;
2106
- container?.requestFullscreen?.().catch(() => undefined);
2385
+ case SIMID_CREATIVE.REQUEST_FULLSCREEN: {
2386
+ const container = this.iframe.closest('.op-ads') ?? this.iframe.parentElement;
2387
+ if (container?.requestFullscreen) {
2388
+ container.requestFullscreen().catch(() => this.sendReject(incomingId, 403, 'Fullscreen denied'));
2389
+ }
2390
+ else {
2391
+ this.sendReject(incomingId, 403, 'Fullscreen not supported');
2107
2392
  }
2108
- catch { /* ignore */ }
2109
2393
  break;
2394
+ }
2110
2395
  case SIMID_CREATIVE.REQUEST_RESIZE:
2111
- // Best-effort: notify the creative of current dimensions.
2112
2396
  void this.resize(this.iframe.offsetWidth || window.innerWidth, this.iframe.offsetHeight || window.innerHeight);
2113
2397
  break;
2398
+ case SIMID_CREATIVE.REQUEST_CHANGE_AD_DURATION: {
2399
+ const durationChange = Number(data.args?.durationChange ?? data.args?.duration ?? 0);
2400
+ if (this.callbacks.onRequestChangeAdDuration) {
2401
+ this.callbacks.onRequestChangeAdDuration(durationChange, () => this.sendResolve(incomingId, {}), (errorCode, reason) => this.sendReject(incomingId, errorCode, reason));
2402
+ }
2403
+ else {
2404
+ this.sendReject(incomingId, 403, 'requestChangeAdDuration not supported');
2405
+ }
2406
+ break;
2407
+ }
2114
2408
  case SIMID_CREATIVE.FATAL:
2115
2409
  this.callbacks.onFatal(data.errorCode ?? 901, data.reason ?? 'Creative fatal error');
2116
2410
  break;
@@ -2119,63 +2413,177 @@ class SimidSession {
2119
2413
  break;
2120
2414
  }
2121
2415
  }
2122
- // ─── Creative-ready handshake ─────────────────────────────────────────────
2123
- async onCreativeReady(msg) {
2416
+ // ─── Session initialization ───────────────────────────────────────────────
2417
+ /**
2418
+ * SIMID 1.2: creative sends createSession first.
2419
+ * Player responds with resolve, then immediately sends init.
2420
+ */
2421
+ onCreateSession(messageId, sessionId) {
2422
+ if (sessionId)
2423
+ this.sessionId = sessionId;
2424
+ this.sendResolve(messageId);
2425
+ if (!this.initSent) {
2426
+ this.initSent = true;
2427
+ this.initPromise = this.send(SIMID_PLAYER.INIT, {
2428
+ creativeData: this.buildCreativeData(),
2429
+ environmentData: this.buildEnvironmentData(),
2430
+ })
2431
+ .then(() => {
2432
+ // Creative resolved SIMID:Player:init → send startCreative immediately.
2433
+ // Creatives that never send SIMID:Creative:ready (e.g. Google's compiled sample)
2434
+ // rely on this path to trigger the interactive content.
2435
+ if (!this.started && !this.destroyed) {
2436
+ this.started = true;
2437
+ return this.send(SIMID_PLAYER.START_CREATIVE).catch(() => undefined);
2438
+ }
2439
+ })
2440
+ .catch(() => undefined);
2441
+ }
2442
+ }
2443
+ /**
2444
+ * Creative signals it is ready for startCreative.
2445
+ * If no createSession was received (older creatives), init is sent here as a fallback.
2446
+ */
2447
+ async onCreativeReady() {
2124
2448
  if (this.started)
2125
2449
  return;
2126
2450
  this.started = true;
2451
+ try {
2452
+ if (!this.initSent) {
2453
+ // Fallback: older creatives that skip createSession.
2454
+ this.initSent = true;
2455
+ await this.send(SIMID_PLAYER.INIT, {
2456
+ creativeData: this.buildCreativeData(),
2457
+ environmentData: this.buildEnvironmentData(),
2458
+ });
2459
+ }
2460
+ else if (this.initPromise) {
2461
+ // Wait for the in-flight init to be acknowledged before startCreative.
2462
+ await this.initPromise;
2463
+ }
2464
+ await this.send(SIMID_PLAYER.START_CREATIVE);
2465
+ }
2466
+ catch {
2467
+ /* Creative may reject — continue ad playback regardless */
2468
+ }
2469
+ }
2470
+ // ─── Data builders ────────────────────────────────────────────────────────
2471
+ buildEnvironmentData() {
2127
2472
  const v = this.adVideo;
2128
- const rect = this.iframe.getBoundingClientRect();
2129
- const creativeData = {};
2130
- const environmentData = {
2131
- playerWidth: rect.width || v.offsetWidth || 640,
2132
- playerHeight: rect.height || v.offsetHeight || 360,
2133
- videoDuration: Number.isFinite(v.duration) ? v.duration : 0,
2134
- videoVolume: v.muted ? 0 : (Number.isFinite(v.volume) ? v.volume : 1),
2135
- fullscreen: !!(document.fullscreenElement),
2473
+ const playerRect = this.iframe.getBoundingClientRect();
2474
+ const videoRect = v.getBoundingClientRect();
2475
+ const pw = Math.round(playerRect.width) || v.offsetWidth || 640;
2476
+ const ph = Math.round(playerRect.height) || v.offsetHeight || 360;
2477
+ const vw = Math.round(videoRect.width) || pw;
2478
+ const vh = Math.round(videoRect.height) || ph;
2479
+ const vol = v.muted ? 0 : Number.isFinite(v.volume) ? v.volume : 1;
2480
+ return {
2481
+ // ── SIMID 1.2 required fields ────────────────────────────────────────
2482
+ videoDimensions: {
2483
+ x: Math.round(videoRect.left),
2484
+ y: Math.round(videoRect.top),
2485
+ width: vw,
2486
+ height: vh,
2487
+ },
2488
+ creativeDimensions: {
2489
+ x: Math.round(playerRect.left),
2490
+ y: Math.round(playerRect.top),
2491
+ width: pw,
2492
+ height: ph,
2493
+ },
2494
+ fullscreen: !!document.fullscreenElement,
2136
2495
  fullscreenAllowed: true,
2496
+ variableDurationAllowed: typeof this.callbacks.onRequestChangeAdDuration === 'function',
2497
+ skippableState: 'notSkippable',
2498
+ version: '1.2',
2499
+ // ── SIMID 1.2 optional fields ────────────────────────────────────────
2500
+ siteUrl: typeof window !== 'undefined' ? window.location.href : '',
2501
+ muted: v.muted,
2502
+ volume: vol,
2503
+ // ── Legacy compatibility (older SIMID creatives) ─────────────────────
2504
+ playerWidth: pw,
2505
+ playerHeight: ph,
2506
+ videoDuration: Number.isFinite(v.duration) ? v.duration : 0,
2507
+ videoVolume: vol,
2137
2508
  };
2138
- try {
2139
- await this.send(SIMID_PLAYER.INIT, { creativeData, environmentData }, msg.msgId ? undefined : this.nextMsgId());
2140
- await this.send(SIMID_PLAYER.START_AD);
2141
- }
2142
- catch { /* Creative may reject — continue ad playback regardless */ }
2143
2509
  }
2144
- // ─── Player → Creative API ────────────────────────────────────────────────
2510
+ buildCreativeData() {
2511
+ return {
2512
+ adParameters: this.creativeInfo?.adParameters ?? '',
2513
+ clickThruUrl: this.creativeInfo?.clickThruUri ?? '',
2514
+ clickThruUri: this.creativeInfo?.clickThruUri ?? '',
2515
+ };
2516
+ }
2517
+ /** Current media state snapshot, used to respond to SIMID:Creative:getMediaState. */
2518
+ getMediaState() {
2519
+ const v = this.adVideo;
2520
+ return {
2521
+ currentSrc: v.currentSrc || v.src || '',
2522
+ currentTime: v.currentTime,
2523
+ duration: Number.isFinite(v.duration) ? v.duration : 0,
2524
+ ended: v.ended,
2525
+ muted: v.muted,
2526
+ paused: v.paused,
2527
+ volume: v.volume,
2528
+ fullscreen: !!document.fullscreenElement,
2529
+ };
2530
+ }
2531
+ // ─── Player → Creative public API ─────────────────────────────────────────
2532
+ /** Manually send SIMID:Player:init (e.g. when not using the automatic handshake). */
2145
2533
  init(creativeData, environmentData) {
2146
2534
  return this.send(SIMID_PLAYER.INIT, { creativeData, environmentData });
2147
2535
  }
2536
+ /** Manually send SIMID:Player:startCreative. */
2148
2537
  start() {
2149
- return this.send(SIMID_PLAYER.START_AD);
2538
+ return this.send(SIMID_PLAYER.START_CREATIVE);
2150
2539
  }
2151
2540
  progress(currentTime, duration) {
2152
2541
  if (this.destroyed)
2153
2542
  return;
2154
- const msg = {
2155
- type: SIMID_PLAYER.AD_PROGRESS,
2156
- msgId: this.nextMsgId(),
2157
- args: { currentTime, duration, remainingTime: Math.max(0, duration - currentTime) },
2158
- };
2159
2543
  try {
2160
- this.iframe.contentWindow?.postMessage(msg, '*');
2544
+ this.postMsg({
2545
+ type: SIMID_PLAYER.AD_PROGRESS,
2546
+ messageId: this.nextMsgId(),
2547
+ sessionId: this.sessionId || undefined,
2548
+ timestamp: Date.now(),
2549
+ args: { currentTime, duration, remainingTime: Math.max(0, duration - currentTime) },
2550
+ });
2551
+ }
2552
+ catch {
2553
+ /* ignore */
2161
2554
  }
2162
- catch { /* ignore */ }
2163
2555
  }
2164
2556
  pause() {
2165
2557
  if (this.destroyed)
2166
2558
  return;
2167
2559
  try {
2168
- this.iframe.contentWindow?.postMessage({ type: SIMID_PLAYER.AD_PAUSED, msgId: this.nextMsgId() }, '*');
2560
+ this.postMsg({
2561
+ type: SIMID_PLAYER.AD_PAUSED,
2562
+ messageId: this.nextMsgId(),
2563
+ sessionId: this.sessionId || undefined,
2564
+ timestamp: Date.now(),
2565
+ args: {},
2566
+ });
2567
+ }
2568
+ catch {
2569
+ /* ignore */
2169
2570
  }
2170
- catch { /* ignore */ }
2171
2571
  }
2172
2572
  resume() {
2173
2573
  if (this.destroyed)
2174
2574
  return;
2175
2575
  try {
2176
- this.iframe.contentWindow?.postMessage({ type: SIMID_PLAYER.AD_PLAYING, msgId: this.nextMsgId() }, '*');
2576
+ this.postMsg({
2577
+ type: SIMID_PLAYER.AD_PLAYING,
2578
+ messageId: this.nextMsgId(),
2579
+ sessionId: this.sessionId || undefined,
2580
+ timestamp: Date.now(),
2581
+ args: {},
2582
+ });
2583
+ }
2584
+ catch {
2585
+ /* ignore */
2177
2586
  }
2178
- catch { /* ignore */ }
2179
2587
  }
2180
2588
  stop() {
2181
2589
  if (this.destroyed)
@@ -2186,21 +2594,49 @@ class SimidSession {
2186
2594
  if (this.destroyed)
2187
2595
  return;
2188
2596
  try {
2189
- this.iframe.contentWindow?.postMessage({ type: SIMID_PLAYER.AD_SKIPPED, msgId: this.nextMsgId() }, '*');
2597
+ this.postMsg({
2598
+ type: SIMID_PLAYER.AD_SKIPPED,
2599
+ messageId: this.nextMsgId(),
2600
+ sessionId: this.sessionId || undefined,
2601
+ timestamp: Date.now(),
2602
+ args: {},
2603
+ });
2604
+ }
2605
+ catch {
2606
+ /* ignore */
2190
2607
  }
2191
- catch { /* ignore */ }
2192
2608
  }
2193
2609
  volumeChange(volume, muted) {
2194
2610
  if (this.destroyed)
2195
2611
  return;
2196
2612
  try {
2197
- this.iframe.contentWindow?.postMessage({
2613
+ this.postMsg({
2198
2614
  type: SIMID_PLAYER.AD_VOLUME,
2199
- msgId: this.nextMsgId(),
2615
+ messageId: this.nextMsgId(),
2616
+ sessionId: this.sessionId || undefined,
2617
+ timestamp: Date.now(),
2200
2618
  args: { volume, muted },
2201
- }, '*');
2619
+ });
2620
+ }
2621
+ catch {
2622
+ /* ignore */
2623
+ }
2624
+ }
2625
+ adDurationChange(duration) {
2626
+ if (this.destroyed)
2627
+ return;
2628
+ try {
2629
+ this.postMsg({
2630
+ type: SIMID_PLAYER.AD_DURATION_CHANGE,
2631
+ messageId: this.nextMsgId(),
2632
+ sessionId: this.sessionId || undefined,
2633
+ timestamp: Date.now(),
2634
+ args: { duration },
2635
+ });
2636
+ }
2637
+ catch {
2638
+ /* ignore */
2202
2639
  }
2203
- catch { /* ignore */ }
2204
2640
  }
2205
2641
  resize(width, height) {
2206
2642
  return this.send(SIMID_PLAYER.RESIZE, { width, height });
@@ -2209,20 +2645,91 @@ class SimidSession {
2209
2645
  if (this.destroyed)
2210
2646
  return;
2211
2647
  try {
2212
- this.iframe.contentWindow?.postMessage({
2648
+ this.postMsg({
2213
2649
  type: SIMID_PLAYER.FATAL,
2214
- msgId: this.nextMsgId(),
2650
+ messageId: this.nextMsgId(),
2651
+ sessionId: this.sessionId || undefined,
2652
+ timestamp: Date.now(),
2215
2653
  args: { errorCode, reason },
2216
- }, '*');
2654
+ });
2655
+ }
2656
+ catch {
2657
+ /* ignore */
2658
+ }
2659
+ }
2660
+ // ─── Media event bridging ─────────────────────────────────────────────────
2661
+ /**
2662
+ * Bridge ad video DOM events to SIMID:Media:* postMessages and
2663
+ * document visibility changes to SIMID:Player:appBackgrounded/Foregrounded.
2664
+ * Called once from the constructor; listeners are cleaned up in destroy().
2665
+ */
2666
+ bindMediaEvents() {
2667
+ const v = this.adVideo;
2668
+ const mediaEventMap = [
2669
+ ['durationchange', SIMID_MEDIA.DURATION_CHANGE],
2670
+ ['ended', SIMID_MEDIA.ENDED],
2671
+ ['error', SIMID_MEDIA.ERROR],
2672
+ ['pause', SIMID_MEDIA.PAUSE],
2673
+ ['play', SIMID_MEDIA.PLAY],
2674
+ ['playing', SIMID_MEDIA.PLAYING],
2675
+ ['seeked', SIMID_MEDIA.SEEKED],
2676
+ ['seeking', SIMID_MEDIA.SEEKING],
2677
+ ['stalled', SIMID_MEDIA.STALLED],
2678
+ ['timeupdate', SIMID_MEDIA.TIME_UPDATE],
2679
+ ['volumechange', SIMID_MEDIA.VOLUME_CHANGE],
2680
+ ];
2681
+ for (const [domEvent, simidType] of mediaEventMap) {
2682
+ const handler = () => {
2683
+ if (this.destroyed)
2684
+ return;
2685
+ try {
2686
+ this.postMsg({
2687
+ type: simidType,
2688
+ messageId: this.nextMsgId(),
2689
+ sessionId: this.sessionId || undefined,
2690
+ timestamp: Date.now(),
2691
+ args: this.getMediaState(),
2692
+ });
2693
+ }
2694
+ catch {
2695
+ /* ignore */
2696
+ }
2697
+ };
2698
+ v.addEventListener(domEvent, handler);
2699
+ this.mediaListeners.push({ event: domEvent, handler });
2217
2700
  }
2218
- catch { /* ignore */ }
2701
+ this.visibilityHandler = () => {
2702
+ if (this.destroyed)
2703
+ return;
2704
+ const type = document.hidden ? SIMID_PLAYER.APP_BACKGROUNDED : SIMID_PLAYER.APP_FOREGROUNDED;
2705
+ try {
2706
+ this.postMsg({
2707
+ type,
2708
+ messageId: this.nextMsgId(),
2709
+ sessionId: this.sessionId || undefined,
2710
+ timestamp: Date.now(),
2711
+ args: {},
2712
+ });
2713
+ }
2714
+ catch {
2715
+ /* ignore */
2716
+ }
2717
+ };
2718
+ document.addEventListener('visibilitychange', this.visibilityHandler);
2219
2719
  }
2220
2720
  destroy() {
2221
2721
  if (this.destroyed)
2222
2722
  return;
2223
2723
  this.destroyed = true;
2224
2724
  window.removeEventListener('message', this.messageListener);
2225
- // Reject all pending promises.
2725
+ for (const { event, handler } of this.mediaListeners) {
2726
+ this.adVideo.removeEventListener(event, handler);
2727
+ }
2728
+ this.mediaListeners = [];
2729
+ if (this.visibilityHandler) {
2730
+ document.removeEventListener('visibilitychange', this.visibilityHandler);
2731
+ this.visibilityHandler = null;
2732
+ }
2226
2733
  for (const [, p] of this.pending) {
2227
2734
  p.reject({ errorCode: 900, reason: 'SimidSession destroyed' });
2228
2735
  }
@@ -2295,16 +2802,6 @@ function extendAds(player, plugin) {
2295
2802
  }
2296
2803
 
2297
2804
  class AdsPlugin {
2298
- get dom() {
2299
- if (!this._dom) {
2300
- const overlay = document.createElement('div');
2301
- this._dom = new AdDomManager(overlay, this.cfg, () => this.adVideo, () => this.tracker, () => { });
2302
- }
2303
- return this._dom;
2304
- }
2305
- set dom(v) {
2306
- this._dom = v;
2307
- }
2308
2805
  constructor(config = {}) {
2309
2806
  Object.defineProperty(this, "name", {
2310
2807
  enumerable: true,
@@ -2522,6 +3019,7 @@ class AdsPlugin {
2522
3019
  companionSelector: config.companionSelector,
2523
3020
  adSourcesMode: config.adSourcesMode ?? 'waterfall',
2524
3021
  omid: config.omid ?? {},
3022
+ labels: config.labels ?? {},
2525
3023
  };
2526
3024
  }
2527
3025
  setup(ctx) {
@@ -2604,6 +3102,16 @@ class AdsPlugin {
2604
3102
  this.dom.ensureOverlayMounted(this.ctx.core.media);
2605
3103
  this.dom.mountSimidIframe(simidUrl);
2606
3104
  }
3105
+ get dom() {
3106
+ if (!this._dom) {
3107
+ const overlay = document.createElement('div');
3108
+ this._dom = new AdDomManager(overlay, this.cfg, () => this.adVideo, () => this.tracker, () => { });
3109
+ }
3110
+ return this._dom;
3111
+ }
3112
+ set dom(v) {
3113
+ this._dom = v;
3114
+ }
2607
3115
  // ─── Preroll interception ─────────────────────────────────────────────────────
2608
3116
  bindPrerollInterceptors() {
2609
3117
  const { events, core } = this.ctx;
@@ -2958,6 +3466,14 @@ class AdsPlugin {
2958
3466
  const simidUrl = extractSimidUrl(item.creative, rawDoc);
2959
3467
  if (simidUrl && this.adVideo) {
2960
3468
  const iframe = this.dom.mountSimidIframe(simidUrl);
3469
+ const clickThruRaw = item.creative?.videoClickThroughURLTemplate?.url ??
3470
+ item.creative?.videoClickThroughURLTemplate ??
3471
+ item.creative?.videoClicks?.clickThrough ??
3472
+ '';
3473
+ const simidCreativeInfo = {
3474
+ adParameters: String(item.creative?.linear?.adParameters?.value ?? item.creative?.adParameters?.value ?? ''),
3475
+ clickThruUri: typeof clickThruRaw === 'string' ? clickThruRaw : String(clickThruRaw || ''),
3476
+ };
2961
3477
  this.simidSession = new SimidSession(iframe, this.adVideo, {
2962
3478
  onSkip: () => this.requestSkip('api'),
2963
3479
  onStop: () => {
@@ -2992,7 +3508,15 @@ class AdsPlugin {
2992
3508
  this.simidSession?.destroy();
2993
3509
  this.simidSession = undefined;
2994
3510
  },
2995
- });
3511
+ onRequestChangeAdDuration: (durationChange, resolve, _reject) => {
3512
+ // Accept the request; notify the creative of the new total duration.
3513
+ resolve();
3514
+ const v = this.adVideo;
3515
+ if (v && Number.isFinite(v.duration)) {
3516
+ this.simidSession?.adDurationChange(v.duration + durationChange);
3517
+ }
3518
+ },
3519
+ }, simidCreativeInfo);
2996
3520
  this.sessionUnsubs.push(() => {
2997
3521
  this.simidSession?.destroy();
2998
3522
  this.simidSession = undefined;
@@ -3010,6 +3534,9 @@ class AdsPlugin {
3010
3534
  }
3011
3535
  this.bus.emit('ads:allAdsCompleted', { break: meta });
3012
3536
  this.ctx.events.emit('ads.allAdsCompleted', { break: meta });
3537
+ const announcer = this.overlay && this.overlay.querySelector('.op-ads__sr-announcer');
3538
+ if (announcer)
3539
+ announcer.textContent = this.cfg.labels?.adEnded || 'Advertisement ended';
3013
3540
  this.finish({
3014
3541
  resume: meta.kind !== 'postroll' && (this.userPlayIntent || this.resumeAfter),
3015
3542
  suppressResume: opts?.suppressResumeOnSuccess,
@@ -3032,6 +3559,15 @@ class AdsPlugin {
3032
3559
  this.overlay.replaceChildren();
3033
3560
  this.overlay.style.display = 'block';
3034
3561
  this.active = true;
3562
+ if (!this.overlay.querySelector('.op-ads__sr-announcer')) {
3563
+ const announcer = document.createElement('div');
3564
+ announcer.className = 'op-ads__sr-announcer op-player__sr-only';
3565
+ announcer.setAttribute('role', 'status');
3566
+ announcer.setAttribute('aria-live', 'polite');
3567
+ announcer.setAttribute('aria-atomic', 'true');
3568
+ announcer.textContent = this.cfg.labels?.advertisement || 'Advertisement';
3569
+ this.overlay.appendChild(announcer);
3570
+ }
3035
3571
  const items = collectNonLinearCreatives(parsed);
3036
3572
  if (!items.length)
3037
3573
  return;