@action-x/ad-sdk 0.1.5 → 0.1.7
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.cjs +30 -34
- package/dist/index.d.ts +19 -8
- package/dist/index.js +287 -249
- package/dist/index.umd.js +22 -26
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,57 +1,53 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class
|
|
2
|
-
src="${
|
|
3
|
-
alt="${
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class R{constructor(){this.events={}}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)}off(e,t){if(!this.events[e])return;const i=this.events[e].indexOf(t);i>-1&&this.events[e].splice(i,1)}emit(e,...t){this.events[e]&&this.events[e].forEach(i=>{try{i(...t)}catch(s){console.error(`[EventEmitter] Error in event handler for "${e}":`,s)}})}removeAllListeners(e){e?delete this.events[e]:this.events={}}listenerCount(e){var t;return((t=this.events[e])==null?void 0:t.length)||0}}class w{static getClickUrl(e){return e.tracking.clickUrl||e.tracking.click_url||"#"}static getImpressionUrl(e){return e.tracking.impressionUrl||e.tracking.impression_url||""}static getCtaText(e){return e.adapted.ctaText||e.adapted.cta_text||"Learn More"}static renderActionCard(e,t={}){var f;const{variant:i="horizontal",includeWrapper:s=!0}=t,n=e.adapted,o=this.getClickUrl(e),a=this.getImpressionUrl(e),c=s?`<div class="ax-ad-card ax-ad-card-${i}" data-ad-id="${e.original.id}">`:"",l=(f=n.image)!=null&&f.url?`<img
|
|
2
|
+
src="${n.image.url}"
|
|
3
|
+
alt="${n.title}"
|
|
4
4
|
class="ax-ad-image"
|
|
5
5
|
loading="lazy"
|
|
6
|
-
/>`:"",d=
|
|
7
|
-
|
|
8
|
-
</div>`:"",u=s.brand?`<span class="ax-ad-brand">${s.brand}</span>`:"",f=`
|
|
9
|
-
${c}
|
|
6
|
+
/>`:"",d=(n.brand||"").trim(),u=d&&d.toLowerCase()!=="unknown"?`<span class="ax-ad-brand">${n.brand}</span>`:"",h=`
|
|
7
|
+
${l}
|
|
10
8
|
<div class="ax-ad-content">
|
|
11
9
|
${u}
|
|
12
|
-
<h3 class="ax-ad-title">${
|
|
13
|
-
${
|
|
14
|
-
${l}
|
|
10
|
+
<h3 class="ax-ad-title">${n.title}</h3>
|
|
11
|
+
${n.body?`<p class="ax-ad-body">${n.body}</p>`:""}
|
|
15
12
|
<div class="ax-ad-footer">
|
|
16
|
-
${d}
|
|
17
13
|
<a
|
|
18
|
-
href="${
|
|
14
|
+
href="${o}"
|
|
19
15
|
class="ax-ad-cta"
|
|
20
16
|
target="_blank"
|
|
21
17
|
rel="sponsored noopener noreferrer"
|
|
22
18
|
data-ad-id="${e.original.id}"
|
|
23
|
-
data-impression-url="${
|
|
19
|
+
data-impression-url="${a}"
|
|
24
20
|
>
|
|
25
|
-
${
|
|
21
|
+
${this.getCtaText(e)}
|
|
26
22
|
</a>
|
|
27
23
|
</div>
|
|
28
24
|
</div>
|
|
29
|
-
`,p=
|
|
25
|
+
`,p=s?"</div>":"";return c+h+p}static renderSuffixAd(e){const t=e.adapted,i=this.getClickUrl(e),s=this.getImpressionUrl(e);return`
|
|
30
26
|
<div class="ax-ad-suffix" data-ad-id="${e.original.id}">
|
|
31
27
|
<div class="ax-ad-suffix-content">
|
|
32
28
|
${t.title?`<h4 class="ax-ad-suffix-title">${t.title}</h4>`:""}
|
|
33
29
|
${t.body?`<p class="ax-ad-suffix-body">${t.body}</p>`:""}
|
|
34
30
|
<a
|
|
35
|
-
href="${i
|
|
31
|
+
href="${i}"
|
|
36
32
|
class="ax-ad-suffix-link"
|
|
37
33
|
target="_blank"
|
|
38
34
|
rel="sponsored noopener noreferrer"
|
|
39
35
|
data-ad-id="${e.original.id}"
|
|
40
|
-
data-impression-url="${
|
|
36
|
+
data-impression-url="${s}"
|
|
41
37
|
>
|
|
42
|
-
${
|
|
38
|
+
${this.getCtaText(e)}
|
|
43
39
|
</a>
|
|
44
40
|
</div>
|
|
45
41
|
</div>
|
|
46
|
-
`}static renderSponsoredSource(e){var n;const t=e.adapted,i=e.
|
|
42
|
+
`}static renderSponsoredSource(e){var n;const t=e.adapted,i=this.getClickUrl(e),s=this.getImpressionUrl(e);return`
|
|
47
43
|
<div class="ax-ad-source" data-ad-id="${e.original.id}">
|
|
48
44
|
<a
|
|
49
|
-
href="${i
|
|
45
|
+
href="${i}"
|
|
50
46
|
class="ax-ad-source-link"
|
|
51
47
|
target="_blank"
|
|
52
48
|
rel="sponsored noopener noreferrer"
|
|
53
49
|
data-ad-id="${e.original.id}"
|
|
54
|
-
data-impression-url="${
|
|
50
|
+
data-impression-url="${s}"
|
|
55
51
|
>
|
|
56
52
|
${(n=t.image)!=null&&n.url?`<img src="${t.image.url}" alt="" class="ax-ad-source-icon" />`:""}
|
|
57
53
|
<div class="ax-ad-source-info">
|
|
@@ -61,25 +57,25 @@
|
|
|
61
57
|
<span class="ax-ad-source-badge">Sponsored</span>
|
|
62
58
|
</a>
|
|
63
59
|
</div>
|
|
64
|
-
`}static renderLeadGenAd(e){const t=e.adapted,i=e.
|
|
60
|
+
`}static renderLeadGenAd(e){const t=e.adapted,i=this.getClickUrl(e),s=this.getImpressionUrl(e);return`
|
|
65
61
|
<div class="ax-ad-leadgen" data-ad-id="${e.original.id}">
|
|
66
62
|
<div class="ax-ad-leadgen-content">
|
|
67
63
|
${t.title?`<h3 class="ax-ad-leadgen-title">${t.title}</h3>`:""}
|
|
68
64
|
${t.body?`<p class="ax-ad-leadgen-body">${t.body}</p>`:""}
|
|
69
65
|
<a
|
|
70
|
-
href="${i
|
|
66
|
+
href="${i}"
|
|
71
67
|
class="ax-ad-leadgen-cta"
|
|
72
68
|
target="_blank"
|
|
73
69
|
rel="sponsored noopener noreferrer"
|
|
74
70
|
data-ad-id="${e.original.id}"
|
|
75
|
-
data-impression-url="${
|
|
71
|
+
data-impression-url="${s}"
|
|
76
72
|
>
|
|
77
|
-
${
|
|
73
|
+
${this.getCtaText(e)}
|
|
78
74
|
</a>
|
|
79
75
|
</div>
|
|
80
76
|
</div>
|
|
81
|
-
`}static renderAds(e,t=
|
|
82
|
-
`)}}const K="ad_session_id";function
|
|
77
|
+
`}static renderAds(e,t=w.renderActionCard.bind(w)){return e.map(t).join(`
|
|
78
|
+
`)}}const K="ad_session_id";function N(){if(typeof window<"u"){const r=window.__AD_CONFIG__;if(r!=null&&r.apiKey)return r.apiKey}}function D(){var r;return typeof window<"u"?!!((r=window.__AD_CONFIG__)!=null&&r.debug):!1}function _(r){if(r)return r;if(typeof window<"u"){const e=window.__AD_CONFIG__;if(e!=null&&e.apiBaseUrl)return e.apiBaseUrl}return"/api/v1"}class U{constructor(e={}){this.memoryCache=new Map,this.sessionKey=e.sessionKey||K,this.storage=e.storage||"sessionStorage",(typeof window>"u"||typeof window.sessionStorage>"u")&&(this.storage="memory")}getSessionId(){if(this.storage==="sessionStorage"){let e=sessionStorage.getItem(this.sessionKey);return e||(e=this.generateSessionId(),sessionStorage.setItem(this.sessionKey,e)),e}else{let e=this.memoryCache.get(this.sessionKey);return e||(e=this.generateSessionId(),this.memoryCache.set(this.sessionKey,e)),e}}regenerateSessionId(){const e=this.generateSessionId();return this.storage==="sessionStorage"?sessionStorage.setItem(this.sessionKey,e):this.memoryCache.set(this.sessionKey,e),e}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}clearSessionId(){this.storage==="sessionStorage"?sessionStorage.removeItem(this.sessionKey):this.memoryCache.delete(this.sessionKey)}}const H=new U,m=()=>H.getSessionId();class v{constructor(e={}){this.explicitBaseUrl=e.baseUrl,this.timeout=e.timeout||1e4,this.retryAttempts=e.retryAttempts??2,this.retryDelay=e.retryDelay||1e3,this.debug=e.debug||!1}async trackImpression(e){return this.sendRequest(`${_(this.explicitBaseUrl)}/ads/impression`,e,"impression")}async trackClick(e){return this.sendRequest(`${_(this.explicitBaseUrl)}/ads/click`,e,"click")}async sendRequest(e,t,i){let s=null;for(let n=0;n<=this.retryAttempts;n++){const o=this.debug||D();try{o&&(console.log(`[Analytics] Request URL (${i}):`,e),console.log(`[Analytics] Sending ${i} event (attempt ${n+1}):`,t));const a=new AbortController,c=setTimeout(()=>a.abort(),this.timeout),l={"Content-Type":"application/json"},d=N();d&&(l["X-API-Key"]=d,o&&console.log(`[Analytics] Adding X-API-Key header for ${i} event`));const u=await fetch(e,{method:"POST",headers:l,body:JSON.stringify(t),keepalive:!0,signal:a.signal});if(clearTimeout(c),!u.ok)throw new Error(`HTTP ${u.status}: ${u.statusText}`);const h=await u.json();return o&&console.log(`[Analytics] ${i} event tracked successfully:`,h),h}catch(a){s=a,o&&console.warn(`[Analytics] ${i} tracking failed (attempt ${n+1}):`,a),n<this.retryAttempts&&await this.delay(this.retryDelay*(n+1))}}return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts+1} attempts:`,s),null}delay(e){return new Promise(t=>setTimeout(t,e))}}const O=new v,A=(r,e)=>e!=null&&e.baseUrl?new v({baseUrl:e.baseUrl}).trackImpression(r):O.trackImpression(r),I=(r,e)=>e!=null&&e.baseUrl?new v({baseUrl:e.baseUrl}).trackClick(r):O.trackClick(r);function F(r,e){return`vt_${r}_${e}`}async function G(r){return Promise.all(r.map(e=>A(e)))}async function j(r){return Promise.all(r.map(e=>I(e)))}function z(r){const e=new v(r);return{trackImpression:t=>e.trackImpression(t),trackClick:t=>e.trackClick(t)}}function W(r={}){const e=new U(r);return{getSessionId:()=>e.getSessionId(),regenerateSessionId:()=>e.regenerateSessionId(),clearSessionId:()=>e.clearSessionId()}}const M=class M{static isDebugEnabled(){var e;return typeof window<"u"?!!((e=window.__AD_CONFIG__)!=null&&e.debug):!1}static getClickUrl(e){return e.tracking.clickUrl||e.tracking.click_url||""}static getViewToken(e){return e.tracking.viewToken||e.tracking.view_token}static renderActionCard(e,t,i={}){t.innerHTML=w.renderActionCard(e,i);const s=t.querySelector(".ax-ad-cta");return s&&s.addEventListener("click",n=>{n.preventDefault(),this.handleClick(e,i)}),this.trackImpression(e,t,i),t}static renderSuffixAd(e,t,i={}){const s=i.variant||"block";t.innerHTML=this.generateSuffixAdHTML(e,s);const n=t.querySelector(".ax-ad-suffix-link");return n&&n.addEventListener("click",o=>{o.preventDefault(),this.handleClick(e,i)}),this.trackImpression(e,t,i),t}static renderSponsoredSource(e,t,i={}){const s=i.variant||"card";t.innerHTML=this.generateSponsoredSourceHTML(e,s);const n=t.querySelector(".ax-ad-source-link");return n&&n.addEventListener("click",o=>{o.preventDefault(),this.handleClick(e,i)}),this.trackImpression(e,t,i),t}static renderLeadGenAd(e,t,i={}){t.innerHTML=w.renderLeadGenAd(e);const s=t.querySelector(".ax-ad-leadgen-cta");return s&&s.addEventListener("click",n=>{n.preventDefault(),this.handleClick(e,i)}),this.trackImpression(e,t,i),t}static renderAds(e,t,i=this.renderActionCard.bind(this),s){t.innerHTML="";const n=document.createElement("div");return n.className="ax-ads-container",e.forEach(o=>{const a=document.createElement("div");a.className="ax-ad-wrapper",i.call(this,o,a,s),n.appendChild(a)}),t.appendChild(n),t}static handleClick(e,t){const{analytics:i,onClick:s}=t,n=this.getClickUrl(e);if(!n){console.warn("[DOMRenderer] Missing click url for ad:",e.original.id);return}s&&s(e),i&&I({requestId:i.requestId,adId:e.original.id,destinationUrl:n,slotId:i.slotId,sessionId:m(),adTitle:e.adapted.title,format:e.original.type,userId:i.userId},{baseUrl:i.apiBaseUrl}).catch(o=>{console.error("[DOMRenderer] Analytics click tracking failed:",o)}),this.isDebugEnabled()&&console.log("[DOMRenderer] Redirect URL:",n),window.open(n,"_blank","noopener,noreferrer")}static trackImpression(e,t,i){const{analytics:s,onImpression:n}=i,o=s?`${s.requestId}:${s.slotId}:${e.original.id}:${this.getViewToken(e)||""}`:`no-analytics:${e.original.id}:${this.getViewToken(e)||""}`;if(this.trackedImpressionKeys.has(o))return;let a=!1;const c=()=>{a||this.trackedImpressionKeys.has(o)||(a=!0,this.trackedImpressionKeys.add(o),l())},l=()=>{s?A({requestId:s.requestId,adId:e.original.id,slotId:s.slotId,position:s.position,totalAds:s.totalAds,sessionId:m(),adTitle:e.adapted.title,format:e.original.type,source:"internal",viewToken:this.getViewToken(e),userId:s.userId},{baseUrl:s.apiBaseUrl}).then(()=>{n&&n(e)}).catch(d=>{console.error("[DOMRenderer] Analytics impression tracking failed:",d)}):n&&n(e)};if(typeof IntersectionObserver<"u"){let d=!1,u=null;const h=new IntersectionObserver(f=>{f.forEach(k=>{d=k.isIntersecting&&k.intersectionRatio>=.5,d?u||(u=setTimeout(()=>{u=null,d&&(c(),h.disconnect())},1e3)):u&&(clearTimeout(u),u=null)})},{threshold:.5}),p=t.querySelector(`[data-ad-id="${e.original.id}"]`)||t;h.observe(p)}else c()}static generateSuffixAdHTML(e,t){const i=e.adapted.title||"",s=e.adapted.body||"";return t==="inline"?`
|
|
83
79
|
<span class="ax-ad-suffix-link ax-ad-variant-inline" data-ad-id="${e.original.id}">
|
|
84
80
|
${i}
|
|
85
81
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="display:inline;vertical-align:middle;margin-left:4px">
|
|
@@ -101,11 +97,11 @@
|
|
|
101
97
|
</svg>
|
|
102
98
|
</div>
|
|
103
99
|
</div>
|
|
104
|
-
${
|
|
100
|
+
${s?`<p class="ax-ad-suffix-body">${s}</p>`:""}
|
|
105
101
|
</div>
|
|
106
|
-
`}static generateSponsoredSourceHTML(e,t){var
|
|
102
|
+
`}static generateSponsoredSourceHTML(e,t){var o;const i=e.adapted.title||"",s=e.adapted.body||"",n=((o=e.adapted.image)==null?void 0:o.url)||"";return t==="list-item"?`
|
|
107
103
|
<div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
|
|
108
|
-
${
|
|
104
|
+
${n?`<img src="${n}" alt="${i}" loading="lazy" />`:""}
|
|
109
105
|
<div class="ax-ad-source-info">
|
|
110
106
|
<span class="ax-ad-source-name">${i}</span>
|
|
111
107
|
<span class="ax-ad-sponsored-badge" style="font-size:9px">Ad</span>
|
|
@@ -117,23 +113,23 @@
|
|
|
117
113
|
`:t==="minimal"?`
|
|
118
114
|
<div data-ad-id="${e.original.id}" style="display:inline-flex">
|
|
119
115
|
<a class="ax-ad-source-link ax-ad-variant-minimal">
|
|
120
|
-
${
|
|
116
|
+
${n?`<img src="${n}" alt="${i}" loading="lazy" style="width:16px;height:16px;border-radius:2px;object-fit:cover" />`:""}
|
|
121
117
|
<span>${i}</span>
|
|
122
118
|
<span class="ax-ad-sponsored-badge" style="font-size:9px">Ad</span>
|
|
123
119
|
</a>
|
|
124
120
|
</div>
|
|
125
121
|
`:`
|
|
126
122
|
<div class="ax-ad-source ax-ad-variant-card" data-ad-id="${e.original.id}">
|
|
127
|
-
${
|
|
123
|
+
${n?`<img src="${n}" alt="${i}" loading="lazy" style="width:48px;height:48px;border-radius:6px;object-fit:cover;flex-shrink:0" />`:""}
|
|
128
124
|
<div class="ax-ad-source-info">
|
|
129
125
|
<div style="display:flex;align-items:center;gap:8px;margin-bottom:4px">
|
|
130
126
|
<span class="ax-ad-source-name">${i}</span>
|
|
131
127
|
<span class="ax-ad-sponsored-badge">Sponsored</span>
|
|
132
128
|
</div>
|
|
133
|
-
${
|
|
129
|
+
${s?`<p class="ax-ad-source-desc">${s}</p>`:""}
|
|
134
130
|
</div>
|
|
135
131
|
<svg width="16" height="16" fill="none" stroke="#d1d5db" viewBox="0 0 24 24" style="flex-shrink:0">
|
|
136
132
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
137
133
|
</svg>
|
|
138
134
|
</div>
|
|
139
|
-
`}};U.trackedImpressionKeys=new Set;let y=U;class T{constructor(){this.cachedStaticInfo=null,this.cacheTimestamp=0,this.CACHE_TTL=36e5}inferAppInfo(){if(typeof window>"u")return{bundle:"unknown",ver:"1.0.0",name:"Unknown App",publisher:{id:"unknown"}};const e=this.inferBundle(),t=this.inferAppName(),i=this.inferAppVersion(),n=this.inferPublisherId();return{bundle:e,ver:i,name:t,publisher:{id:n,domain:window.location.hostname}}}inferBundle(){var t;if(typeof window>"u")return"unknown";const e=(t=window.location)==null?void 0:t.hostname;return e?e.replace(/^www\./,"").replace(/:\d+$/,""):"unknown"}inferAppName(){var n,s;if(typeof document>"u")return"Unknown App";const e=document.title;if(e&&e!=="Loading..."&&e.length<100)return e;const t=(n=document.querySelector('meta[property="og:title"]'))==null?void 0:n.getAttribute("content");if(t)return t;const i=(s=document.querySelector('meta[name="application-name"]'))==null?void 0:s.getAttribute("content");return i||"Unknown App"}inferAppVersion(){if(typeof document>"u")return"1.0.0";const e=['meta[name="version"]','meta[name="app-version"]','meta[name="application-version"]','link[rel="manifest"]'];for(const t of e){const i=document.querySelector(t);if(i){if(t.includes("manifest"))return"1.0.0";const n=i.getAttribute("content");if(n)return n}}return"1.0.0"}inferPublisherId(){var i,n;if(typeof document>"u")return"unknown";const e=(i=document.querySelector('meta[name="publisher-id"]'))==null?void 0:i.getAttribute("content");if(e)return e;const t=(n=window.location)==null?void 0:n.hostname;return t?t.replace(/\./g,"_"):"unknown"}static getInstance(){return this.instance||(this.instance=new T),this.instance}collect(e){const t=Date.now();(!this.cachedStaticInfo||t-this.cacheTimestamp>this.CACHE_TTL)&&(this.cachedStaticInfo=this.collectStaticInfo(),this.cacheTimestamp=t);const i=this.collectDynamicInfo();return{device:{ua:this.cachedStaticInfo.ua,os:this.cachedStaticInfo.os,osv:this.cachedStaticInfo.osv,devicetype:this.cachedStaticInfo.devicetype,model:this.cachedStaticInfo.model,make:this.cachedStaticInfo.make,language:this.cachedStaticInfo.language,connectiontype:i.connectiontype??0,bandwidth:i.bandwidth,...(e==null?void 0:e.device)||{}},app:{...this.inferAppInfo(),...(e==null?void 0:e.app)||{}},user:{...this.collectUserInfo(),...(e==null?void 0:e.user)||{}},geo:{...this.collectGeoInfo(),...(e==null?void 0:e.geo)||{}},timestamp:t}}collectStaticInfo(){if(typeof navigator>"u")return this.getFallbackInfo();const e=navigator.userAgent,t=this.detectOS(e),i=this.detectOSVersion(e);return{ua:e,os:t,osv:i,devicetype:this.detectDeviceType(e),model:this.detectModel(e),make:this.detectMake(e),language:navigator.language||"en-US"}}collectDynamicInfo(){if(typeof navigator>"u")return{connectiontype:0};const e=this.getConnectionInfo();return{connectiontype:(e==null?void 0:e.type)||0,bandwidth:e==null?void 0:e.downlink}}collectUserInfo(){let e;try{e=localStorage.getItem("chatbox_user_id")||"",e||(e=this.generateUUID(),localStorage.setItem("chatbox_user_id",e))}catch{e=this.generateUUID()}return{id:e,language:(navigator==null?void 0:navigator.language)||"en-US"}}collectGeoInfo(){if(typeof navigator>"u"||typeof Intl>"u")return{};const e=Intl.DateTimeFormat().resolvedOptions().timeZone,t=navigator.language;return{country:this.inferCountry(t,e),timezone:e}}detectOS(e){return e?/iPad|iPhone|iPod/.test(e)?"iOS":/Android/.test(e)?"Android":/Windows/.test(e)?"Windows":/Macintosh|Mac OS/.test(e)?"macOS":/Linux/.test(e)?"Linux":/CrOS/.test(e)?"Chrome OS":"Unknown":"Unknown"}detectOSVersion(e){if(!e)return"Unknown";const t=e.match(/OS (\d+)_(\d+)_?(\d+)?/);if(t)return`${t[1]}.${t[2]}${t[3]?"."+t[3]:""}`;const i=e.match(/Android (\d+)\.(\d+)/);if(i)return`${i[1]}.${i[2]}`;const n=e.match(/Windows NT (\d+\.\d+)/);if(n)return n[1];const s=e.match(/Mac OS X (\d+[._]\d+)/);return s?s[1].replace("_","."):"Unknown"}detectDeviceType(e){return e?/iPad|Tablet/i.test(e)||/Android/.test(e)&&!/Mobile/.test(e)?2:/iPhone|iPod|Mobile|Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test(e)?1:/Windows|Macintosh|Linux|x86_64/i.test(e)?3:/SmartTV|TV|WebTV|GoogleTV|AppleTV/i.test(e)?4:0:0}detectModel(e){if(!e)return;const t=e.match(/iPhone(?:;\s*[^\)]*)?\s*(\d+,\d)?/);if(t)return`iPhone${t[1]||""}`;if(/iPad/.test(e))return"iPad";const i=e.match(/Samsung-.*(SM-\w+)/);if(i)return i[1];if(/Pixel/.test(e))return"Google Pixel";const n=e.match(/(BARC-|HUAWEI-)?([A-Z]{2}\-\w{4})/);if(n)return n[2];const s=e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);if(s)return s[1]+" "+s[2];if(/OnePlus/.test(e)){const r=e.match(/OnePlus\s([A-Z\d]+)/);return r?"OnePlus "+r[1]:"OnePlus"}}detectMake(e){if(e){if(/iPad|iPhone|iPod/.test(e))return"Apple";if(/Samsung/.test(e))return"Samsung";if(/Pixel/.test(e))return"Google";if(/Huawei|HONOR/.test(e))return"Huawei";if(/Xiaomi|Redmi|POCO/.test(e))return"Xiaomi";if(/OnePlus/.test(e))return"OnePlus";if(/Sony/.test(e))return"Sony";if(/LG/.test(e))return"LG";if(/Motorola|Moto/.test(e))return"Motorola";if(/Nokia/.test(e))return"Nokia";if(/HTC/.test(e))return"HTC";if(/OPPO/.test(e))return"OPPO";if(/vivo/.test(e))return"vivo";if(/Realme/.test(e))return"Realme"}}getConnectionInfo(){if(typeof navigator>"u")return null;const e=navigator,t=e.connection||e.mozConnection||e.webkitConnection;return t?{type:this.mapConnectionType(t.effectiveType),downlink:t.downlink,rtt:t.rtt}:null}mapConnectionType(e){if(!e)return 0;switch(e.toLowerCase()){case"slow-2g":case"2g":return 3;case"3g":return 4;case"4g":return 5;default:return 0}}inferCountry(e,t){if(!e&&!t)return;const i={"Asia/Shanghai":"CN","Asia/Hong_Kong":"HK","Asia/Taipei":"TW","Asia/Tokyo":"JP","Asia/Seoul":"KR","Asia/Singapore":"SG","Asia/Dubai":"AE","Asia/Kolkata":"IN","Asia/Jakarta":"ID","Asia/Manila":"PH","Asia/Bangkok":"TH","Asia/Kuala_Lumpur":"MY","America/New_York":"US","America/Chicago":"US","America/Denver":"US","America/Los_Angeles":"US","America/Toronto":"CA","America/Vancouver":"CA","America/Mexico_City":"MX","America/Sao_Paulo":"BR","America/Buenos_Aires":"AR","Europe/London":"GB","Europe/Paris":"FR","Europe/Berlin":"DE","Europe/Madrid":"ES","Europe/Rome":"IT","Europe/Amsterdam":"NL","Europe/Brussels":"BE","Europe/Zurich":"CH","Europe/Vienna":"AT","Europe/Stockholm":"SE","Europe/Oslo":"NO","Europe/Copenhagen":"DK","Europe/Helsinki":"FI","Europe/Dublin":"IE","Europe/Lisbon":"PT","Europe/Athens":"GR","Europe/Prague":"CZ","Europe/Warsaw":"PL","Europe/Budapest":"HU","Europe/Bucharest":"RO","Australia/Sydney":"AU","Pacific/Auckland":"NZ"};if(t&&i[t])return i[t];if(e){const n=e.split("-")[1];if(n)return n.toUpperCase()}}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}getFallbackInfo(){return{ua:"Unknown",os:"Unknown",osv:"Unknown",devicetype:0,language:"en-US"}}clearCache(){this.cachedStaticInfo=null,this.cacheTimestamp=0}}const I=()=>T.getInstance();function b(o){return I().collect(o)}function z(){return b().device}function B(){return b().user}function W(){return b().app}function Q(){return b().geo}function J(){return B().id}function X(){I().clearCache()}function Z(o){const e=b(o);return JSON.stringify(e,null,2)}function Y(){var t;const o=b();return[o.device.os,o.device.osv,o.app.name,o.user.id.slice(0,8)+"...",((t=o.geo)==null?void 0:t.country)||"Unknown"].join(" / ")}function ee(o){var e,t;return{id:o.original.id,type:o.original.type,score:o.original.score,source:"internal",content:{title:o.adapted.title,body:o.adapted.body,image:(e=o.adapted.image)==null?void 0:e.url,cta_text:o.adapted.ctaText,price:(t=o.adapted.price)==null?void 0:t.display,rating:o.adapted.rating,brand:o.adapted.brand},tracking:{click_url:o.tracking.clickUrl,impression_url:o.tracking.impressionUrl},metadata:{viewToken:o.tracking.viewToken,styling:o.adapted.styling}}}async function O(o,e={}){const t=e.apiBaseUrl||"/api/v1",n=I().collect(),s={...o,clientInfo:n},r={"Content-Type":"application/json"};e.apiKey&&(r["X-API-Key"]=e.apiKey);const a=await fetch(`${t}/ads/request`,{method:"POST",headers:r,body:JSON.stringify(s)});if(!a.ok)throw new Error(`Ad request failed: ${a.status} ${a.statusText}`);const c=await a.json();if(!c.success)throw new Error(c.error||"Ad request failed");return c.data}const te={width:400,height:200},$={variant:"horizontal",count:1,preferences:{}};function E(o={}){const e={variant:o.variant??$.variant,count:o.count??$.count,preferences:{...$.preferences,...o.preferences}};return[{slotId:"action_card",slotName:"Action Card",format:"action_card",variant:e.variant,size:te,count:e.count,preferences:e.preferences,placement:{position:"below_fold",context:"post_response"}}]}const g=class g{constructor(e){this.slots={},this.isLoading=!1,this.currentRequestId=null,this.adsAnalyticsMap=new Map,this.config=e,this.enabled=e.enabled!==!1,this.eventBus=new L,this.slots_config=E(e.cardOption),typeof window<"u"&&(window.__AD_CONFIG__={...window.__AD_CONFIG__||{},apiKey:e.apiKey,apiBaseUrl:e.apiBaseUrl}),this.config.debug&&console.log("[AdManager] Initialized with config:",{apiBaseUrl:e.apiBaseUrl,hasApiKey:!!e.apiKey,enabled:this.enabled})}async requestAds(e){const t="conversationContext"in e?e:{conversationContext:e},i=this.buildRequestKey(t),n=g.inFlightRequests.get(i);if(n)return this.config.debug&&console.log("[AdManager] Reusing in-flight request for identical context"),n;if(!this.enabled)throw this.config.debug&&console.warn("[AdManager] Ads are disabled, skipping request"),new Error("Ads are disabled");if(this.isLoading)throw this.config.debug&&console.warn("[AdManager] Request already in progress"),new Error("Request already in progress");this.isLoading=!0,this.eventBus.emit("adsLoading"),this.config.debug&&console.log("[AdManager] Starting ad request...");const s=(async()=>{try{const r=await O({conversationContext:t.conversationContext,userContext:t.userContext?{...t.userContext,sessionId:t.userContext.sessionId??m()}:{sessionId:m()},slots:this.slots_config},{apiBaseUrl:this.config.apiBaseUrl,apiKey:this.config.apiKey});this.currentRequestId=r.requestId,this.adsAnalyticsMap.clear(),r.slots.forEach(c=>{c.ads.forEach((d,l)=>{const u=d.original.id;this.adsAnalyticsMap.set(u,{requestId:r.requestId,slotId:c.slotId,position:l,totalAds:c.ads.length,apiBaseUrl:this.config.apiBaseUrl})})});const a={};return r.slots.forEach(c=>{a[c.slotId]=c}),this.slots=a,this.eventBus.emit("adsUpdated",this.slots),this.config.debug&&console.log("[AdManager] Ads received:",{slotCount:Object.keys(this.slots).length,slots:Object.keys(this.slots)}),r}catch(r){const a=r;throw this.eventBus.emit("adsError",a),a}finally{this.isLoading=!1,g.inFlightRequests.delete(i)}})();return g.inFlightRequests.set(i,s),s}buildRequestKey(e){return JSON.stringify({apiBaseUrl:this.config.apiBaseUrl,apiKey:this.config.apiKey,conversationContext:e.conversationContext,userContext:e.userContext||null,slots:this.slots_config})}render(e,t,i={}){const n=typeof e!="string",s=n?g.DEFAULT_SLOT_ID:e,r=n?e:t,a=(n?t:i)||{};if(!r)return this.config.debug&&console.warn("[AdManager] Render container is required"),null;const c=this.slots[s];if(!c||!c.ads||c.ads.length===0)return this.config.debug&&console.warn("[AdManager] No ads in slot:",s),null;const d=a.adIndex??0,l=c.ads[d];if(!l)return this.config.debug&&console.warn(`[AdManager] Ad at index ${d} not found in slot:`,s),null;const u=this.adsAnalyticsMap.get(l.original.id),f=this.slots_config.find(k=>k.slotId===s),p=(f==null?void 0:f.format)||"action_card";r.innerHTML="";const h={analytics:u,variant:a.variant,onClick:a.onClick,onImpression:a.onImpression};return p==="suffix"?y.renderSuffixAd(l,r,h):p==="source"?y.renderSponsoredSource(l,r,h):p==="lead_gen"?y.renderLeadGenAd(l,r,h):y.renderActionCard(l,r,h)}getSlots(e){return e?this.slots[e]:this.slots}hasAds(e){var i;const t=this.slots[e];return(t==null?void 0:t.status)==="filled"&&((i=t.ads)==null?void 0:i.length)>0}getAds(e){var t;return((t=this.slots[e])==null?void 0:t.ads)||[]}getLoadingStatus(){return this.isLoading}setEnabled(e){this.enabled=e,this.config.debug&&console.log("[AdManager] Ads",e?"enabled":"disabled")}updateConfig(e){this.config={...this.config,...e},e.cardOption!==void 0&&(this.slots_config=E(this.config.cardOption)),this.config.debug&&console.log("[AdManager] Config updated:",e)}clearSlots(){this.slots={},this.currentRequestId=null,this.adsAnalyticsMap.clear(),this.config.debug&&console.log("[AdManager] Slots and analytics cleared")}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}removeAllListeners(e){this.eventBus.removeAllListeners(e)}getCurrentRequestId(){return this.currentRequestId}getAdAnalytics(e){return this.adsAnalyticsMap.get(e)||null}getAdsAnalytics(e){const t=new Map;return e.forEach(i=>{const n=this.adsAnalyticsMap.get(i);n&&t.set(i,n)}),t}async trackAdClick(e,t,i){const n=this.adsAnalyticsMap.get(e);if(!n||!this.currentRequestId)return this.config.debug&&console.warn("[AdManager] No analytics info for ad:",e),null;const s=m(),r=await S({requestId:this.currentRequestId,adId:e,destinationUrl:t,sessionId:s,slotId:n.slotId,adTitle:i==null?void 0:i.title,format:i==null?void 0:i.format,source:i==null?void 0:i.source},{baseUrl:n.apiBaseUrl});return r&&(this.eventBus.emit("adClicked",e,n.slotId),this.config.debug&&console.log("[AdManager] Click tracked via Analytics API:",r.eventId)),r}async trackAdImpressionAPI(e,t){const i=this.adsAnalyticsMap.get(e);if(!i||!this.currentRequestId)return this.config.debug&&console.warn("[AdManager] No analytics info for ad:",e),null;const n=m(),s=await A({requestId:this.currentRequestId,adId:e,slotId:i.slotId,position:i.position,totalAds:i.totalAds,sessionId:n,adTitle:t==null?void 0:t.title,format:t==null?void 0:t.format,source:t==null?void 0:t.source,viewToken:t==null?void 0:t.viewToken},{baseUrl:i.apiBaseUrl});return s&&(this.eventBus.emit("adImpression",e,i.slotId),this.config.debug&&console.log("[AdManager] Impression tracked via Analytics API:",s.eventId)),s}destroy(){this.removeAllListeners(),this.clearSlots(),this.config.debug&&console.log("[AdManager] Destroyed")}};g.DEFAULT_SLOT_ID="action_card",g.inFlightRequests=new Map;let C=g;function _(){if(typeof window<"u"){const o=window.__AD_CONFIG__;if(o!=null&&o.apiKey)return o.apiKey}}class q{constructor(e={},t="/api/v1"){var i,n;this.observers=new Map,this.metrics=new Map,this.timers=new Map,this.batchTimers=new Map,this.eventQueue=new Map,this.isTracking=new Map,this.config={minVisiblePercentage:e.minVisiblePercentage??50,minViewableDuration:e.minViewableDuration??1e3,maxTrackingDuration:e.maxTrackingDuration??6e4,batchConfig:{maxBatchSize:((i=e.batchConfig)==null?void 0:i.maxBatchSize)??5,maxBatchWaitMs:((n=e.batchConfig)==null?void 0:n.maxBatchWaitMs)??1e4},debug:e.debug??!1},this.baseUrl=t}startTracking(e,t,i,n,s){if(this.isTracking.get(e)){this.log(`[ViewabilityTracker] Already tracking ${e}, skipping`);return}this.log(`[ViewabilityTracker] Starting tracking for ${e}`);const r={visiblePercentage:0,maxVisiblePercentage:0,totalVisibleTimeMs:0,currentVisibleTimeMs:0,isViewable:!1,viewableAt:null,enteredViewportAt:null,enterCount:0};this.metrics.set(e,r),this.isTracking.set(e,!0),this.eventQueue.set(e,[]);const a=new IntersectionObserver(d=>this.handleIntersection(e,d[0],i,n,s),{threshold:this.createThresholds()});a.observe(t),this.observers.set(e,a),this.startMonitoring(e,i,n,s);const c=setTimeout(()=>{this.endTracking(e,i,n,s)},this.config.maxTrackingDuration);this.timers.set(e,c)}stopTracking(e){this.log(`[ViewabilityTracker] Manual stop tracking for ${e}`),this.cleanup(e)}getMetrics(e){return this.metrics.get(e)}handleIntersection(e,t,i,n,s){const r=this.metrics.get(e);if(!r||!this.isTracking.get(e))return;const a=r.isViewable,c=Math.round(t.intersectionRatio*100);r.visiblePercentage=c,r.maxVisiblePercentage=Math.max(r.maxVisiblePercentage,c);const d=Date.now(),l=c>=this.config.minVisiblePercentage;if(l&&!r.enteredViewportAt&&(r.enteredViewportAt=d,r.enterCount++,this.log(`[ViewabilityTracker] ${e} entered viewport at ${d}`),this.queueEvent(e,{adId:e,sessionId:i,requestId:n,viewToken:s,eventType:"enter_viewport",visiblePercentage:c,maxVisiblePercentage:r.maxVisiblePercentage,totalVisibleTimeMs:r.totalVisibleTimeMs,isViewable:!1,timestamp:d})),!l&&r.enteredViewportAt){const u=d-r.enteredViewportAt;r.totalVisibleTimeMs+=u,r.enteredViewportAt=null,r.currentVisibleTimeMs=0,this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${r.totalVisibleTimeMs}ms`),this.queueEvent(e,{adId:e,sessionId:i,requestId:n,viewToken:s,eventType:"exit_viewport",visiblePercentage:c,maxVisiblePercentage:r.maxVisiblePercentage,totalVisibleTimeMs:r.totalVisibleTimeMs,isViewable:r.isViewable,timestamp:d})}r.isViewable!==a&&r.isViewable&&this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`),this.metrics.set(e,r)}startMonitoring(e,t,i,n){const r=setInterval(()=>{const a=this.metrics.get(e);if(!a||!this.isTracking.get(e)){clearInterval(r);return}const c=Date.now(),d=a.isViewable;if(a.enteredViewportAt){const l=c-a.enteredViewportAt;a.currentVisibleTimeMs=l,l>=this.config.minViewableDuration&&a.visiblePercentage>=this.config.minVisiblePercentage&&(a.isViewable=!0,d||(a.viewableAt=a.enteredViewportAt,this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`),this.queueEvent(e,{adId:e,sessionId:t,requestId:i,viewToken:n,eventType:"become_viewable",visiblePercentage:a.visiblePercentage,maxVisiblePercentage:a.maxVisiblePercentage,totalVisibleTimeMs:a.totalVisibleTimeMs,isViewable:!0,timestamp:c})))}a.enteredViewportAt&&(a.totalVisibleTimeMs+=100),this.metrics.set(e,a)},100);this.timers.set(`${e}_monitoring`,r)}queueEvent(e,t){var s,r;const i=this.eventQueue.get(e);if(!i){this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);return}i.push(t),this.log(`[ViewabilityTracker] Queued ${t.eventType} for ${e} (queue size: ${i.length})`);const n=((s=this.config.batchConfig)==null?void 0:s.maxBatchSize)??5;if(i.length>=n)this.flushQueue(e);else{const a=this.batchTimers.get(e);a&&clearTimeout(a);const c=((r=this.config.batchConfig)==null?void 0:r.maxBatchWaitMs)??1e4,d=setTimeout(()=>{this.flushQueue(e)},c);this.batchTimers.set(e,d)}}async flushQueue(e){const t=this.eventQueue.get(e);if(!t||t.length===0)return;const i=[...t];t.length=0,this.log(`[ViewabilityTracker] Flushing ${i.length} events for ${e}`);try{const n={"Content-Type":"application/json"},s=_();s&&(n["x-api-key"]=s),await fetch(`${this.baseUrl}/ads/viewability/batch`,{method:"POST",headers:n,body:JSON.stringify({events:i})}),this.log(`[ViewabilityTracker] Successfully sent ${i.length} events for ${e}`)}catch(n){this.log(`[ViewabilityTracker] Failed to send events for ${e}:`,n),t.unshift(...i)}}endTracking(e,t,i,n){const s=this.metrics.get(e);if(!s)return;this.log(`[ViewabilityTracker] Ending tracking for ${e}`),this.flushQueue(e);const r=Date.now();this.queueEvent(e,{adId:e,sessionId:t,requestId:i,viewToken:n,eventType:"end_tracking",visiblePercentage:s.visiblePercentage,maxVisiblePercentage:s.maxVisiblePercentage,totalVisibleTimeMs:s.totalVisibleTimeMs,isViewable:s.isViewable,timestamp:r}),this.flushQueue(e),this.cleanup(e)}cleanup(e){const t=this.observers.get(e);t&&(t.disconnect(),this.observers.delete(e));const i=this.timers.get(e);i&&(clearTimeout(i),this.timers.delete(e));const n=this.timers.get(`${e}_monitoring`);n&&(clearInterval(n),this.timers.delete(`${e}_monitoring`));const s=this.batchTimers.get(e);s&&(clearTimeout(s),this.batchTimers.delete(e)),this.flushQueue(e),this.isTracking.delete(e),this.metrics.delete(e),this.eventQueue.delete(e)}createThresholds(){return[0,.25,.5,.75,.9,1]}stopAll(){const e=Array.from(this.isTracking.keys());for(const t of e)this.cleanup(t)}log(...e){this.config.debug&&console.log(...e)}setupBeforeUnload(){typeof window<"u"&&window.addEventListener("beforeunload",()=>{for(const e of this.eventQueue.keys()){const t=this.eventQueue.get(e);if(t&&t.length>0){const i={"Content-Type":"application/json"},n=_();n&&(i["x-api-key"]=n),fetch(`${this.baseUrl}/ads/viewability/batch`,{method:"POST",headers:i,keepalive:!0,body:JSON.stringify({events:t})})}}})}}let x=null;function ie(o,e){return x||(x=new q(o,e),x.setupBeforeUnload()),x}const ne="0.1.0";exports.AdManager=C;exports.AnalyticsSender=w;exports.ClientInfoCollector=T;exports.DOMRenderer=y;exports.HTMLRenderer=v;exports.SDK_VERSION=ne;exports.SessionManager=M;exports.ViewabilityTracker=q;exports.adaptAdToKoahAd=ee;exports.clearClientInfoCache=X;exports.createAnalytics=F;exports.createSession=j;exports.fetchAds=O;exports.generateViewToken=H;exports.getAppInfo=W;exports.getClientInfo=b;exports.getClientInfoCollector=I;exports.getClientInfoJSON=Z;exports.getClientInfoSummary=Y;exports.getDeviceInfo=z;exports.getGeoInfo=Q;exports.getSessionId=m;exports.getUserId=J;exports.getUserInfo=B;exports.getViewabilityTracker=ie;exports.trackAdClick=S;exports.trackAdImpression=A;exports.trackClicksBatch=G;exports.trackImpressionsBatch=D;
|
|
135
|
+
`}};M.trackedImpressionKeys=new Set;let y=M;class S{constructor(){this.cachedStaticInfo=null,this.cacheTimestamp=0,this.CACHE_TTL=36e5}inferAppInfo(){if(typeof window>"u")return{bundle:"unknown",ver:"1.0.0",name:"Unknown App",publisher:{id:"unknown"}};const e=this.inferBundle(),t=this.inferAppName(),i=this.inferAppVersion(),s=this.inferPublisherId();return{bundle:e,ver:i,name:t,publisher:{id:s,domain:window.location.hostname}}}inferBundle(){var t;if(typeof window>"u")return"unknown";const e=(t=window.location)==null?void 0:t.hostname;return e?e.replace(/^www\./,"").replace(/:\d+$/,""):"unknown"}inferAppName(){var s,n;if(typeof document>"u")return"Unknown App";const e=document.title;if(e&&e!=="Loading..."&&e.length<100)return e;const t=(s=document.querySelector('meta[property="og:title"]'))==null?void 0:s.getAttribute("content");if(t)return t;const i=(n=document.querySelector('meta[name="application-name"]'))==null?void 0:n.getAttribute("content");return i||"Unknown App"}inferAppVersion(){if(typeof document>"u")return"1.0.0";const e=['meta[name="version"]','meta[name="app-version"]','meta[name="application-version"]','link[rel="manifest"]'];for(const t of e){const i=document.querySelector(t);if(i){if(t.includes("manifest"))return"1.0.0";const s=i.getAttribute("content");if(s)return s}}return"1.0.0"}inferPublisherId(){var i,s;if(typeof document>"u")return"unknown";const e=(i=document.querySelector('meta[name="publisher-id"]'))==null?void 0:i.getAttribute("content");if(e)return e;const t=(s=window.location)==null?void 0:s.hostname;return t?t.replace(/\./g,"_"):"unknown"}static getInstance(){return this.instance||(this.instance=new S),this.instance}collect(e){const t=Date.now();(!this.cachedStaticInfo||t-this.cacheTimestamp>this.CACHE_TTL)&&(this.cachedStaticInfo=this.collectStaticInfo(),this.cacheTimestamp=t);const i=this.collectDynamicInfo();return{device:{ua:this.cachedStaticInfo.ua,os:this.cachedStaticInfo.os,osv:this.cachedStaticInfo.osv,devicetype:this.cachedStaticInfo.devicetype,model:this.cachedStaticInfo.model,make:this.cachedStaticInfo.make,language:this.cachedStaticInfo.language,connectiontype:i.connectiontype??0,bandwidth:i.bandwidth,...(e==null?void 0:e.device)||{}},app:{...this.inferAppInfo(),...(e==null?void 0:e.app)||{}},user:{...this.collectUserInfo(),...(e==null?void 0:e.user)||{}},geo:{...this.collectGeoInfo(),...(e==null?void 0:e.geo)||{}},timestamp:t}}collectStaticInfo(){if(typeof navigator>"u")return this.getFallbackInfo();const e=navigator.userAgent,t=this.detectOS(e),i=this.detectOSVersion(e);return{ua:e,os:t,osv:i,devicetype:this.detectDeviceType(e),model:this.detectModel(e),make:this.detectMake(e),language:navigator.language||"en-US"}}collectDynamicInfo(){if(typeof navigator>"u")return{connectiontype:0};const e=this.getConnectionInfo();return{connectiontype:(e==null?void 0:e.type)||0,bandwidth:e==null?void 0:e.downlink}}collectUserInfo(){let e;try{e=localStorage.getItem("actionx_user_id")||"",e||(e=this.generateUUID(),localStorage.setItem("actionx_user_id",e))}catch{e=this.generateUUID()}return{id:e,language:(navigator==null?void 0:navigator.language)||"en-US"}}collectGeoInfo(){if(typeof navigator>"u"||typeof Intl>"u")return{};const e=Intl.DateTimeFormat().resolvedOptions().timeZone,t=navigator.language;return{country:this.inferCountry(t,e),timezone:e}}detectOS(e){return e?/iPad|iPhone|iPod/.test(e)?"iOS":/Android/.test(e)?"Android":/Windows/.test(e)?"Windows":/Macintosh|Mac OS/.test(e)?"macOS":/Linux/.test(e)?"Linux":/CrOS/.test(e)?"Chrome OS":"Unknown":"Unknown"}detectOSVersion(e){if(!e)return"Unknown";const t=e.match(/OS (\d+)_(\d+)_?(\d+)?/);if(t)return`${t[1]}.${t[2]}${t[3]?"."+t[3]:""}`;const i=e.match(/Android (\d+)\.(\d+)/);if(i)return`${i[1]}.${i[2]}`;const s=e.match(/Windows NT (\d+\.\d+)/);if(s)return s[1];const n=e.match(/Mac OS X (\d+[._]\d+)/);return n?n[1].replace("_","."):"Unknown"}detectDeviceType(e){return e?/iPad|Tablet/i.test(e)||/Android/.test(e)&&!/Mobile/.test(e)?2:/iPhone|iPod|Mobile|Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test(e)?1:/Windows|Macintosh|Linux|x86_64/i.test(e)?3:/SmartTV|TV|WebTV|GoogleTV|AppleTV/i.test(e)?4:0:0}detectModel(e){if(!e)return;const t=e.match(/iPhone(?:;\s*[^\)]*)?\s*(\d+,\d)?/);if(t)return`iPhone${t[1]||""}`;if(/iPad/.test(e))return"iPad";const i=e.match(/Samsung-.*(SM-\w+)/);if(i)return i[1];if(/Pixel/.test(e))return"Google Pixel";const s=e.match(/(BARC-|HUAWEI-)?([A-Z]{2}\-\w{4})/);if(s)return s[2];const n=e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);if(n)return n[1]+" "+n[2];if(/OnePlus/.test(e)){const o=e.match(/OnePlus\s([A-Z\d]+)/);return o?"OnePlus "+o[1]:"OnePlus"}}detectMake(e){if(e){if(/iPad|iPhone|iPod/.test(e))return"Apple";if(/Samsung/.test(e))return"Samsung";if(/Pixel/.test(e))return"Google";if(/Huawei|HONOR/.test(e))return"Huawei";if(/Xiaomi|Redmi|POCO/.test(e))return"Xiaomi";if(/OnePlus/.test(e))return"OnePlus";if(/Sony/.test(e))return"Sony";if(/LG/.test(e))return"LG";if(/Motorola|Moto/.test(e))return"Motorola";if(/Nokia/.test(e))return"Nokia";if(/HTC/.test(e))return"HTC";if(/OPPO/.test(e))return"OPPO";if(/vivo/.test(e))return"vivo";if(/Realme/.test(e))return"Realme"}}getConnectionInfo(){if(typeof navigator>"u")return null;const e=navigator,t=e.connection||e.mozConnection||e.webkitConnection;return t?{type:this.mapConnectionType(t.effectiveType),downlink:t.downlink,rtt:t.rtt}:null}mapConnectionType(e){if(!e)return 0;switch(e.toLowerCase()){case"slow-2g":case"2g":return 3;case"3g":return 4;case"4g":return 5;default:return 0}}inferCountry(e,t){if(!e&&!t)return;const i={"Asia/Shanghai":"CN","Asia/Hong_Kong":"HK","Asia/Taipei":"TW","Asia/Tokyo":"JP","Asia/Seoul":"KR","Asia/Singapore":"SG","Asia/Dubai":"AE","Asia/Kolkata":"IN","Asia/Jakarta":"ID","Asia/Manila":"PH","Asia/Bangkok":"TH","Asia/Kuala_Lumpur":"MY","America/New_York":"US","America/Chicago":"US","America/Denver":"US","America/Los_Angeles":"US","America/Toronto":"CA","America/Vancouver":"CA","America/Mexico_City":"MX","America/Sao_Paulo":"BR","America/Buenos_Aires":"AR","Europe/London":"GB","Europe/Paris":"FR","Europe/Berlin":"DE","Europe/Madrid":"ES","Europe/Rome":"IT","Europe/Amsterdam":"NL","Europe/Brussels":"BE","Europe/Zurich":"CH","Europe/Vienna":"AT","Europe/Stockholm":"SE","Europe/Oslo":"NO","Europe/Copenhagen":"DK","Europe/Helsinki":"FI","Europe/Dublin":"IE","Europe/Lisbon":"PT","Europe/Athens":"GR","Europe/Prague":"CZ","Europe/Warsaw":"PL","Europe/Budapest":"HU","Europe/Bucharest":"RO","Australia/Sydney":"AU","Pacific/Auckland":"NZ"};if(t&&i[t])return i[t];if(e){const s=e.split("-")[1];if(s)return s.toUpperCase()}}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}getFallbackInfo(){return{ua:"Unknown",os:"Unknown",osv:"Unknown",devicetype:0,language:"en-US"}}clearCache(){this.cachedStaticInfo=null,this.cacheTimestamp=0}}const T=()=>S.getInstance();function b(r){return T().collect(r)}function Q(){return b().device}function B(){return b().user}function J(){return b().app}function X(){return b().geo}function Z(){return B().id}function Y(){T().clearCache()}function ee(r){const e=b(r);return JSON.stringify(e,null,2)}function te(){var t;const r=b();return[r.device.os,r.device.osv,r.app.name,r.user.id.slice(0,8)+"...",((t=r.geo)==null?void 0:t.country)||"Unknown"].join(" / ")}function V(){var r;return typeof window<"u"?!!((r=window.__AD_CONFIG__)!=null&&r.debug):!1}function ie(r){var e,t;return{id:r.original.id,type:r.original.type,score:r.original.score,source:"internal",content:{title:r.adapted.title,body:r.adapted.body,image:(e=r.adapted.image)==null?void 0:e.url,cta_text:r.adapted.ctaText,price:(t=r.adapted.price)==null?void 0:t.display,rating:r.adapted.rating,brand:r.adapted.brand},tracking:{click_url:r.tracking.clickUrl||r.tracking.click_url||"",impression_url:r.tracking.impressionUrl||r.tracking.impression_url||""},metadata:{viewToken:r.tracking.viewToken||r.tracking.view_token,styling:r.adapted.styling}}}async function q(r,e={}){const t=e.apiBaseUrl||"/api/v1",s=T().collect(),n={...r,clientInfo:s},o={"Content-Type":"application/json"};e.apiKey&&(o["X-API-Key"]=e.apiKey),V()&&(console.log("[fetchAds] Request URL:",`${t}/ads/request`),console.log("[fetchAds] Request params:",r),console.log("[fetchAds] Request body:",n));const a=await fetch(`${t}/ads/request`,{method:"POST",headers:o,body:JSON.stringify(n)});if(!a.ok)throw new Error(`Ad request failed: ${a.status} ${a.statusText}`);const c=await a.json();if(V()&&console.log("[fetchAds] Response:",c),!c.success)throw new Error(c.error||"Ad request failed");return c.data}const se={width:400,height:200},C={variant:"horizontal",count:1,preferences:{}};function E(r={}){const e={variant:r.variant??C.variant,count:r.count??C.count,preferences:{...C.preferences,...r.preferences}};return[{slotId:"action_card",slotName:"Action Card",format:"action_card",variant:e.variant,size:se,count:e.count,preferences:e.preferences,placement:{position:"below_fold",context:"post_response"}}]}const g=class g{constructor(e){this.slots={},this.isLoading=!1,this.currentRequestId=null,this.adsAnalyticsMap=new Map,this.config=e,this.enabled=e.enabled!==!1,this.eventBus=new R,this.slots_config=E(e.cardOption),typeof window<"u"&&(window.__AD_CONFIG__={...window.__AD_CONFIG__||{},apiKey:e.apiKey,apiBaseUrl:e.apiBaseUrl,debug:!!e.debug}),this.config.debug&&console.log("[AdManager] Initialized with config:",{apiBaseUrl:e.apiBaseUrl,hasApiKey:!!e.apiKey,enabled:this.enabled})}async requestAds(e){var o;const t="conversationContext"in e?e:{conversationContext:e};this.currentUserId=(o=t.userContext)==null?void 0:o.userId;const i=this.buildRequestKey(t),s=g.inFlightRequests.get(i);if(s)return this.config.debug&&console.log("[AdManager] Reusing in-flight request for identical context"),s;if(!this.enabled)throw this.config.debug&&console.warn("[AdManager] Ads are disabled, skipping request"),new Error("Ads are disabled");if(this.isLoading)throw this.config.debug&&console.warn("[AdManager] Request already in progress"),new Error("Request already in progress");this.isLoading=!0,this.eventBus.emit("adsLoading"),this.config.debug&&console.log("[AdManager] Starting ad request...");const n=(async()=>{try{const a=await q({conversationContext:t.conversationContext,userContext:t.userContext?{...t.userContext,sessionId:t.userContext.sessionId??m()}:{sessionId:m()},slots:this.slots_config},{apiBaseUrl:this.config.apiBaseUrl,apiKey:this.config.apiKey});this.currentRequestId=a.requestId,this.adsAnalyticsMap.clear(),a.slots.forEach(l=>{l.ads.forEach((d,u)=>{const h=d.original.id;this.adsAnalyticsMap.set(h,{requestId:a.requestId,slotId:l.slotId,position:u,totalAds:l.ads.length,apiBaseUrl:this.config.apiBaseUrl,userId:this.currentUserId})})});const c={};return a.slots.forEach(l=>{c[l.slotId]=l}),this.slots=c,this.eventBus.emit("adsUpdated",this.slots),this.config.debug&&console.log("[AdManager] Ads received:",{slotCount:Object.keys(this.slots).length,slots:Object.keys(this.slots)}),a}catch(a){const c=a;throw this.eventBus.emit("adsError",c),c}finally{this.isLoading=!1,g.inFlightRequests.delete(i)}})();return g.inFlightRequests.set(i,n),n}buildRequestKey(e){return JSON.stringify({apiBaseUrl:this.config.apiBaseUrl,apiKey:this.config.apiKey,conversationContext:e.conversationContext,userContext:e.userContext||null,slots:this.slots_config})}render(e,t,i={}){const s=typeof e!="string",n=s?g.DEFAULT_SLOT_ID:e,o=s?e:t,a=(s?t:i)||{};if(!o)return this.config.debug&&console.warn("[AdManager] Render container is required"),null;const c=this.slots[n];if(!c||!c.ads||c.ads.length===0)return this.config.debug&&console.warn("[AdManager] No ads in slot:",n),null;const l=a.adIndex??0,d=c.ads[l];if(!d)return this.config.debug&&console.warn(`[AdManager] Ad at index ${l} not found in slot:`,n),null;const u=this.adsAnalyticsMap.get(d.original.id),h=this.slots_config.find(k=>k.slotId===n),p=(h==null?void 0:h.format)||"action_card";o.innerHTML="";const f={analytics:u,variant:a.variant,onClick:a.onClick,onImpression:a.onImpression};return p==="suffix"?y.renderSuffixAd(d,o,f):p==="source"?y.renderSponsoredSource(d,o,f):p==="lead_gen"?y.renderLeadGenAd(d,o,f):y.renderActionCard(d,o,f)}getSlots(e){return e?this.slots[e]:this.slots}hasAds(e){var i;const t=this.slots[e];return(t==null?void 0:t.status)==="filled"&&((i=t.ads)==null?void 0:i.length)>0}getAds(e){var t;return((t=this.slots[e])==null?void 0:t.ads)||[]}getLoadingStatus(){return this.isLoading}setEnabled(e){this.enabled=e,this.config.debug&&console.log("[AdManager] Ads",e?"enabled":"disabled")}updateConfig(e){this.config={...this.config,...e},e.cardOption!==void 0&&(this.slots_config=E(this.config.cardOption)),this.config.debug&&console.log("[AdManager] Config updated:",e)}clearSlots(){this.slots={},this.currentRequestId=null,this.adsAnalyticsMap.clear(),this.config.debug&&console.log("[AdManager] Slots and analytics cleared")}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}removeAllListeners(e){this.eventBus.removeAllListeners(e)}getCurrentRequestId(){return this.currentRequestId}getAdAnalytics(e){return this.adsAnalyticsMap.get(e)||null}getAdsAnalytics(e){const t=new Map;return e.forEach(i=>{const s=this.adsAnalyticsMap.get(i);s&&t.set(i,s)}),t}async trackAdClick(e,t,i){const s=this.adsAnalyticsMap.get(e);if(!s||!this.currentRequestId)return this.config.debug&&console.warn("[AdManager] No analytics info for ad:",e),null;const n=m(),o=await I({requestId:this.currentRequestId,adId:e,destinationUrl:t,sessionId:n,slotId:s.slotId,adTitle:i==null?void 0:i.title,format:i==null?void 0:i.format,source:i==null?void 0:i.source,userId:s.userId??this.currentUserId},{baseUrl:s.apiBaseUrl});return o&&(this.eventBus.emit("adClicked",e,s.slotId),this.config.debug&&console.log("[AdManager] Click tracked via Analytics API:",o.eventId)),o}async trackAdImpressionAPI(e,t){const i=this.adsAnalyticsMap.get(e);if(!i||!this.currentRequestId)return this.config.debug&&console.warn("[AdManager] No analytics info for ad:",e),null;const s=m(),n=await A({requestId:this.currentRequestId,adId:e,slotId:i.slotId,position:i.position,totalAds:i.totalAds,sessionId:s,adTitle:t==null?void 0:t.title,format:t==null?void 0:t.format,source:t==null?void 0:t.source,viewToken:t==null?void 0:t.viewToken,userId:i.userId??this.currentUserId},{baseUrl:i.apiBaseUrl});return n&&(this.eventBus.emit("adImpression",e,i.slotId),this.config.debug&&console.log("[AdManager] Impression tracked via Analytics API:",n.eventId)),n}destroy(){this.removeAllListeners(),this.clearSlots(),this.config.debug&&console.log("[AdManager] Destroyed")}};g.DEFAULT_SLOT_ID="action_card",g.inFlightRequests=new Map;let $=g;function P(){if(typeof window<"u"){const r=window.__AD_CONFIG__;if(r!=null&&r.apiKey)return r.apiKey}}class L{constructor(e={},t="/api/v1"){var i,s;this.observers=new Map,this.metrics=new Map,this.timers=new Map,this.batchTimers=new Map,this.eventQueue=new Map,this.isTracking=new Map,this.config={minVisiblePercentage:e.minVisiblePercentage??50,minViewableDuration:e.minViewableDuration??1e3,maxTrackingDuration:e.maxTrackingDuration??6e4,batchConfig:{maxBatchSize:((i=e.batchConfig)==null?void 0:i.maxBatchSize)??5,maxBatchWaitMs:((s=e.batchConfig)==null?void 0:s.maxBatchWaitMs)??1e4},debug:e.debug??!1},this.baseUrl=t}startTracking(e,t,i,s,n){if(this.isTracking.get(e)){this.log(`[ViewabilityTracker] Already tracking ${e}, skipping`);return}this.log(`[ViewabilityTracker] Starting tracking for ${e}`);const o={visiblePercentage:0,maxVisiblePercentage:0,totalVisibleTimeMs:0,currentVisibleTimeMs:0,isViewable:!1,viewableAt:null,enteredViewportAt:null,enterCount:0};this.metrics.set(e,o),this.isTracking.set(e,!0),this.eventQueue.set(e,[]);const a=new IntersectionObserver(l=>this.handleIntersection(e,l[0],i,s,n),{threshold:this.createThresholds()});a.observe(t),this.observers.set(e,a),this.startMonitoring(e,i,s,n);const c=setTimeout(()=>{this.endTracking(e,i,s,n)},this.config.maxTrackingDuration);this.timers.set(e,c)}stopTracking(e){this.log(`[ViewabilityTracker] Manual stop tracking for ${e}`),this.cleanup(e)}getMetrics(e){return this.metrics.get(e)}handleIntersection(e,t,i,s,n){const o=this.metrics.get(e);if(!o||!this.isTracking.get(e))return;const a=o.isViewable,c=Math.round(t.intersectionRatio*100);o.visiblePercentage=c,o.maxVisiblePercentage=Math.max(o.maxVisiblePercentage,c);const l=Date.now(),d=c>=this.config.minVisiblePercentage;if(d&&!o.enteredViewportAt&&(o.enteredViewportAt=l,o.enterCount++,this.log(`[ViewabilityTracker] ${e} entered viewport at ${l}`),this.queueEvent(e,{adId:e,sessionId:i,requestId:s,viewToken:n,eventType:"enter_viewport",visiblePercentage:c,maxVisiblePercentage:o.maxVisiblePercentage,totalVisibleTimeMs:o.totalVisibleTimeMs,isViewable:!1,timestamp:l})),!d&&o.enteredViewportAt){const u=l-o.enteredViewportAt;o.totalVisibleTimeMs+=u,o.enteredViewportAt=null,o.currentVisibleTimeMs=0,this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${o.totalVisibleTimeMs}ms`),this.queueEvent(e,{adId:e,sessionId:i,requestId:s,viewToken:n,eventType:"exit_viewport",visiblePercentage:c,maxVisiblePercentage:o.maxVisiblePercentage,totalVisibleTimeMs:o.totalVisibleTimeMs,isViewable:o.isViewable,timestamp:l})}o.isViewable!==a&&o.isViewable&&this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`),this.metrics.set(e,o)}startMonitoring(e,t,i,s){const o=setInterval(()=>{const a=this.metrics.get(e);if(!a||!this.isTracking.get(e)){clearInterval(o);return}const c=Date.now(),l=a.isViewable;if(a.enteredViewportAt){const d=c-a.enteredViewportAt;a.currentVisibleTimeMs=d,d>=this.config.minViewableDuration&&a.visiblePercentage>=this.config.minVisiblePercentage&&(a.isViewable=!0,l||(a.viewableAt=a.enteredViewportAt,this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`),this.queueEvent(e,{adId:e,sessionId:t,requestId:i,viewToken:s,eventType:"become_viewable",visiblePercentage:a.visiblePercentage,maxVisiblePercentage:a.maxVisiblePercentage,totalVisibleTimeMs:a.totalVisibleTimeMs,isViewable:!0,timestamp:c})))}a.enteredViewportAt&&(a.totalVisibleTimeMs+=100),this.metrics.set(e,a)},100);this.timers.set(`${e}_monitoring`,o)}queueEvent(e,t){var n,o;const i=this.eventQueue.get(e);if(!i){this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);return}i.push(t),this.log(`[ViewabilityTracker] Queued ${t.eventType} for ${e} (queue size: ${i.length})`);const s=((n=this.config.batchConfig)==null?void 0:n.maxBatchSize)??5;if(i.length>=s)this.flushQueue(e);else{const a=this.batchTimers.get(e);a&&clearTimeout(a);const c=((o=this.config.batchConfig)==null?void 0:o.maxBatchWaitMs)??1e4,l=setTimeout(()=>{this.flushQueue(e)},c);this.batchTimers.set(e,l)}}async flushQueue(e){const t=this.eventQueue.get(e);if(!t||t.length===0)return;const i=[...t];t.length=0,this.log(`[ViewabilityTracker] Flushing ${i.length} events for ${e}`);try{const s={"Content-Type":"application/json"},n=P();n&&(s["x-api-key"]=n),await fetch(`${this.baseUrl}/ads/viewability/batch`,{method:"POST",headers:s,body:JSON.stringify({events:i})}),this.log(`[ViewabilityTracker] Successfully sent ${i.length} events for ${e}`)}catch(s){this.log(`[ViewabilityTracker] Failed to send events for ${e}:`,s),t.unshift(...i)}}endTracking(e,t,i,s){const n=this.metrics.get(e);if(!n)return;this.log(`[ViewabilityTracker] Ending tracking for ${e}`),this.flushQueue(e);const o=Date.now();this.queueEvent(e,{adId:e,sessionId:t,requestId:i,viewToken:s,eventType:"end_tracking",visiblePercentage:n.visiblePercentage,maxVisiblePercentage:n.maxVisiblePercentage,totalVisibleTimeMs:n.totalVisibleTimeMs,isViewable:n.isViewable,timestamp:o}),this.flushQueue(e),this.cleanup(e)}cleanup(e){const t=this.observers.get(e);t&&(t.disconnect(),this.observers.delete(e));const i=this.timers.get(e);i&&(clearTimeout(i),this.timers.delete(e));const s=this.timers.get(`${e}_monitoring`);s&&(clearInterval(s),this.timers.delete(`${e}_monitoring`));const n=this.batchTimers.get(e);n&&(clearTimeout(n),this.batchTimers.delete(e)),this.flushQueue(e),this.isTracking.delete(e),this.metrics.delete(e),this.eventQueue.delete(e)}createThresholds(){return[0,.25,.5,.75,.9,1]}stopAll(){const e=Array.from(this.isTracking.keys());for(const t of e)this.cleanup(t)}log(...e){this.config.debug&&console.log(...e)}setupBeforeUnload(){typeof window<"u"&&window.addEventListener("beforeunload",()=>{for(const e of this.eventQueue.keys()){const t=this.eventQueue.get(e);if(t&&t.length>0){const i={"Content-Type":"application/json"},s=P();s&&(i["x-api-key"]=s),fetch(`${this.baseUrl}/ads/viewability/batch`,{method:"POST",headers:i,keepalive:!0,body:JSON.stringify({events:t})})}}})}}let x=null;function ne(r,e){return x||(x=new L(r,e),x.setupBeforeUnload()),x}const re="0.1.0";exports.AdManager=$;exports.AnalyticsSender=v;exports.ClientInfoCollector=S;exports.DOMRenderer=y;exports.HTMLRenderer=w;exports.SDK_VERSION=re;exports.SessionManager=U;exports.ViewabilityTracker=L;exports.adaptAdToKoahAd=ie;exports.clearClientInfoCache=Y;exports.createAnalytics=z;exports.createSession=W;exports.fetchAds=q;exports.generateViewToken=F;exports.getAppInfo=J;exports.getClientInfo=b;exports.getClientInfoCollector=T;exports.getClientInfoJSON=ee;exports.getClientInfoSummary=te;exports.getDeviceInfo=Q;exports.getGeoInfo=X;exports.getSessionId=m;exports.getUserId=Z;exports.getUserInfo=B;exports.getViewabilityTracker=ne;exports.trackAdClick=I;exports.trackAdImpression=A;exports.trackClicksBatch=j;exports.trackImpressionsBatch=G;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Action Card Variant
|
|
3
3
|
*/
|
|
4
|
-
export declare type ActionCardVariant = 'horizontal' | 'vertical'
|
|
4
|
+
export declare type ActionCardVariant = 'horizontal' | 'vertical';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Analytics 信息(用于 SDK 内部传递)
|
|
@@ -12,6 +12,7 @@ export declare interface AdAnalyticsInfo {
|
|
|
12
12
|
position: number;
|
|
13
13
|
totalAds: number;
|
|
14
14
|
apiBaseUrl?: string;
|
|
15
|
+
userId?: string;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -43,9 +44,12 @@ export declare interface AdaptedAdContent {
|
|
|
43
44
|
entityLinkContent?: EntityLinkAdContent;
|
|
44
45
|
};
|
|
45
46
|
tracking: {
|
|
46
|
-
impressionUrl
|
|
47
|
-
clickUrl
|
|
48
|
-
viewToken
|
|
47
|
+
impressionUrl?: string;
|
|
48
|
+
clickUrl?: string;
|
|
49
|
+
viewToken?: string;
|
|
50
|
+
impression_url?: string;
|
|
51
|
+
click_url?: string;
|
|
52
|
+
view_token?: string;
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -99,6 +103,7 @@ export declare class AdManager {
|
|
|
99
103
|
private static readonly DEFAULT_SLOT_ID;
|
|
100
104
|
private static inFlightRequests;
|
|
101
105
|
private currentRequestId;
|
|
106
|
+
private currentUserId;
|
|
102
107
|
private adsAnalyticsMap;
|
|
103
108
|
constructor(config: AdManagerConfig);
|
|
104
109
|
/**
|
|
@@ -124,13 +129,13 @@ export declare class AdManager {
|
|
|
124
129
|
*/
|
|
125
130
|
render(container: HTMLElement, options?: {
|
|
126
131
|
adIndex?: number;
|
|
127
|
-
variant?: 'horizontal' | 'vertical' | '
|
|
132
|
+
variant?: 'horizontal' | 'vertical' | 'block' | 'inline' | 'minimal' | 'card' | 'list-item';
|
|
128
133
|
onClick?: (ad: any) => void;
|
|
129
134
|
onImpression?: (ad: any) => void;
|
|
130
135
|
}): HTMLElement | null;
|
|
131
136
|
render(slotId: string, container: HTMLElement, options?: {
|
|
132
137
|
adIndex?: number;
|
|
133
|
-
variant?: 'horizontal' | 'vertical' | '
|
|
138
|
+
variant?: 'horizontal' | 'vertical' | 'block' | 'inline' | 'minimal' | 'card' | 'list-item';
|
|
134
139
|
onClick?: (ad: any) => void;
|
|
135
140
|
onImpression?: (ad: any) => void;
|
|
136
141
|
}): HTMLElement | null;
|
|
@@ -698,11 +703,14 @@ export declare interface DeviceInfo {
|
|
|
698
703
|
*/
|
|
699
704
|
export declare class DOMRenderer {
|
|
700
705
|
private static trackedImpressionKeys;
|
|
706
|
+
private static isDebugEnabled;
|
|
707
|
+
private static getClickUrl;
|
|
708
|
+
private static getViewToken;
|
|
701
709
|
/**
|
|
702
710
|
* Render Action Card ad into container
|
|
703
711
|
*/
|
|
704
712
|
static renderActionCard(ad: AdaptedAdContent, container: HTMLElement, options?: {
|
|
705
|
-
variant?: 'horizontal' | 'vertical'
|
|
713
|
+
variant?: 'horizontal' | 'vertical';
|
|
706
714
|
analytics?: AdAnalyticsInfo;
|
|
707
715
|
onClick?: (ad: AdaptedAdContent) => void;
|
|
708
716
|
onImpression?: (ad: AdaptedAdContent) => void;
|
|
@@ -1027,6 +1035,9 @@ export declare interface GlobalSuggestions {
|
|
|
1027
1035
|
* CSS class names use ax-ad-* namespace
|
|
1028
1036
|
*/
|
|
1029
1037
|
export declare class HTMLRenderer {
|
|
1038
|
+
private static getClickUrl;
|
|
1039
|
+
private static getImpressionUrl;
|
|
1040
|
+
private static getCtaText;
|
|
1030
1041
|
/**
|
|
1031
1042
|
* Render Action Card ad as HTML string
|
|
1032
1043
|
*
|
|
@@ -1035,7 +1046,7 @@ export declare class HTMLRenderer {
|
|
|
1035
1046
|
* @returns HTML string
|
|
1036
1047
|
*/
|
|
1037
1048
|
static renderActionCard(ad: AdaptedAdContent, options?: {
|
|
1038
|
-
variant?: 'horizontal' | 'vertical'
|
|
1049
|
+
variant?: 'horizontal' | 'vertical';
|
|
1039
1050
|
includeWrapper?: boolean;
|
|
1040
1051
|
}): string;
|
|
1041
1052
|
/**
|