@action-x/ad-sdk 0.1.9 → 0.1.11

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
@@ -1,4 +1,4 @@
1
- class B {
1
+ class q {
2
2
  constructor() {
3
3
  this.events = {};
4
4
  }
@@ -42,7 +42,10 @@ class B {
42
42
  return ((t = this.events[e]) == null ? void 0 : t.length) || 0;
43
43
  }
44
44
  }
45
- class w {
45
+ function m(r) {
46
+ return r.replace(/<[^>]+>/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").replace(/\s{2,}/g, " ").trim();
47
+ }
48
+ class v {
46
49
  static getClickUrl(e) {
47
50
  return e.tracking.clickUrl || e.tracking.click_url || "#";
48
51
  }
@@ -61,27 +64,29 @@ class w {
61
64
  */
62
65
  static renderActionCard(e, t = {}) {
63
66
  var f;
64
- const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, r = this.getClickUrl(e), a = this.getImpressionUrl(e), c = (f = n.image) != null && f.url ? `<img
65
- src="${n.image.url}"
66
- alt="${n.title}"
67
- class="ax-ad-image"
68
- loading="lazy"
69
- />` : "", d = (n.brand || "").trim(), l = d && d.toLowerCase() !== "unknown" ? `<span class="ax-ad-brand">${n.brand}</span>` : "", u = `
67
+ const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, o = this.getClickUrl(e), a = this.getImpressionUrl(e), c = (f = n.image) != null && f.url ? `<div class="ax-ad-image-wrap">
68
+ <img
69
+ src="${n.image.url}"
70
+ alt="${n.title}"
71
+ class="ax-ad-image"
72
+ loading="lazy"
73
+ />
74
+ </div>` : "", u = (n.brand || "").trim(), l = u && u.toLowerCase() !== "unknown" ? `<span class="ax-ad-brand">${n.brand}</span>` : "", d = `
70
75
  ${c}
71
76
  <div class="ax-ad-content">
72
77
  ${l}
73
78
  <h3 class="ax-ad-title">${n.title}</h3>
74
- ${n.body ? `<p class="ax-ad-body">${n.body}</p>` : ""}
79
+ ${n.body ? `<p class="ax-ad-body">${m(n.body)}</p>` : ""}
75
80
  </div>
76
81
  `, h = s ? `<a
77
- href="${r}"
82
+ href="${o}"
78
83
  class="ax-ad-card ax-ad-card-${i} ax-ad-card-link"
79
84
  target="_blank"
80
85
  rel="sponsored noopener noreferrer"
81
86
  data-ad-id="${e.original.id}"
82
87
  data-impression-url="${a}"
83
88
  >` : "", p = s ? "</a>" : "";
84
- return h + u + p;
89
+ return h + d + p;
85
90
  }
86
91
  /**
87
92
  * Render Suffix ad as HTML string
@@ -95,7 +100,7 @@ class w {
95
100
  <div class="ax-ad-suffix" data-ad-id="${e.original.id}">
96
101
  <div class="ax-ad-suffix-content">
97
102
  ${t.title ? `<h4 class="ax-ad-suffix-title">${t.title}</h4>` : ""}
98
- ${t.body ? `<p class="ax-ad-suffix-body">${t.body}</p>` : ""}
103
+ ${t.body ? `<p class="ax-ad-suffix-body">${m(t.body)}</p>` : ""}
99
104
  <a
100
105
  href="${i}"
101
106
  class="ax-ad-suffix-link"
@@ -132,7 +137,7 @@ class w {
132
137
  ${(n = t.image) != null && n.url ? `<img src="${t.image.url}" alt="" class="ax-ad-source-icon" />` : ""}
133
138
  <div class="ax-ad-source-info">
134
139
  <span class="ax-ad-source-name">${t.title}</span>
135
- ${t.body ? `<span class="ax-ad-source-desc">${t.body}</span>` : ""}
140
+ ${t.body ? `<span class="ax-ad-source-desc">${m(t.body)}</span>` : ""}
136
141
  </div>
137
142
  <span class="ax-ad-source-badge">Sponsored</span>
138
143
  </a>
@@ -151,7 +156,7 @@ class w {
151
156
  <div class="ax-ad-leadgen" data-ad-id="${e.original.id}">
152
157
  <div class="ax-ad-leadgen-content">
153
158
  ${t.title ? `<h3 class="ax-ad-leadgen-title">${t.title}</h3>` : ""}
154
- ${t.body ? `<p class="ax-ad-leadgen-body">${t.body}</p>` : ""}
159
+ ${t.body ? `<p class="ax-ad-leadgen-body">${m(t.body)}</p>` : ""}
155
160
  <a
156
161
  href="${i}"
157
162
  class="ax-ad-leadgen-cta"
@@ -173,25 +178,25 @@ class w {
173
178
  * @param renderFn - Render function to use
174
179
  * @returns HTML string with all ads
175
180
  */
176
- static renderAds(e, t = w.renderActionCard.bind(w)) {
181
+ static renderAds(e, t = v.renderActionCard.bind(v)) {
177
182
  return e.map(t).join(`
178
183
  `);
179
184
  }
180
185
  }
181
- const q = "ad_session_id";
182
- function L() {
186
+ const L = "ad_session_id";
187
+ function R() {
183
188
  if (typeof window < "u") {
184
- const o = window.__AD_CONFIG__;
185
- if (o != null && o.apiKey)
186
- return o.apiKey;
189
+ const r = window.__AD_CONFIG__;
190
+ if (r != null && r.apiKey)
191
+ return r.apiKey;
187
192
  }
188
193
  }
189
- function R() {
190
- var o;
191
- return typeof window < "u" ? !!((o = window.__AD_CONFIG__) != null && o.debug) : !1;
194
+ function K() {
195
+ var r;
196
+ return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
192
197
  }
193
- function U(o) {
194
- if (o) return o;
198
+ function U(r) {
199
+ if (r) return r;
195
200
  if (typeof window < "u") {
196
201
  const e = window.__AD_CONFIG__;
197
202
  if (e != null && e.apiBaseUrl)
@@ -201,7 +206,7 @@ function U(o) {
201
206
  }
202
207
  class P {
203
208
  constructor(e = {}) {
204
- this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey || q, this.storage = e.storage || "sessionStorage", (typeof window > "u" || typeof window.sessionStorage > "u") && (this.storage = "memory");
209
+ this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey || L, this.storage = e.storage || "sessionStorage", (typeof window > "u" || typeof window.sessionStorage > "u") && (this.storage = "memory");
205
210
  }
206
211
  /**
207
212
  * 获取 Session ID
@@ -235,8 +240,8 @@ class P {
235
240
  this.storage === "sessionStorage" ? sessionStorage.removeItem(this.sessionKey) : this.memoryCache.delete(this.sessionKey);
236
241
  }
237
242
  }
238
- const K = new P(), m = () => K.getSessionId();
239
- class x {
243
+ const N = new P(), w = () => N.getSessionId();
244
+ class A {
240
245
  constructor(e = {}) {
241
246
  this.explicitBaseUrl = e.baseUrl, this.timeout = e.timeout || 1e4, this.retryAttempts = e.retryAttempts ?? 2, this.retryDelay = e.retryDelay || 1e3, this.debug = e.debug || !1;
242
247
  }
@@ -267,26 +272,26 @@ class x {
267
272
  async sendRequest(e, t, i) {
268
273
  let s = null;
269
274
  for (let n = 0; n <= this.retryAttempts; n++) {
270
- const r = this.debug || R();
275
+ const o = this.debug || K();
271
276
  try {
272
- r && (console.log(`[Analytics] Request URL (${i}):`, e), console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t));
273
- const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout), d = {
277
+ o && (console.log(`[Analytics] Request URL (${i}):`, e), console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t));
278
+ const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout), u = {
274
279
  "Content-Type": "application/json"
275
- }, l = L();
276
- l && (d["X-API-Key"] = l, r && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
277
- const u = await fetch(e, {
280
+ }, l = R();
281
+ l && (u["X-API-Key"] = l, o && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
282
+ const d = await fetch(e, {
278
283
  method: "POST",
279
- headers: d,
284
+ headers: u,
280
285
  body: JSON.stringify(t),
281
286
  keepalive: !0,
282
287
  signal: a.signal
283
288
  });
284
- if (clearTimeout(c), !u.ok)
285
- throw new Error(`HTTP ${u.status}: ${u.statusText}`);
286
- const h = await u.json();
287
- return r && console.log(`[Analytics] ${i} event tracked successfully:`, h), h;
289
+ if (clearTimeout(c), !d.ok)
290
+ throw new Error(`HTTP ${d.status}: ${d.statusText}`);
291
+ const h = await d.json();
292
+ return o && console.log(`[Analytics] ${i} event tracked successfully:`, h), h;
288
293
  } catch (a) {
289
- s = a, r && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, a), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
294
+ s = a, o && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, a), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
290
295
  }
291
296
  }
292
297
  return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`, s), null;
@@ -298,25 +303,25 @@ class x {
298
303
  return new Promise((t) => setTimeout(t, e));
299
304
  }
300
305
  }
301
- const O = new x(), I = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackImpression(o) : O.trackImpression(o), S = (o, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackClick(o) : O.trackClick(o);
302
- function z(o, e) {
303
- return `vt_${o}_${e}`;
306
+ const O = new A(), S = (r, e) => e != null && e.baseUrl ? new A({ baseUrl: e.baseUrl }).trackImpression(r) : O.trackImpression(r), B = (r, e) => e != null && e.baseUrl ? new A({ baseUrl: e.baseUrl }).trackClick(r) : O.trackClick(r);
307
+ function j(r, e) {
308
+ return `vt_${r}_${e}`;
304
309
  }
305
- async function j(o) {
306
- return Promise.all(o.map((e) => I(e)));
310
+ async function W(r) {
311
+ return Promise.all(r.map((e) => S(e)));
307
312
  }
308
- async function W(o) {
309
- return Promise.all(o.map((e) => S(e)));
313
+ async function Q(r) {
314
+ return Promise.all(r.map((e) => B(e)));
310
315
  }
311
- function Q(o) {
312
- const e = new x(o);
316
+ function J(r) {
317
+ const e = new A(r);
313
318
  return {
314
319
  trackImpression: (t) => e.trackImpression(t),
315
320
  trackClick: (t) => e.trackClick(t)
316
321
  };
317
322
  }
318
- function J(o = {}) {
319
- const e = new P(o);
323
+ function X(r = {}) {
324
+ const e = new P(r);
320
325
  return {
321
326
  getSessionId: () => e.getSessionId(),
322
327
  regenerateSessionId: () => e.regenerateSessionId(),
@@ -338,7 +343,7 @@ const C = class C {
338
343
  * Render Action Card ad into container
339
344
  */
340
345
  static renderActionCard(e, t, i = {}) {
341
- t.innerHTML = w.renderActionCard(e, i);
346
+ t.innerHTML = v.renderActionCard(e, i);
342
347
  const s = t.querySelector(".ax-ad-card-link");
343
348
  return s && s.addEventListener("click", (n) => {
344
349
  n.preventDefault(), this.handleClick(e, i);
@@ -351,8 +356,8 @@ const C = class C {
351
356
  const s = i.variant || "block";
352
357
  t.innerHTML = this.generateSuffixAdHTML(e, s);
353
358
  const n = t.querySelector(".ax-ad-suffix-link");
354
- return n && n.addEventListener("click", (r) => {
355
- r.preventDefault(), this.handleClick(e, i);
359
+ return n && n.addEventListener("click", (o) => {
360
+ o.preventDefault(), this.handleClick(e, i);
356
361
  }), this.trackImpression(e, t, i), t;
357
362
  }
358
363
  /**
@@ -362,15 +367,15 @@ const C = class C {
362
367
  const s = i.variant || "card";
363
368
  t.innerHTML = this.generateSponsoredSourceHTML(e, s);
364
369
  const n = t.querySelector(".ax-ad-source-link");
365
- return n && n.addEventListener("click", (r) => {
366
- r.preventDefault(), this.handleClick(e, i);
370
+ return n && n.addEventListener("click", (o) => {
371
+ o.preventDefault(), this.handleClick(e, i);
367
372
  }), this.trackImpression(e, t, i), t;
368
373
  }
369
374
  /**
370
375
  * Render Lead Gen ad into container
371
376
  */
372
377
  static renderLeadGenAd(e, t, i = {}) {
373
- t.innerHTML = w.renderLeadGenAd(e);
378
+ t.innerHTML = v.renderLeadGenAd(e);
374
379
  const s = t.querySelector(".ax-ad-leadgen-cta");
375
380
  return s && s.addEventListener("click", (n) => {
376
381
  n.preventDefault(), this.handleClick(e, i);
@@ -382,53 +387,42 @@ const C = class C {
382
387
  static renderAds(e, t, i = this.renderActionCard.bind(this), s) {
383
388
  t.innerHTML = "";
384
389
  const n = document.createElement("div");
385
- return n.className = "ax-ads-container", e.forEach((r) => {
390
+ return n.className = "ax-ads-container", e.forEach((o) => {
386
391
  const a = document.createElement("div");
387
- a.className = "ax-ad-wrapper", i.call(this, r, a, s), n.appendChild(a);
392
+ a.className = "ax-ad-wrapper", i.call(this, o, a, s), n.appendChild(a);
388
393
  }), t.appendChild(n), t;
389
394
  }
390
395
  /**
391
396
  * Handle ad click
392
- * First tracks the click (async, non-blocking), then opens the URL.
397
+ * Directly opens click_url in a new window.
393
398
  */
394
399
  static handleClick(e, t) {
395
- const { analytics: i, onClick: s } = t, n = this.getClickUrl(e);
396
- if (!n) {
400
+ const { onClick: i } = t, s = this.getClickUrl(e);
401
+ if (!s) {
397
402
  console.warn("[DOMRenderer] Missing click url for ad:", e.original.id);
398
403
  return;
399
404
  }
400
- s && s(e), i && S({
401
- requestId: i.requestId,
402
- adId: e.original.id,
403
- destinationUrl: n,
404
- slotId: i.slotId,
405
- sessionId: m(),
406
- adTitle: e.adapted.title,
407
- format: e.original.type,
408
- userId: i.userId
409
- }, { baseUrl: i.apiBaseUrl }).catch((r) => {
410
- console.error("[DOMRenderer] Analytics click tracking failed:", r);
411
- }), this.isDebugEnabled() && console.log("[DOMRenderer] Redirect URL:", n), window.open(n, "_blank", "noopener,noreferrer");
405
+ i && i(e), this.isDebugEnabled() && console.log("[DOMRenderer] Redirect URL:", s), window.open(s, "_blank", "noopener,noreferrer");
412
406
  }
413
407
  /**
414
408
  * Track ad impression using IntersectionObserver (50% visible + 1000ms delay)
415
409
  * Falls back to immediate tracking if IntersectionObserver is unavailable.
416
410
  */
417
411
  static trackImpression(e, t, i) {
418
- const { analytics: s, onImpression: n } = i, r = s ? `${s.requestId}:${s.slotId}:${e.original.id}:${this.getViewToken(e) || ""}` : `no-analytics:${e.original.id}:${this.getViewToken(e) || ""}`;
419
- if (this.trackedImpressionKeys.has(r))
412
+ 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) || ""}`;
413
+ if (this.trackedImpressionKeys.has(o))
420
414
  return;
421
415
  let a = !1;
422
416
  const c = () => {
423
- a || this.trackedImpressionKeys.has(r) || (a = !0, this.trackedImpressionKeys.add(r), d());
424
- }, d = () => {
425
- s ? I({
417
+ a || this.trackedImpressionKeys.has(o) || (a = !0, this.trackedImpressionKeys.add(o), u());
418
+ }, u = () => {
419
+ s ? S({
426
420
  requestId: s.requestId,
427
421
  adId: e.original.id,
428
422
  slotId: s.slotId,
429
423
  position: s.position,
430
424
  totalAds: s.totalAds,
431
- sessionId: m(),
425
+ sessionId: w(),
432
426
  adTitle: e.adapted.title,
433
427
  format: e.original.type,
434
428
  source: "internal",
@@ -441,13 +435,13 @@ const C = class C {
441
435
  }) : n && n(e);
442
436
  };
443
437
  if (typeof IntersectionObserver < "u") {
444
- let l = !1, u = null;
438
+ let l = !1, d = null;
445
439
  const h = new IntersectionObserver(
446
440
  (f) => {
447
- f.forEach((v) => {
448
- l = v.isIntersecting && v.intersectionRatio >= 0.5, l ? u || (u = setTimeout(() => {
449
- u = null, l && (c(), h.disconnect());
450
- }, 1e3)) : u && (clearTimeout(u), u = null);
441
+ f.forEach((k) => {
442
+ l = k.isIntersecting && k.intersectionRatio >= 0.5, l ? d || (d = setTimeout(() => {
443
+ d = null, l && (c(), h.disconnect());
444
+ }, 1e3)) : d && (clearTimeout(d), d = null);
451
445
  });
452
446
  },
453
447
  { threshold: 0.5 }
@@ -460,7 +454,7 @@ const C = class C {
460
454
  * Generate HTML for Suffix Ad variants
461
455
  */
462
456
  static generateSuffixAdHTML(e, t) {
463
- const i = e.adapted.title || "", s = e.adapted.body || "";
457
+ const i = e.adapted.title || "", s = m(e.adapted.body || "");
464
458
  return t === "inline" ? `
465
459
  <span class="ax-ad-suffix-link ax-ad-variant-inline" data-ad-id="${e.original.id}">
466
460
  ${i}
@@ -491,8 +485,8 @@ const C = class C {
491
485
  * Generate HTML for Sponsored Source Ad variants
492
486
  */
493
487
  static generateSponsoredSourceHTML(e, t) {
494
- var r;
495
- const i = e.adapted.title || "", s = e.adapted.body || "", n = ((r = e.adapted.image) == null ? void 0 : r.url) || "";
488
+ var o;
489
+ const i = e.adapted.title || "", s = m(e.adapted.body || ""), n = ((o = e.adapted.image) == null ? void 0 : o.url) || "";
496
490
  return t === "list-item" ? `
497
491
  <div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
498
492
  ${n ? `<img src="${n}" alt="${i}" loading="lazy" />` : ""}
@@ -774,8 +768,8 @@ class T {
774
768
  const n = e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);
775
769
  if (n) return n[1] + " " + n[2];
776
770
  if (/OnePlus/.test(e)) {
777
- const r = e.match(/OnePlus\s([A-Z\d]+)/);
778
- return r ? "OnePlus " + r[1] : "OnePlus";
771
+ const o = e.match(/OnePlus\s([A-Z\d]+)/);
772
+ return o ? "OnePlus " + o[1] : "OnePlus";
779
773
  }
780
774
  }
781
775
  /**
@@ -922,85 +916,85 @@ class T {
922
916
  }
923
917
  }
924
918
  const $ = () => T.getInstance();
925
- function b(o) {
926
- return $().collect(o);
919
+ function b(r) {
920
+ return $().collect(r);
927
921
  }
928
- function X() {
922
+ function Z() {
929
923
  return b().device;
930
924
  }
931
- function N() {
925
+ function H() {
932
926
  return b().user;
933
927
  }
934
- function Z() {
928
+ function Y() {
935
929
  return b().app;
936
930
  }
937
- function Y() {
931
+ function ee() {
938
932
  return b().geo;
939
933
  }
940
934
  function D() {
941
- return N().id;
935
+ return H().id;
942
936
  }
943
- function ee() {
937
+ function te() {
944
938
  $().clearCache();
945
939
  }
946
- function te(o) {
947
- const e = b(o);
940
+ function ie(r) {
941
+ const e = b(r);
948
942
  return JSON.stringify(e, null, 2);
949
943
  }
950
- function ie() {
944
+ function se() {
951
945
  var t;
952
- const o = b();
946
+ const r = b();
953
947
  return [
954
- o.device.os,
955
- o.device.osv,
956
- o.app.name,
957
- o.user.id.slice(0, 8) + "...",
958
- ((t = o.geo) == null ? void 0 : t.country) || "Unknown"
948
+ r.device.os,
949
+ r.device.osv,
950
+ r.app.name,
951
+ r.user.id.slice(0, 8) + "...",
952
+ ((t = r.geo) == null ? void 0 : t.country) || "Unknown"
959
953
  ].join(" / ");
960
954
  }
961
955
  function M() {
962
- var o;
963
- return typeof window < "u" ? !!((o = window.__AD_CONFIG__) != null && o.debug) : !1;
956
+ var r;
957
+ return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
964
958
  }
965
- function se(o) {
959
+ function ne(r) {
966
960
  var e, t;
967
961
  return {
968
- id: o.original.id,
969
- type: o.original.type,
970
- score: o.original.score,
962
+ id: r.original.id,
963
+ type: r.original.type,
964
+ score: r.original.score,
971
965
  source: "internal",
972
966
  // Default source
973
967
  content: {
974
- title: o.adapted.title,
975
- body: o.adapted.body,
976
- image: (e = o.adapted.image) == null ? void 0 : e.url,
977
- cta_text: o.adapted.ctaText,
978
- price: (t = o.adapted.price) == null ? void 0 : t.display,
979
- rating: o.adapted.rating,
980
- brand: o.adapted.brand
968
+ title: r.adapted.title,
969
+ body: r.adapted.body,
970
+ image: (e = r.adapted.image) == null ? void 0 : e.url,
971
+ cta_text: r.adapted.ctaText,
972
+ price: (t = r.adapted.price) == null ? void 0 : t.display,
973
+ rating: r.adapted.rating,
974
+ brand: r.adapted.brand
981
975
  },
982
976
  tracking: {
983
- click_url: o.tracking.clickUrl || o.tracking.click_url || "",
984
- impression_url: o.tracking.impressionUrl || o.tracking.impression_url || ""
977
+ click_url: r.tracking.clickUrl || r.tracking.click_url || "",
978
+ impression_url: r.tracking.impressionUrl || r.tracking.impression_url || ""
985
979
  },
986
980
  metadata: {
987
- viewToken: o.tracking.viewToken || o.tracking.view_token,
988
- styling: o.adapted.styling
981
+ viewToken: r.tracking.viewToken || r.tracking.view_token,
982
+ styling: r.adapted.styling
989
983
  }
990
984
  };
991
985
  }
992
- async function H(o, e = {}) {
986
+ async function F(r, e = {}) {
993
987
  const t = e.apiBaseUrl || "/api/v1", s = $().collect(), n = {
994
- ...o,
988
+ ...r,
995
989
  clientInfo: s
996
990
  // Auto-injected
997
- }, r = {
991
+ }, o = {
998
992
  "Content-Type": "application/json"
999
993
  };
1000
- e.apiKey && (r["X-API-Key"] = e.apiKey), M() && (console.log("[fetchAds] Request URL:", `${t}/ads/request`), console.log("[fetchAds] Request params:", o), console.log("[fetchAds] Request body:", n));
994
+ e.apiKey && (o["X-API-Key"] = e.apiKey), M() && (console.log("[fetchAds] Request URL:", `${t}/ads/request`), console.log("[fetchAds] Request params:", r), console.log("[fetchAds] Request body:", n));
1001
995
  const a = await fetch(`${t}/ads/request`, {
1002
996
  method: "POST",
1003
- headers: r,
997
+ headers: o,
1004
998
  body: JSON.stringify(n)
1005
999
  });
1006
1000
  if (!a.ok)
@@ -1010,16 +1004,16 @@ async function H(o, e = {}) {
1010
1004
  throw new Error(c.error || "Ad request failed");
1011
1005
  return c.data;
1012
1006
  }
1013
- const F = { width: 400, height: 200 }, A = {
1007
+ const G = { width: 400, height: 200 }, I = {
1014
1008
  variant: "horizontal",
1015
1009
  count: 1,
1016
1010
  preferences: {}
1017
1011
  };
1018
- function _(o = {}) {
1012
+ function _(r = {}) {
1019
1013
  const e = {
1020
- variant: o.variant ?? A.variant,
1021
- count: o.count ?? A.count,
1022
- preferences: { ...A.preferences, ...o.preferences }
1014
+ variant: r.variant ?? I.variant,
1015
+ count: r.count ?? I.count,
1016
+ preferences: { ...I.preferences, ...r.preferences }
1023
1017
  };
1024
1018
  return [
1025
1019
  {
@@ -1027,7 +1021,7 @@ function _(o = {}) {
1027
1021
  slotName: "Action Card",
1028
1022
  format: "action_card",
1029
1023
  variant: e.variant,
1030
- size: F,
1024
+ size: G,
1031
1025
  count: e.count,
1032
1026
  preferences: e.preferences,
1033
1027
  placement: { position: "below_fold", context: "post_response" }
@@ -1036,7 +1030,7 @@ function _(o = {}) {
1036
1030
  }
1037
1031
  const g = class g {
1038
1032
  constructor(e) {
1039
- this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new B(), this.slots_config = _(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
1033
+ this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new q(), this.slots_config = _(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
1040
1034
  ...window.__AD_CONFIG__ || {},
1041
1035
  apiKey: e.apiKey,
1042
1036
  apiBaseUrl: e.apiBaseUrl,
@@ -1060,14 +1054,14 @@ const g = class g {
1060
1054
  this.isLoading = !0, this.eventBus.emit("adsLoading"), this.config.debug && console.log("[AdManager] Starting ad request...");
1061
1055
  const n = (async () => {
1062
1056
  try {
1063
- const r = await H(
1057
+ const o = await F(
1064
1058
  {
1065
1059
  conversationContext: t.conversationContext,
1066
1060
  userContext: t.userContext ? {
1067
1061
  ...t.userContext,
1068
1062
  userId: t.userContext.userId ?? this.currentUserId,
1069
- sessionId: t.userContext.sessionId ?? m()
1070
- } : { userId: this.currentUserId, sessionId: m() },
1063
+ sessionId: t.userContext.sessionId ?? w()
1064
+ } : { userId: this.currentUserId, sessionId: w() },
1071
1065
  slots: this.slots_config
1072
1066
  },
1073
1067
  {
@@ -1075,11 +1069,11 @@ const g = class g {
1075
1069
  apiKey: this.config.apiKey
1076
1070
  }
1077
1071
  );
1078
- this.currentRequestId = r.requestId, this.adsAnalyticsMap.clear(), r.slots.forEach((c) => {
1079
- c.ads.forEach((d, l) => {
1080
- const u = d.original.id;
1081
- this.adsAnalyticsMap.set(u, {
1082
- requestId: r.requestId,
1072
+ this.currentRequestId = o.requestId, this.adsAnalyticsMap.clear(), o.slots.forEach((c) => {
1073
+ c.ads.forEach((u, l) => {
1074
+ const d = u.original.id;
1075
+ this.adsAnalyticsMap.set(d, {
1076
+ requestId: o.requestId,
1083
1077
  slotId: c.slotId,
1084
1078
  position: l,
1085
1079
  totalAds: c.ads.length,
@@ -1089,14 +1083,14 @@ const g = class g {
1089
1083
  });
1090
1084
  });
1091
1085
  const a = {};
1092
- return r.slots.forEach((c) => {
1086
+ return o.slots.forEach((c) => {
1093
1087
  a[c.slotId] = c;
1094
1088
  }), this.slots = a, this.eventBus.emit("adsUpdated", this.slots), this.config.debug && console.log("[AdManager] Ads received:", {
1095
1089
  slotCount: Object.keys(this.slots).length,
1096
1090
  slots: Object.keys(this.slots)
1097
- }), r;
1098
- } catch (r) {
1099
- const a = r;
1091
+ }), o;
1092
+ } catch (o) {
1093
+ const a = o;
1100
1094
  throw this.eventBus.emit("adsError", a), a;
1101
1095
  } finally {
1102
1096
  this.isLoading = !1, g.inFlightRequests.delete(i);
@@ -1123,24 +1117,24 @@ const g = class g {
1123
1117
  }
1124
1118
  }
1125
1119
  render(e, t, i = {}) {
1126
- const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, r = s ? e : t, a = (s ? t : i) || {};
1127
- if (!r)
1120
+ const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, o = s ? e : t, a = (s ? t : i) || {};
1121
+ if (!o)
1128
1122
  return this.config.debug && console.warn("[AdManager] Render container is required"), null;
1129
1123
  const c = this.slots[n];
1130
1124
  if (!c || !c.ads || c.ads.length === 0)
1131
1125
  return this.config.debug && console.warn("[AdManager] No ads in slot:", n), null;
1132
- const d = a.adIndex ?? 0, l = c.ads[d];
1126
+ const u = a.adIndex ?? 0, l = c.ads[u];
1133
1127
  if (!l)
1134
- return this.config.debug && console.warn(`[AdManager] Ad at index ${d} not found in slot:`, n), null;
1135
- const u = this.adsAnalyticsMap.get(l.original.id), h = this.slots_config.find((v) => v.slotId === n), p = (h == null ? void 0 : h.format) || "action_card";
1136
- r.innerHTML = "";
1128
+ return this.config.debug && console.warn(`[AdManager] Ad at index ${u} not found in slot:`, n), null;
1129
+ const d = this.adsAnalyticsMap.get(l.original.id), h = this.slots_config.find((k) => k.slotId === n), p = (h == null ? void 0 : h.format) || "action_card";
1130
+ o.innerHTML = "";
1137
1131
  const f = {
1138
- analytics: u,
1132
+ analytics: d,
1139
1133
  variant: a.variant,
1140
1134
  onClick: a.onClick,
1141
1135
  onImpression: a.onImpression
1142
1136
  };
1143
- return p === "suffix" ? y.renderSuffixAd(l, r, f) : p === "source" ? y.renderSponsoredSource(l, r, f) : p === "lead_gen" ? y.renderLeadGenAd(l, r, f) : y.renderActionCard(l, r, f);
1137
+ return p === "suffix" ? y.renderSuffixAd(l, o, f) : p === "source" ? y.renderSponsoredSource(l, o, f) : p === "lead_gen" ? y.renderLeadGenAd(l, o, f) : y.renderActionCard(l, o, f);
1144
1138
  }
1145
1139
  /**
1146
1140
  * Get ad slots data
@@ -1234,7 +1228,7 @@ const g = class g {
1234
1228
  const s = this.adsAnalyticsMap.get(e);
1235
1229
  if (!s || !this.currentRequestId)
1236
1230
  return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
1237
- const n = m(), r = await S({
1231
+ const n = w(), o = await B({
1238
1232
  requestId: this.currentRequestId,
1239
1233
  adId: e,
1240
1234
  destinationUrl: t,
@@ -1245,7 +1239,7 @@ const g = class g {
1245
1239
  source: i == null ? void 0 : i.source,
1246
1240
  userId: s.userId ?? this.currentUserId
1247
1241
  }, { baseUrl: s.apiBaseUrl });
1248
- return r && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", r.eventId)), r;
1242
+ return o && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", o.eventId)), o;
1249
1243
  }
1250
1244
  /**
1251
1245
  * Track ad impression using Analytics API
@@ -1254,7 +1248,7 @@ const g = class g {
1254
1248
  const i = this.adsAnalyticsMap.get(e);
1255
1249
  if (!i || !this.currentRequestId)
1256
1250
  return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
1257
- const s = m(), n = await I({
1251
+ const s = w(), n = await S({
1258
1252
  requestId: this.currentRequestId,
1259
1253
  adId: e,
1260
1254
  slotId: i.slotId,
@@ -1280,12 +1274,12 @@ g.DEFAULT_SLOT_ID = "action_card", g.inFlightRequests = /* @__PURE__ */ new Map(
1280
1274
  let V = g;
1281
1275
  function E() {
1282
1276
  if (typeof window < "u") {
1283
- const o = window.__AD_CONFIG__;
1284
- if (o != null && o.apiKey)
1285
- return o.apiKey;
1277
+ const r = window.__AD_CONFIG__;
1278
+ if (r != null && r.apiKey)
1279
+ return r.apiKey;
1286
1280
  }
1287
1281
  }
1288
- class G {
1282
+ class z {
1289
1283
  constructor(e = {}, t = "/api/v1") {
1290
1284
  var i, s;
1291
1285
  this.observers = /* @__PURE__ */ new Map(), this.metrics = /* @__PURE__ */ new Map(), this.timers = /* @__PURE__ */ new Map(), this.batchTimers = /* @__PURE__ */ new Map(), this.eventQueue = /* @__PURE__ */ new Map(), this.isTracking = /* @__PURE__ */ new Map(), this.config = {
@@ -1308,7 +1302,7 @@ class G {
1308
1302
  return;
1309
1303
  }
1310
1304
  this.log(`[ViewabilityTracker] Starting tracking for ${e}`);
1311
- const r = {
1305
+ const o = {
1312
1306
  visiblePercentage: 0,
1313
1307
  maxVisiblePercentage: 0,
1314
1308
  totalVisibleTimeMs: 0,
@@ -1318,9 +1312,9 @@ class G {
1318
1312
  enteredViewportAt: null,
1319
1313
  enterCount: 0
1320
1314
  };
1321
- this.metrics.set(e, r), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
1315
+ this.metrics.set(e, o), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
1322
1316
  const a = new IntersectionObserver(
1323
- (d) => this.handleIntersection(e, d[0], i, s, n),
1317
+ (u) => this.handleIntersection(e, u[0], i, s, n),
1324
1318
  {
1325
1319
  threshold: this.createThresholds()
1326
1320
  }
@@ -1348,54 +1342,54 @@ class G {
1348
1342
  * Event-driven: Only process when state actually changes
1349
1343
  */
1350
1344
  handleIntersection(e, t, i, s, n) {
1351
- const r = this.metrics.get(e);
1352
- if (!r || !this.isTracking.get(e)) return;
1353
- const a = r.isViewable, c = Math.round(t.intersectionRatio * 100);
1354
- r.visiblePercentage = c, r.maxVisiblePercentage = Math.max(r.maxVisiblePercentage, c);
1355
- const d = Date.now(), l = c >= this.config.minVisiblePercentage;
1356
- if (l && !r.enteredViewportAt && (r.enteredViewportAt = d, r.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${d}`), this.queueEvent(e, {
1345
+ const o = this.metrics.get(e);
1346
+ if (!o || !this.isTracking.get(e)) return;
1347
+ const a = o.isViewable, c = Math.round(t.intersectionRatio * 100);
1348
+ o.visiblePercentage = c, o.maxVisiblePercentage = Math.max(o.maxVisiblePercentage, c);
1349
+ const u = Date.now(), l = c >= this.config.minVisiblePercentage;
1350
+ if (l && !o.enteredViewportAt && (o.enteredViewportAt = u, o.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${u}`), this.queueEvent(e, {
1357
1351
  adId: e,
1358
1352
  sessionId: i,
1359
1353
  requestId: s,
1360
1354
  viewToken: n,
1361
1355
  eventType: "enter_viewport",
1362
1356
  visiblePercentage: c,
1363
- maxVisiblePercentage: r.maxVisiblePercentage,
1364
- totalVisibleTimeMs: r.totalVisibleTimeMs,
1357
+ maxVisiblePercentage: o.maxVisiblePercentage,
1358
+ totalVisibleTimeMs: o.totalVisibleTimeMs,
1365
1359
  isViewable: !1,
1366
- timestamp: d
1367
- })), !l && r.enteredViewportAt) {
1368
- const u = d - r.enteredViewportAt;
1369
- r.totalVisibleTimeMs += u, r.enteredViewportAt = null, r.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${r.totalVisibleTimeMs}ms`), this.queueEvent(e, {
1360
+ timestamp: u
1361
+ })), !l && o.enteredViewportAt) {
1362
+ const d = u - o.enteredViewportAt;
1363
+ o.totalVisibleTimeMs += d, o.enteredViewportAt = null, o.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${o.totalVisibleTimeMs}ms`), this.queueEvent(e, {
1370
1364
  adId: e,
1371
1365
  sessionId: i,
1372
1366
  requestId: s,
1373
1367
  viewToken: n,
1374
1368
  eventType: "exit_viewport",
1375
1369
  visiblePercentage: c,
1376
- maxVisiblePercentage: r.maxVisiblePercentage,
1377
- totalVisibleTimeMs: r.totalVisibleTimeMs,
1378
- isViewable: r.isViewable,
1379
- timestamp: d
1370
+ maxVisiblePercentage: o.maxVisiblePercentage,
1371
+ totalVisibleTimeMs: o.totalVisibleTimeMs,
1372
+ isViewable: o.isViewable,
1373
+ timestamp: u
1380
1374
  });
1381
1375
  }
1382
- r.isViewable !== a && r.isViewable && this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`), this.metrics.set(e, r);
1376
+ o.isViewable !== a && o.isViewable && this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`), this.metrics.set(e, o);
1383
1377
  }
1384
1378
  /**
1385
1379
  * Start monitoring loop for tracking duration
1386
1380
  * Runs every 100ms to track continuous visible time
1387
1381
  */
1388
1382
  startMonitoring(e, t, i, s) {
1389
- const r = setInterval(() => {
1383
+ const o = setInterval(() => {
1390
1384
  const a = this.metrics.get(e);
1391
1385
  if (!a || !this.isTracking.get(e)) {
1392
- clearInterval(r);
1386
+ clearInterval(o);
1393
1387
  return;
1394
1388
  }
1395
- const c = Date.now(), d = a.isViewable;
1389
+ const c = Date.now(), u = a.isViewable;
1396
1390
  if (a.enteredViewportAt) {
1397
1391
  const l = c - a.enteredViewportAt;
1398
- 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, {
1392
+ a.currentVisibleTimeMs = l, l >= this.config.minViewableDuration && a.visiblePercentage >= this.config.minVisiblePercentage && (a.isViewable = !0, u || (a.viewableAt = a.enteredViewportAt, this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`), this.queueEvent(e, {
1399
1393
  adId: e,
1400
1394
  sessionId: t,
1401
1395
  requestId: i,
@@ -1410,13 +1404,13 @@ class G {
1410
1404
  }
1411
1405
  a.enteredViewportAt && (a.totalVisibleTimeMs += 100), this.metrics.set(e, a);
1412
1406
  }, 100);
1413
- this.timers.set(`${e}_monitoring`, r);
1407
+ this.timers.set(`${e}_monitoring`, o);
1414
1408
  }
1415
1409
  /**
1416
1410
  * Queue an event to be sent (batched)
1417
1411
  */
1418
1412
  queueEvent(e, t) {
1419
- var n, r;
1413
+ var n, o;
1420
1414
  const i = this.eventQueue.get(e);
1421
1415
  if (!i) {
1422
1416
  this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);
@@ -1429,10 +1423,10 @@ class G {
1429
1423
  else {
1430
1424
  const a = this.batchTimers.get(e);
1431
1425
  a && clearTimeout(a);
1432
- const c = ((r = this.config.batchConfig) == null ? void 0 : r.maxBatchWaitMs) ?? 1e4, d = setTimeout(() => {
1426
+ const c = ((o = this.config.batchConfig) == null ? void 0 : o.maxBatchWaitMs) ?? 1e4, u = setTimeout(() => {
1433
1427
  this.flushQueue(e);
1434
1428
  }, c);
1435
- this.batchTimers.set(e, d);
1429
+ this.batchTimers.set(e, u);
1436
1430
  }
1437
1431
  }
1438
1432
  /**
@@ -1463,7 +1457,7 @@ class G {
1463
1457
  const n = this.metrics.get(e);
1464
1458
  if (!n) return;
1465
1459
  this.log(`[ViewabilityTracker] Ending tracking for ${e}`), this.flushQueue(e);
1466
- const r = Date.now();
1460
+ const o = Date.now();
1467
1461
  this.queueEvent(e, {
1468
1462
  adId: e,
1469
1463
  sessionId: t,
@@ -1474,7 +1468,7 @@ class G {
1474
1468
  maxVisiblePercentage: n.maxVisiblePercentage,
1475
1469
  totalVisibleTimeMs: n.totalVisibleTimeMs,
1476
1470
  isViewable: n.isViewable,
1477
- timestamp: r
1471
+ timestamp: o
1478
1472
  }), this.flushQueue(e), this.cleanup(e);
1479
1473
  }
1480
1474
  /**
@@ -1532,39 +1526,39 @@ class G {
1532
1526
  });
1533
1527
  }
1534
1528
  }
1535
- let k = null;
1536
- function ne(o, e) {
1537
- return k || (k = new G(o, e), k.setupBeforeUnload()), k;
1529
+ let x = null;
1530
+ function re(r, e) {
1531
+ return x || (x = new z(r, e), x.setupBeforeUnload()), x;
1538
1532
  }
1539
- const re = "0.1.0";
1533
+ const oe = "0.1.0";
1540
1534
  export {
1541
1535
  V as AdManager,
1542
- x as AnalyticsSender,
1536
+ A as AnalyticsSender,
1543
1537
  T as ClientInfoCollector,
1544
1538
  y as DOMRenderer,
1545
- w as HTMLRenderer,
1546
- re as SDK_VERSION,
1539
+ v as HTMLRenderer,
1540
+ oe as SDK_VERSION,
1547
1541
  P as SessionManager,
1548
- G as ViewabilityTracker,
1549
- se as adaptAdToKoahAd,
1550
- ee as clearClientInfoCache,
1551
- Q as createAnalytics,
1552
- J as createSession,
1553
- H as fetchAds,
1554
- z as generateViewToken,
1555
- Z as getAppInfo,
1542
+ z as ViewabilityTracker,
1543
+ ne as adaptAdToKoahAd,
1544
+ te as clearClientInfoCache,
1545
+ J as createAnalytics,
1546
+ X as createSession,
1547
+ F as fetchAds,
1548
+ j as generateViewToken,
1549
+ Y as getAppInfo,
1556
1550
  b as getClientInfo,
1557
1551
  $ as getClientInfoCollector,
1558
- te as getClientInfoJSON,
1559
- ie as getClientInfoSummary,
1560
- X as getDeviceInfo,
1561
- Y as getGeoInfo,
1562
- m as getSessionId,
1552
+ ie as getClientInfoJSON,
1553
+ se as getClientInfoSummary,
1554
+ Z as getDeviceInfo,
1555
+ ee as getGeoInfo,
1556
+ w as getSessionId,
1563
1557
  D as getUserId,
1564
- N as getUserInfo,
1565
- ne as getViewabilityTracker,
1566
- S as trackAdClick,
1567
- I as trackAdImpression,
1568
- W as trackClicksBatch,
1569
- j as trackImpressionsBatch
1558
+ H as getUserInfo,
1559
+ re as getViewabilityTracker,
1560
+ B as trackAdClick,
1561
+ S as trackAdImpression,
1562
+ Q as trackClicksBatch,
1563
+ W as trackImpressionsBatch
1570
1564
  };