@hanzo/event 0.3.43 → 0.3.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consent.d.ts +36 -0
- package/dist/consent.d.ts.map +1 -0
- package/dist/cookie.d.ts +5 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/events.d.ts +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/index.cjs +477 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +459 -38
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +1 -1
- package/dist/react.mjs.map +1 -1
- package/dist/tags.d.ts +42 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/touch.d.ts +7 -0
- package/dist/touch.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/consent.test.ts +140 -0
- package/src/consent.ts +116 -0
- package/src/cookie.ts +28 -0
- package/src/events.ts +1 -1
- package/src/index.ts +8 -0
- package/src/tags.test.ts +187 -0
- package/src/tags.ts +449 -0
- package/src/touch.ts +68 -0
package/dist/index.cjs
CHANGED
|
@@ -19,20 +19,20 @@ var SOCIAL_HOSTS = [
|
|
|
19
19
|
var SEARCH_HOSTS = ["google.", "bing.", "duckduckgo.", "yahoo.", "baidu.", "ecosia."];
|
|
20
20
|
function parseAttribution(search, referrer) {
|
|
21
21
|
const q = new URLSearchParams(search || "");
|
|
22
|
-
const
|
|
22
|
+
const get2 = (k) => {
|
|
23
23
|
const v = q.get(k);
|
|
24
24
|
return v ? v.trim() : void 0;
|
|
25
25
|
};
|
|
26
26
|
const a = {
|
|
27
27
|
utm: {
|
|
28
|
-
source:
|
|
29
|
-
medium:
|
|
30
|
-
campaign:
|
|
31
|
-
term:
|
|
32
|
-
content:
|
|
28
|
+
source: get2("utm_source"),
|
|
29
|
+
medium: get2("utm_medium"),
|
|
30
|
+
campaign: get2("utm_campaign"),
|
|
31
|
+
term: get2("utm_term"),
|
|
32
|
+
content: get2("utm_content")
|
|
33
33
|
},
|
|
34
34
|
referrer: referrer ? referrer.trim() : void 0,
|
|
35
|
-
refCode:
|
|
35
|
+
refCode: get2("ref") || get2("refCode") || get2("ref_code") || void 0
|
|
36
36
|
};
|
|
37
37
|
a.channel = deriveChannel(a);
|
|
38
38
|
return a;
|
|
@@ -289,13 +289,13 @@ var HZ_ANON_ADOPT = ["hz_anon_id", "hz_id"];
|
|
|
289
289
|
var HZ_ANON_DOMAIN = "hanzo.ai";
|
|
290
290
|
var HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60;
|
|
291
291
|
var hzAnonMemo;
|
|
292
|
-
function hzUuidv7(
|
|
292
|
+
function hzUuidv7(now2) {
|
|
293
293
|
var b = new Uint8Array(16);
|
|
294
294
|
var i;
|
|
295
295
|
var c = typeof crypto !== "undefined" ? crypto : void 0;
|
|
296
296
|
if (c && typeof c.getRandomValues === "function") c.getRandomValues(b);
|
|
297
297
|
else for (i = 0; i < 16; i++) b[i] = Math.random() * 256 | 0;
|
|
298
|
-
var t = Math.floor(
|
|
298
|
+
var t = Math.floor(now2 === void 0 ? Date.now() : now2);
|
|
299
299
|
for (i = 5; i >= 0; i--) {
|
|
300
300
|
b[i] = t % 256;
|
|
301
301
|
t = Math.floor(t / 256);
|
|
@@ -407,7 +407,7 @@ function uuidv7Time(id) {
|
|
|
407
407
|
}
|
|
408
408
|
|
|
409
409
|
// package.json
|
|
410
|
-
var version = "0.3.
|
|
410
|
+
var version = "0.3.44";
|
|
411
411
|
|
|
412
412
|
// src/version.ts
|
|
413
413
|
var VERSION = version;
|
|
@@ -540,22 +540,22 @@ function coerceTag(v) {
|
|
|
540
540
|
return s.length > MAX_TAG_LEN ? s.slice(0, MAX_TAG_LEN) : s;
|
|
541
541
|
}
|
|
542
542
|
function buildSentryEvent(input) {
|
|
543
|
-
const { error, options = {}, identity, capturePII = false } = input;
|
|
543
|
+
const { error, options: options2 = {}, identity, capturePII = false } = input;
|
|
544
544
|
const norm = normalizeError(error);
|
|
545
|
-
const handled =
|
|
546
|
-
const level =
|
|
547
|
-
const
|
|
548
|
-
if (identity.product)
|
|
549
|
-
if (identity.sessionId)
|
|
545
|
+
const handled = options2.handled !== false;
|
|
546
|
+
const level = options2.level ?? (handled ? "error" : "fatal");
|
|
547
|
+
const tags2 = { handled: String(handled) };
|
|
548
|
+
if (identity.product) tags2.product = identity.product;
|
|
549
|
+
if (identity.sessionId) tags2.session = identity.sessionId;
|
|
550
550
|
try {
|
|
551
|
-
const props =
|
|
551
|
+
const props = options2.properties ?? {};
|
|
552
552
|
let n = 0;
|
|
553
553
|
for (const k of Object.keys(props)) {
|
|
554
554
|
if (n >= MAX_TAGS) break;
|
|
555
555
|
try {
|
|
556
556
|
const val = props[k];
|
|
557
557
|
if (val === void 0 || val === null) continue;
|
|
558
|
-
|
|
558
|
+
tags2[k] = scrubText(coerceTag(val), capturePII);
|
|
559
559
|
n++;
|
|
560
560
|
} catch {
|
|
561
561
|
continue;
|
|
@@ -580,7 +580,7 @@ function buildSentryEvent(input) {
|
|
|
580
580
|
}
|
|
581
581
|
]
|
|
582
582
|
},
|
|
583
|
-
tags,
|
|
583
|
+
tags: tags2,
|
|
584
584
|
sdk: { name: "@hanzo/event", version: VERSION }
|
|
585
585
|
};
|
|
586
586
|
if (identity.userId) event.user = { id: identity.userId };
|
|
@@ -710,7 +710,7 @@ function ls() {
|
|
|
710
710
|
function anonId() {
|
|
711
711
|
return hzAnonId() || void 0;
|
|
712
712
|
}
|
|
713
|
-
function sessionId(
|
|
713
|
+
function sessionId(now2 = Date.now()) {
|
|
714
714
|
const s = ls();
|
|
715
715
|
if (!s) return void 0;
|
|
716
716
|
let state = null;
|
|
@@ -719,17 +719,17 @@ function sessionId(now = Date.now()) {
|
|
|
719
719
|
} catch {
|
|
720
720
|
state = null;
|
|
721
721
|
}
|
|
722
|
-
if (!state ||
|
|
723
|
-
state = { id: hzUuidv7(
|
|
722
|
+
if (!state || now2 - state.last > SESSION_TTL_MS) {
|
|
723
|
+
state = { id: hzUuidv7(now2), last: now2 };
|
|
724
724
|
} else {
|
|
725
|
-
state.last =
|
|
725
|
+
state.last = now2;
|
|
726
726
|
}
|
|
727
727
|
s.setItem(KEY.session, JSON.stringify(state));
|
|
728
728
|
return state.id;
|
|
729
729
|
}
|
|
730
|
-
function adoptSession(id,
|
|
730
|
+
function adoptSession(id, now2 = Date.now()) {
|
|
731
731
|
const s = ls();
|
|
732
|
-
if (s) s.setItem(KEY.session, JSON.stringify({ id, last:
|
|
732
|
+
if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now2 }));
|
|
733
733
|
}
|
|
734
734
|
function adoptAnonId(id) {
|
|
735
735
|
hzAnonAdopt(id);
|
|
@@ -815,10 +815,10 @@ function linkUrl(url, state, fromHost, base) {
|
|
|
815
815
|
}
|
|
816
816
|
if (u.protocol !== "https:" && u.protocol !== "http:") return url;
|
|
817
817
|
if (!orgOf(u.hostname) || u.hostname === fromHost) return url;
|
|
818
|
-
const
|
|
819
|
-
if (isId(state.anonId))
|
|
820
|
-
if (isId(state.sessionId))
|
|
821
|
-
if (state.firstTouch)
|
|
818
|
+
const set2 = (k, v) => v && u.searchParams.set(k, v);
|
|
819
|
+
if (isId(state.anonId)) set2(LINK_PARAMS.anon, state.anonId);
|
|
820
|
+
if (isId(state.sessionId)) set2(LINK_PARAMS.session, state.sessionId);
|
|
821
|
+
if (state.firstTouch) set2(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch));
|
|
822
822
|
return u.toString();
|
|
823
823
|
}
|
|
824
824
|
function readLink(search) {
|
|
@@ -1168,11 +1168,11 @@ var Analytics = class {
|
|
|
1168
1168
|
* or publishable key is attached here — the two planes authenticate
|
|
1169
1169
|
* independently. Errors are sent one envelope per event, immediately: batching
|
|
1170
1170
|
* a crash report is how you lose it. */
|
|
1171
|
-
sendError(err,
|
|
1171
|
+
sendError(err, options2) {
|
|
1172
1172
|
if (!this.cfg.enabled || !this.dsn) return;
|
|
1173
1173
|
const event = buildSentryEvent({
|
|
1174
1174
|
error: err,
|
|
1175
|
-
options,
|
|
1175
|
+
options: options2,
|
|
1176
1176
|
identity: this.errorIdentity(),
|
|
1177
1177
|
capturePII: this.cfg.capturePII ?? false
|
|
1178
1178
|
});
|
|
@@ -1259,16 +1259,16 @@ var Analytics = class {
|
|
|
1259
1259
|
};
|
|
1260
1260
|
var CLIENTS = /* @__PURE__ */ Symbol.for("hanzo.event.clients");
|
|
1261
1261
|
function registry() {
|
|
1262
|
-
const
|
|
1263
|
-
const existing =
|
|
1262
|
+
const g2 = globalThis;
|
|
1263
|
+
const existing = g2[CLIENTS];
|
|
1264
1264
|
if (existing) return existing;
|
|
1265
1265
|
const fresh = /* @__PURE__ */ new Map();
|
|
1266
|
-
|
|
1266
|
+
g2[CLIENTS] = fresh;
|
|
1267
1267
|
return fresh;
|
|
1268
1268
|
}
|
|
1269
1269
|
function resetClients() {
|
|
1270
|
-
const
|
|
1271
|
-
delete
|
|
1270
|
+
const g2 = globalThis;
|
|
1271
|
+
delete g2[CLIENTS];
|
|
1272
1272
|
}
|
|
1273
1273
|
function createAnalytics(config) {
|
|
1274
1274
|
if (!isBrowser() || config.enabled === false) return new Analytics(config);
|
|
@@ -1284,6 +1284,427 @@ function createAnalytics(config) {
|
|
|
1284
1284
|
return fresh;
|
|
1285
1285
|
}
|
|
1286
1286
|
|
|
1287
|
+
// src/cookie.ts
|
|
1288
|
+
var DAY = 86400;
|
|
1289
|
+
function domain() {
|
|
1290
|
+
const h = window.location.hostname;
|
|
1291
|
+
if (h === "localhost" || /^[\d.]+$/.test(h) || h.includes(":")) return "";
|
|
1292
|
+
const parts = h.split(".");
|
|
1293
|
+
return parts.length > 2 ? `; Domain=.${parts.slice(-2).join(".")}` : `; Domain=.${h}`;
|
|
1294
|
+
}
|
|
1295
|
+
function get(name) {
|
|
1296
|
+
if (typeof document === "undefined") return void 0;
|
|
1297
|
+
const hit = document.cookie.split("; ").find((c) => c.startsWith(`${name}=`));
|
|
1298
|
+
return hit ? decodeURIComponent(hit.slice(name.length + 1)) : void 0;
|
|
1299
|
+
}
|
|
1300
|
+
function set(name, value, days) {
|
|
1301
|
+
if (typeof document === "undefined") return;
|
|
1302
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
1303
|
+
document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${days * DAY}; Path=/; SameSite=Lax${domain()}${secure}`;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// src/consent.ts
|
|
1307
|
+
var CONSENT_COOKIE = "hz_consent";
|
|
1308
|
+
var CONSENT_EVENT = "hzconsent";
|
|
1309
|
+
var US = /^(America\/(New_York|Chicago|Denver|Los_Angeles|Phoenix|Anchorage|Adak|Boise|Detroit|Juneau|Sitka|Nome|Yakutat|Menominee|Metlakatla|Indiana\/.*|Kentucky\/.*|North_Dakota\/.*)|Pacific\/Honolulu|US\/.*)$/;
|
|
1310
|
+
function gpc() {
|
|
1311
|
+
if (typeof navigator === "undefined") return false;
|
|
1312
|
+
return navigator.globalPrivacyControl === true;
|
|
1313
|
+
}
|
|
1314
|
+
function refused() {
|
|
1315
|
+
if (typeof window === "undefined") return false;
|
|
1316
|
+
const n = navigator;
|
|
1317
|
+
const dnt = n.doNotTrack ?? window.doNotTrack ?? n.msDoNotTrack;
|
|
1318
|
+
return gpc() || dnt === "1" || dnt === "yes";
|
|
1319
|
+
}
|
|
1320
|
+
function region() {
|
|
1321
|
+
try {
|
|
1322
|
+
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? "";
|
|
1323
|
+
return US.test(zone) ? "opt-out" : "opt-in";
|
|
1324
|
+
} catch {
|
|
1325
|
+
return "opt-in";
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
function stored() {
|
|
1329
|
+
return get(CONSENT_COOKIE) !== void 0;
|
|
1330
|
+
}
|
|
1331
|
+
function read2() {
|
|
1332
|
+
const kept = get(CONSENT_COOKIE);
|
|
1333
|
+
const on = kept !== void 0 ? kept.split(",") : region() === "opt-in" || refused() ? [] : ["analytics", "marketing", "ads"];
|
|
1334
|
+
const has = (k) => on.includes(k);
|
|
1335
|
+
return { analytics: has("analytics"), marketing: has("marketing") && !gpc(), ads: has("ads") && !gpc() };
|
|
1336
|
+
}
|
|
1337
|
+
function asks() {
|
|
1338
|
+
return typeof document !== "undefined" && region() === "opt-in" && !stored();
|
|
1339
|
+
}
|
|
1340
|
+
function render(c) {
|
|
1341
|
+
return ["analytics", "marketing", "ads"].filter((k) => c[k]).join(",");
|
|
1342
|
+
}
|
|
1343
|
+
function save(c) {
|
|
1344
|
+
const out = { analytics: c.analytics, marketing: c.marketing && !gpc(), ads: c.ads && !gpc() };
|
|
1345
|
+
set(CONSENT_COOKIE, render(out), 395);
|
|
1346
|
+
if (typeof window !== "undefined") window.dispatchEvent(new Event(CONSENT_EVENT));
|
|
1347
|
+
}
|
|
1348
|
+
var acceptAll = () => save({ analytics: true, marketing: true, ads: true });
|
|
1349
|
+
var rejectAll = () => save({ analytics: false, marketing: false, ads: false });
|
|
1350
|
+
|
|
1351
|
+
// src/touch.ts
|
|
1352
|
+
var CLICK_IDS = ["gclid", "gbraid", "wbraid", "fbclid", "li_fat_id", "twclid", "ttclid"];
|
|
1353
|
+
var DAYS = 90;
|
|
1354
|
+
var now = () => Math.floor(Date.now() / 1e3);
|
|
1355
|
+
var rand = () => Math.floor(Math.random() * 2 ** 31);
|
|
1356
|
+
function capture(c) {
|
|
1357
|
+
if (typeof window === "undefined") return;
|
|
1358
|
+
if (c.marketing) {
|
|
1359
|
+
const q = new URLSearchParams(window.location.search);
|
|
1360
|
+
const click = {};
|
|
1361
|
+
for (const k of CLICK_IDS) {
|
|
1362
|
+
const v = q.get(k)?.trim();
|
|
1363
|
+
if (v) click[k] = v;
|
|
1364
|
+
}
|
|
1365
|
+
if (Object.keys(click).length) {
|
|
1366
|
+
click.clicked = now();
|
|
1367
|
+
set("hz_touch", JSON.stringify(click), DAYS);
|
|
1368
|
+
if (click.fbclid) set("_fbc", `fb.1.${Date.now()}.${click.fbclid}`, DAYS);
|
|
1369
|
+
}
|
|
1370
|
+
if (!get("_fbp")) set("_fbp", `fb.1.${Date.now()}.${rand()}`, DAYS);
|
|
1371
|
+
}
|
|
1372
|
+
if (c.analytics && !get("_ga") && !get("hz_cid")) set("hz_cid", `${rand()}.${now()}`, 730);
|
|
1373
|
+
}
|
|
1374
|
+
function touch(c) {
|
|
1375
|
+
const out = {};
|
|
1376
|
+
if (c.marketing) {
|
|
1377
|
+
try {
|
|
1378
|
+
Object.assign(out, JSON.parse(get("hz_touch") ?? "{}"));
|
|
1379
|
+
} catch {
|
|
1380
|
+
}
|
|
1381
|
+
const fbc = get("_fbc");
|
|
1382
|
+
const fbp = get("_fbp");
|
|
1383
|
+
if (fbc) out.fbc = fbc;
|
|
1384
|
+
if (fbp) out.fbp = fbp;
|
|
1385
|
+
}
|
|
1386
|
+
if (c.analytics) {
|
|
1387
|
+
const ga = get("_ga")?.split(".");
|
|
1388
|
+
const cid = ga && ga.length >= 4 ? ga.slice(-2).join(".") : get("hz_cid");
|
|
1389
|
+
if (cid) out.cid = cid;
|
|
1390
|
+
}
|
|
1391
|
+
return out;
|
|
1392
|
+
}
|
|
1393
|
+
var page = () => window;
|
|
1394
|
+
var tags = [];
|
|
1395
|
+
var configured = false;
|
|
1396
|
+
var options = {};
|
|
1397
|
+
var loaded = /* @__PURE__ */ new Set();
|
|
1398
|
+
var google = "idle";
|
|
1399
|
+
var configAnswered = false;
|
|
1400
|
+
var held = [];
|
|
1401
|
+
var leaving = false;
|
|
1402
|
+
function settled() {
|
|
1403
|
+
return configAnswered && google !== "wait";
|
|
1404
|
+
}
|
|
1405
|
+
function flush() {
|
|
1406
|
+
if (settled() || leaving) held.splice(0).forEach((send) => send());
|
|
1407
|
+
}
|
|
1408
|
+
function script(src, onload, onerror) {
|
|
1409
|
+
const s = document.createElement("script");
|
|
1410
|
+
s.async = true;
|
|
1411
|
+
s.src = src;
|
|
1412
|
+
if (onload) s.onload = onload;
|
|
1413
|
+
if (onerror) s.onerror = onerror;
|
|
1414
|
+
document.head.appendChild(s);
|
|
1415
|
+
}
|
|
1416
|
+
function gtagStub() {
|
|
1417
|
+
const p = page();
|
|
1418
|
+
p.dataLayer = p.dataLayer || [];
|
|
1419
|
+
if (!p.gtag) {
|
|
1420
|
+
p.gtag = function() {
|
|
1421
|
+
p.dataLayer.push(arguments);
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
return p.gtag;
|
|
1425
|
+
}
|
|
1426
|
+
var g = (on) => on ? "granted" : "denied";
|
|
1427
|
+
function consentMode(c, first) {
|
|
1428
|
+
const gtag = gtagStub();
|
|
1429
|
+
const state = {
|
|
1430
|
+
analytics_storage: g(c.analytics),
|
|
1431
|
+
ad_storage: g(c.marketing),
|
|
1432
|
+
ad_user_data: g(c.marketing),
|
|
1433
|
+
ad_personalization: g(c.marketing && c.ads)
|
|
1434
|
+
};
|
|
1435
|
+
if (first) {
|
|
1436
|
+
gtag("consent", "default", {
|
|
1437
|
+
analytics_storage: "denied",
|
|
1438
|
+
ad_storage: "denied",
|
|
1439
|
+
ad_user_data: "denied",
|
|
1440
|
+
ad_personalization: "denied",
|
|
1441
|
+
wait_for_update: 500
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
gtag("consent", "update", state);
|
|
1445
|
+
}
|
|
1446
|
+
function loadGoogle(ids) {
|
|
1447
|
+
const gtag = gtagStub();
|
|
1448
|
+
const fresh = ids.filter((id) => !loaded.has(id));
|
|
1449
|
+
if (!fresh.length) return;
|
|
1450
|
+
if (google === "idle") {
|
|
1451
|
+
google = "wait";
|
|
1452
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
1453
|
+
const done = (to) => () => {
|
|
1454
|
+
if (google !== "wait") return;
|
|
1455
|
+
google = to;
|
|
1456
|
+
flush();
|
|
1457
|
+
};
|
|
1458
|
+
script(`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(fresh[0])}`, done("loaded"), done("failed"));
|
|
1459
|
+
setTimeout(done("failed"), 8e3);
|
|
1460
|
+
}
|
|
1461
|
+
for (const id of fresh) {
|
|
1462
|
+
loaded.add(id);
|
|
1463
|
+
gtag("config", id, options.domains ? { linker: { domains: options.domains } } : {});
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
function loadMeta(id, c) {
|
|
1467
|
+
const p = page();
|
|
1468
|
+
if (!p.fbq) {
|
|
1469
|
+
const n = p.fbq = function(...a) {
|
|
1470
|
+
if (n.callMethod) n.callMethod(...a);
|
|
1471
|
+
else n.queue.push(a);
|
|
1472
|
+
};
|
|
1473
|
+
if (!p._fbq) p._fbq = n;
|
|
1474
|
+
n.push = n;
|
|
1475
|
+
n.loaded = true;
|
|
1476
|
+
n.version = "2.0";
|
|
1477
|
+
n.queue = [];
|
|
1478
|
+
script("https://connect.facebook.net/en_US/fbevents.js");
|
|
1479
|
+
}
|
|
1480
|
+
if (!c.ads) p.fbq("dataProcessingOptions", ["LDU"], 0, 0);
|
|
1481
|
+
p.fbq("init", id);
|
|
1482
|
+
p.fbq("track", "PageView");
|
|
1483
|
+
}
|
|
1484
|
+
function loadLinkedIn(id) {
|
|
1485
|
+
const p = page();
|
|
1486
|
+
p._linkedin_data_partner_ids = p._linkedin_data_partner_ids || [];
|
|
1487
|
+
p._linkedin_data_partner_ids.push(id);
|
|
1488
|
+
if (!p.lintrk) {
|
|
1489
|
+
const l = p.lintrk = function(...a) {
|
|
1490
|
+
l.q.push(a);
|
|
1491
|
+
};
|
|
1492
|
+
l.q = [];
|
|
1493
|
+
}
|
|
1494
|
+
script("https://snap.licdn.com/li.lms-analytics/insight.min.js");
|
|
1495
|
+
}
|
|
1496
|
+
function loadX(id) {
|
|
1497
|
+
const p = page();
|
|
1498
|
+
if (!p.twq) {
|
|
1499
|
+
const s = p.twq = function(...a) {
|
|
1500
|
+
if (s.exe) s.exe(...a);
|
|
1501
|
+
else s.queue.push(a);
|
|
1502
|
+
};
|
|
1503
|
+
s.version = "1.1";
|
|
1504
|
+
s.queue = [];
|
|
1505
|
+
script("https://static.ads-twitter.com/uwt.js");
|
|
1506
|
+
}
|
|
1507
|
+
p.twq("config", id);
|
|
1508
|
+
}
|
|
1509
|
+
var TIKTOK_METHODS = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie"];
|
|
1510
|
+
function loadTikTok(id) {
|
|
1511
|
+
const p = page();
|
|
1512
|
+
p.TiktokAnalyticsObject = "ttq";
|
|
1513
|
+
const q = p.ttq = p.ttq || [];
|
|
1514
|
+
if (!q._i) {
|
|
1515
|
+
q.methods = TIKTOK_METHODS;
|
|
1516
|
+
for (const m of TIKTOK_METHODS) q[m] = (...a) => q.push([m, ...a]);
|
|
1517
|
+
q._i = {};
|
|
1518
|
+
q._t = {};
|
|
1519
|
+
q._o = {};
|
|
1520
|
+
q.load = (sdk) => {
|
|
1521
|
+
q._i[sdk] = [];
|
|
1522
|
+
q._t[sdk] = Date.now();
|
|
1523
|
+
script(`https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${encodeURIComponent(sdk)}&lib=ttq`);
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
q.load(id);
|
|
1527
|
+
q.page();
|
|
1528
|
+
}
|
|
1529
|
+
var NEEDS = {
|
|
1530
|
+
ga: "analytics",
|
|
1531
|
+
gads: "marketing",
|
|
1532
|
+
meta: "marketing",
|
|
1533
|
+
linkedin: "marketing",
|
|
1534
|
+
x: "marketing",
|
|
1535
|
+
tiktok: "marketing"
|
|
1536
|
+
};
|
|
1537
|
+
var allowed = (t, c) => t.type === "ga" ? c.analytics || c.marketing : Boolean(NEEDS[t.type] && c[NEEDS[t.type]]);
|
|
1538
|
+
function apply() {
|
|
1539
|
+
if (typeof window === "undefined" || !configured) return;
|
|
1540
|
+
const c = read2();
|
|
1541
|
+
capture(c);
|
|
1542
|
+
const on = tags.filter((t) => allowed(t, c));
|
|
1543
|
+
const ids = on.filter((t) => t.type === "ga" || t.type === "gads").map((t) => t.id);
|
|
1544
|
+
if (ids.length) {
|
|
1545
|
+
consentMode(c, !loaded.has("consent"));
|
|
1546
|
+
loaded.add("consent");
|
|
1547
|
+
loadGoogle(ids);
|
|
1548
|
+
}
|
|
1549
|
+
for (const t of on) {
|
|
1550
|
+
const k = `${t.type}:${t.id}`;
|
|
1551
|
+
if (loaded.has(k)) continue;
|
|
1552
|
+
if (t.type === "meta") loadMeta(t.id, c);
|
|
1553
|
+
else if (t.type === "linkedin") loadLinkedIn(t.id);
|
|
1554
|
+
else if (t.type === "x") loadX(t.id);
|
|
1555
|
+
else if (t.type === "tiktok") loadTikTok(t.id);
|
|
1556
|
+
else continue;
|
|
1557
|
+
loaded.add(k);
|
|
1558
|
+
}
|
|
1559
|
+
flush();
|
|
1560
|
+
}
|
|
1561
|
+
function start(o = {}) {
|
|
1562
|
+
if (typeof window === "undefined") return () => void 0;
|
|
1563
|
+
options = o;
|
|
1564
|
+
addEventListener(CONSENT_EVENT, apply);
|
|
1565
|
+
addEventListener("pagehide", pagehide);
|
|
1566
|
+
if (!configured) {
|
|
1567
|
+
configured = true;
|
|
1568
|
+
const base = (o.base ?? "https://api.hanzo.ai").replace(/\/$/, "");
|
|
1569
|
+
const q = new URLSearchParams();
|
|
1570
|
+
if (o.key) q.set("key", o.key);
|
|
1571
|
+
q.set("host", o.host ?? window.location.hostname);
|
|
1572
|
+
const answer = (list) => {
|
|
1573
|
+
tags = list;
|
|
1574
|
+
configAnswered = true;
|
|
1575
|
+
apply();
|
|
1576
|
+
};
|
|
1577
|
+
const cap = setTimeout(() => answer([]), 3e3);
|
|
1578
|
+
fetch(`${base}/v1/project/tags?${q}`).then((r) => r.ok ? r.json() : { tags: [] }).then((j) => {
|
|
1579
|
+
clearTimeout(cap);
|
|
1580
|
+
answer(Array.isArray(j.tags) ? j.tags : []);
|
|
1581
|
+
}).catch(() => {
|
|
1582
|
+
clearTimeout(cap);
|
|
1583
|
+
answer([]);
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
return () => {
|
|
1587
|
+
removeEventListener(CONSENT_EVENT, apply);
|
|
1588
|
+
removeEventListener("pagehide", pagehide);
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
function pagehide() {
|
|
1592
|
+
leaving = true;
|
|
1593
|
+
flush();
|
|
1594
|
+
}
|
|
1595
|
+
function reach() {
|
|
1596
|
+
const c = read2();
|
|
1597
|
+
const to = [];
|
|
1598
|
+
for (const t of tags) {
|
|
1599
|
+
if (!allowed(t, c)) continue;
|
|
1600
|
+
const running = t.type === "ga" ? google === "loaded" && c.analytics : t.type === "gads" ? google === "loaded" && c.marketing : loaded.has(`${t.type}:${t.id}`);
|
|
1601
|
+
if (running && !to.includes(t.type)) to.push(t.type);
|
|
1602
|
+
}
|
|
1603
|
+
return to.join(",");
|
|
1604
|
+
}
|
|
1605
|
+
var META_STANDARD = /* @__PURE__ */ new Set([
|
|
1606
|
+
"AddPaymentInfo",
|
|
1607
|
+
"AddToCart",
|
|
1608
|
+
"AddToWishlist",
|
|
1609
|
+
"CompleteRegistration",
|
|
1610
|
+
"Contact",
|
|
1611
|
+
"CustomizeProduct",
|
|
1612
|
+
"Donate",
|
|
1613
|
+
"FindLocation",
|
|
1614
|
+
"InitiateCheckout",
|
|
1615
|
+
"Lead",
|
|
1616
|
+
"Purchase",
|
|
1617
|
+
"Schedule",
|
|
1618
|
+
"Search",
|
|
1619
|
+
"StartTrial",
|
|
1620
|
+
"SubmitApplication",
|
|
1621
|
+
"Subscribe",
|
|
1622
|
+
"ViewContent"
|
|
1623
|
+
]);
|
|
1624
|
+
function shape(platform, p) {
|
|
1625
|
+
const items = Array.isArray(p.items) ? p.items : [];
|
|
1626
|
+
const out = {};
|
|
1627
|
+
if (typeof p.value === "number") out.value = p.value;
|
|
1628
|
+
out.currency = typeof p.currency === "string" ? p.currency : "USD";
|
|
1629
|
+
if (!items.length) return out;
|
|
1630
|
+
if (platform === "meta") {
|
|
1631
|
+
out.content_type = "product";
|
|
1632
|
+
out.content_ids = items.map((i) => i.item_id);
|
|
1633
|
+
out.contents = items.map((i) => ({ id: i.item_id, quantity: i.quantity ?? 1, item_price: i.price }));
|
|
1634
|
+
out.content_name = items[0].item_name;
|
|
1635
|
+
out.num_items = items.reduce((n, i) => n + (i.quantity ?? 1), 0);
|
|
1636
|
+
} else if (platform === "tiktok") {
|
|
1637
|
+
out.content_type = "product";
|
|
1638
|
+
out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, quantity: i.quantity ?? 1, price: i.price }));
|
|
1639
|
+
} else {
|
|
1640
|
+
out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, content_price: i.price, num_items: i.quantity ?? 1 }));
|
|
1641
|
+
}
|
|
1642
|
+
return out;
|
|
1643
|
+
}
|
|
1644
|
+
function unpriced(p) {
|
|
1645
|
+
const out = { ...p, value: 0 };
|
|
1646
|
+
if (Array.isArray(p.items)) out.items = p.items.map((i) => ({ ...i, price: 0 }));
|
|
1647
|
+
return out;
|
|
1648
|
+
}
|
|
1649
|
+
function mirror(name, params, id, to = reach()) {
|
|
1650
|
+
const p = page();
|
|
1651
|
+
const on = new Set(to.split(",").filter(Boolean));
|
|
1652
|
+
const ga4 = events.namesOn(name, "ga4");
|
|
1653
|
+
const test = params.test === true;
|
|
1654
|
+
if (test) params = unpriced(params);
|
|
1655
|
+
const transaction = typeof params.order_id === "string" ? { transaction_id: params.order_id } : {};
|
|
1656
|
+
for (const t of tags) {
|
|
1657
|
+
if (!on.has(t.type)) continue;
|
|
1658
|
+
const rule = t.events?.[name];
|
|
1659
|
+
if (t.type === "ga") {
|
|
1660
|
+
for (const n of ga4) {
|
|
1661
|
+
p.gtag?.("event", n, { ...params, ...transaction, event_id: id, transport_type: "beacon", ...test ? { debug_mode: true } : {} });
|
|
1662
|
+
}
|
|
1663
|
+
} else if (t.type === "gads" && rule) {
|
|
1664
|
+
p.gtag?.("event", "conversion", {
|
|
1665
|
+
send_to: rule,
|
|
1666
|
+
value: typeof params.value === "number" ? params.value : void 0,
|
|
1667
|
+
currency: typeof params.currency === "string" ? params.currency : "USD",
|
|
1668
|
+
...transaction
|
|
1669
|
+
});
|
|
1670
|
+
} else if (t.type === "meta") {
|
|
1671
|
+
for (const n of events.namesOn(name, "meta")) {
|
|
1672
|
+
p.fbq?.(META_STANDARD.has(n) ? "track" : "trackCustom", n, shape("meta", params), { eventID: id });
|
|
1673
|
+
}
|
|
1674
|
+
} else if (t.type === "tiktok") {
|
|
1675
|
+
for (const n of events.namesOn(name, "tiktok")) p.ttq?.track?.(n, shape("tiktok", params), { event_id: id });
|
|
1676
|
+
} else if (t.type === "linkedin" && rule && events.namesOn(name, "linkedin").length) {
|
|
1677
|
+
p.lintrk?.("track", { conversion_id: Number(rule) });
|
|
1678
|
+
} else if (t.type === "x" && rule && events.namesOn(name, "x").length) {
|
|
1679
|
+
p.twq?.("event", rule, { ...shape("x", params), conversion_id: id });
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
function track(stream, name, params = {}) {
|
|
1684
|
+
if (typeof window === "undefined") return;
|
|
1685
|
+
if (!leaving && !settled()) {
|
|
1686
|
+
held.push(() => track(stream, name, params));
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
const c = read2();
|
|
1690
|
+
const event_id = crypto.randomUUID();
|
|
1691
|
+
const to = reach();
|
|
1692
|
+
mirror(name, params, event_id, to);
|
|
1693
|
+
stream?.capture(name, {
|
|
1694
|
+
...params,
|
|
1695
|
+
...touch(c),
|
|
1696
|
+
event_id,
|
|
1697
|
+
consent: render(c),
|
|
1698
|
+
tags: to,
|
|
1699
|
+
userAgent: navigator.userAgent,
|
|
1700
|
+
url: window.location.href
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
function visit() {
|
|
1704
|
+
const c = read2();
|
|
1705
|
+
return { ...touch(c), consent: render(c), tags: reach(), userAgent: navigator.userAgent, url: window.location.href };
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1287
1708
|
// src/goals.ts
|
|
1288
1709
|
var GOALS = {
|
|
1289
1710
|
// Signup: the conversion is signup_completed, along the site signup funnel.
|
|
@@ -1369,15 +1790,21 @@ Object.defineProperty(exports, "eventsOf", {
|
|
|
1369
1790
|
get: function () { return events.eventsOf; }
|
|
1370
1791
|
});
|
|
1371
1792
|
exports.Analytics = Analytics;
|
|
1793
|
+
exports.CLICK_IDS = CLICK_IDS;
|
|
1372
1794
|
exports.COHORTS = COHORTS;
|
|
1795
|
+
exports.CONSENT_COOKIE = CONSENT_COOKIE;
|
|
1796
|
+
exports.CONSENT_EVENT = CONSENT_EVENT;
|
|
1373
1797
|
exports.GOALS = GOALS;
|
|
1374
1798
|
exports.LINK_PARAMS = LINK_PARAMS;
|
|
1375
1799
|
exports.ORG_DOMAIN = ORG_DOMAIN;
|
|
1376
1800
|
exports.ORG_KEY = ORG_KEY;
|
|
1377
1801
|
exports.PRODUCT_PROJECT = PRODUCT_PROJECT;
|
|
1378
1802
|
exports.VERSION = VERSION;
|
|
1803
|
+
exports.acceptAll = acceptAll;
|
|
1804
|
+
exports.asks = asks;
|
|
1379
1805
|
exports.buildEnvelope = buildEnvelope;
|
|
1380
1806
|
exports.buildSentryEvent = buildSentryEvent;
|
|
1807
|
+
exports.captureClick = capture;
|
|
1381
1808
|
exports.createAnalytics = createAnalytics;
|
|
1382
1809
|
exports.deriveChannel = deriveChannel;
|
|
1383
1810
|
exports.digest = digest;
|
|
@@ -1388,22 +1815,36 @@ exports.fingerprint = fingerprint;
|
|
|
1388
1815
|
exports.framesFromStack = framesFromStack;
|
|
1389
1816
|
exports.getCohort = getCohort;
|
|
1390
1817
|
exports.getFirstTouch = getFirstTouch;
|
|
1818
|
+
exports.gpc = gpc;
|
|
1391
1819
|
exports.hasAttribution = hasAttribution;
|
|
1392
1820
|
exports.hostOf = hostOf;
|
|
1393
1821
|
exports.isoWeek = isoWeek;
|
|
1394
1822
|
exports.keyFor = keyFor;
|
|
1395
1823
|
exports.keyForPage = keyForPage;
|
|
1396
1824
|
exports.linkUrl = linkUrl;
|
|
1825
|
+
exports.mirror = mirror;
|
|
1397
1826
|
exports.orgOf = orgOf;
|
|
1398
1827
|
exports.parseAttribution = parseAttribution;
|
|
1399
1828
|
exports.parseDsn = parseDsn;
|
|
1829
|
+
exports.reach = reach;
|
|
1830
|
+
exports.readConsent = read2;
|
|
1400
1831
|
exports.readLink = readLink;
|
|
1401
1832
|
exports.redactSecrets = redactSecrets;
|
|
1833
|
+
exports.refused = refused;
|
|
1834
|
+
exports.region = region;
|
|
1835
|
+
exports.rejectAll = rejectAll;
|
|
1836
|
+
exports.renderConsent = render;
|
|
1402
1837
|
exports.resetClients = resetClients;
|
|
1838
|
+
exports.saveConsent = save;
|
|
1403
1839
|
exports.scrubPII = scrubPII;
|
|
1404
1840
|
exports.scrubText = scrubText;
|
|
1841
|
+
exports.startTags = start;
|
|
1842
|
+
exports.storedConsent = stored;
|
|
1405
1843
|
exports.stripLink = stripLink;
|
|
1844
|
+
exports.touch = touch;
|
|
1845
|
+
exports.track = track;
|
|
1406
1846
|
exports.uuidv7 = hzUuidv7;
|
|
1407
1847
|
exports.uuidv7Time = uuidv7Time;
|
|
1848
|
+
exports.visit = visit;
|
|
1408
1849
|
//# sourceMappingURL=index.cjs.map
|
|
1409
1850
|
//# sourceMappingURL=index.cjs.map
|