@treasuredata/web-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +807 -0
  4. package/dist/browser.d.ts +9 -0
  5. package/dist/checksums.txt +8 -0
  6. package/dist/core/config.d.ts +10 -0
  7. package/dist/core/config.template.d.ts +10 -0
  8. package/dist/core/configurator.d.ts +35 -0
  9. package/dist/core/sdk.d.ts +3 -0
  10. package/dist/index.d.ts +37 -0
  11. package/dist/init.d.ts +18 -0
  12. package/dist/loader.d.ts +59 -0
  13. package/dist/loader.js +1 -0
  14. package/dist/loader.min.js +1 -0
  15. package/dist/plugins/clicks.d.ts +21 -0
  16. package/dist/plugins/conversion-api.d.ts +23 -0
  17. package/dist/plugins/global-id.d.ts +17 -0
  18. package/dist/plugins/in-browser-message.d.ts +6 -0
  19. package/dist/plugins/page-personalize/bridge/constants.d.ts +9 -0
  20. package/dist/plugins/page-personalize/bridge/rpc.d.ts +15 -0
  21. package/dist/plugins/page-personalize/index.d.ts +34 -0
  22. package/dist/plugins/page-personalize/injection/inject.d.ts +17 -0
  23. package/dist/plugins/page-personalize/modes/preview.d.ts +3 -0
  24. package/dist/plugins/page-personalize/modes/spot-selection.d.ts +9 -0
  25. package/dist/plugins/page-personalize/offers.d.ts +72 -0
  26. package/dist/plugins/page-personalize/router.d.ts +17 -0
  27. package/dist/plugins/page-personalize/types.d.ts +27 -0
  28. package/dist/plugins/page-personalize/utils/selector-generator.d.ts +6 -0
  29. package/dist/plugins/personalization.d.ts +39 -0
  30. package/dist/plugins/record.d.ts +32 -0
  31. package/dist/plugins/server-cookie.d.ts +14 -0
  32. package/dist/plugins/session.d.ts +25 -0
  33. package/dist/plugins/track.d.ts +16 -0
  34. package/dist/plugins/utm.d.ts +16 -0
  35. package/dist/td-sdk.cjs +3263 -0
  36. package/dist/td-sdk.esm.js +3263 -0
  37. package/dist/td-sdk.esm.min.js +1 -0
  38. package/dist/td-sdk.js +3176 -0
  39. package/dist/td-sdk.min.cjs +1 -0
  40. package/dist/td-sdk.min.js +1 -0
  41. package/dist/treasure.d.ts +198 -0
  42. package/dist/types/index.d.ts +177 -0
  43. package/dist/utils/element.d.ts +20 -0
  44. package/dist/utils/lodash.d.ts +18 -0
  45. package/dist/utils/misc.d.ts +17 -0
  46. package/dist/utils/set-cookie.d.ts +14 -0
  47. package/dist/utils/uuid.d.ts +14 -0
  48. package/dist/utils/xhr.d.ts +58 -0
  49. package/dist/vendor/js-cookies.d.ts +19 -0
  50. package/package.json +90 -0
@@ -0,0 +1,3263 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ function createSDK(config) {
4
+ if (!config || typeof config.writeKey !== "string" || !config.writeKey) {
5
+ throw new Error("TreasureSDK: writeKey is required");
6
+ }
7
+ if (!config.database) {
8
+ throw new Error("TreasureSDK: database is required");
9
+ }
10
+ const logger = {
11
+ debug: (...args) => {
12
+ if (config.development) console.debug("[TreasureSDK]", ...args);
13
+ },
14
+ warn: (...args) => console.warn("[TreasureSDK]", ...args),
15
+ error: (...args) => console.error("[TreasureSDK]", ...args)
16
+ };
17
+ const core = {
18
+ config: { ...config },
19
+ log: logger
20
+ };
21
+ const sdk = {
22
+ ...core,
23
+ use(plugin) {
24
+ core.log.debug(`Loading plugin: ${plugin.name}`);
25
+ const methods = plugin.setup(core, sdk);
26
+ for (const key of Object.keys(methods)) {
27
+ if (key in sdk) {
28
+ throw new Error(
29
+ `TreasureSDK: plugin "${plugin.name}" conflicts on "${key}"`
30
+ );
31
+ }
32
+ }
33
+ Object.assign(sdk, methods);
34
+ return sdk;
35
+ },
36
+ getWriteKey() {
37
+ return core.config.writeKey;
38
+ },
39
+ setWriteKey(writeKey) {
40
+ if (!writeKey || typeof writeKey !== "string") {
41
+ throw new Error("TreasureSDK: writeKey must be a non-empty string");
42
+ }
43
+ core.config.writeKey = writeKey;
44
+ }
45
+ };
46
+ return sdk;
47
+ }
48
+ function isObject$1(value) {
49
+ return typeof value === "object" && value !== null && !Array.isArray(value);
50
+ }
51
+ function isString(value) {
52
+ return typeof value === "string";
53
+ }
54
+ function isArray(value) {
55
+ return Array.isArray(value);
56
+ }
57
+ function isEmpty(value) {
58
+ if (value == null) return true;
59
+ if (isArray(value) || isString(value)) return value.length === 0;
60
+ if (isObject$1(value)) return Object.keys(value).length === 0;
61
+ return false;
62
+ }
63
+ function assign(target, ...sources) {
64
+ return Object.assign(target, ...sources);
65
+ }
66
+ function omit(obj, ...keysToOmit) {
67
+ const result = { ...obj };
68
+ keysToOmit.forEach((key) => delete result[key]);
69
+ return result;
70
+ }
71
+ function disposable(action) {
72
+ let disposed = false;
73
+ return function dispose() {
74
+ if (!disposed) {
75
+ disposed = true;
76
+ action();
77
+ }
78
+ };
79
+ }
80
+ function invariant$1(condition, text) {
81
+ if (!condition) {
82
+ throw new Error(text);
83
+ }
84
+ }
85
+ function isLocalStorageAccessible() {
86
+ const test = "__td__";
87
+ try {
88
+ localStorage.setItem(test, test);
89
+ localStorage.removeItem(test);
90
+ return true;
91
+ } catch {
92
+ return false;
93
+ }
94
+ }
95
+ const adlHeaders = {
96
+ "Content-Type": "application/vnd.treasuredata.v1+json",
97
+ Accept: "application/vnd.treasuredata.v1+json"
98
+ };
99
+ const globalIdAdlHeaders = {
100
+ "Content-Type": "application/vnd.treasuredata.v1.js+json",
101
+ Accept: "application/vnd.treasuredata.v1.js+json"
102
+ };
103
+ const CONFIG = {
104
+ VERSION: "1.0.0",
105
+ HOST: "us01.records.in.treasuredata.com",
106
+ DATABASE: "",
107
+ PATHNAME: "/"
108
+ };
109
+ function encode(val) {
110
+ try {
111
+ return encodeURIComponent(val);
112
+ } catch (e) {
113
+ console.error("error encode %o", e);
114
+ return null;
115
+ }
116
+ }
117
+ function decode(val) {
118
+ try {
119
+ return decodeURIComponent(val);
120
+ } catch (err) {
121
+ console.error("error decode %o", err);
122
+ return null;
123
+ }
124
+ }
125
+ function handleSkey(sKey) {
126
+ const encoded = encode(sKey);
127
+ return encoded ? encoded.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&") : "";
128
+ }
129
+ const cookie = {
130
+ getItem(sKey) {
131
+ if (!sKey) {
132
+ return null;
133
+ }
134
+ const regex = new RegExp(
135
+ "(?:(?:^|.*;)\\s*" + handleSkey(sKey) + "\\s*\\=\\s*([^;]*).*$)|^.*$"
136
+ );
137
+ const match = document.cookie.replace(regex, "$1");
138
+ return decode(match) || null;
139
+ },
140
+ setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure, sameSite) {
141
+ if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
142
+ return false;
143
+ }
144
+ let sExpires = "";
145
+ if (vEnd) {
146
+ if (typeof vEnd === "number") {
147
+ if (vEnd === Infinity) {
148
+ sExpires = "; expires=Fri, 31 Dec 9999 23:59:59 GMT";
149
+ } else {
150
+ sExpires = "; max-age=" + vEnd;
151
+ }
152
+ } else if (typeof vEnd === "string") {
153
+ sExpires = "; expires=" + vEnd;
154
+ } else if (vEnd instanceof Date) {
155
+ sExpires = "; expires=" + vEnd.toUTCString();
156
+ }
157
+ }
158
+ let secureAndSameSite = "";
159
+ if (sameSite && sameSite.toUpperCase() === "NONE") {
160
+ secureAndSameSite = "; Secure; SameSite=" + sameSite;
161
+ } else {
162
+ if (bSecure) {
163
+ secureAndSameSite += "; Secure";
164
+ }
165
+ if (sameSite) {
166
+ secureAndSameSite += "; SameSite=" + sameSite;
167
+ }
168
+ }
169
+ const encodedKey = encode(sKey);
170
+ const encodedValue = encode(sValue);
171
+ if (!encodedKey || !encodedValue) {
172
+ return false;
173
+ }
174
+ document.cookie = [
175
+ encodedKey,
176
+ "=",
177
+ encodedValue,
178
+ sExpires,
179
+ sDomain ? "; domain=" + sDomain : "",
180
+ sPath ? "; path=" + sPath : "",
181
+ secureAndSameSite
182
+ ].join("");
183
+ return true;
184
+ },
185
+ removeItem(sKey, sPath, sDomain) {
186
+ if (!this.hasItem(sKey)) {
187
+ return false;
188
+ }
189
+ const encodedKey = encode(sKey);
190
+ if (!encodedKey) {
191
+ return false;
192
+ }
193
+ document.cookie = [
194
+ encodedKey,
195
+ "=; expires=Thu, 01 Jan 1970 00:00:00 GMT",
196
+ sDomain ? "; domain=" + sDomain : "",
197
+ sPath ? "; path=" + sPath : ""
198
+ ].join("");
199
+ return true;
200
+ },
201
+ hasItem(sKey) {
202
+ if (!sKey) {
203
+ return false;
204
+ }
205
+ const encodedKey = encode(sKey);
206
+ if (!encodedKey) {
207
+ return false;
208
+ }
209
+ return new RegExp(
210
+ "(?:^|;\\s*)" + encodedKey.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&") + "\\s*\\="
211
+ ).test(document.cookie);
212
+ },
213
+ keys() {
214
+ const aKeys = document.cookie.replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:=[^;]*)?;\s*/);
215
+ return aKeys.map((key) => decode(key)).filter((key) => key !== null);
216
+ }
217
+ };
218
+ function validateOptions(options) {
219
+ invariant$1(
220
+ isObject$1(options),
221
+ "Check out our JavaScript SDK Usage Guide: https://github.com/treasure-data/td-js-sdk#api"
222
+ );
223
+ invariant$1(isString(options.writeKey), "Must provide a writeKey");
224
+ invariant$1(isString(options.database), "Must provide a database");
225
+ invariant$1(
226
+ options.database && /^[a-z0-9_]{3,255}$/.test(options.database),
227
+ "Database must be between 3 and 255 characters and must consist only of lower case letters, numbers, and _"
228
+ );
229
+ }
230
+ function defaultSSCCookieDomain() {
231
+ if (typeof document === "undefined") {
232
+ return "localhost";
233
+ }
234
+ const domainChunks = document.location.hostname.split(".");
235
+ for (let i = domainChunks.length - 2; i >= 1; i--) {
236
+ const domain = domainChunks.slice(i).join(".");
237
+ const name = "_td_domain_" + domain;
238
+ cookie.setItem(name, domain, 3600, "/", domain);
239
+ if (cookie.getItem(name) === domain) {
240
+ return domain;
241
+ }
242
+ }
243
+ return document.location.hostname;
244
+ }
245
+ const DEFAULT_CONFIG = {
246
+ database: CONFIG.DATABASE,
247
+ development: false,
248
+ globalIdCookie: "_td_global",
249
+ host: CONFIG.HOST,
250
+ logging: true,
251
+ pathname: CONFIG.PATHNAME,
252
+ requestType: "fetch",
253
+ jsonpTimeout: 1e4,
254
+ startInSignedMode: false,
255
+ useServerSideCookie: false,
256
+ sscDomain: defaultSSCCookieDomain,
257
+ sscServer: function(cookieDomain) {
258
+ return ["ssc", cookieDomain].join(".");
259
+ },
260
+ storeConsentByLocalStorage: false
261
+ };
262
+ function configure(options) {
263
+ const client = assign(
264
+ {},
265
+ {
266
+ globals: {}
267
+ },
268
+ DEFAULT_CONFIG,
269
+ options,
270
+ {
271
+ requestType: "fetch"
272
+ }
273
+ );
274
+ validateOptions(client);
275
+ if (!client.endpoint) {
276
+ client.endpoint = "https://" + client.host + client.pathname;
277
+ }
278
+ if (!client.storage) {
279
+ client.storage = {
280
+ name: "_td",
281
+ domain: typeof window !== "undefined" && typeof document !== "undefined" ? document.location.hostname : "localhost",
282
+ expires: 63072e3,
283
+ // 2 years in seconds
284
+ path: "/"
285
+ };
286
+ }
287
+ return client;
288
+ }
289
+ function findDomains(domain) {
290
+ const domainChunks = domain.split(".");
291
+ const domains = [];
292
+ for (let i = domainChunks.length - 1; i >= 0; i--) {
293
+ domains.push(domainChunks.slice(i).join("."));
294
+ }
295
+ return domains;
296
+ }
297
+ function setCookie(storage, name, value) {
298
+ const clone = { ...storage };
299
+ const is = {
300
+ ip: storage.domain.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/),
301
+ local: storage.domain === "localhost",
302
+ custom: storage.customDomain
303
+ };
304
+ const expires = /* @__PURE__ */ new Date();
305
+ expires.setSeconds(expires.getSeconds() + clone.expires);
306
+ if (is.local) {
307
+ if (!value) {
308
+ cookie.removeItem(name, clone.path, clone.domain);
309
+ } else {
310
+ cookie.setItem(name, value, expires, clone.path);
311
+ }
312
+ } else if (is.ip || is.custom) {
313
+ if (!value) {
314
+ cookie.removeItem(name, clone.path, clone.domain);
315
+ } else {
316
+ cookie.setItem(
317
+ name,
318
+ value,
319
+ expires,
320
+ clone.path,
321
+ clone.domain,
322
+ true,
323
+ "None"
324
+ );
325
+ }
326
+ } else {
327
+ const domains = findDomains(storage.domain);
328
+ const ll = domains.length;
329
+ let i = 0;
330
+ if (!value) {
331
+ for (; i < ll; i++) {
332
+ cookie.removeItem(name, storage.path, domains[i]);
333
+ }
334
+ } else {
335
+ if (cookie.getItem(name) === value) return;
336
+ for (; i < ll; i++) {
337
+ clone.domain = domains[i];
338
+ cookie.setItem(
339
+ name,
340
+ value,
341
+ expires,
342
+ clone.path,
343
+ clone.domain,
344
+ true,
345
+ "None"
346
+ );
347
+ if (cookie.getItem(name) === value) {
348
+ storage.domain = clone.domain;
349
+ break;
350
+ }
351
+ }
352
+ }
353
+ }
354
+ }
355
+ function generateUUID$1() {
356
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
357
+ return crypto.randomUUID();
358
+ }
359
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
360
+ const bytes = new Uint8Array(16);
361
+ crypto.getRandomValues(bytes);
362
+ bytes[6] = bytes[6] & 15 | 64;
363
+ bytes[8] = bytes[8] & 63 | 128;
364
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
365
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
366
+ }
367
+ throw new Error(
368
+ "Secure random number generation is not available in this environment"
369
+ );
370
+ }
371
+ function isValidUUID(uuid) {
372
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
373
+ return uuidRegex.test(uuid);
374
+ }
375
+ const FETCH_CREDENTIALS = {
376
+ "same-origin": "same-origin",
377
+ include: "include",
378
+ omit: "omit"
379
+ };
380
+ function toJSON(text) {
381
+ let result;
382
+ try {
383
+ result = JSON.parse(text);
384
+ } catch {
385
+ result = {};
386
+ }
387
+ return result;
388
+ }
389
+ function getCredentials(options = {}) {
390
+ return FETCH_CREDENTIALS[options.credentials || "include"] || "include";
391
+ }
392
+ function post(url, body, options = {}) {
393
+ const headers = options.headers || {};
394
+ const credentials = getCredentials(options);
395
+ const fetchOptions = {
396
+ method: "POST",
397
+ headers,
398
+ keepalive: true,
399
+ body: JSON.stringify(body)
400
+ };
401
+ {
402
+ fetchOptions.credentials = credentials;
403
+ }
404
+ if (options.signal) {
405
+ fetchOptions.signal = options.signal;
406
+ }
407
+ return fetch(url, fetchOptions).then(function(response) {
408
+ if (!response.ok) {
409
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
410
+ }
411
+ return response.text();
412
+ }).then(function(text) {
413
+ return toJSON(text);
414
+ });
415
+ }
416
+ function get(url, options = {}) {
417
+ const headers = options.headers || {};
418
+ const credentials = getCredentials(options);
419
+ const fetchOptions = {
420
+ method: "GET",
421
+ headers
422
+ };
423
+ {
424
+ fetchOptions.credentials = credentials;
425
+ }
426
+ if (options.signal) {
427
+ fetchOptions.signal = options.signal;
428
+ }
429
+ return fetch(url, fetchOptions).then(function(response) {
430
+ if (!response.ok) {
431
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
432
+ }
433
+ return response.text();
434
+ }).then(function(text) {
435
+ return toJSON(text);
436
+ });
437
+ }
438
+ function withTimeout(promiseFactory, milliseconds, timeoutMessage) {
439
+ const controller = new AbortController();
440
+ let timeoutId;
441
+ const timeoutPromise2 = new Promise((_, reject) => {
442
+ timeoutId = setTimeout(() => {
443
+ controller.abort();
444
+ reject(new Error(timeoutMessage || "Operation Timeout"));
445
+ }, milliseconds);
446
+ });
447
+ const promise = promiseFactory(controller.signal).finally(() => {
448
+ clearTimeout(timeoutId);
449
+ });
450
+ return Promise.race([promise, timeoutPromise2]).catch((error) => {
451
+ clearTimeout(timeoutId);
452
+ if (error.name === "AbortError") {
453
+ throw new Error(timeoutMessage || "Operation Timeout");
454
+ }
455
+ throw error;
456
+ });
457
+ }
458
+ function postWithTimeout(url, body, milliseconds, options = {}) {
459
+ return withTimeout(
460
+ (signal) => post(url, body, { ...options, signal }),
461
+ milliseconds,
462
+ "Request Timeout"
463
+ );
464
+ }
465
+ function getWithTimeout(url, milliseconds, options = {}) {
466
+ return withTimeout(
467
+ (signal) => get(url, { ...options, signal }),
468
+ milliseconds,
469
+ "Request Timeout"
470
+ );
471
+ }
472
+ function timeoutPromise(promiseFactory, milliseconds, timeoutMessage) {
473
+ return withTimeout((_signal) => promiseFactory(), milliseconds, timeoutMessage);
474
+ }
475
+ const api = {
476
+ post,
477
+ get,
478
+ postWithTimeout,
479
+ getWithTimeout,
480
+ withTimeout,
481
+ timeoutPromise
482
+ };
483
+ const SERVER_COOKIE_NAME = "_td_ssc_id";
484
+ const COOKIE_NAME = SERVER_COOKIE_NAME;
485
+ function serverCookie() {
486
+ return {
487
+ name: "serverCookie",
488
+ setup(core, sdk) {
489
+ const config = core.config;
490
+ let serverCookieDomain;
491
+ let serverCookieDomainHost;
492
+ const noop = () => {
493
+ };
494
+ function initializeServerCookieConfig() {
495
+ if (!serverCookieDomainHost) {
496
+ if (typeof config.sscDomain === "function") {
497
+ serverCookieDomain = config.sscDomain();
498
+ } else {
499
+ serverCookieDomain = config.sscDomain || (typeof window !== "undefined" ? window.location.hostname : "localhost");
500
+ }
501
+ if (typeof config.sscServer === "function") {
502
+ serverCookieDomainHost = config.sscServer(serverCookieDomain);
503
+ } else {
504
+ serverCookieDomainHost = config.sscServer || `ssc.${serverCookieDomain}`;
505
+ }
506
+ }
507
+ }
508
+ function fetchServerCookie(success, error, forceFetch = false) {
509
+ const successCallback = success || noop;
510
+ const errorCallback = error || noop;
511
+ if (typeof sdk.inSignedMode === "function" && !sdk.inSignedMode()) {
512
+ return errorCallback("not in signed in mode");
513
+ }
514
+ if (!config.useServerSideCookie) {
515
+ return errorCallback("server side cookie not enabled");
516
+ }
517
+ initializeServerCookieConfig();
518
+ if (!serverCookieDomain || !serverCookieDomainHost) {
519
+ return errorCallback(
520
+ "server cookie configuration not properly initialized"
521
+ );
522
+ }
523
+ const url = `https://${serverCookieDomainHost}/get_cookie_id?cookie_domain=${encodeURIComponent(serverCookieDomain)}&r=${Date.now()}`;
524
+ const cachedSSCId = cookie.getItem(COOKIE_NAME);
525
+ if (cachedSSCId && !forceFetch) {
526
+ setTimeout(() => {
527
+ successCallback(cachedSSCId);
528
+ }, 0);
529
+ return;
530
+ }
531
+ api.getWithTimeout(url, 1e4).then((response) => {
532
+ successCallback(response.td_ssc_id);
533
+ }).catch((err) => {
534
+ errorCallback(err);
535
+ });
536
+ }
537
+ return {
538
+ fetchServerCookie
539
+ };
540
+ }
541
+ };
542
+ }
543
+ const BLOCKEVENTSCOOKIE = "__td_blockEvents";
544
+ const SIGNEDMODECOOKIE = "__td_signed";
545
+ function configureStorage(storage) {
546
+ if (storage === "none") return null;
547
+ const s = typeof storage === "object" && storage !== null ? storage : {};
548
+ return {
549
+ name: s.name || "_td",
550
+ expires: s.expires ?? 63072e3,
551
+ domain: s.domain || document.location.hostname,
552
+ customDomain: !!s.domain,
553
+ path: s.path || "/"
554
+ };
555
+ }
556
+ function setStorageCookie(storage, name, value) {
557
+ try {
558
+ setCookie(storage, name, value || "");
559
+ } catch {
560
+ }
561
+ }
562
+ function session() {
563
+ return {
564
+ name: "session",
565
+ setup(core, sdk) {
566
+ const config = core.config;
567
+ const startInSignedMode = config.startInSignedMode ?? false;
568
+ const storeConsentByLocalStorage = config.storeConsentByLocalStorage ?? false;
569
+ const globals = {};
570
+ function set(table, property, value) {
571
+ let tableName;
572
+ let prop = property;
573
+ if (typeof table === "object" && table !== null) {
574
+ prop = table;
575
+ tableName = "$global";
576
+ } else {
577
+ tableName = table;
578
+ }
579
+ const bucket = globals[tableName] || {};
580
+ globals[tableName] = bucket;
581
+ if (typeof prop === "object" && prop !== null) {
582
+ Object.assign(bucket, prop);
583
+ } else if (typeof prop === "string" && value !== void 0) {
584
+ bucket[prop] = value;
585
+ }
586
+ }
587
+ function get2(table, key) {
588
+ const t = table || "$global";
589
+ globals[t] = globals[t] || {};
590
+ return key ? globals[t]?.[key] ?? null : globals[t];
591
+ }
592
+ const storage = configureStorage(config.storage);
593
+ let clientId;
594
+ if (config.clientId != null) {
595
+ clientId = typeof config.clientId === "number" ? config.clientId.toString() : config.clientId;
596
+ }
597
+ if (!clientId || typeof clientId !== "string") {
598
+ if (storage?.name && typeof document !== "undefined") {
599
+ clientId = cookie.getItem(storage.name) ?? void 0;
600
+ }
601
+ if (!clientId || clientId === "undefined") {
602
+ clientId = generateUUID$1();
603
+ }
604
+ }
605
+ let uuid = clientId.replace(/\0/g, "");
606
+ function getUUID() {
607
+ return uuid;
608
+ }
609
+ function persistUUID(storageOption, id) {
610
+ if (cookie.getItem(storageOption.name) === id) return;
611
+ try {
612
+ setCookie(storageOption, storageOption.name, id);
613
+ } catch {
614
+ }
615
+ }
616
+ function resetUUID(suggestedStorage, suggestedClientId) {
617
+ uuid = (suggestedClientId || generateUUID$1()).replace(/\0/g, "");
618
+ const storageToUse = suggestedStorage || config.storage;
619
+ if (storageToUse && typeof storageToUse === "object") {
620
+ const storageOption = configureStorage(storageToUse);
621
+ if (storageOption?.expires && inSignedMode()) {
622
+ persistUUID(storageOption, uuid);
623
+ }
624
+ }
625
+ }
626
+ if (storage?.expires && inSignedMode()) {
627
+ persistUUID(storage, uuid);
628
+ }
629
+ function inSignedMode() {
630
+ if (storeConsentByLocalStorage) {
631
+ if (!isLocalStorageAccessible()) return startInSignedMode;
632
+ const val2 = localStorage.getItem(SIGNEDMODECOOKIE);
633
+ return val2 !== "false" && (val2 === "true" || startInSignedMode);
634
+ }
635
+ if (typeof document === "undefined") return startInSignedMode;
636
+ const val = cookie.getItem(SIGNEDMODECOOKIE);
637
+ return val !== "false" && (val === "true" || startInSignedMode);
638
+ }
639
+ function setSignedMode() {
640
+ if (storeConsentByLocalStorage) {
641
+ if (isLocalStorageAccessible()) {
642
+ localStorage.setItem(SIGNEDMODECOOKIE, "true");
643
+ }
644
+ } else if (config.storage && typeof config.storage === "object") {
645
+ setStorageCookie(config.storage, SIGNEDMODECOOKIE, "true");
646
+ }
647
+ const currentUUID = getUUID();
648
+ resetUUID(config.storage, currentUUID);
649
+ }
650
+ function setAnonymousMode(keepIdentifier) {
651
+ if (storeConsentByLocalStorage) {
652
+ if (isLocalStorageAccessible()) {
653
+ localStorage.setItem(SIGNEDMODECOOKIE, "false");
654
+ }
655
+ } else if (config.storage && typeof config.storage === "object") {
656
+ setStorageCookie(config.storage, SIGNEDMODECOOKIE, "false");
657
+ }
658
+ if (!keepIdentifier) {
659
+ if (config.storage && typeof config.storage === "object") {
660
+ setStorageCookie(config.storage, config.storage.name);
661
+ }
662
+ removeCachedGlobalID();
663
+ sdk.removeServerCookie();
664
+ }
665
+ }
666
+ function areEventsBlocked() {
667
+ return cookie.getItem(BLOCKEVENTSCOOKIE) === "true";
668
+ }
669
+ function blockEvents() {
670
+ if (config.storage && typeof config.storage === "object") {
671
+ setStorageCookie(config.storage, BLOCKEVENTSCOOKIE, "true");
672
+ }
673
+ }
674
+ function unblockEvents() {
675
+ if (config.storage && typeof config.storage === "object") {
676
+ setStorageCookie(config.storage, BLOCKEVENTSCOOKIE, "false");
677
+ }
678
+ }
679
+ function removeCachedGlobalID() {
680
+ if (globals["$global"]) {
681
+ delete globals["$global"]["td_global_id"];
682
+ }
683
+ if (config.storage && typeof config.storage === "object") {
684
+ const globalIdCookie = config.globalIdCookie || "_td_global";
685
+ setStorageCookie(config.storage, globalIdCookie, "");
686
+ }
687
+ if (isLocalStorageAccessible()) {
688
+ const globalIdCookie = config.globalIdCookie || "_td_global";
689
+ try {
690
+ localStorage.removeItem(globalIdCookie);
691
+ } catch {
692
+ }
693
+ }
694
+ }
695
+ function removeServerCookie() {
696
+ if (config.storage && typeof config.storage === "object") {
697
+ setStorageCookie(config.storage, SERVER_COOKIE_NAME, "");
698
+ const otherCookieNames = ["__td_ssc", "_td_ssc"];
699
+ otherCookieNames.forEach((cookieName) => {
700
+ setStorageCookie(config.storage, cookieName, "");
701
+ });
702
+ if (config.useServerSideCookie && config.globalIdCookie) {
703
+ setStorageCookie(config.storage, config.globalIdCookie, "");
704
+ }
705
+ }
706
+ if (isLocalStorageAccessible()) {
707
+ [SERVER_COOKIE_NAME, "__td_ssc", "_td_ssc"].forEach((key) => {
708
+ try {
709
+ localStorage.removeItem(key);
710
+ } catch {
711
+ }
712
+ });
713
+ }
714
+ }
715
+ function isGlobalIdEnabled() {
716
+ return get2(void 0, "td_global_id") === "td_global_id";
717
+ }
718
+ return {
719
+ inSignedMode,
720
+ setSignedMode,
721
+ setAnonymousMode,
722
+ blockEvents,
723
+ unblockEvents,
724
+ areEventsBlocked,
725
+ getUUID,
726
+ resetUUID,
727
+ set,
728
+ get: get2,
729
+ removeCachedGlobalID,
730
+ removeServerCookie,
731
+ isGlobalIdEnabled
732
+ };
733
+ }
734
+ };
735
+ }
736
+ const DEFAULT_HOST = "us01.records.in.treasuredata.com";
737
+ const DEFAULT_PATHNAME = "/";
738
+ function validateRecord(table, record2) {
739
+ invariant$1(isString(table), "Must provide a table");
740
+ invariant$1(
741
+ /^[a-z0-9_]{3,255}$/.test(table),
742
+ "Table must be between 3 and 255 characters and must consist only of lower case letters, numbers, and _"
743
+ );
744
+ invariant$1(isObject$1(record2), "Must provide a record");
745
+ }
746
+ const _validateRecord = validateRecord;
747
+ function record() {
748
+ return {
749
+ name: "record",
750
+ setup(core, sdk) {
751
+ const config = core.config;
752
+ const host = config.host || DEFAULT_HOST;
753
+ const pathname = config.pathname || DEFAULT_PATHNAME;
754
+ const endpoint = config.endpoint || `https://${host}${pathname}`;
755
+ let windowBeingUnloaded = false;
756
+ if (typeof window !== "undefined" && window.addEventListener) {
757
+ const handleUnload = () => {
758
+ windowBeingUnloaded = true;
759
+ };
760
+ window.addEventListener("beforeunload", handleUnload);
761
+ window.addEventListener("unload", handleUnload);
762
+ core._unloadHandlers = [
763
+ () => window.removeEventListener("beforeunload", handleUnload),
764
+ () => window.removeEventListener("unload", handleUnload)
765
+ ];
766
+ }
767
+ core._windowBeingUnloaded = () => windowBeingUnloaded;
768
+ function applyProperties(table, payload) {
769
+ return Object.assign(
770
+ {},
771
+ sdk.get("$global"),
772
+ sdk.get(table),
773
+ payload
774
+ );
775
+ }
776
+ const api2 = {
777
+ addRecord(table, record2, success, error, options) {
778
+ validateRecord(table, record2);
779
+ const propertiesRecord = applyProperties(table, record2);
780
+ const finalRecord = sdk.inSignedMode() ? propertiesRecord : omitKeys(propertiesRecord, [
781
+ "td_ip",
782
+ "td_client_id",
783
+ "td_global_id"
784
+ ]);
785
+ const request = {
786
+ apikey: config.writeKey,
787
+ record: finalRecord,
788
+ time: null,
789
+ url: `${endpoint}${options?.database ?? config.database}/${table}`
790
+ };
791
+ if (request.record.time != null) {
792
+ request.time = request.record.time;
793
+ }
794
+ if (config.development) {
795
+ core.log.debug("addRecord", request);
796
+ success?.({
797
+ success: true,
798
+ message: "Development mode - record not sent"
799
+ });
800
+ } else if (!sdk.areEventsBlocked()) {
801
+ submitRecord(
802
+ {
803
+ ...request,
804
+ inSignedMode: sdk.inSignedMode(),
805
+ isGlobalIdEnabled: sdk.isGlobalIdEnabled(),
806
+ windowBeingUnloaded: core._windowBeingUnloaded?.() ?? false,
807
+ timeoutMs: config.jsonpTimeout ?? 6e4
808
+ },
809
+ success,
810
+ error
811
+ );
812
+ }
813
+ }
814
+ };
815
+ return api2;
816
+ }
817
+ };
818
+ }
819
+ function omitKeys(obj, keys) {
820
+ const result = {};
821
+ for (const key of Object.keys(obj)) {
822
+ if (!keys.includes(key)) {
823
+ const value = obj[key];
824
+ if (value !== void 0) {
825
+ result[key] = value;
826
+ }
827
+ }
828
+ }
829
+ return result;
830
+ }
831
+ async function submitRecord(request, success, error) {
832
+ const noop = () => {
833
+ };
834
+ const successCallback = success || noop;
835
+ const errorCallback = error || noop;
836
+ const params = ["modified=" + encodeURIComponent((/* @__PURE__ */ new Date()).getTime())];
837
+ if (request.time) {
838
+ params.push("time=" + encodeURIComponent(request.time));
839
+ }
840
+ const url = request.url + "?" + params.join("&");
841
+ const isClickedLink = request.record.tag === "a" && !!request.record.href;
842
+ const requestHeaders = {};
843
+ requestHeaders["Authorization"] = "TD1 " + request.apikey;
844
+ if (typeof navigator !== "undefined") {
845
+ requestHeaders["User-Agent"] = navigator.userAgent;
846
+ }
847
+ if (request.inSignedMode && request.isGlobalIdEnabled) {
848
+ Object.assign(requestHeaders, globalIdAdlHeaders);
849
+ } else {
850
+ Object.assign(requestHeaders, adlHeaders);
851
+ }
852
+ const payload = { events: [request.record] };
853
+ try {
854
+ if (typeof window !== "undefined" && (request.windowBeingUnloaded || isClickedLink)) {
855
+ const response = await api.postWithTimeout(
856
+ url,
857
+ payload,
858
+ request.timeoutMs,
859
+ { headers: requestHeaders, credentials: "include" }
860
+ );
861
+ successCallback(response);
862
+ } else {
863
+ const response = await api.post(url, payload, {
864
+ headers: requestHeaders,
865
+ credentials: "include"
866
+ });
867
+ successCallback(response);
868
+ }
869
+ } catch (err) {
870
+ const tdError = err instanceof Error ? { ...err, name: err.name, message: err.message } : new Error("Unknown error occurred");
871
+ errorCallback(tdError);
872
+ }
873
+ }
874
+ const POPUP_CONTAINER_ID = "td-engage-popup-container";
875
+ let inlineObserver = null;
876
+ let navigationCleanupInstalled = false;
877
+ let accumulatedInline = [];
878
+ function parseAppearance(raw) {
879
+ if (typeof raw === "object" && raw !== null) return raw;
880
+ try {
881
+ return JSON.parse(raw);
882
+ } catch {
883
+ return {};
884
+ }
885
+ }
886
+ function parseMessages(tdApp) {
887
+ try {
888
+ const messagesRaw = tdApp["td_in_browser.messages"];
889
+ if (!messagesRaw) return [];
890
+ return JSON.parse(messagesRaw);
891
+ } catch {
892
+ return [];
893
+ }
894
+ }
895
+ function removeExistingPopup() {
896
+ document.getElementById(POPUP_CONTAINER_ID)?.remove();
897
+ }
898
+ function isPopupDisplayed() {
899
+ return document.getElementById(POPUP_CONTAINER_ID) !== null;
900
+ }
901
+ function resetForNavigation() {
902
+ removeExistingPopup();
903
+ if (inlineObserver) {
904
+ inlineObserver.disconnect();
905
+ inlineObserver = null;
906
+ }
907
+ accumulatedInline = [];
908
+ }
909
+ function ensureNavigationCleanup() {
910
+ if (navigationCleanupInstalled) return;
911
+ if (typeof window === "undefined" || !window.history) return;
912
+ window.addEventListener("popstate", resetForNavigation);
913
+ window.addEventListener("hashchange", resetForNavigation);
914
+ try {
915
+ const wrap2 = (method) => {
916
+ const original = window.history[method];
917
+ window.history[method] = function(...args) {
918
+ const result = original.apply(this, args);
919
+ resetForNavigation();
920
+ return result;
921
+ };
922
+ };
923
+ wrap2("pushState");
924
+ wrap2("replaceState");
925
+ } catch {
926
+ }
927
+ navigationCleanupInstalled = true;
928
+ }
929
+ function renderPopup(message) {
930
+ try {
931
+ const a = parseAppearance(message.appearance_setting);
932
+ const isDesktop = window.innerWidth > 620;
933
+ removeExistingPopup();
934
+ const placement = a.position?.placement ?? "center";
935
+ const isTop = placement.startsWith("top");
936
+ const isBottom = placement.startsWith("bottom");
937
+ const isLeft = placement.endsWith("left");
938
+ const isRight = placement.endsWith("right");
939
+ const inset = isDesktop ? a.inset?.desktop ?? 40 : a.inset?.mobile ?? 16;
940
+ const maxWidth = isDesktop ? a.width?.desktop_max_width ?? 600 : a.width?.mobile_max_width ?? 300;
941
+ const container = document.createElement("div");
942
+ container.id = POPUP_CONTAINER_ID;
943
+ const alignItems = isBottom ? "end" : isTop ? "start" : "center";
944
+ const justifyItems = isLeft ? "start" : isRight ? "end" : "center";
945
+ Object.assign(container.style, {
946
+ position: a.position?.fixed_on_scroll === false ? "absolute" : "fixed",
947
+ inset: "0",
948
+ display: "grid",
949
+ placeItems: `${alignItems} ${justifyItems}`,
950
+ padding: `${inset}px`,
951
+ pointerEvents: "none",
952
+ boxSizing: "border-box"
953
+ });
954
+ container.style.setProperty(
955
+ "z-index",
956
+ "var(--td-popup-z-index, 2147483647)"
957
+ );
958
+ const shadow = container.attachShadow({ mode: "open" });
959
+ const style = document.createElement("style");
960
+ style.textContent = `
961
+ :host { --td-popup-z-index: 2147483647; --td-popup-frame-z-index: 1; --td-close-btn-cursor: pointer; --td-close-btn-line-height: 1; }
962
+ .td-overlay { position: fixed; inset: 0; pointer-events: auto; }
963
+ .td-frame { position: relative; width: 100%; pointer-events: auto; box-sizing: border-box; z-index: var(--td-popup-frame-z-index); }
964
+ .td-close { position: absolute; background: transparent; border: none; cursor: var(--td-close-btn-cursor); line-height: var(--td-close-btn-line-height); padding: 0; display: flex; align-items: center; justify-content: center; z-index: 1; }
965
+ `;
966
+ shadow.appendChild(style);
967
+ if (a.overlay?.enabled) {
968
+ const overlayEl = document.createElement("div");
969
+ overlayEl.className = "td-overlay";
970
+ Object.assign(overlayEl.style, {
971
+ background: a.overlay.color ?? "#000000B3"
972
+ });
973
+ if (a.overlay.close_on_click_outside) {
974
+ overlayEl.setAttribute("data-engage-popup-close", "");
975
+ }
976
+ shadow.appendChild(overlayEl);
977
+ }
978
+ const frame = document.createElement("div");
979
+ frame.className = "td-frame";
980
+ const bgPadding = a.background?.padding ?? 0;
981
+ Object.assign(frame.style, {
982
+ maxWidth: `${maxWidth}px`,
983
+ background: a.background?.color ?? "#FFFFFF",
984
+ borderRadius: `${a.background?.border_radius ?? 8}px`,
985
+ padding: `${bgPadding}px`
986
+ });
987
+ if (a.close_button?.enabled !== false) {
988
+ const size = a.close_button?.size ?? 28;
989
+ const offsetTop = a.close_button?.offset_top ?? 2;
990
+ const offsetRight = a.close_button?.offset_right ?? 4;
991
+ const closeBtn = document.createElement("button");
992
+ closeBtn.type = "button";
993
+ closeBtn.className = "td-close";
994
+ closeBtn.setAttribute("aria-label", "Close");
995
+ closeBtn.setAttribute("data-engage-popup-close", "");
996
+ Object.assign(closeBtn.style, {
997
+ top: `${offsetTop}px`,
998
+ right: `${offsetRight}px`,
999
+ width: `${size}px`,
1000
+ height: `${size}px`,
1001
+ fontSize: `${size * 0.7}px`,
1002
+ color: a.close_button?.color ?? "#FFFFFF"
1003
+ });
1004
+ closeBtn.textContent = "×";
1005
+ frame.appendChild(closeBtn);
1006
+ }
1007
+ const content = document.createElement("div");
1008
+ content.innerHTML = message.content_html;
1009
+ frame.appendChild(content);
1010
+ shadow.appendChild(frame);
1011
+ shadow.addEventListener("click", (e) => {
1012
+ const target = e.target;
1013
+ if (target.hasAttribute("data-engage-popup-close")) {
1014
+ container.remove();
1015
+ }
1016
+ });
1017
+ document.body.appendChild(container);
1018
+ } catch {
1019
+ }
1020
+ }
1021
+ function renderInline(message) {
1022
+ if (!message.css_selector) return;
1023
+ try {
1024
+ const els = document.querySelectorAll(message.css_selector);
1025
+ for (const el of els) {
1026
+ el.innerHTML = message.content_html;
1027
+ }
1028
+ } catch {
1029
+ }
1030
+ }
1031
+ function compareMessages(a, b) {
1032
+ const tsDiff = Number(b.created_at_millisecond ?? 0) - Number(a.created_at_millisecond ?? 0);
1033
+ if (tsDiff !== 0) return tsDiff;
1034
+ const sectionDiff = b._sectionName.localeCompare(a._sectionName);
1035
+ if (sectionDiff !== 0) return sectionDiff;
1036
+ return b._arrayIndex - a._arrayIndex;
1037
+ }
1038
+ function sortedInlineMessages(messages) {
1039
+ return messages.filter((m) => m.type === "inline" && m.css_selector).sort((a, b) => -compareMessages(a, b));
1040
+ }
1041
+ function pickPopup(messages) {
1042
+ const popups = messages.filter((m) => m.type === "popup").sort(compareMessages);
1043
+ return popups[0];
1044
+ }
1045
+ function applyAccumulatedInline() {
1046
+ for (const msg of accumulatedInline) {
1047
+ renderInline(msg);
1048
+ }
1049
+ }
1050
+ function setupInlineObserver() {
1051
+ if (inlineObserver) {
1052
+ inlineObserver.disconnect();
1053
+ inlineObserver = null;
1054
+ }
1055
+ if (accumulatedInline.length === 0) return;
1056
+ inlineObserver = new MutationObserver(() => {
1057
+ inlineObserver.disconnect();
1058
+ applyAccumulatedInline();
1059
+ inlineObserver.observe(document.body, { childList: true, subtree: true });
1060
+ });
1061
+ inlineObserver.observe(document.body, { childList: true, subtree: true });
1062
+ }
1063
+ function extractMessages(response) {
1064
+ const offers = response.offers;
1065
+ if (!offers) return [];
1066
+ const allMessages = [];
1067
+ for (const [sectionName, section] of Object.entries(offers)) {
1068
+ const tdApp = section?.td_app;
1069
+ if (!tdApp) continue;
1070
+ const messages = parseMessages(tdApp);
1071
+ messages.forEach((m, i) => {
1072
+ allMessages.push({ ...m, _sectionName: sectionName, _arrayIndex: i });
1073
+ });
1074
+ }
1075
+ return allMessages;
1076
+ }
1077
+ function handlePersonalizationResponse(response) {
1078
+ try {
1079
+ const messages = extractMessages(response);
1080
+ if (messages.length === 0) return;
1081
+ ensureNavigationCleanup();
1082
+ if (!isPopupDisplayed()) {
1083
+ const popup = pickPopup(messages);
1084
+ if (popup) {
1085
+ renderPopup(popup);
1086
+ }
1087
+ }
1088
+ const inline = sortedInlineMessages(messages);
1089
+ if (inline.length > 0) {
1090
+ accumulatedInline.push(...inline);
1091
+ applyAccumulatedInline();
1092
+ setupInlineObserver();
1093
+ }
1094
+ } catch {
1095
+ }
1096
+ }
1097
+ function configureValues(getUUID, version2) {
1098
+ return {
1099
+ td_version: () => version2,
1100
+ td_client_id: getUUID,
1101
+ td_charset: () => (document.characterSet || document.charset || "-").toLowerCase(),
1102
+ td_language: () => {
1103
+ const nav = navigator;
1104
+ return (nav && (nav.language || nav.browserLanguage) || "-").toLowerCase();
1105
+ },
1106
+ td_color: () => screen ? screen.colorDepth + "-bit" : "-",
1107
+ td_screen: () => screen ? `${screen.width}x${screen.height}` : "-",
1108
+ td_viewport: () => {
1109
+ const clientHeight = document.documentElement && document.documentElement.clientHeight;
1110
+ const clientWidth = document.documentElement && document.documentElement.clientWidth;
1111
+ const innerHeight = window.innerHeight;
1112
+ const innerWidth = window.innerWidth;
1113
+ const height = (clientHeight || 0) < innerHeight ? innerHeight : clientHeight || 0;
1114
+ const width = (clientWidth || 0) < innerWidth ? innerWidth : clientWidth || 0;
1115
+ return `${width}x${height}`;
1116
+ },
1117
+ td_title: () => document.title,
1118
+ td_description: () => getMetaContent("description"),
1119
+ td_url: () => {
1120
+ return !document.location || !document.location.href ? "" : document.location.href.split("#")[0] || "";
1121
+ },
1122
+ td_user_agent: () => {
1123
+ const userAgent = navigator.userAgent;
1124
+ const sdkUserAgent = `WEBSDK/${version2}`;
1125
+ return [userAgent, sdkUserAgent].join(";");
1126
+ },
1127
+ td_platform: () => {
1128
+ return navigator.platform || navigator.userAgentData?.platform || "-";
1129
+ },
1130
+ td_host: () => document.location.host,
1131
+ td_path: () => document.location.pathname,
1132
+ td_referrer: () => document.referrer
1133
+ };
1134
+ }
1135
+ function getMetaContent(metaName) {
1136
+ const head = document.head || document.getElementsByTagName("head")[0];
1137
+ const metas = head.getElementsByTagName("meta");
1138
+ const metaLength = metas.length;
1139
+ for (let i = 0; i < metaLength; i++) {
1140
+ const meta = metas[i];
1141
+ if (meta && meta.getAttribute("name") === metaName) {
1142
+ return (meta.getAttribute("content") || "").substr(0, 8192);
1143
+ }
1144
+ }
1145
+ return "";
1146
+ }
1147
+ function track() {
1148
+ return {
1149
+ name: "track",
1150
+ setup(core, sdk) {
1151
+ const trackValues = configureValues(() => sdk.getUUID(), CONFIG.VERSION);
1152
+ function getTrackValues() {
1153
+ const result = {};
1154
+ for (const [key, value] of Object.entries(trackValues)) {
1155
+ if (value) {
1156
+ result[key] = typeof value === "function" ? value() : value;
1157
+ }
1158
+ }
1159
+ return result;
1160
+ }
1161
+ function trackEvent(table, record2, success, failure) {
1162
+ const tableName = table || "events";
1163
+ const values = getTrackValues();
1164
+ const merged = Object.assign(values, record2);
1165
+ const personalization2 = core.config.personalization;
1166
+ if (personalization2) {
1167
+ const personalizationConfig = {
1168
+ endpoint: personalization2.endpoint,
1169
+ database: personalization2.database || core.config.database,
1170
+ table: tableName,
1171
+ token: personalization2.token
1172
+ };
1173
+ const payload = {
1174
+ ...sdk.get("$global"),
1175
+ ...sdk.get(tableName),
1176
+ ...getTrackValues(),
1177
+ ...record2
1178
+ };
1179
+ sdk.fetchPersonalization(
1180
+ personalizationConfig,
1181
+ payload,
1182
+ (response) => {
1183
+ handlePersonalizationResponse(response);
1184
+ if (typeof sdk.applyPersonalization === "function") {
1185
+ sdk.applyPersonalization(
1186
+ response
1187
+ );
1188
+ }
1189
+ },
1190
+ (error) => {
1191
+ core.log.error("Personalization failed:", error);
1192
+ }
1193
+ );
1194
+ return;
1195
+ }
1196
+ sdk.addRecord(tableName, merged, success, failure);
1197
+ }
1198
+ function trackPageview(table, success, failure, options) {
1199
+ const tableName = table || "pageviews";
1200
+ const eventRecord = options?.payload ?? {};
1201
+ trackEvent(tableName, eventRecord, success, failure);
1202
+ }
1203
+ function getPersonalizationConfig() {
1204
+ return core.config.personalization;
1205
+ }
1206
+ function setPersonalizationConfig(options) {
1207
+ core.config.personalization = options;
1208
+ }
1209
+ return {
1210
+ trackEvent,
1211
+ trackPageview,
1212
+ getTrackValues,
1213
+ getPersonalizationConfig,
1214
+ setPersonalizationConfig
1215
+ };
1216
+ }
1217
+ };
1218
+ }
1219
+ function getEventTarget(event) {
1220
+ const target = event.target || event.srcElement || document;
1221
+ return target.nodeType === 3 ? target.parentNode : target;
1222
+ }
1223
+ function addEventListener(el, type, fn) {
1224
+ if ("addEventListener" in el) {
1225
+ el.addEventListener(type, handler, false);
1226
+ return disposable(() => {
1227
+ el.removeEventListener(type, handler, false);
1228
+ });
1229
+ } else if ("attachEvent" in el) {
1230
+ el.attachEvent("on" + type, handler);
1231
+ return disposable(() => {
1232
+ el.detachEvent("on" + type, handler);
1233
+ });
1234
+ } else {
1235
+ throw new Error("addEventListener not supported");
1236
+ }
1237
+ function handler(event) {
1238
+ fn.call(el, event || window.event);
1239
+ }
1240
+ }
1241
+ function htmlTreeAsString(elem) {
1242
+ const MAX_TRAVERSE_HEIGHT = 5;
1243
+ const MAX_OUTPUT_LEN = 80;
1244
+ const out = [];
1245
+ let height = 0;
1246
+ let len = 0;
1247
+ const separator = " > ";
1248
+ const sepLength = separator.length;
1249
+ let nextStr;
1250
+ let currentElem = elem;
1251
+ while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {
1252
+ nextStr = htmlElementAsString(currentElem);
1253
+ if (nextStr === "html" || height > 1 && len + out.length * sepLength + nextStr.length >= MAX_OUTPUT_LEN) {
1254
+ break;
1255
+ }
1256
+ out.push(nextStr);
1257
+ len += nextStr.length;
1258
+ currentElem = currentElem.parentNode;
1259
+ }
1260
+ const result = out.reverse().join(separator);
1261
+ if (result.length > MAX_OUTPUT_LEN) {
1262
+ return result.substring(0, MAX_OUTPUT_LEN - 3) + "...";
1263
+ }
1264
+ return result;
1265
+ }
1266
+ function htmlElementAsString(elem) {
1267
+ const out = [];
1268
+ let classes;
1269
+ let key;
1270
+ let attr;
1271
+ let i;
1272
+ if (!elem || !elem.tagName) {
1273
+ return "";
1274
+ }
1275
+ out.push(elem.tagName.toLowerCase());
1276
+ if (elem.id) {
1277
+ out.push("#" + elem.id);
1278
+ }
1279
+ const className = elem.className;
1280
+ if (className && isString(className)) {
1281
+ classes = className.split(" ");
1282
+ for (i = 0; i < classes.length; i++) {
1283
+ const cls = classes[i];
1284
+ if (cls && cls.trim()) {
1285
+ out.push("." + cls.trim());
1286
+ }
1287
+ }
1288
+ }
1289
+ const attrWhitelist = ["type", "name", "title", "alt"];
1290
+ for (i = 0; i < attrWhitelist.length; i++) {
1291
+ key = attrWhitelist[i];
1292
+ attr = elem.getAttribute(key);
1293
+ if (attr) {
1294
+ out.push("[" + key + '="' + attr + '"]');
1295
+ }
1296
+ }
1297
+ return out.join("");
1298
+ }
1299
+ function hasAttribute(element2, attrName) {
1300
+ if (typeof element2.hasAttribute === "function") {
1301
+ return element2.hasAttribute(attrName);
1302
+ }
1303
+ return element2.getAttribute(attrName) !== null;
1304
+ }
1305
+ const element = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1306
+ __proto__: null,
1307
+ addEventListener,
1308
+ getEventTarget,
1309
+ hasAttribute,
1310
+ htmlElementAsString,
1311
+ htmlTreeAsString
1312
+ }, Symbol.toStringTag, { value: "Module" }));
1313
+ function findElement(el) {
1314
+ if (!el || !el.tagName) return null;
1315
+ let currentEl = el;
1316
+ let tag = currentEl.tagName.toLowerCase();
1317
+ while (tag && tag !== "body" && currentEl) {
1318
+ const type = currentEl.getAttribute("type");
1319
+ if (tag === "input" && type === "password") return null;
1320
+ const role = currentEl.getAttribute("role");
1321
+ if (role === "button" || role === "link" || tag === "a" || tag === "button" || tag === "input") {
1322
+ return currentEl;
1323
+ }
1324
+ currentEl = currentEl.parentNode;
1325
+ tag = currentEl && currentEl.tagName ? currentEl.tagName.toLowerCase() : "";
1326
+ }
1327
+ return null;
1328
+ }
1329
+ function createTreeHasIgnoreAttribute(ignoreAttribute) {
1330
+ const dataIgnoreAttribute = "data-" + ignoreAttribute;
1331
+ return function treeHasIgnoreAttribute(el) {
1332
+ if (!el || !el.tagName || el.tagName.toLowerCase() === "html") return false;
1333
+ if (hasAttribute(el, ignoreAttribute) || hasAttribute(el, dataIgnoreAttribute))
1334
+ return true;
1335
+ return treeHasIgnoreAttribute(el.parentNode);
1336
+ };
1337
+ }
1338
+ function getElementData(el) {
1339
+ const data = {
1340
+ tag: el.tagName.toLowerCase(),
1341
+ tree: htmlTreeAsString(el)
1342
+ };
1343
+ const attributesToCapture = [
1344
+ "alt",
1345
+ "class",
1346
+ "href",
1347
+ "id",
1348
+ "name",
1349
+ "role",
1350
+ "title",
1351
+ "type"
1352
+ ];
1353
+ attributesToCapture.forEach((attrName) => {
1354
+ if (hasAttribute(el, attrName)) {
1355
+ const value = el.getAttribute(attrName);
1356
+ if (value) data[attrName] = value;
1357
+ }
1358
+ });
1359
+ return data;
1360
+ }
1361
+ function clicks() {
1362
+ return {
1363
+ name: "clicks",
1364
+ setup(_core, sdk) {
1365
+ let clickTrackingInstalled = false;
1366
+ return {
1367
+ trackClicks(options) {
1368
+ if (clickTrackingInstalled) return void 0;
1369
+ const opts = {
1370
+ element: options?.element ?? window.document,
1371
+ extendClickData: options?.extendClickData ?? ((_e, data) => data),
1372
+ ignoreAttribute: options?.ignoreAttribute ?? "td-ignore",
1373
+ tableName: options?.tableName ?? "clicks"
1374
+ };
1375
+ const treeHasIgnoreAttribute = createTreeHasIgnoreAttribute(
1376
+ opts.ignoreAttribute
1377
+ );
1378
+ const removeClickTracker = addEventListener(
1379
+ opts.element,
1380
+ "click",
1381
+ (e) => {
1382
+ const eventTarget = getEventTarget(e);
1383
+ const target = findElement(eventTarget);
1384
+ if (target && !treeHasIgnoreAttribute(target)) {
1385
+ const elementData = getElementData(target);
1386
+ const data = opts.extendClickData(
1387
+ e,
1388
+ elementData
1389
+ );
1390
+ if (data) {
1391
+ sdk.trackEvent(opts.tableName, data);
1392
+ }
1393
+ }
1394
+ }
1395
+ );
1396
+ clickTrackingInstalled = true;
1397
+ return disposable(() => {
1398
+ removeClickTracker();
1399
+ clickTrackingInstalled = false;
1400
+ });
1401
+ }
1402
+ };
1403
+ }
1404
+ };
1405
+ }
1406
+ const DEFAULT_UTM_PARAMS = [
1407
+ "utm_id",
1408
+ "utm_medium",
1409
+ "utm_source_platform",
1410
+ "utm_source",
1411
+ "utm_campaign",
1412
+ "utm_marketing_tactic"
1413
+ ];
1414
+ function collectUTMParametersFromURL(utmParams = DEFAULT_UTM_PARAMS) {
1415
+ if (typeof window === "undefined" || !window.location) {
1416
+ return {};
1417
+ }
1418
+ const searchString = window.location.search;
1419
+ const URLSearchParamsClass = window.URLSearchParams || URLSearchParams;
1420
+ const searchParams = new URLSearchParamsClass(searchString);
1421
+ const hasParams = utmParams.some((param) => searchParams.has(param));
1422
+ if (!hasParams) {
1423
+ return {};
1424
+ }
1425
+ return utmParams.reduce(
1426
+ (acc, paramName) => {
1427
+ const paramValue = searchParams.get(paramName);
1428
+ if (paramValue) {
1429
+ acc[paramName] = paramValue;
1430
+ }
1431
+ return acc;
1432
+ },
1433
+ {}
1434
+ );
1435
+ }
1436
+ function utm(options = {}) {
1437
+ return {
1438
+ name: "utm",
1439
+ setup(_core, sdk) {
1440
+ const opts = {
1441
+ customParameters: options.customParameters || DEFAULT_UTM_PARAMS,
1442
+ autoCollect: options.autoCollect ?? true,
1443
+ table: options.table || "$global"
1444
+ };
1445
+ let collectedParams = {};
1446
+ function collectUTMParameters() {
1447
+ const params = collectUTMParametersFromURL(opts.customParameters);
1448
+ if (isObject$1(params) && !isEmpty(params)) {
1449
+ if (opts.table === "$global") {
1450
+ sdk.set(params);
1451
+ } else {
1452
+ Object.keys(params).forEach((paramName) => {
1453
+ sdk.set(opts.table, paramName, params[paramName]);
1454
+ });
1455
+ }
1456
+ collectedParams = { ...collectedParams, ...params };
1457
+ }
1458
+ return params;
1459
+ }
1460
+ function getUTMParameters() {
1461
+ return { ...collectedParams };
1462
+ }
1463
+ if (opts.autoCollect) {
1464
+ collectUTMParameters();
1465
+ }
1466
+ return {
1467
+ getUTMParameters,
1468
+ collectUTMParameters
1469
+ };
1470
+ }
1471
+ };
1472
+ }
1473
+ const DEFAULT_CDP_HOST = "cdp.in.treasuredata.com";
1474
+ function invariant(condition, message) {
1475
+ if (!condition) {
1476
+ throw new Error(message);
1477
+ }
1478
+ }
1479
+ function personalization() {
1480
+ return {
1481
+ name: "personalization",
1482
+ setup(core, sdk) {
1483
+ const config = core.config;
1484
+ const cdpHost = config.cdpHost || DEFAULT_CDP_HOST;
1485
+ function fetchUserSegments(tokenOrOptions, successCallback, errorCallback) {
1486
+ const noop = () => {
1487
+ };
1488
+ const success = successCallback || noop;
1489
+ const error = errorCallback || noop;
1490
+ const isConfigObject = isObject$1(tokenOrOptions) && !isArray(tokenOrOptions);
1491
+ const audienceToken = isConfigObject ? tokenOrOptions.audienceToken : tokenOrOptions;
1492
+ const keys = isConfigObject && tokenOrOptions.keys || {};
1493
+ invariant(
1494
+ typeof audienceToken === "string" || isArray(audienceToken),
1495
+ `audienceToken must be a string or array; received "${String(audienceToken)}"`
1496
+ );
1497
+ invariant(
1498
+ isObject$1(keys),
1499
+ `keys must be an object; received "${String(keys)}"`
1500
+ );
1501
+ const token = isArray(audienceToken) ? audienceToken.join(",") : audienceToken;
1502
+ const keysArray = [];
1503
+ Object.keys(keys).forEach((key) => {
1504
+ keysArray.push(`key.${key}=${String(keys[key])}`);
1505
+ });
1506
+ const keyString = keysArray.join("&");
1507
+ const url = `https://${cdpHost}/cdp/lookup/collect/segments?version=2&token=${token}${keyString ? "&" + keyString : ""}`;
1508
+ api.getWithTimeout(url, 1e4, {
1509
+ headers: {
1510
+ "Content-Type": "application/json"
1511
+ }
1512
+ }).then(success).catch(error);
1513
+ }
1514
+ function fetchPersonalization(config2, data, successCallback, errorCallback) {
1515
+ const noop = () => {
1516
+ };
1517
+ const success = successCallback || noop;
1518
+ const error = errorCallback || noop;
1519
+ invariant(
1520
+ isObject$1(config2),
1521
+ `config must be an object, received "${String(config2)}"`
1522
+ );
1523
+ invariant(!!config2.endpoint, "endpoint is invalid");
1524
+ invariant(!!config2.database, "database is invalid");
1525
+ invariant(!!config2.table, "table is invalid");
1526
+ invariant(!!config2.token, "token is invalid");
1527
+ const eventsBlocked = typeof sdk.areEventsBlocked === "function" ? sdk.areEventsBlocked() : false;
1528
+ if (eventsBlocked) {
1529
+ return;
1530
+ }
1531
+ const url = `https://${config2.endpoint}/public/${config2.database}/${config2.table}`;
1532
+ let payload = data || {};
1533
+ const isSignedMode = typeof sdk.inSignedMode === "function" ? sdk.inSignedMode() : true;
1534
+ if (!isSignedMode) {
1535
+ payload = omit(
1536
+ payload,
1537
+ "td_ip",
1538
+ "td_client_id",
1539
+ "td_global_id"
1540
+ );
1541
+ }
1542
+ api.postWithTimeout(url, payload, 1e4, {
1543
+ headers: {
1544
+ "Content-Type": "application/vnd.treasuredata.v1+json",
1545
+ Authorization: `TD1 ${core.config.writeKey}`,
1546
+ "WP13n-Token": config2.token
1547
+ }
1548
+ }).then(success).catch(error);
1549
+ }
1550
+ return {
1551
+ fetchUserSegments,
1552
+ fetchPersonalization
1553
+ };
1554
+ }
1555
+ };
1556
+ }
1557
+ const VENDOR_FUNCTION_MAPPINGS = {
1558
+ google_ads: ["getGoogle_gclid_Param", "getGoogle_wbraid_Param"],
1559
+ google_ga: ["getGoogle_ga_Cookie"],
1560
+ google_mp: ["getGoogle_gcl_Cookies"],
1561
+ meta: [
1562
+ "getFacebook_fbp_Cookie",
1563
+ "getFacebook_fbc_Cookie",
1564
+ "getFacebook_fbclid_Param"
1565
+ ],
1566
+ instagram: [
1567
+ "getInstagram_shbts_Cookie",
1568
+ "getInstagram_shbid_Cookie",
1569
+ "getInstagram_ds_user_id_Cookie",
1570
+ "getInstagram_ig_did_Cookie"
1571
+ ],
1572
+ yahoojp_ads: [
1573
+ "getYahoo_ly_c_Param",
1574
+ "getYahoo_ly_c_Cookie",
1575
+ "getYahoo_ly_r_Cookie",
1576
+ "getYahoo_ly_su_Cookie",
1577
+ "getYahoo_yclid_Param",
1578
+ "getYahoo_yj_r_Param",
1579
+ "getYahoo_ycl_yjad_Cookie",
1580
+ "getYahoo_yjr_yjad_Cookie",
1581
+ "getYahoo_yjsu_yjad_Cookie"
1582
+ ],
1583
+ line: [
1584
+ "getLine_lt_cid_Cookie",
1585
+ "getLine_lt_sid_Cookie",
1586
+ "getLine_ldtag_cl_Param"
1587
+ ],
1588
+ x: ["getX_twclid_Param", "getX_twclid_Cookie"],
1589
+ pinterest: ["getPinterest_epik_Param", "getPinterest_epik_Cookie"],
1590
+ snapchat: ["getSnapchat_sccid_Param"],
1591
+ tiktok: ["getTiktok_ttp_Cookie"],
1592
+ marketo: ["getMarketo_mkto_trk_Cookie"],
1593
+ tealium: ["getTealium_utag_main_Cookie"]
1594
+ };
1595
+ function getCookie(key) {
1596
+ if (typeof document === "undefined") return null;
1597
+ return cookie.getItem(key);
1598
+ }
1599
+ function getCookieByNamePrefix(prefix) {
1600
+ if (typeof document === "undefined") return {};
1601
+ return cookie.keys().filter((key) => key.startsWith(prefix)).reduce(
1602
+ (acc, key) => {
1603
+ const value = cookie.getItem(key);
1604
+ if (value !== null) acc[key] = value;
1605
+ return acc;
1606
+ },
1607
+ {}
1608
+ );
1609
+ }
1610
+ function getParam(key) {
1611
+ if (typeof window === "undefined" || !window.location) return null;
1612
+ const queryString = window.location.search;
1613
+ const URLSearchParamsClass = window.URLSearchParams || URLSearchParams;
1614
+ const urlParams = new URLSearchParamsClass(queryString);
1615
+ return urlParams.get(key);
1616
+ }
1617
+ function conversionAPI() {
1618
+ return {
1619
+ name: "conversionAPI",
1620
+ setup(_core, sdk) {
1621
+ const tagCollectors = {
1622
+ // Google
1623
+ getGoogle_gclid_Param: () => ({ gclid: getParam("gclid") }),
1624
+ getGoogle_wbraid_Param: () => ({ wbraid: getParam("wbraid") }),
1625
+ getGoogle_ga_Cookie: () => ({ _ga: getCookie("_ga") }),
1626
+ getGoogle_gcl_Cookies: (options = {}) => {
1627
+ const prefix = options.gclPrefix || "_gcl";
1628
+ return getCookieByNamePrefix(prefix);
1629
+ },
1630
+ // Meta/Facebook
1631
+ getFacebook_fbp_Cookie: () => ({ _fbp: getCookie("_fbp") }),
1632
+ getFacebook_fbc_Cookie: () => ({ _fbc: getCookie("_fbc") }),
1633
+ getFacebook_fbclid_Param: () => ({ fbclid: getParam("fbclid") }),
1634
+ // Instagram
1635
+ getInstagram_shbts_Cookie: () => ({ shbts: getCookie("shbts") }),
1636
+ getInstagram_shbid_Cookie: () => ({ shbid: getCookie("shbid") }),
1637
+ getInstagram_ds_user_id_Cookie: () => ({
1638
+ ds_user_id: getCookie("ds_user_id")
1639
+ }),
1640
+ getInstagram_ig_did_Cookie: () => ({ ig_did: getCookie("ig_did") }),
1641
+ // Yahoo Japan
1642
+ getYahoo_yclid_Param: () => ({ yclid: getParam("yclid") }),
1643
+ getYahoo_yj_r_Param: () => ({ yj_r: getParam("yj_r") }),
1644
+ getYahoo_ycl_yjad_Cookie: () => ({ _ycl_yjad: getCookie("_ycl_yjad") }),
1645
+ getYahoo_yjr_yjad_Cookie: () => ({ _yjr_yjad: getCookie("_yjr_yjad") }),
1646
+ getYahoo_yjsu_yjad_Cookie: () => ({
1647
+ _yjsu_yjad: getCookie("_yjsu_yjad")
1648
+ }),
1649
+ getYahoo_ly_c_Param: () => ({ ly_c: getParam("_ly_c") }),
1650
+ getYahoo_ly_c_Cookie: () => ({ ly_c: getCookie("_ly_c") }),
1651
+ getYahoo_ly_r_Cookie: () => ({ ly_r: getCookie("_ly_r") }),
1652
+ getYahoo_ly_su_Cookie: () => ({ ly_su: getCookie("_ly_su") }),
1653
+ // Line
1654
+ getLine_lt_cid_Cookie: () => ({ __lt_cid: getCookie("__lt__cid") }),
1655
+ getLine_lt_sid_Cookie: () => ({ __lt_sid: getCookie("__lt__sid") }),
1656
+ getLine_ldtag_cl_Param: () => ({ ldtag_cl: getParam("ldtag_cl") }),
1657
+ // Twitter/X
1658
+ getX_twclid_Param: () => ({ twclid: getParam("twclid") }),
1659
+ getX_twclid_Cookie: () => ({ _twclid: getCookie("_twclid") }),
1660
+ // Pinterest
1661
+ getPinterest_epik_Param: () => ({ epik: getParam("epik") }),
1662
+ getPinterest_epik_Cookie: () => ({ _epik: getCookie("_epik") }),
1663
+ // Snapchat
1664
+ getSnapchat_sccid_Param: () => ({ ScCid: getParam("ScCid") }),
1665
+ // TikTok
1666
+ getTiktok_ttp_Cookie: () => ({ _ttp: getCookie("_ttp") }),
1667
+ // Marketo
1668
+ getMarketo_mkto_trk_Cookie: () => ({
1669
+ _mkto_trk: getCookie("_mkto_trk")
1670
+ }),
1671
+ // Tealium
1672
+ getTealium_utag_main_Cookie: () => ({
1673
+ utag_main: getCookie("utag_main")
1674
+ })
1675
+ };
1676
+ function collectTagsByVendors(vendors = [], options = {}) {
1677
+ return vendors.reduce(
1678
+ (acc, vendor) => {
1679
+ const fnNames = VENDOR_FUNCTION_MAPPINGS[vendor] || [];
1680
+ fnNames.forEach((fnName) => {
1681
+ const result = tagCollectors[fnName](options);
1682
+ Object.assign(acc, result);
1683
+ });
1684
+ return acc;
1685
+ },
1686
+ {}
1687
+ );
1688
+ }
1689
+ function collectTagsByCookieNames(cookieNames = []) {
1690
+ return cookieNames.reduce(
1691
+ (acc, cookieName) => {
1692
+ acc[cookieName] = getCookie(cookieName);
1693
+ return acc;
1694
+ },
1695
+ {}
1696
+ );
1697
+ }
1698
+ function collectTagsByParamNames(params = []) {
1699
+ return params.reduce(
1700
+ (acc, paramName) => {
1701
+ acc[paramName] = getParam(paramName);
1702
+ return acc;
1703
+ },
1704
+ {}
1705
+ );
1706
+ }
1707
+ function collectAllTags(options = {}) {
1708
+ const tags = {};
1709
+ const vendorKeys = Object.keys(VENDOR_FUNCTION_MAPPINGS);
1710
+ vendorKeys.forEach((vendor) => {
1711
+ const vendorFns = VENDOR_FUNCTION_MAPPINGS[vendor];
1712
+ if (vendorFns) {
1713
+ vendorFns.forEach((fnName) => {
1714
+ const result = tagCollectors[fnName](options);
1715
+ Object.assign(tags, result);
1716
+ });
1717
+ }
1718
+ });
1719
+ return Object.keys(tags).reduce(
1720
+ (acc, key) => {
1721
+ if (tags[key]) {
1722
+ acc[key] = tags[key];
1723
+ }
1724
+ return acc;
1725
+ },
1726
+ {}
1727
+ );
1728
+ }
1729
+ function collectTags(config = {}, options = {}) {
1730
+ const isEmptyConfigValues = isEmpty(config.vendors) && isEmpty(config.cookies) && isEmpty(config.params);
1731
+ let tags = {};
1732
+ if (isEmpty(config) || isEmptyConfigValues) {
1733
+ tags = collectAllTags(options);
1734
+ } else {
1735
+ if (!isEmpty(config.vendors)) {
1736
+ Object.assign(tags, collectTagsByVendors(config.vendors, options));
1737
+ }
1738
+ if (!isEmpty(config.cookies)) {
1739
+ Object.assign(tags, collectTagsByCookieNames(config.cookies));
1740
+ }
1741
+ if (!isEmpty(config.params)) {
1742
+ Object.assign(tags, collectTagsByParamNames(config.params));
1743
+ }
1744
+ }
1745
+ Object.keys(tags).forEach((tagKey) => {
1746
+ const tagValue = tags[tagKey];
1747
+ if (tagValue) {
1748
+ sdk.set({ [tagKey]: tagValue });
1749
+ }
1750
+ });
1751
+ }
1752
+ return {
1753
+ collectTags
1754
+ };
1755
+ }
1756
+ };
1757
+ }
1758
+ const MODE_QUERY_PARAM = "td-personalization-mode";
1759
+ const INIT_MESSAGE_TYPE = "td:p13n-studio:init";
1760
+ const READY_MESSAGE_TYPE = "td:p13n-studio:ready";
1761
+ const PROD_ORIGINS = [
1762
+ // us01
1763
+ "https://console-development-next.us01.treasuredata.com",
1764
+ "https://console-staging-next.us01.treasuredata.com",
1765
+ "https://console-next.us01.treasuredata.com",
1766
+ // tokyo
1767
+ "https://console-staging-next.treasuredata.co.jp",
1768
+ "https://console-next.treasuredata.co.jp",
1769
+ // eu01
1770
+ "https://console-development-next.eu01.treasuredata.com",
1771
+ "https://console-next.eu01.treasuredata.com",
1772
+ // ap02
1773
+ "https://console-next.ap02.treasuredata.com",
1774
+ // ap03
1775
+ "https://console-staging-next.ap03.treasuredata.com",
1776
+ "https://console-next.ap03.treasuredata.com"
1777
+ ];
1778
+ const ALLOWED_PARENT_ORIGINS = Object.freeze(
1779
+ [...PROD_ORIGINS]
1780
+ );
1781
+ /**
1782
+ * @license
1783
+ * Copyright 2019 Google LLC
1784
+ * SPDX-License-Identifier: Apache-2.0
1785
+ */
1786
+ const proxyMarker = Symbol("Comlink.proxy");
1787
+ const createEndpoint = Symbol("Comlink.endpoint");
1788
+ const releaseProxy = Symbol("Comlink.releaseProxy");
1789
+ const finalizer = Symbol("Comlink.finalizer");
1790
+ const throwMarker = Symbol("Comlink.thrown");
1791
+ const isObject = (val) => typeof val === "object" && val !== null || typeof val === "function";
1792
+ const proxyTransferHandler = {
1793
+ canHandle: (val) => isObject(val) && val[proxyMarker],
1794
+ serialize(obj) {
1795
+ const { port1, port2 } = new MessageChannel();
1796
+ expose(obj, port1);
1797
+ return [port2, [port2]];
1798
+ },
1799
+ deserialize(port) {
1800
+ port.start();
1801
+ return wrap(port);
1802
+ }
1803
+ };
1804
+ const throwTransferHandler = {
1805
+ canHandle: (value) => isObject(value) && throwMarker in value,
1806
+ serialize({ value }) {
1807
+ let serialized;
1808
+ if (value instanceof Error) {
1809
+ serialized = {
1810
+ isError: true,
1811
+ value: {
1812
+ message: value.message,
1813
+ name: value.name,
1814
+ stack: value.stack
1815
+ }
1816
+ };
1817
+ } else {
1818
+ serialized = { isError: false, value };
1819
+ }
1820
+ return [serialized, []];
1821
+ },
1822
+ deserialize(serialized) {
1823
+ if (serialized.isError) {
1824
+ throw Object.assign(new Error(serialized.value.message), serialized.value);
1825
+ }
1826
+ throw serialized.value;
1827
+ }
1828
+ };
1829
+ const transferHandlers = /* @__PURE__ */ new Map([
1830
+ ["proxy", proxyTransferHandler],
1831
+ ["throw", throwTransferHandler]
1832
+ ]);
1833
+ function isAllowedOrigin(allowedOrigins, origin) {
1834
+ for (const allowedOrigin of allowedOrigins) {
1835
+ if (origin === allowedOrigin || allowedOrigin === "*") {
1836
+ return true;
1837
+ }
1838
+ if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
1839
+ return true;
1840
+ }
1841
+ }
1842
+ return false;
1843
+ }
1844
+ function expose(obj, ep = globalThis, allowedOrigins = ["*"]) {
1845
+ ep.addEventListener("message", function callback(ev) {
1846
+ if (!ev || !ev.data) {
1847
+ return;
1848
+ }
1849
+ if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
1850
+ console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
1851
+ return;
1852
+ }
1853
+ const { id, type, path } = Object.assign({ path: [] }, ev.data);
1854
+ const argumentList = (ev.data.argumentList || []).map(fromWireValue);
1855
+ let returnValue;
1856
+ try {
1857
+ const parent = path.slice(0, -1).reduce((obj2, prop) => obj2[prop], obj);
1858
+ const rawValue = path.reduce((obj2, prop) => obj2[prop], obj);
1859
+ switch (type) {
1860
+ case "GET":
1861
+ {
1862
+ returnValue = rawValue;
1863
+ }
1864
+ break;
1865
+ case "SET":
1866
+ {
1867
+ parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
1868
+ returnValue = true;
1869
+ }
1870
+ break;
1871
+ case "APPLY":
1872
+ {
1873
+ returnValue = rawValue.apply(parent, argumentList);
1874
+ }
1875
+ break;
1876
+ case "CONSTRUCT":
1877
+ {
1878
+ const value = new rawValue(...argumentList);
1879
+ returnValue = proxy(value);
1880
+ }
1881
+ break;
1882
+ case "ENDPOINT":
1883
+ {
1884
+ const { port1, port2 } = new MessageChannel();
1885
+ expose(obj, port2);
1886
+ returnValue = transfer(port1, [port1]);
1887
+ }
1888
+ break;
1889
+ case "RELEASE":
1890
+ {
1891
+ returnValue = void 0;
1892
+ }
1893
+ break;
1894
+ default:
1895
+ return;
1896
+ }
1897
+ } catch (value) {
1898
+ returnValue = { value, [throwMarker]: 0 };
1899
+ }
1900
+ Promise.resolve(returnValue).catch((value) => {
1901
+ return { value, [throwMarker]: 0 };
1902
+ }).then((returnValue2) => {
1903
+ const [wireValue, transferables] = toWireValue(returnValue2);
1904
+ ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
1905
+ if (type === "RELEASE") {
1906
+ ep.removeEventListener("message", callback);
1907
+ closeEndPoint(ep);
1908
+ if (finalizer in obj && typeof obj[finalizer] === "function") {
1909
+ obj[finalizer]();
1910
+ }
1911
+ }
1912
+ }).catch((error) => {
1913
+ const [wireValue, transferables] = toWireValue({
1914
+ value: new TypeError("Unserializable return value"),
1915
+ [throwMarker]: 0
1916
+ });
1917
+ ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
1918
+ });
1919
+ });
1920
+ if (ep.start) {
1921
+ ep.start();
1922
+ }
1923
+ }
1924
+ function isMessagePort(endpoint) {
1925
+ return endpoint.constructor.name === "MessagePort";
1926
+ }
1927
+ function closeEndPoint(endpoint) {
1928
+ if (isMessagePort(endpoint))
1929
+ endpoint.close();
1930
+ }
1931
+ function wrap(ep, target) {
1932
+ const pendingListeners = /* @__PURE__ */ new Map();
1933
+ ep.addEventListener("message", function handleMessage(ev) {
1934
+ const { data } = ev;
1935
+ if (!data || !data.id) {
1936
+ return;
1937
+ }
1938
+ const resolver = pendingListeners.get(data.id);
1939
+ if (!resolver) {
1940
+ return;
1941
+ }
1942
+ try {
1943
+ resolver(data);
1944
+ } finally {
1945
+ pendingListeners.delete(data.id);
1946
+ }
1947
+ });
1948
+ return createProxy(ep, pendingListeners, [], target);
1949
+ }
1950
+ function throwIfProxyReleased(isReleased) {
1951
+ if (isReleased) {
1952
+ throw new Error("Proxy has been released and is not useable");
1953
+ }
1954
+ }
1955
+ function releaseEndpoint(ep) {
1956
+ return requestResponseMessage(ep, /* @__PURE__ */ new Map(), {
1957
+ type: "RELEASE"
1958
+ }).then(() => {
1959
+ closeEndPoint(ep);
1960
+ });
1961
+ }
1962
+ const proxyCounter = /* @__PURE__ */ new WeakMap();
1963
+ const proxyFinalizers = "FinalizationRegistry" in globalThis && new FinalizationRegistry((ep) => {
1964
+ const newCount = (proxyCounter.get(ep) || 0) - 1;
1965
+ proxyCounter.set(ep, newCount);
1966
+ if (newCount === 0) {
1967
+ releaseEndpoint(ep);
1968
+ }
1969
+ });
1970
+ function registerProxy(proxy2, ep) {
1971
+ const newCount = (proxyCounter.get(ep) || 0) + 1;
1972
+ proxyCounter.set(ep, newCount);
1973
+ if (proxyFinalizers) {
1974
+ proxyFinalizers.register(proxy2, ep, proxy2);
1975
+ }
1976
+ }
1977
+ function unregisterProxy(proxy2) {
1978
+ if (proxyFinalizers) {
1979
+ proxyFinalizers.unregister(proxy2);
1980
+ }
1981
+ }
1982
+ function createProxy(ep, pendingListeners, path = [], target = function() {
1983
+ }) {
1984
+ let isProxyReleased = false;
1985
+ const proxy2 = new Proxy(target, {
1986
+ get(_target, prop) {
1987
+ throwIfProxyReleased(isProxyReleased);
1988
+ if (prop === releaseProxy) {
1989
+ return () => {
1990
+ unregisterProxy(proxy2);
1991
+ releaseEndpoint(ep);
1992
+ pendingListeners.clear();
1993
+ isProxyReleased = true;
1994
+ };
1995
+ }
1996
+ if (prop === "then") {
1997
+ if (path.length === 0) {
1998
+ return { then: () => proxy2 };
1999
+ }
2000
+ const r = requestResponseMessage(ep, pendingListeners, {
2001
+ type: "GET",
2002
+ path: path.map((p) => p.toString())
2003
+ }).then(fromWireValue);
2004
+ return r.then.bind(r);
2005
+ }
2006
+ return createProxy(ep, pendingListeners, [...path, prop]);
2007
+ },
2008
+ set(_target, prop, rawValue) {
2009
+ throwIfProxyReleased(isProxyReleased);
2010
+ const [value, transferables] = toWireValue(rawValue);
2011
+ return requestResponseMessage(ep, pendingListeners, {
2012
+ type: "SET",
2013
+ path: [...path, prop].map((p) => p.toString()),
2014
+ value
2015
+ }, transferables).then(fromWireValue);
2016
+ },
2017
+ apply(_target, _thisArg, rawArgumentList) {
2018
+ throwIfProxyReleased(isProxyReleased);
2019
+ const last = path[path.length - 1];
2020
+ if (last === createEndpoint) {
2021
+ return requestResponseMessage(ep, pendingListeners, {
2022
+ type: "ENDPOINT"
2023
+ }).then(fromWireValue);
2024
+ }
2025
+ if (last === "bind") {
2026
+ return createProxy(ep, pendingListeners, path.slice(0, -1));
2027
+ }
2028
+ const [argumentList, transferables] = processArguments(rawArgumentList);
2029
+ return requestResponseMessage(ep, pendingListeners, {
2030
+ type: "APPLY",
2031
+ path: path.map((p) => p.toString()),
2032
+ argumentList
2033
+ }, transferables).then(fromWireValue);
2034
+ },
2035
+ construct(_target, rawArgumentList) {
2036
+ throwIfProxyReleased(isProxyReleased);
2037
+ const [argumentList, transferables] = processArguments(rawArgumentList);
2038
+ return requestResponseMessage(ep, pendingListeners, {
2039
+ type: "CONSTRUCT",
2040
+ path: path.map((p) => p.toString()),
2041
+ argumentList
2042
+ }, transferables).then(fromWireValue);
2043
+ }
2044
+ });
2045
+ registerProxy(proxy2, ep);
2046
+ return proxy2;
2047
+ }
2048
+ function myFlat(arr) {
2049
+ return Array.prototype.concat.apply([], arr);
2050
+ }
2051
+ function processArguments(argumentList) {
2052
+ const processed = argumentList.map(toWireValue);
2053
+ return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
2054
+ }
2055
+ const transferCache = /* @__PURE__ */ new WeakMap();
2056
+ function transfer(obj, transfers) {
2057
+ transferCache.set(obj, transfers);
2058
+ return obj;
2059
+ }
2060
+ function proxy(obj) {
2061
+ return Object.assign(obj, { [proxyMarker]: true });
2062
+ }
2063
+ function toWireValue(value) {
2064
+ for (const [name, handler] of transferHandlers) {
2065
+ if (handler.canHandle(value)) {
2066
+ const [serializedValue, transferables] = handler.serialize(value);
2067
+ return [
2068
+ {
2069
+ type: "HANDLER",
2070
+ name,
2071
+ value: serializedValue
2072
+ },
2073
+ transferables
2074
+ ];
2075
+ }
2076
+ }
2077
+ return [
2078
+ {
2079
+ type: "RAW",
2080
+ value
2081
+ },
2082
+ transferCache.get(value) || []
2083
+ ];
2084
+ }
2085
+ function fromWireValue(value) {
2086
+ switch (value.type) {
2087
+ case "HANDLER":
2088
+ return transferHandlers.get(value.name).deserialize(value.value);
2089
+ case "RAW":
2090
+ return value.value;
2091
+ }
2092
+ }
2093
+ function requestResponseMessage(ep, pendingListeners, msg, transfers) {
2094
+ return new Promise((resolve) => {
2095
+ const id = generateUUID();
2096
+ pendingListeners.set(id, resolve);
2097
+ if (ep.start) {
2098
+ ep.start();
2099
+ }
2100
+ ep.postMessage(Object.assign({ id }, msg), transfers);
2101
+ });
2102
+ }
2103
+ function generateUUID() {
2104
+ return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-");
2105
+ }
2106
+ function onParentPort(onPort) {
2107
+ let activePort = null;
2108
+ const onInit = (ev) => {
2109
+ if (!ALLOWED_PARENT_ORIGINS.includes(ev.origin)) return;
2110
+ if (ev.data !== INIT_MESSAGE_TYPE) return;
2111
+ const port = ev.ports[0];
2112
+ if (!port) return;
2113
+ window.removeEventListener("message", onInit);
2114
+ activePort = port;
2115
+ onPort(port);
2116
+ };
2117
+ window.addEventListener("message", onInit);
2118
+ try {
2119
+ window.parent.postMessage(READY_MESSAGE_TYPE, "*");
2120
+ } catch {
2121
+ }
2122
+ return {
2123
+ dispose() {
2124
+ window.removeEventListener("message", onInit);
2125
+ activePort?.close();
2126
+ activePort = null;
2127
+ }
2128
+ };
2129
+ }
2130
+ function exposeRpc(rpc) {
2131
+ return onParentPort((port) => {
2132
+ expose(rpc, port);
2133
+ });
2134
+ }
2135
+ function wrapParentRpc() {
2136
+ let api2 = null;
2137
+ const runtime = onParentPort((port) => {
2138
+ port.start();
2139
+ api2 = wrap(port);
2140
+ });
2141
+ return {
2142
+ getApi: () => api2,
2143
+ dispose() {
2144
+ runtime.dispose?.();
2145
+ api2 = null;
2146
+ }
2147
+ };
2148
+ }
2149
+ function querySpot(doc, selector) {
2150
+ try {
2151
+ const nodes = doc.querySelectorAll(selector);
2152
+ return { element: nodes[0] ?? null, matchCount: nodes.length };
2153
+ } catch {
2154
+ return null;
2155
+ }
2156
+ }
2157
+ function ensureShadowRoot(host) {
2158
+ if (host.shadowRoot) return { ok: true, shadow: host.shadowRoot };
2159
+ try {
2160
+ return { ok: true, shadow: host.attachShadow({ mode: "open" }) };
2161
+ } catch (err) {
2162
+ return { ok: false, name: err instanceof Error ? err.name : "" };
2163
+ }
2164
+ }
2165
+ function classifyShadowError(name) {
2166
+ switch (name) {
2167
+ case "NotSupportedError":
2168
+ return "unsupported_element";
2169
+ case "InvalidStateError":
2170
+ return "already_has_shadow";
2171
+ default:
2172
+ return "injection_error";
2173
+ }
2174
+ }
2175
+ function applySpot(doc, spot) {
2176
+ const query = querySpot(doc, spot.selector);
2177
+ if (!query) {
2178
+ return { selector: spot.selector, success: false, reason: "invalid_spot" };
2179
+ }
2180
+ if (!query.element) {
2181
+ return {
2182
+ selector: spot.selector,
2183
+ success: false,
2184
+ reason: "not_found",
2185
+ matchCount: 0
2186
+ };
2187
+ }
2188
+ const shadowResult = ensureShadowRoot(query.element);
2189
+ if (!shadowResult.ok) {
2190
+ return {
2191
+ selector: spot.selector,
2192
+ success: false,
2193
+ reason: classifyShadowError(shadowResult.name),
2194
+ matchCount: query.matchCount
2195
+ };
2196
+ }
2197
+ const shadow = shadowResult.shadow;
2198
+ try {
2199
+ shadow.replaceChildren();
2200
+ if (spot.css) {
2201
+ const style = doc.createElement("style");
2202
+ style.textContent = spot.css;
2203
+ shadow.appendChild(style);
2204
+ }
2205
+ if (spot.html) {
2206
+ const wrapper = doc.createElement("div");
2207
+ wrapper.innerHTML = spot.html;
2208
+ shadow.appendChild(wrapper);
2209
+ }
2210
+ return {
2211
+ selector: spot.selector,
2212
+ success: true,
2213
+ matchCount: query.matchCount
2214
+ };
2215
+ } catch {
2216
+ return {
2217
+ selector: spot.selector,
2218
+ success: false,
2219
+ reason: "injection_error",
2220
+ matchCount: query.matchCount
2221
+ };
2222
+ }
2223
+ }
2224
+ function removeSpot(doc, ref) {
2225
+ let host;
2226
+ try {
2227
+ host = doc.querySelector(ref.selector);
2228
+ } catch {
2229
+ return;
2230
+ }
2231
+ const shadow = host?.shadowRoot;
2232
+ if (!shadow) return;
2233
+ shadow.replaceChildren(doc.createElement("slot"));
2234
+ }
2235
+ function validateSpot(value) {
2236
+ if (!value || typeof value !== "object") {
2237
+ return { ok: false, reason: `not an object (${typeof value})` };
2238
+ }
2239
+ const v = value;
2240
+ if (typeof v["selector"] !== "string") {
2241
+ return {
2242
+ ok: false,
2243
+ reason: `selector not a string (${typeof v["selector"]})`
2244
+ };
2245
+ }
2246
+ if (v["selector"].length === 0) {
2247
+ return { ok: false, reason: "selector empty" };
2248
+ }
2249
+ if (v["html"] !== void 0 && typeof v["html"] !== "string") {
2250
+ return { ok: false, reason: `html not a string (${typeof v["html"]})` };
2251
+ }
2252
+ if (v["css"] !== void 0 && typeof v["css"] !== "string") {
2253
+ return { ok: false, reason: `css not a string (${typeof v["css"]})` };
2254
+ }
2255
+ return { ok: true, spot: value };
2256
+ }
2257
+ function isSpotRef(value) {
2258
+ if (!value || typeof value !== "object") return false;
2259
+ const sel = value.selector;
2260
+ return typeof sel === "string" && sel.length > 0;
2261
+ }
2262
+ function getSelector(value) {
2263
+ if (value && typeof value === "object" && "selector" in value) {
2264
+ return value.selector;
2265
+ }
2266
+ return null;
2267
+ }
2268
+ function buildRpc(log) {
2269
+ return {
2270
+ async applySpots(spots) {
2271
+ invariant$1(
2272
+ Array.isArray(spots),
2273
+ "pagePersonalize/preview: applySpots requires an array"
2274
+ );
2275
+ return spots.map((entry, i) => {
2276
+ const validated = validateSpot(entry);
2277
+ if (!validated.ok) {
2278
+ log.warn(
2279
+ `pagePersonalize/preview: applySpots[${i}] invalid_spot: ${validated.reason}`
2280
+ );
2281
+ return {
2282
+ selector: getSelector(entry),
2283
+ success: false,
2284
+ reason: "invalid_spot"
2285
+ };
2286
+ }
2287
+ const result = applySpot(document, validated.spot);
2288
+ if (!result.success) {
2289
+ log.warn(
2290
+ `pagePersonalize/preview: applySpot "${result.selector}" -> ${result.reason}` + (result.matchCount !== void 0 ? ` (matchCount=${result.matchCount})` : "")
2291
+ );
2292
+ }
2293
+ return result;
2294
+ });
2295
+ },
2296
+ async removeSpots(spots) {
2297
+ invariant$1(
2298
+ Array.isArray(spots),
2299
+ "pagePersonalize/preview: removeSpots requires an array"
2300
+ );
2301
+ for (let i = 0; i < spots.length; i++) {
2302
+ const entry = spots[i];
2303
+ if (!isSpotRef(entry)) {
2304
+ log.warn(
2305
+ `pagePersonalize/preview: removeSpots[${i}] skipped malformed ref`
2306
+ );
2307
+ continue;
2308
+ }
2309
+ removeSpot(document, entry);
2310
+ }
2311
+ }
2312
+ };
2313
+ }
2314
+ const previewHandler = {
2315
+ mode: "preview",
2316
+ activate(core) {
2317
+ return exposeRpc(buildRpc(core.log));
2318
+ }
2319
+ };
2320
+ const UNSTABLE_ID_PATTERNS = [
2321
+ /^[0-9]+$/,
2322
+ // numeric-only
2323
+ /^:r/,
2324
+ // React :r IDs
2325
+ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i
2326
+ // UUIDs
2327
+ ];
2328
+ const UNSTABLE_DATA_VALUE_PATTERNS = [
2329
+ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i,
2330
+ // UUIDs
2331
+ /^[a-z0-9]{20,}$/i
2332
+ // long token-like strings
2333
+ ];
2334
+ const UNSTABLE_CLASS_PATTERNS = [
2335
+ /^css-/,
2336
+ // CSS-in-JS (emotion, etc.)
2337
+ /^sc-/,
2338
+ // styled-components
2339
+ /^emotion-/,
2340
+ /^[a-zA-Z0-9]{5,}$/
2341
+ // random 5+ char alphanum (likely generated)
2342
+ ];
2343
+ const SEMANTIC_TAGS = [
2344
+ "main",
2345
+ "nav",
2346
+ "header",
2347
+ "footer",
2348
+ "aside",
2349
+ "article",
2350
+ "section"
2351
+ ];
2352
+ const ARIA_LANDMARK_ROLES = [
2353
+ "banner",
2354
+ "complementary",
2355
+ "contentinfo",
2356
+ "form",
2357
+ "main",
2358
+ "navigation",
2359
+ "region",
2360
+ "search"
2361
+ ];
2362
+ function isStableId(id) {
2363
+ return !UNSTABLE_ID_PATTERNS.some((pattern) => pattern.test(id));
2364
+ }
2365
+ function isStableDataValue(value) {
2366
+ return !UNSTABLE_DATA_VALUE_PATTERNS.some((pattern) => pattern.test(value));
2367
+ }
2368
+ function isStableClass(className) {
2369
+ if (className.startsWith("p13n-sdk-")) return false;
2370
+ return !UNSTABLE_CLASS_PATTERNS.some((pattern) => pattern.test(className));
2371
+ }
2372
+ function isUnique(selector) {
2373
+ return document.querySelectorAll(selector).length === 1;
2374
+ }
2375
+ function validate(selector, element2) {
2376
+ try {
2377
+ return document.querySelector(selector) === element2;
2378
+ } catch {
2379
+ return false;
2380
+ }
2381
+ }
2382
+ function getTagName(element2) {
2383
+ return element2.localName;
2384
+ }
2385
+ function tryDirectAnchor(element2) {
2386
+ if (element2.id && isStableId(element2.id)) {
2387
+ const selector = `#${CSS.escape(element2.id)}`;
2388
+ if (validate(selector, element2)) return selector;
2389
+ }
2390
+ for (const attr of element2.attributes) {
2391
+ if (attr.name.startsWith("data-") && attr.value && isStableDataValue(attr.value)) {
2392
+ const selector = `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`;
2393
+ if (isUnique(selector) && validate(selector, element2)) return selector;
2394
+ }
2395
+ }
2396
+ for (const cls of element2.classList) {
2397
+ if (isStableClass(cls)) {
2398
+ const selector = `.${CSS.escape(cls)}`;
2399
+ if (isUnique(selector) && validate(selector, element2)) return selector;
2400
+ }
2401
+ }
2402
+ const tag = getTagName(element2);
2403
+ for (const cls of element2.classList) {
2404
+ if (isStableClass(cls)) {
2405
+ const selector = `${tag}.${CSS.escape(cls)}`;
2406
+ if (isUnique(selector) && validate(selector, element2)) return selector;
2407
+ }
2408
+ }
2409
+ const role = element2.getAttribute("role");
2410
+ if (role && ARIA_LANDMARK_ROLES.includes(role)) {
2411
+ const selector = `[role="${role}"]`;
2412
+ if (isUnique(selector) && validate(selector, element2)) return selector;
2413
+ }
2414
+ if (SEMANTIC_TAGS.includes(tag)) {
2415
+ if (isUnique(tag) && validate(tag, element2)) return tag;
2416
+ }
2417
+ return null;
2418
+ }
2419
+ function getNthOfTypeIndex(element2) {
2420
+ const tag = getTagName(element2);
2421
+ let index = 1;
2422
+ let sibling = element2.previousElementSibling;
2423
+ while (sibling) {
2424
+ if (sibling.localName === tag) index++;
2425
+ sibling = sibling.previousElementSibling;
2426
+ }
2427
+ return index;
2428
+ }
2429
+ function buildRelativePath(from, to) {
2430
+ const parts = [];
2431
+ let current = to;
2432
+ while (current && current !== from) {
2433
+ const tag = getTagName(current);
2434
+ const index = getNthOfTypeIndex(current);
2435
+ parts.unshift(`${tag}:nth-of-type(${index})`);
2436
+ current = current.parentElement;
2437
+ }
2438
+ return parts.join(" > ");
2439
+ }
2440
+ function tryAnchoredPath(element2) {
2441
+ let ancestor = element2.parentElement;
2442
+ while (ancestor && ancestor !== document.documentElement) {
2443
+ const anchorSelector = tryDirectAnchor(ancestor);
2444
+ if (anchorSelector) {
2445
+ const relativePath = buildRelativePath(ancestor, element2);
2446
+ const selector = `${anchorSelector} > ${relativePath}`;
2447
+ if (validate(selector, element2)) return selector;
2448
+ }
2449
+ ancestor = ancestor.parentElement;
2450
+ }
2451
+ return null;
2452
+ }
2453
+ function buildFullPath(element2) {
2454
+ const parts = [];
2455
+ let current = element2;
2456
+ while (current && current !== document.documentElement) {
2457
+ const tag = getTagName(current);
2458
+ const index = getNthOfTypeIndex(current);
2459
+ parts.unshift(`${tag}:nth-of-type(${index})`);
2460
+ current = current.parentElement;
2461
+ }
2462
+ const selector = `html > ${parts.join(" > ")}`;
2463
+ if (validate(selector, element2)) return selector;
2464
+ return null;
2465
+ }
2466
+ function generateSelector(element2) {
2467
+ if (!element2 || element2 === document.documentElement || element2 === document.body) {
2468
+ return element2 === document.body ? "body" : "html";
2469
+ }
2470
+ const direct = tryDirectAnchor(element2);
2471
+ if (direct) return direct;
2472
+ const anchored = tryAnchoredPath(element2);
2473
+ if (anchored) return anchored;
2474
+ return buildFullPath(element2) ?? element2.localName;
2475
+ }
2476
+ const SDK_ATTR = "data-p13n-sdk";
2477
+ const HIGHLIGHT_CLASS = "p13n-sdk-highlight";
2478
+ const SUPPRESSED_EVENTS = [
2479
+ "mousedown",
2480
+ "mouseup",
2481
+ "pointerdown",
2482
+ "pointerup",
2483
+ "keydown",
2484
+ "keyup",
2485
+ "focusin",
2486
+ "submit"
2487
+ ];
2488
+ const INJECTED_CSS = `
2489
+ .${HIGHLIGHT_CLASS} {
2490
+ outline: 2px solid blue !important;
2491
+ outline-offset: -2px !important;
2492
+ cursor: crosshair !important;
2493
+ }
2494
+ .p13n-sdk-tooltip {
2495
+ position: fixed;
2496
+ z-index: 2147483647;
2497
+ background: rgba(0, 0, 0, 0.8);
2498
+ color: #fff;
2499
+ font-family: monospace;
2500
+ font-size: 12px;
2501
+ padding: 4px 8px;
2502
+ border-radius: 4px;
2503
+ pointer-events: none;
2504
+ white-space: nowrap;
2505
+ }
2506
+ `;
2507
+ function isSdkElement(target) {
2508
+ let current = target;
2509
+ while (current) {
2510
+ if (current.hasAttribute && current.hasAttribute(SDK_ATTR)) return true;
2511
+ current = current.parentElement;
2512
+ }
2513
+ return false;
2514
+ }
2515
+ function getElementDimensions(element2) {
2516
+ if (element2.offsetWidth !== 0) {
2517
+ return { width: element2.offsetWidth, height: element2.offsetHeight };
2518
+ }
2519
+ const rect = element2.getBoundingClientRect();
2520
+ return { width: Math.round(rect.width), height: Math.round(rect.height) };
2521
+ }
2522
+ function createSelectionRuntime(onSelect) {
2523
+ let highlightedElement = null;
2524
+ const style = document.createElement("style");
2525
+ style.setAttribute(SDK_ATTR, "");
2526
+ style.textContent = INJECTED_CSS;
2527
+ document.head.appendChild(style);
2528
+ const tooltip = document.createElement("div");
2529
+ tooltip.className = "p13n-sdk-tooltip";
2530
+ tooltip.setAttribute(SDK_ATTR, "");
2531
+ tooltip.style.display = "none";
2532
+ document.body.appendChild(tooltip);
2533
+ function positionTooltip(event) {
2534
+ const offset = 15;
2535
+ let x = event.clientX + offset;
2536
+ let y = event.clientY + offset;
2537
+ const tooltipRect = tooltip.getBoundingClientRect();
2538
+ const tooltipWidth = tooltipRect.width || 150;
2539
+ const tooltipHeight = tooltipRect.height || 24;
2540
+ if (x + tooltipWidth > window.innerWidth) {
2541
+ x = event.clientX - offset - tooltipWidth;
2542
+ }
2543
+ if (y + tooltipHeight > window.innerHeight) {
2544
+ y = event.clientY - offset - tooltipHeight;
2545
+ }
2546
+ tooltip.style.left = `${x}px`;
2547
+ tooltip.style.top = `${y}px`;
2548
+ }
2549
+ function onMouseOver(event) {
2550
+ const target = event.target;
2551
+ if (!(target instanceof HTMLElement)) return;
2552
+ if (isSdkElement(target)) return;
2553
+ if (highlightedElement && highlightedElement !== target) {
2554
+ highlightedElement.classList.remove(HIGHLIGHT_CLASS);
2555
+ }
2556
+ highlightedElement = target;
2557
+ target.classList.add(HIGHLIGHT_CLASS);
2558
+ const tag = target.localName;
2559
+ const { width, height } = getElementDimensions(target);
2560
+ tooltip.textContent = `${tag} ${width}×${height}`;
2561
+ tooltip.style.display = "block";
2562
+ positionTooltip(event);
2563
+ }
2564
+ function onMouseMove(event) {
2565
+ if (tooltip.style.display === "block") {
2566
+ positionTooltip(event);
2567
+ }
2568
+ }
2569
+ function onMouseOut(event) {
2570
+ const target = event.target;
2571
+ if (!(target instanceof HTMLElement)) return;
2572
+ if (isSdkElement(target)) return;
2573
+ if (highlightedElement === target) {
2574
+ target.classList.remove(HIGHLIGHT_CLASS);
2575
+ highlightedElement = null;
2576
+ }
2577
+ tooltip.style.display = "none";
2578
+ }
2579
+ function suppressEvent(event) {
2580
+ if (isSdkElement(event.target)) return;
2581
+ event.preventDefault();
2582
+ event.stopPropagation();
2583
+ event.stopImmediatePropagation();
2584
+ }
2585
+ function onClick(event) {
2586
+ const target = event.target;
2587
+ if (!(target instanceof HTMLElement)) return;
2588
+ suppressEvent(event);
2589
+ const selector = generateSelector(target);
2590
+ onSelect(selector);
2591
+ }
2592
+ function attachListeners() {
2593
+ document.addEventListener("mouseover", onMouseOver, true);
2594
+ document.addEventListener("mousemove", onMouseMove, true);
2595
+ document.addEventListener("mouseout", onMouseOut, true);
2596
+ document.addEventListener("click", onClick, true);
2597
+ for (const eventType of SUPPRESSED_EVENTS) {
2598
+ document.addEventListener(eventType, suppressEvent, true);
2599
+ }
2600
+ }
2601
+ function detachListeners() {
2602
+ document.removeEventListener("mouseover", onMouseOver, true);
2603
+ document.removeEventListener("mousemove", onMouseMove, true);
2604
+ document.removeEventListener("mouseout", onMouseOut, true);
2605
+ document.removeEventListener("click", onClick, true);
2606
+ for (const eventType of SUPPRESSED_EVENTS) {
2607
+ document.removeEventListener(eventType, suppressEvent, true);
2608
+ }
2609
+ }
2610
+ function clearHighlightState() {
2611
+ if (highlightedElement) {
2612
+ highlightedElement.classList.remove(HIGHLIGHT_CLASS);
2613
+ highlightedElement = null;
2614
+ }
2615
+ tooltip.style.display = "none";
2616
+ }
2617
+ attachListeners();
2618
+ return {
2619
+ dispose() {
2620
+ detachListeners();
2621
+ clearHighlightState();
2622
+ tooltip.remove();
2623
+ style.remove();
2624
+ highlightedElement = null;
2625
+ }
2626
+ };
2627
+ }
2628
+ const spotSelectionHandler = {
2629
+ mode: "spot-selection",
2630
+ activate(core) {
2631
+ const bridge = wrapParentRpc();
2632
+ const runtime = createSelectionRuntime((selector) => {
2633
+ const api2 = bridge.getApi();
2634
+ if (api2) {
2635
+ api2.onSpotSelected(selector);
2636
+ } else {
2637
+ core.log.warn(
2638
+ "pagePersonalize/spot-selection: no parent RPC connection, cannot send selector"
2639
+ );
2640
+ }
2641
+ });
2642
+ return {
2643
+ dispose() {
2644
+ runtime.dispose?.();
2645
+ bridge.dispose?.();
2646
+ }
2647
+ };
2648
+ }
2649
+ };
2650
+ const MODE_HANDLERS = {
2651
+ preview: previewHandler,
2652
+ "spot-selection": spotSelectionHandler
2653
+ };
2654
+ function readMode() {
2655
+ if (typeof window === "undefined" || !window.location) return null;
2656
+ let raw_mode_param;
2657
+ try {
2658
+ raw_mode_param = new URLSearchParams(window.location.search).get(
2659
+ MODE_QUERY_PARAM
2660
+ );
2661
+ } catch {
2662
+ return null;
2663
+ }
2664
+ if (!raw_mode_param) return null;
2665
+ if (Object.hasOwn(MODE_HANDLERS, raw_mode_param))
2666
+ return raw_mode_param;
2667
+ return null;
2668
+ }
2669
+ function runRouter(core) {
2670
+ const mode = readMode();
2671
+ if (!mode) return null;
2672
+ let runtime;
2673
+ try {
2674
+ runtime = MODE_HANDLERS[mode].activate(core);
2675
+ } catch (err) {
2676
+ core.log.error(
2677
+ `pagePersonalize: activation failed for mode "${mode}":`,
2678
+ err
2679
+ );
2680
+ return null;
2681
+ }
2682
+ return runtime ? mode : null;
2683
+ }
2684
+ function numAttr(attrs, key) {
2685
+ const raw = attrs[key];
2686
+ if (typeof raw !== "string" || raw.length === 0) return null;
2687
+ const n = Number(raw);
2688
+ return Number.isFinite(n) ? n : null;
2689
+ }
2690
+ function strAttr(attrs, key) {
2691
+ const raw = attrs[key];
2692
+ return typeof raw === "string" && raw.length > 0 ? raw : null;
2693
+ }
2694
+ function isInWindow(attrs, now) {
2695
+ const start = numAttr(attrs, "td_personalization.campaigns_start_date");
2696
+ if (start !== null && now < start) return false;
2697
+ const end = numAttr(attrs, "td_personalization.campaigns_end_date");
2698
+ if (end !== null && now >= end) return false;
2699
+ return true;
2700
+ }
2701
+ function isLiveOffer(offer, now) {
2702
+ const attrs = offer.attributes;
2703
+ return !!attrs && typeof attrs === "object" && isInWindow(attrs, now);
2704
+ }
2705
+ function toScoredOffer(offer) {
2706
+ const attrs = offer.attributes;
2707
+ if (!attrs) return null;
2708
+ const rank = numAttr(attrs, "td_personalization.audience_rank");
2709
+ if (rank === null) return null;
2710
+ const updated = numAttr(attrs, "td_personalization.campaign_updated_at") ?? -Infinity;
2711
+ return { offer, updated, rank };
2712
+ }
2713
+ function maxBy(items, ranksAbove) {
2714
+ return items.reduce(
2715
+ (best, item) => best === null || ranksAbove(item, best) ? item : best,
2716
+ null
2717
+ );
2718
+ }
2719
+ function selectWinningOffer(payload, now = Date.now() / 1e3) {
2720
+ const offers = payload?.offers;
2721
+ if (!offers || typeof offers !== "object") return null;
2722
+ const candidates = Object.values(offers).filter((offer) => isLiveOffer(offer, now)).flatMap((offer) => toScoredOffer(offer) ?? []);
2723
+ const winner = maxBy(
2724
+ candidates,
2725
+ (a, b) => a.updated > b.updated || a.updated === b.updated && a.rank < b.rank
2726
+ );
2727
+ return winner?.offer ?? null;
2728
+ }
2729
+ function parseEntries(p13n) {
2730
+ if (typeof p13n !== "string") return null;
2731
+ try {
2732
+ const parsed = JSON.parse(p13n);
2733
+ return Array.isArray(parsed) ? parsed : null;
2734
+ } catch {
2735
+ return null;
2736
+ }
2737
+ }
2738
+ function toSpot(entry) {
2739
+ if (!entry || typeof entry !== "object") return null;
2740
+ const {
2741
+ css_selector: selector,
2742
+ html_value: html,
2743
+ css_value: css
2744
+ } = entry;
2745
+ if (typeof selector !== "string" || selector.length === 0) return null;
2746
+ if (typeof html !== "string") return null;
2747
+ if (typeof css !== "string") return null;
2748
+ return { selector, html, css };
2749
+ }
2750
+ function decodeEntry(entry, campaign) {
2751
+ const spot = toSpot(entry);
2752
+ if (!spot) return null;
2753
+ const id = entry.id;
2754
+ const creative = typeof id === "number" && Number.isFinite(id) ? String(id) : null;
2755
+ const impression = campaign && creative ? { campaign, creative } : null;
2756
+ return { spot, impression };
2757
+ }
2758
+ function decodeOffers(payload, now) {
2759
+ const offer = selectWinningOffer(payload, now);
2760
+ if (!offer) return [];
2761
+ const attrs = offer.attributes;
2762
+ const campaign = attrs ? strAttr(attrs, "td_personalization.campaign") : null;
2763
+ const entries = parseEntries(attrs?.["td_personalization.content"]);
2764
+ if (!entries) return [];
2765
+ return entries.flatMap((entry) => decodeEntry(entry, campaign) ?? []);
2766
+ }
2767
+ const PERSONALIZATION_DATABASE = "td_c360_personalization";
2768
+ const PERSONALIZATION_TABLE = "events";
2769
+ const CLICKABLE_SELECTOR = 'a, button, [role="button"], [role="link"]';
2770
+ const CAMPAIGN_ATTR = "data-td-personalization-campaign";
2771
+ const CREATIVE_ATTR = "data-td-personalization-creative";
2772
+ function pagePersonalize() {
2773
+ return {
2774
+ name: "pagePersonalize",
2775
+ setup(core, sdk) {
2776
+ const activeMode = runRouter(core);
2777
+ function reportEvent(event, ref) {
2778
+ const base = typeof sdk.getTrackValues === "function" ? sdk.getTrackValues() : {};
2779
+ sdk.addRecord(
2780
+ PERSONALIZATION_TABLE,
2781
+ {
2782
+ ...base,
2783
+ td_event: event,
2784
+ td_personalization_campaign: ref.campaign,
2785
+ td_personalization_creative: ref.creative
2786
+ },
2787
+ void 0,
2788
+ void 0,
2789
+ { database: PERSONALIZATION_DATABASE }
2790
+ );
2791
+ }
2792
+ function handleSpotClick(e) {
2793
+ const node = e.target;
2794
+ if (!(node instanceof Element) || !node.closest(CLICKABLE_SELECTOR)) {
2795
+ return;
2796
+ }
2797
+ const host = e.currentTarget.host;
2798
+ const campaign = host.getAttribute(CAMPAIGN_ATTR);
2799
+ const creative = host.getAttribute(CREATIVE_ATTR);
2800
+ if (campaign && creative) reportEvent("click", { campaign, creative });
2801
+ }
2802
+ function trackSpotClicks(selector, ref) {
2803
+ const host = document.querySelector(selector);
2804
+ if (!host?.shadowRoot) return;
2805
+ host.setAttribute(CAMPAIGN_ATTR, ref.campaign);
2806
+ host.setAttribute(CREATIVE_ATTR, ref.creative);
2807
+ host.shadowRoot.addEventListener("click", handleSpotClick);
2808
+ }
2809
+ function applyPersonalization(payload, options) {
2810
+ if (typeof document === "undefined") return;
2811
+ if (activeMode !== null && !options?.force) return;
2812
+ for (const { spot, impression } of decodeOffers(payload)) {
2813
+ const result = applySpot(document, spot);
2814
+ if (result.success && impression) {
2815
+ reportEvent("impression", impression);
2816
+ trackSpotClicks(spot.selector, impression);
2817
+ }
2818
+ }
2819
+ }
2820
+ function personalizePage(config, data, successCallback, errorCallback) {
2821
+ if (activeMode !== null) {
2822
+ core.log.debug(
2823
+ `pagePersonalize: personalizePage suppressed in "${activeMode}" mode`
2824
+ );
2825
+ return;
2826
+ }
2827
+ const body = {};
2828
+ if (typeof document !== "undefined" && document.location) {
2829
+ body["td_url"] = document.location.href.split("#")[0];
2830
+ body["td_host"] = document.location.host;
2831
+ body["td_path"] = document.location.pathname;
2832
+ }
2833
+ Object.assign(body, data);
2834
+ sdk.fetchPersonalization(
2835
+ config,
2836
+ body,
2837
+ (response) => {
2838
+ const payload = response;
2839
+ applyPersonalization(payload);
2840
+ successCallback?.(payload);
2841
+ },
2842
+ errorCallback
2843
+ );
2844
+ }
2845
+ return { applyPersonalization, personalizePage };
2846
+ }
2847
+ };
2848
+ }
2849
+ function globalId() {
2850
+ return {
2851
+ name: "globalId",
2852
+ setup(core, sdk) {
2853
+ const config = core.config;
2854
+ const noop = () => {
2855
+ };
2856
+ function fetchGlobalID(success, error, forceFetch = false, options = {}) {
2857
+ const successCallback = success || noop;
2858
+ const errorCallback = error || noop;
2859
+ if (!sdk.inSignedMode()) {
2860
+ return errorCallback("not in signed in mode");
2861
+ }
2862
+ if (!sdk.isGlobalIdEnabled()) {
2863
+ return errorCallback("global id is not enabled");
2864
+ }
2865
+ const cookieName = config.globalIdCookie || "_td_global";
2866
+ const cachedGlobalId = cookie.getItem(cookieName);
2867
+ if (cachedGlobalId && !forceFetch) {
2868
+ setTimeout(() => successCallback(cachedGlobalId), 0);
2869
+ return;
2870
+ }
2871
+ const sameSite = options.sameSite || "None";
2872
+ const url = `https://${config.host}`;
2873
+ const headers = {
2874
+ Authorization: `TD1 ${config.writeKey}`,
2875
+ "Content-Type": globalIdAdlHeaders["Content-Type"],
2876
+ Accept: globalIdAdlHeaders["Accept"]
2877
+ };
2878
+ if (typeof navigator !== "undefined") {
2879
+ headers["User-Agent"] = navigator.userAgent;
2880
+ }
2881
+ api.get(url, { headers }).then((res) => {
2882
+ if (!res["global_id"]) {
2883
+ successCallback(null);
2884
+ return;
2885
+ }
2886
+ const globalIdValue = res["global_id"];
2887
+ const maxAge = options.maxAge ?? 6e3;
2888
+ cookie.setItem(
2889
+ cookieName,
2890
+ globalIdValue,
2891
+ maxAge,
2892
+ options.path,
2893
+ options.domain,
2894
+ options.secure,
2895
+ sameSite
2896
+ );
2897
+ successCallback(globalIdValue);
2898
+ }).catch((err) => {
2899
+ errorCallback(err);
2900
+ });
2901
+ }
2902
+ return { fetchGlobalID };
2903
+ }
2904
+ };
2905
+ }
2906
+ const LOADER_METHODS = [
2907
+ "set",
2908
+ "collectTags",
2909
+ "blockEvents",
2910
+ "unblockEvents",
2911
+ "setSignedMode",
2912
+ "setAnonymousMode",
2913
+ "fetchServerCookie",
2914
+ "fetchGlobalID",
2915
+ "fetchUserSegments",
2916
+ "fetchPersonalization",
2917
+ "resetUUID",
2918
+ "addRecord",
2919
+ "trackEvent",
2920
+ "trackPageview",
2921
+ "trackClicks",
2922
+ "ready"
2923
+ ];
2924
+ function escapeForInlineScript(value) {
2925
+ return value.replace(/[<>\u2028\u2029/]/g, (char) => {
2926
+ switch (char) {
2927
+ case "<":
2928
+ return "\\u003C";
2929
+ case ">":
2930
+ return "\\u003E";
2931
+ case "/":
2932
+ return "\\u002F";
2933
+ case "\u2028":
2934
+ return "\\u2028";
2935
+ case "\u2029":
2936
+ return "\\u2029";
2937
+ default:
2938
+ return char;
2939
+ }
2940
+ });
2941
+ }
2942
+ function createLoader(globalName, scriptUrl) {
2943
+ const serializedMethods = escapeForInlineScript(
2944
+ JSON.stringify(LOADER_METHODS)
2945
+ );
2946
+ const serializedScriptUrl = escapeForInlineScript(JSON.stringify(scriptUrl));
2947
+ const serializedGlobalName = escapeForInlineScript(JSON.stringify(globalName));
2948
+ return `!function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=${serializedMethods},c=0;c<s.length;c++){var o=s[c];e[t].prototype[o]=r(o)}var n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=("https:"===document.location.protocol?"https:":"http:")+${serializedScriptUrl};var i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(n,i)}}(${serializedGlobalName},this);`;
2949
+ }
2950
+ function processQueuedCalls(loaderClient, actualClient) {
2951
+ if (loaderClient._init && loaderClient._init.length > 0) ;
2952
+ LOADER_METHODS.forEach((method) => {
2953
+ const queuedCalls = loaderClient["_" + method];
2954
+ if (queuedCalls && Array.isArray(queuedCalls) && queuedCalls.length > 0) {
2955
+ queuedCalls.forEach((args) => {
2956
+ if (typeof actualClient[method] === "function") {
2957
+ actualClient[method].apply(actualClient, args);
2958
+ }
2959
+ });
2960
+ }
2961
+ });
2962
+ }
2963
+ function replaceLoaderStub(globalName, sdkConstructor) {
2964
+ const global = typeof window !== "undefined" ? window : globalThis;
2965
+ if (global[globalName] && global[globalName].clients) {
2966
+ const clients = global[globalName].clients;
2967
+ global[globalName] = sdkConstructor;
2968
+ clients.forEach((loaderClient) => {
2969
+ let actualClient;
2970
+ if (loaderClient._init && loaderClient._init.length > 0) {
2971
+ const initArgs = loaderClient._init[0];
2972
+ actualClient = new sdkConstructor(...initArgs || []);
2973
+ } else {
2974
+ actualClient = new sdkConstructor();
2975
+ }
2976
+ processQueuedCalls(loaderClient, actualClient);
2977
+ Object.setPrototypeOf(loaderClient, actualClient);
2978
+ Object.assign(loaderClient, actualClient);
2979
+ });
2980
+ }
2981
+ }
2982
+ class Treasure {
2983
+ _sdk;
2984
+ constructor(config) {
2985
+ if (!(this instanceof Treasure)) {
2986
+ return new Treasure(config);
2987
+ }
2988
+ this._sdk = this.init(config);
2989
+ this.bindMethods();
2990
+ return this;
2991
+ }
2992
+ /**
2993
+ * Initialize the SDK with all plugins
2994
+ */
2995
+ init(config) {
2996
+ const processedConfig = configure(config);
2997
+ const sdk = createSDK(processedConfig).use(session()).use(record()).use(track()).use(clicks()).use(utm()).use(personalization()).use(conversionAPI()).use(serverCookie()).use(globalId()).use(pagePersonalize());
2998
+ return sdk;
2999
+ }
3000
+ /**
3001
+ * Bind all SDK methods to this instance for direct access
3002
+ */
3003
+ bindMethods() {
3004
+ const methodNames = /* @__PURE__ */ new Set();
3005
+ let current = this._sdk;
3006
+ while (current && current !== Object.prototype) {
3007
+ Object.getOwnPropertyNames(current).forEach((name) => {
3008
+ if (typeof current[name] === "function" && name !== "constructor") {
3009
+ methodNames.add(name);
3010
+ }
3011
+ });
3012
+ current = Object.getPrototypeOf(current);
3013
+ }
3014
+ methodNames.forEach((methodName) => {
3015
+ if (!this.hasOwnProperty(methodName) && methodName !== "init" && methodName !== "bindMethods") {
3016
+ this[methodName] = this._sdk[methodName].bind(
3017
+ this._sdk
3018
+ );
3019
+ }
3020
+ });
3021
+ }
3022
+ /**
3023
+ * Get the underlying SDK instance
3024
+ */
3025
+ get sdk() {
3026
+ return this._sdk;
3027
+ }
3028
+ /**
3029
+ * Get the configuration
3030
+ */
3031
+ get config() {
3032
+ return this._sdk.config;
3033
+ }
3034
+ /**
3035
+ * Version information
3036
+ */
3037
+ static version = "1.0.0";
3038
+ get version() {
3039
+ return Treasure.version;
3040
+ }
3041
+ // Core methods
3042
+ /**
3043
+ * Add a record to a table
3044
+ */
3045
+ addRecord = (table, record2, success, error, options) => {
3046
+ return this._sdk.addRecord(table, record2, success, error, options);
3047
+ };
3048
+ /**
3049
+ * Track a custom event
3050
+ */
3051
+ trackEvent = (table, data, success, error) => {
3052
+ return this._sdk.trackEvent(table, data, success, error);
3053
+ };
3054
+ /**
3055
+ * Track a page view
3056
+ */
3057
+ trackPageview = (table, success, error, options) => {
3058
+ return this._sdk.trackPageview(table, success, error, options);
3059
+ };
3060
+ /**
3061
+ * Start tracking clicks
3062
+ */
3063
+ trackClicks = (options) => {
3064
+ return this._sdk.trackClicks(options);
3065
+ };
3066
+ fetchUserSegments(tokenOrOptions, successCallback, errorCallback) {
3067
+ return this._sdk.fetchUserSegments(
3068
+ tokenOrOptions,
3069
+ successCallback,
3070
+ errorCallback
3071
+ );
3072
+ }
3073
+ /**
3074
+ * Fetch personalization data
3075
+ */
3076
+ fetchPersonalization = (config, data, successCallback, errorCallback) => {
3077
+ return this._sdk.fetchPersonalization(
3078
+ config,
3079
+ data,
3080
+ successCallback,
3081
+ errorCallback
3082
+ );
3083
+ };
3084
+ /**
3085
+ * Apply an already-fetched personalization payload to the current page
3086
+ */
3087
+ applyPersonalization = (payload, options) => {
3088
+ this._sdk.applyPersonalization(payload, options);
3089
+ };
3090
+ /**
3091
+ * Fetch personalization offers and apply them to the current page
3092
+ */
3093
+ personalizePage = (config, data, successCallback, errorCallback) => {
3094
+ this._sdk.personalizePage(config, data, successCallback, errorCallback);
3095
+ };
3096
+ /**
3097
+ * Collect UTM parameters
3098
+ */
3099
+ collectUTMParameters = () => {
3100
+ return this._sdk.collectUTMParameters();
3101
+ };
3102
+ /**
3103
+ * Get UTM parameters
3104
+ */
3105
+ getUTMParameters = () => {
3106
+ return this._sdk.getUTMParameters();
3107
+ };
3108
+ /**
3109
+ * Set global or table-specific values
3110
+ */
3111
+ set = (table, property, value) => {
3112
+ return this._sdk.set(table, property, value);
3113
+ };
3114
+ /**
3115
+ * Get global or table-specific values
3116
+ */
3117
+ get = (table, key) => {
3118
+ return this._sdk.get(table, key);
3119
+ };
3120
+ /**
3121
+ * Set signed mode
3122
+ */
3123
+ setSignedMode = () => {
3124
+ return this._sdk.setSignedMode();
3125
+ };
3126
+ /**
3127
+ * Set anonymous mode
3128
+ */
3129
+ setAnonymousMode = (keepIdentifier) => {
3130
+ return this._sdk.setAnonymousMode(keepIdentifier);
3131
+ };
3132
+ /**
3133
+ * Check if in signed mode
3134
+ */
3135
+ inSignedMode = () => {
3136
+ return this._sdk.inSignedMode();
3137
+ };
3138
+ /**
3139
+ * Block events
3140
+ */
3141
+ blockEvents = () => {
3142
+ return this._sdk.blockEvents();
3143
+ };
3144
+ /**
3145
+ * Unblock events
3146
+ */
3147
+ unblockEvents = () => {
3148
+ return this._sdk.unblockEvents();
3149
+ };
3150
+ /**
3151
+ * Check if events are blocked
3152
+ */
3153
+ areEventsBlocked = () => {
3154
+ return this._sdk.areEventsBlocked();
3155
+ };
3156
+ /**
3157
+ * Reset UUID
3158
+ */
3159
+ resetUUID = () => {
3160
+ return this._sdk.resetUUID();
3161
+ };
3162
+ /**
3163
+ * Get track values
3164
+ */
3165
+ getTrackValues = () => {
3166
+ return this._sdk.getTrackValues();
3167
+ };
3168
+ /**
3169
+ * Get the personalization config
3170
+ */
3171
+ getPersonalizationConfig = () => {
3172
+ return this._sdk.getPersonalizationConfig();
3173
+ };
3174
+ /**
3175
+ * Set the personalization config (pass undefined to disable)
3176
+ */
3177
+ setPersonalizationConfig = (options) => {
3178
+ return this._sdk.setPersonalizationConfig(options);
3179
+ };
3180
+ /**
3181
+ * Get the configured write key
3182
+ */
3183
+ getWriteKey = () => {
3184
+ return this._sdk.getWriteKey();
3185
+ };
3186
+ /**
3187
+ * Set the write key
3188
+ */
3189
+ setWriteKey = (writeKey) => {
3190
+ return this._sdk.setWriteKey(writeKey);
3191
+ };
3192
+ /**
3193
+ * Collect conversion tracking tags
3194
+ */
3195
+ collectTags = (options) => {
3196
+ return this._sdk.collectTags(options);
3197
+ };
3198
+ /**
3199
+ * Fetch server-side cookie ID
3200
+ */
3201
+ fetchServerCookie = (success, error, forceFetch) => {
3202
+ return this._sdk.fetchServerCookie(success, error, forceFetch);
3203
+ };
3204
+ /**
3205
+ * Fetch Global ID
3206
+ */
3207
+ fetchGlobalID = (success, error, forceFetch, options) => {
3208
+ return this._sdk.fetchGlobalID(success, error, forceFetch, options);
3209
+ };
3210
+ }
3211
+ if (typeof window !== "undefined") {
3212
+ replaceLoaderStub("Treasure", Treasure);
3213
+ }
3214
+ function initSDK(globalName = "td") {
3215
+ if (typeof window !== "undefined") {
3216
+ replaceLoaderStub(globalName, Treasure);
3217
+ if (!window[globalName]) {
3218
+ window[globalName] = Treasure;
3219
+ }
3220
+ }
3221
+ }
3222
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
3223
+ const scripts = document.getElementsByTagName("script");
3224
+ const currentScript = scripts[scripts.length - 1];
3225
+ if (currentScript && currentScript.hasAttribute("data-auto-init")) {
3226
+ const globalName = currentScript.getAttribute("data-global-name") || "td";
3227
+ initSDK(globalName);
3228
+ }
3229
+ }
3230
+ const version = "1.0.0";
3231
+ exports.BLOCKEVENTSCOOKIE = BLOCKEVENTSCOOKIE;
3232
+ exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
3233
+ exports.SERVER_COOKIE_NAME = SERVER_COOKIE_NAME;
3234
+ exports.SIGNEDMODECOOKIE = SIGNEDMODECOOKIE;
3235
+ exports.Treasure = Treasure;
3236
+ exports._validateRecord = _validateRecord;
3237
+ exports.adlHeaders = adlHeaders;
3238
+ exports.clicks = clicks;
3239
+ exports.configure = configure;
3240
+ exports.conversionAPI = conversionAPI;
3241
+ exports.cookie = cookie;
3242
+ exports.createLoader = createLoader;
3243
+ exports.createSDK = createSDK;
3244
+ exports.default = Treasure;
3245
+ exports.elementUtils = element;
3246
+ exports.generateUUID = generateUUID$1;
3247
+ exports.globalId = globalId;
3248
+ exports.globalIdAdlHeaders = globalIdAdlHeaders;
3249
+ exports.initSDK = initSDK;
3250
+ exports.invariant = invariant$1;
3251
+ exports.isLocalStorageAccessible = isLocalStorageAccessible;
3252
+ exports.isValidUUID = isValidUUID;
3253
+ exports.pagePersonalize = pagePersonalize;
3254
+ exports.personalization = personalization;
3255
+ exports.processQueuedCalls = processQueuedCalls;
3256
+ exports.record = record;
3257
+ exports.replaceLoaderStub = replaceLoaderStub;
3258
+ exports.serverCookie = serverCookie;
3259
+ exports.session = session;
3260
+ exports.setCookie = setCookie;
3261
+ exports.track = track;
3262
+ exports.utm = utm;
3263
+ exports.version = version;