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