@usermaven/sdk-js 1.4.0 → 1.4.1-rc.59

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.
@@ -0,0 +1,1324 @@
1
+ var v = /* @__PURE__ */ ((s) => (s[s.DEBUG = 0] = "DEBUG", s[s.INFO = 1] = "INFO", s[s.WARN = 2] = "WARN", s[s.ERROR = 3] = "ERROR", s))(v || {});
2
+ class J {
3
+ constructor(e) {
4
+ this.level = e;
5
+ }
6
+ debug(e, ...t) {
7
+ this.level <= 0 && console.debug("[Usermaven Debug]:", e, ...t);
8
+ }
9
+ info(e, ...t) {
10
+ this.level <= 1 && console.info("[Usermaven Info]:", e, ...t);
11
+ }
12
+ warn(e, ...t) {
13
+ this.level <= 2 && console.warn("[Usermaven Warning]:", e, ...t);
14
+ }
15
+ error(e, ...t) {
16
+ this.level <= 3 && console.error("[Usermaven Error]:", e, ...t);
17
+ }
18
+ }
19
+ function h(s = 0) {
20
+ return new J(s);
21
+ }
22
+ const I = {
23
+ logLevel: v.ERROR,
24
+ useBeaconApi: !1,
25
+ forceUseFetch: !1,
26
+ trackingHost: "t.usermaven.com",
27
+ autocapture: !1,
28
+ rageClick: !1,
29
+ formTracking: !1,
30
+ autoPageview: !1,
31
+ disableEventPersistence: !1,
32
+ gaHook: !1,
33
+ segmentHook: !1,
34
+ randomizeUrl: !1,
35
+ capture3rdPartyCookies: ["_ga", "_fbp", "_ym_uid", "ajs_user_id", "ajs_anonymous_id"],
36
+ idMethod: "cookie",
37
+ ipPolicy: "keep",
38
+ cookiePolicy: "keep",
39
+ minSendTimeout: 0,
40
+ maxSendTimeout: 2e3,
41
+ maxSendAttempts: 4,
42
+ propertiesStringMaxLength: null,
43
+ propertyBlacklist: [],
44
+ crossDomainLinking: !0,
45
+ maskAllText: !1,
46
+ maskAllElementAttributes: !1
47
+ };
48
+ class Q {
49
+ constructor(e) {
50
+ this.domain = e, this.cookieDomain = this.getCookieDomain(), console.log(this.cookieDomain);
51
+ }
52
+ set(e, t, i = 365, n = !0, r = !1) {
53
+ console.log("Setting cookie", e, t, i, n, r);
54
+ const o = /* @__PURE__ */ new Date();
55
+ o.setTime(o.getTime() + i * 24 * 60 * 60 * 1e3);
56
+ const c = `expires=${o.toUTCString()}`, l = n ? "; Secure" : "", a = r ? "; HttpOnly" : "";
57
+ document.cookie = `${e}=${t};${c};path=/;domain=${this.cookieDomain}${l}${a}`;
58
+ }
59
+ get(e) {
60
+ const t = e + "=", i = document.cookie.split(";");
61
+ for (let n = 0; n < i.length; n++) {
62
+ let r = i[n].trim();
63
+ if (r.indexOf(t) === 0)
64
+ return decodeURIComponent(r.substring(t.length));
65
+ }
66
+ return null;
67
+ }
68
+ delete(e, t = "/") {
69
+ document.cookie = `${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${t};domain=${this.cookieDomain}`;
70
+ }
71
+ getCookieDomain() {
72
+ return typeof window > "u" || this.domain ? this.domain || "" : this.extractRoot(window.location.hostname);
73
+ }
74
+ extractRoot(e) {
75
+ if (this.isIpAddress(e) || e === "localhost")
76
+ return e;
77
+ let t = this.extractTopLevelDomain(e);
78
+ return t || (t = this.extractRootDomain(e)), "." + t;
79
+ }
80
+ isIpAddress(e) {
81
+ const t = e.split(".");
82
+ return t.length === 4 && t.every((i) => !isNaN(Number(i)));
83
+ }
84
+ extractHostname(e) {
85
+ let t;
86
+ return e.indexOf("//") > -1 ? t = e.split("/")[2] : t = e.split("/")[0], t = t.split(":")[0], t = t.split("?")[0], t;
87
+ }
88
+ extractRootDomain(e) {
89
+ let t = this.extractHostname(e);
90
+ const i = t.split("."), n = i.length;
91
+ return n > 2 && (i[n - 1].length == 2 ? (t = i[n - 2] + "." + i[n - 1], i[n - 2].length == 2 && (t = i[n - 3] + "." + t)) : t = i[n - 2] + "." + i[n - 1]), t;
92
+ }
93
+ extractTopLevelDomain(e) {
94
+ const t = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i, i = e.match(t);
95
+ return i ? i[0] : "";
96
+ }
97
+ }
98
+ const W = Object.prototype, X = W.hasOwnProperty, K = Array.prototype, b = K.forEach, $ = {};
99
+ function Z(s, e, t) {
100
+ if (Array.isArray(s)) {
101
+ if (b && s.forEach === b)
102
+ s.forEach(e, t);
103
+ else if ("length" in s && s.length === +s.length) {
104
+ for (let i = 0, n = s.length; i < n; i++)
105
+ if (i in s && e.call(t, s[i], i) === $)
106
+ return;
107
+ }
108
+ }
109
+ }
110
+ const T = function(s) {
111
+ return s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
112
+ }, G = function(s) {
113
+ for (const e in s)
114
+ typeof s[e] == "function" && (s[e] = s[e].bind(s));
115
+ };
116
+ function A(s, e, t) {
117
+ if (s != null) {
118
+ if (b && Array.isArray(s) && s.forEach === b)
119
+ s.forEach(e, t);
120
+ else if ("length" in s && s.length === +s.length) {
121
+ for (let i = 0, n = s.length; i < n; i++)
122
+ if (i in s && e.call(t, s[i], i) === $)
123
+ return;
124
+ } else
125
+ for (const i in s)
126
+ if (X.call(s, i) && e.call(t, s[i], i) === $)
127
+ return;
128
+ }
129
+ }
130
+ const Y = function(s, ...e) {
131
+ return Z(e, function(t) {
132
+ for (const i in t)
133
+ t[i] !== void 0 && (s[i] = t[i]);
134
+ }), s;
135
+ };
136
+ function _(s, e) {
137
+ return s.indexOf(e) !== -1;
138
+ }
139
+ const D = function(s) {
140
+ try {
141
+ return /^\s*\bfunction\b/.test(s);
142
+ } catch {
143
+ return !1;
144
+ }
145
+ }, j = function(s) {
146
+ return s === void 0;
147
+ }, p = function() {
148
+ const s = function(i, n, r, o, c) {
149
+ if (!i) {
150
+ h().error("No valid element provided to register_event");
151
+ return;
152
+ }
153
+ if (i.addEventListener && !o)
154
+ i.addEventListener(n, r, !!c);
155
+ else {
156
+ const l = "on" + n, a = i[l];
157
+ i[l] = e(i, r, a);
158
+ }
159
+ };
160
+ function e(i, n, r) {
161
+ return function(o) {
162
+ if (o = o || t(window.event), !o)
163
+ return;
164
+ let c = !0, l;
165
+ D(r) && (l = r(o));
166
+ const a = n.call(i, o);
167
+ return (l === !1 || a === !1) && (c = !1), c;
168
+ };
169
+ }
170
+ function t(i) {
171
+ return i && (i.preventDefault = t.preventDefault, i.stopPropagation = t.stopPropagation), i;
172
+ }
173
+ return t.preventDefault = function() {
174
+ this.returnValue = !1;
175
+ }, t.stopPropagation = function() {
176
+ this.cancelBubble = !0;
177
+ }, s;
178
+ }(), ee = function(s) {
179
+ return function(...e) {
180
+ try {
181
+ return s.apply(this, e);
182
+ } catch (t) {
183
+ h().error("Implementation error. Please turn on debug and contact support@usermaven.com.", t);
184
+ }
185
+ };
186
+ }, F = function(s) {
187
+ for (const e in s)
188
+ typeof s[e] == "function" && (s[e] = ee(s[e]));
189
+ };
190
+ function R(s) {
191
+ for (let e in s)
192
+ (s[e] === "" || s[e] === null || s[e] === void 0 || typeof s[e] == "object" && Object.keys(s[e]).length === 0) && delete s[e];
193
+ return s;
194
+ }
195
+ function u() {
196
+ try {
197
+ return typeof window < "u" && window.document !== void 0 && window.document.createElement !== void 0;
198
+ } catch {
199
+ return h().warn("window is not available"), !1;
200
+ }
201
+ }
202
+ function f(s = 5) {
203
+ const e = new Uint8Array(s);
204
+ return crypto.getRandomValues(e), Array.from(e, (t) => t.toString(36).padStart(2, "0")).join("").slice(0, s);
205
+ }
206
+ function te(s) {
207
+ return s.replace(
208
+ /([-_][a-z])/g,
209
+ (e) => e.toUpperCase().replace("-", "").replace("_", "")
210
+ );
211
+ }
212
+ function S(s) {
213
+ return typeof s != "object" || s === null ? s : Array.isArray(s) ? s.map(S) : Object.keys(s).reduce((e, t) => {
214
+ const i = te(t);
215
+ return e[i] = S(s[t]), e;
216
+ }, {});
217
+ }
218
+ function E(s) {
219
+ switch (typeof s.className) {
220
+ case "string":
221
+ return s.className;
222
+ case "object":
223
+ return ("baseVal" in s.className ? s.className.baseVal : null) || s.getAttribute("class") || "";
224
+ default:
225
+ return "";
226
+ }
227
+ }
228
+ function N(s) {
229
+ let e = "";
230
+ return M(s) && !q(s) && s.childNodes && s.childNodes.length && A(s.childNodes, function(t) {
231
+ z(t) && t.textContent && (e += T(t.textContent).split(/(\s+)/).filter(x).join("").replace(/[\r\n]/g, " ").replace(/[ ]+/g, " ").substring(0, 255));
232
+ }), T(e);
233
+ }
234
+ function H(s) {
235
+ return !!s && s.nodeType === 1;
236
+ }
237
+ function d(s, e) {
238
+ return !!s && !!s.tagName && s.tagName.toLowerCase() === e.toLowerCase();
239
+ }
240
+ function z(s) {
241
+ return !!s && s.nodeType === 3;
242
+ }
243
+ function B(s) {
244
+ return !!s && s.nodeType === 11;
245
+ }
246
+ const C = ["a", "button", "form", "input", "select", "textarea", "label"];
247
+ function ie(s, e) {
248
+ if (!s || d(s, "html") || !H(s) || s.classList && s.classList.contains("um-no-capture"))
249
+ return !1;
250
+ let t = !1;
251
+ const i = [s];
252
+ let n = !0, r = s;
253
+ for (; r.parentNode && !d(r, "body"); ) {
254
+ if (B(r.parentNode)) {
255
+ i.push(r.parentNode.host), r = r.parentNode.host;
256
+ continue;
257
+ }
258
+ if (n = r.parentNode || !1, !n) break;
259
+ if (C.indexOf(n.tagName.toLowerCase()) > -1)
260
+ t = !0;
261
+ else {
262
+ const l = window.getComputedStyle(n);
263
+ l && l.getPropertyValue("cursor") === "pointer" && (t = !0);
264
+ }
265
+ i.push(n), r = n;
266
+ }
267
+ const o = window.getComputedStyle(s);
268
+ if (o && o.getPropertyValue("cursor") === "pointer" && e.type === "click")
269
+ return !0;
270
+ const c = s.tagName.toLowerCase();
271
+ switch (c) {
272
+ case "html":
273
+ return !1;
274
+ case "form":
275
+ return e.type === "submit";
276
+ case "input":
277
+ return e.type === "change" || e.type === "click";
278
+ case "select":
279
+ case "textarea":
280
+ return e.type === "change" || e.type === "click";
281
+ default:
282
+ return t ? e.type === "click" : e.type === "click" && (C.indexOf(c) > -1 || s.getAttribute("contenteditable") === "true");
283
+ }
284
+ }
285
+ function M(s) {
286
+ if (!s || !H(s))
287
+ return !1;
288
+ if (typeof s.hasAttribute == "function") {
289
+ if (s.hasAttribute(w.FORCE_CAPTURE_ATTR))
290
+ return !0;
291
+ if (s.hasAttribute(w.PREVENT_CAPTURE_ATTR))
292
+ return !1;
293
+ }
294
+ let e = s;
295
+ for (; e && e.parentElement && !d(e, "body"); ) {
296
+ const n = E(e).split(" ");
297
+ if (_(n, "ph-sensitive") || _(n, "ph-no-capture"))
298
+ return !1;
299
+ e = e.parentElement;
300
+ }
301
+ if (_(E(s).split(" "), "ph-include"))
302
+ return !0;
303
+ const t = s.type;
304
+ if (typeof t == "string")
305
+ switch (t.toLowerCase()) {
306
+ case "hidden":
307
+ case "password":
308
+ return !1;
309
+ }
310
+ const i = s.name || s.id || "";
311
+ return !(typeof i == "string" && /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i.test(i.replace(/[^a-zA-Z0-9]/g, "")));
312
+ }
313
+ function q(s) {
314
+ const e = ["button", "checkbox", "submit", "reset"];
315
+ return !!(d(s, "input") && !e.includes(s.type) || d(s, "select") || d(s, "textarea") || s.getAttribute("contenteditable") === "true");
316
+ }
317
+ function x(s) {
318
+ return !(s === null || j(s) || typeof s == "string" && (s = T(s), /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((s || "").replace(/[- ]/g, "")) || /(^\d{3}-?\d{2}-?\d{4}$)/.test(s)));
319
+ }
320
+ function se(s) {
321
+ return typeof s == "string" ? s.substring(0, 10) === "_ngcontent" || s.substring(0, 7) === "_nghost" : !1;
322
+ }
323
+ function P() {
324
+ return f(10);
325
+ }
326
+ function ne(s) {
327
+ return /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(String(s).toLowerCase());
328
+ }
329
+ function re(s, e) {
330
+ let t;
331
+ return function(...i) {
332
+ const n = () => {
333
+ clearTimeout(t), s(...i);
334
+ };
335
+ clearTimeout(t), t = setTimeout(n, e);
336
+ };
337
+ }
338
+ function oe(s) {
339
+ const e = {}, t = s.replace(/^\?/, "").split("&");
340
+ for (let i = 0; i < t.length; i++) {
341
+ const n = t[i].split("=");
342
+ n[0] !== "" && (e[decodeURIComponent(n[0])] = decodeURIComponent(n[1] || ""));
343
+ }
344
+ return e;
345
+ }
346
+ function O(s) {
347
+ return typeof s == "string" || s instanceof String;
348
+ }
349
+ function k(s) {
350
+ return s !== null && typeof s == "object" && s.constructor === Object;
351
+ }
352
+ function ae(s) {
353
+ if (s === null)
354
+ return v.ERROR;
355
+ const e = s.toUpperCase(), t = v[e];
356
+ return t || t === 0 ? t : v.ERROR;
357
+ }
358
+ class ce {
359
+ constructor(e) {
360
+ this.maxScrollDepth = 0, this.milestones = [25, 50, 75, 90], this.lastScrollDepth = 0, this.client = e, this.documentElement = document.documentElement, this.debouncedHandleScroll = re(this.handleScroll.bind(this), 250), this.initializeEventListener();
361
+ }
362
+ initializeEventListener() {
363
+ window.addEventListener("scroll", this.debouncedHandleScroll);
364
+ }
365
+ track() {
366
+ const e = this.getScrollDepth();
367
+ e > this.lastScrollDepth && (this.lastScrollDepth = e, this.checkMilestones(e));
368
+ }
369
+ send(e = "$scroll") {
370
+ const t = {
371
+ percent: this.lastScrollDepth,
372
+ window_height: this.getWindowHeight(),
373
+ document_height: this.getDocumentHeight(),
374
+ scroll_distance: this.getScrollDistance()
375
+ };
376
+ this.client.track(e, t);
377
+ }
378
+ handleScroll() {
379
+ this.track();
380
+ }
381
+ getScrollDepth() {
382
+ const e = this.getWindowHeight(), t = this.getDocumentHeight(), i = this.getScrollDistance(), n = t - e;
383
+ return Math.min(100, Math.floor(i / n * 100));
384
+ }
385
+ getWindowHeight() {
386
+ return window.innerHeight || this.documentElement.clientHeight || document.body.clientHeight || 0;
387
+ }
388
+ getDocumentHeight() {
389
+ return Math.max(
390
+ document.body.scrollHeight || 0,
391
+ this.documentElement.scrollHeight || 0,
392
+ document.body.offsetHeight || 0,
393
+ this.documentElement.offsetHeight || 0,
394
+ document.body.clientHeight || 0,
395
+ this.documentElement.clientHeight || 0
396
+ );
397
+ }
398
+ getScrollDistance() {
399
+ return window.pageYOffset || this.documentElement.scrollTop || document.body.scrollTop || 0;
400
+ }
401
+ checkMilestones(e) {
402
+ this.milestones.filter((i) => e >= i).forEach((i) => {
403
+ this.send(), this.milestones = this.milestones.filter((n) => n !== i);
404
+ });
405
+ }
406
+ }
407
+ const y = class y {
408
+ constructor(e, t, i = h()) {
409
+ this.logger = i, this.scrollDepth = null, this.client = e, this.options = t, this.scrollDepth = new ce(e), G(this), F(this);
410
+ }
411
+ init() {
412
+ if (!(document && document.body)) {
413
+ this.logger.debug("Document not ready yet, trying again in 500 milliseconds..."), setTimeout(() => this.init(), 500);
414
+ return;
415
+ }
416
+ this.addDomEventHandlers();
417
+ }
418
+ addDomEventHandlers() {
419
+ const e = (t) => {
420
+ t = t || window.event, this.captureEvent(t);
421
+ };
422
+ p(document, "submit", e, !1, !0), p(document, "change", e, !1, !0), p(document, "click", e, !1, !0), p(document, "visibilitychange", e, !1, !0), p(document, "scroll", e, !1, !0), p(window, "popstate", e, !1, !0);
423
+ }
424
+ isPageRefresh() {
425
+ if ("PerformanceNavigationTiming" in window) {
426
+ const e = performance.getEntriesByType("navigation");
427
+ if (e.length > 0)
428
+ return e[0].type === "reload";
429
+ }
430
+ return performance.navigation && performance.navigation.type === 1;
431
+ }
432
+ captureEvent(e) {
433
+ var i, n;
434
+ let t = this.getEventTarget(e);
435
+ if (z(t) && (t = t.parentNode || null), e.type === "scroll")
436
+ return (i = this.scrollDepth) == null || i.track(), !0;
437
+ if (e.type === "visibilitychange" && document.visibilityState === "hidden" || e.type === "popstate")
438
+ return this.isPageRefresh() || (n = this.scrollDepth) == null || n.send(), !0;
439
+ if (t && this.shouldCaptureElement(t, e)) {
440
+ const r = this.getElementList(t), o = this.getElementsJson(r, e), c = Y(
441
+ this.getDefaultProperties(e.type),
442
+ {
443
+ $elements: o
444
+ }
445
+ );
446
+ return this.client.track("$autocapture", c), !0;
447
+ }
448
+ }
449
+ shouldCaptureElement(e, t) {
450
+ return !e || typeof e.hasAttribute != "function" ? !1 : e.hasAttribute(y.FORCE_CAPTURE_ATTR) ? !0 : e.hasAttribute(y.PREVENT_CAPTURE_ATTR) ? !1 : ie(e, t);
451
+ }
452
+ getEventTarget(e) {
453
+ var t;
454
+ return typeof e.target > "u" ? e.srcElement || null : (t = e.target) != null && t.shadowRoot ? e.composedPath()[0] || null : e.target || null;
455
+ }
456
+ getElementList(e) {
457
+ const t = [e];
458
+ let i = e;
459
+ for (; i.parentNode && !d(i, "body"); )
460
+ B(i.parentNode) ? (t.push(i.parentNode.host), i = i.parentNode.host) : (t.push(i.parentNode), i = i.parentNode);
461
+ return t;
462
+ }
463
+ getElementsJson(e, t) {
464
+ const i = [];
465
+ let n = null, r = !1;
466
+ return A(e, (o) => {
467
+ if (d(o, "a")) {
468
+ const l = o.getAttribute("href");
469
+ l !== null && M(o) && x(l) && (n = l);
470
+ }
471
+ const c = E(o).split(" ");
472
+ _(c, "ph-no-capture") && (r = !0), i.push(this.getPropertiesFromElement(o));
473
+ }), this.options.maskAllText || (i[0].$el_text = this.sanitizeText(N(e[0]))), n !== null && (i[0].attr__href = n), r ? [] : i;
474
+ }
475
+ getPropertiesFromElement(e) {
476
+ const t = {
477
+ tag_name: e.tagName.toLowerCase()
478
+ };
479
+ C.indexOf(t.tag_name) > -1 && !this.options.maskAllText && (t.$el_text = this.sanitizeText(N(e)));
480
+ const i = E(e);
481
+ i.length > 0 && (t.classes = i.split(" ").filter((c) => c !== "")), A(e.attributes, (c) => {
482
+ q(e) && ["name", "id", "class"].indexOf(c.name) === -1 || !this.options.maskAllElementAttributes && x(c.value) && !se(c.name) && (t["attr__" + c.name] = this.sanitizeAttributeValue(c.name, c.value));
483
+ });
484
+ let n = 1, r = 1, o = e;
485
+ for (; o = this.previousElementSibling(o); )
486
+ n++, o.tagName === e.tagName && r++;
487
+ return t.nth_child = n, t.nth_of_type = r, t;
488
+ }
489
+ previousElementSibling(e) {
490
+ if (e.previousElementSibling)
491
+ return e.previousElementSibling;
492
+ do
493
+ e = e.previousSibling;
494
+ while (e && !H(e));
495
+ return e;
496
+ }
497
+ getDefaultProperties(e) {
498
+ return {
499
+ $event_type: e,
500
+ $ce_version: 1
501
+ };
502
+ }
503
+ // Input sanitization and XSS prevention methods
504
+ sanitizeText(e) {
505
+ e = e.replace(/<[^>]*?>/g, ""), e = this.encodeHtml(e);
506
+ const t = this.options.propertiesStringMaxLength || 255;
507
+ return e.length > t && (e = e.substring(0, t) + "..."), e;
508
+ }
509
+ sanitizeUrl(e) {
510
+ if (!e) return "";
511
+ try {
512
+ const t = new URL(e, window.location.href);
513
+ return t.protocol !== "http:" && t.protocol !== "https:" ? "" : encodeURI(t.toString());
514
+ } catch {
515
+ return this.encodeHtml(e);
516
+ }
517
+ }
518
+ sanitizeAttributeValue(e, t) {
519
+ switch (e.toLowerCase()) {
520
+ case "href":
521
+ case "src":
522
+ return this.sanitizeUrl(t);
523
+ default:
524
+ return this.encodeHtml(t);
525
+ }
526
+ }
527
+ encodeHtml(e) {
528
+ return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
529
+ }
530
+ static enabledForProject(e, t = 10, i = 10) {
531
+ if (!e)
532
+ return !1;
533
+ let n = 0;
534
+ for (let r = 0; r < e.length; r++)
535
+ n += e.charCodeAt(r);
536
+ return n % t < i;
537
+ }
538
+ static isBrowserSupported() {
539
+ return D(document.querySelectorAll);
540
+ }
541
+ };
542
+ y.FORCE_CAPTURE_ATTR = "data-um-force-capture", y.PREVENT_CAPTURE_ATTR = "data-um-no-capture";
543
+ let w = y;
544
+ class le {
545
+ constructor(e) {
546
+ this.client = e, this.lastPageUrl = window.location.href, this.trackInitialPageview(), this.initializePageviewTracking();
547
+ }
548
+ trackInitialPageview() {
549
+ this.trackPageview();
550
+ }
551
+ initializePageviewTracking() {
552
+ window.addEventListener("popstate", this.handlePageview.bind(this));
553
+ const e = history.pushState;
554
+ history.pushState = (...t) => {
555
+ e.apply(history, t), this.handlePageview();
556
+ }, window.addEventListener("hashchange", this.handlePageview.bind(this)), setInterval(this.checkForUrlChange.bind(this), 1e3);
557
+ }
558
+ handlePageview() {
559
+ this.trackPageview();
560
+ }
561
+ checkForUrlChange() {
562
+ window.location.href !== this.lastPageUrl && this.trackPageview();
563
+ }
564
+ trackPageview() {
565
+ const e = window.location.href;
566
+ e !== this.lastPageUrl && (this.lastPageUrl = e, this.client.track("pageview", {
567
+ url: e,
568
+ referrer: document.referrer,
569
+ title: document.title
570
+ }));
571
+ }
572
+ }
573
+ class ue {
574
+ constructor(e, t, i = h()) {
575
+ this.trackingHost = e, this.logger = i, this.config = t;
576
+ }
577
+ async send(e) {
578
+ const t = this.config.key, i = this.constructUrl(t), n = new Blob([JSON.stringify(e)], { type: "application/json" });
579
+ if (navigator.sendBeacon(i, n))
580
+ this.logger.debug(`Successfully queued ${e.length} event(s) via Beacon API`);
581
+ else
582
+ throw new Error("Failed to queue events via Beacon API");
583
+ }
584
+ constructUrl(e) {
585
+ const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", i = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
586
+ return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${i}` : `${this.trackingHost}${n}?token=${e}${t}${i}`;
587
+ }
588
+ // Note: Beacon API doesn't support custom headers, so we can't use them here.
589
+ // If custom headers are crucial, you might want to fall back to XHR or Fetch in those cases.
590
+ }
591
+ class L {
592
+ constructor(e, t, i = h()) {
593
+ this.trackingHost = e, this.logger = i, this.config = t;
594
+ }
595
+ async send(e) {
596
+ const t = this.config.key, i = this.constructUrl(t), n = JSON.stringify(e), r = {
597
+ "Content-Type": "application/json",
598
+ ...this.getCustomHeaders()
599
+ }, o = await fetch(i, {
600
+ method: "POST",
601
+ headers: r,
602
+ body: n
603
+ });
604
+ if (!o.ok)
605
+ throw new Error(`HTTP error! status: ${o.status}`);
606
+ this.logger.debug(`Successfully sent ${e.length} event(s)`), this.postHandle(o.status, await o.text());
607
+ }
608
+ constructUrl(e) {
609
+ const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", i = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
610
+ return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${i}` : `${this.trackingHost}${n}?token=${e}${t}${i}`;
611
+ }
612
+ getCustomHeaders() {
613
+ return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
614
+ }
615
+ postHandle(e, t) {
616
+ this.logger.debug(`Response received. Status: ${e}, Body: ${t}`);
617
+ }
618
+ }
619
+ class he {
620
+ constructor(e, t, i = h()) {
621
+ this.trackingHost = e, this.logger = i, this.config = t;
622
+ }
623
+ send(e) {
624
+ return new Promise((t, i) => {
625
+ const n = new XMLHttpRequest(), r = this.config.key, o = this.constructUrl(r);
626
+ n.open("POST", o, !0), n.setRequestHeader("Content-Type", "application/json");
627
+ const c = this.getCustomHeaders();
628
+ Object.keys(c).forEach((l) => {
629
+ n.setRequestHeader(l, c[l]);
630
+ }), n.onload = () => {
631
+ n.status >= 200 && n.status < 300 ? (this.logger.debug(`Successfully sent ${e.length} event(s)`), t()) : i(new Error(`HTTP error! status: ${n.status}`));
632
+ }, n.onerror = () => {
633
+ i(new Error("Network error"));
634
+ }, n.send(JSON.stringify(e));
635
+ });
636
+ }
637
+ constructUrl(e) {
638
+ const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", i = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
639
+ return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${i}` : `${this.trackingHost}${n}?token=${e}${t}${i}`;
640
+ }
641
+ getCustomHeaders() {
642
+ return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
643
+ }
644
+ postHandle(e, t) {
645
+ this.logger.debug(`Response received. Status: ${e}, Body: ${t}`);
646
+ }
647
+ }
648
+ class V {
649
+ constructor(e, t) {
650
+ this.storage = {}, this.prefix = `usermaven_${e}_`, this.load(), this.logger = t || h();
651
+ }
652
+ set(e, t) {
653
+ this.storage[e] = t, this.save();
654
+ }
655
+ get(e) {
656
+ return this.storage[e];
657
+ }
658
+ remove(e) {
659
+ delete this.storage[e], this.save();
660
+ }
661
+ clear() {
662
+ this.storage = {}, this.save();
663
+ }
664
+ save() {
665
+ if (!u()) {
666
+ this.logger.warn("localStorage is not available in this environment");
667
+ return;
668
+ }
669
+ try {
670
+ localStorage.setItem(this.prefix + "data", JSON.stringify(this.storage));
671
+ } catch (e) {
672
+ this.logger.error("Error saving to localStorage:", e);
673
+ }
674
+ }
675
+ load() {
676
+ if (!u()) {
677
+ this.logger.warn("localStorage is not available in this environment");
678
+ return;
679
+ }
680
+ try {
681
+ const e = localStorage.getItem(this.prefix + "data");
682
+ e && (this.storage = JSON.parse(e));
683
+ } catch (e) {
684
+ this.logger.error("Error loading from localStorage:", e);
685
+ }
686
+ }
687
+ }
688
+ class ge {
689
+ constructor() {
690
+ this.storage = {};
691
+ }
692
+ set(e, t) {
693
+ this.storage[e] = t;
694
+ }
695
+ get(e) {
696
+ return this.storage[e];
697
+ }
698
+ remove(e) {
699
+ delete this.storage[e];
700
+ }
701
+ save() {
702
+ }
703
+ clear() {
704
+ this.storage = {};
705
+ }
706
+ }
707
+ class U {
708
+ // Default to true for server-side
709
+ constructor(e, t = 3, i = 1e3, n = 10, r = 1e3, o = h()) {
710
+ this.transport = e, this.maxRetries = t, this.retryInterval = i, this.batchSize = n, this.batchInterval = r, this.logger = o, this.queue = [], this.processing = !1, this.batchTimeoutId = null, this.isOnline = !0, this.persistence = new V("offline_queue"), u() && (this.isOnline = navigator.onLine, this.loadQueueFromStorage(), this.initNetworkListeners(), this.scheduleBatch());
711
+ }
712
+ add(e) {
713
+ const t = { payload: e, retries: 0, timestamp: Date.now() };
714
+ this.queue.push(t), u() ? this.saveQueueToStorage() : this.processBatch();
715
+ }
716
+ initNetworkListeners() {
717
+ u() && (window.addEventListener("online", () => {
718
+ this.isOnline = !0, this.processBatch();
719
+ }), window.addEventListener("offline", () => {
720
+ this.isOnline = !1;
721
+ }));
722
+ }
723
+ scheduleBatch() {
724
+ u() && (this.batchTimeoutId !== null && clearTimeout(this.batchTimeoutId), this.batchTimeoutId = window.setTimeout(() => this.processBatch(), this.batchInterval));
725
+ }
726
+ async processBatch() {
727
+ if ((!u() || this.isOnline) && !this.processing && this.queue.length > 0) {
728
+ this.processing = !0;
729
+ const e = this.queue.splice(0, this.batchSize), t = e.map((i) => i.payload);
730
+ try {
731
+ await this.transport.send(t), this.logger.debug(`Successfully sent batch of ${e.length} payloads`), u() && this.saveQueueToStorage();
732
+ } catch (i) {
733
+ this.logger.error("Failed to send batch", i), await this.handleBatchFailure(e);
734
+ }
735
+ this.processing = !1;
736
+ }
737
+ u() && this.scheduleBatch();
738
+ }
739
+ async handleBatchFailure(e) {
740
+ for (const t of e)
741
+ t.retries < this.maxRetries ? (t.retries++, this.queue.unshift(t), this.logger.warn(`Retry attempt ${t.retries} for payload`)) : this.logger.error("Max retries reached, discarding payload", t.payload);
742
+ u() && (this.saveQueueToStorage(), await new Promise((t) => setTimeout(t, this.retryInterval)));
743
+ }
744
+ loadQueueFromStorage() {
745
+ if (u()) {
746
+ const e = this.persistence.get("queue");
747
+ e && (this.queue = JSON.parse(e));
748
+ }
749
+ }
750
+ saveQueueToStorage() {
751
+ u() && this.persistence.set("queue", JSON.stringify(this.queue));
752
+ }
753
+ }
754
+ class de {
755
+ constructor(e) {
756
+ this.clicks = [], this.threshold = 3, this.timeWindow = 2e3, this.distanceThreshold = 30, this.client = e, this.initializeEventListener(), F(this);
757
+ }
758
+ initializeEventListener() {
759
+ document.addEventListener("click", this.handleClick.bind(this));
760
+ }
761
+ handleClick(e) {
762
+ const t = e.target;
763
+ this.shouldCaptureElement(t) && this.click(e.clientX, e.clientY, Date.now());
764
+ }
765
+ shouldCaptureElement(e) {
766
+ return !e.closest(".um-no-capture");
767
+ }
768
+ click(e, t, i) {
769
+ const n = { x: e, y: t, timestamp: i };
770
+ this.clicks.push(n), this.clicks = this.clicks.filter((r) => i - r.timestamp < this.timeWindow), this.clicks.length >= this.threshold && this.checkRageClick();
771
+ }
772
+ checkRageClick() {
773
+ const e = this.clicks[0], i = (this.clicks[this.clicks.length - 1].timestamp - e.timestamp) / 1e3;
774
+ this.clicks.every((r, o) => {
775
+ if (o === 0) return !0;
776
+ const c = this.clicks[o - 1];
777
+ return Math.sqrt(Math.pow(r.x - c.x, 2) + Math.pow(r.y - c.y, 2)) < this.distanceThreshold;
778
+ }) && this.sendRageClickEvent(i);
779
+ }
780
+ sendRageClickEvent(e) {
781
+ const t = this.clicks[this.clicks.length - 1];
782
+ document.elementFromPoint(t.x, t.y) && this.client.track("$rage_click", {
783
+ no_of_clicks: this.clicks.length,
784
+ time: e.toFixed(2)
785
+ }), this.clicks = [];
786
+ }
787
+ }
788
+ class fe {
789
+ constructor(e, t, i = h()) {
790
+ this.trackingHost = e, this.logger = i, this.config = t;
791
+ }
792
+ async send(e) {
793
+ const t = this.config.key, i = new (void 0)(this.constructUrl(t)), n = {
794
+ hostname: i.hostname,
795
+ port: 443,
796
+ path: `${i.pathname}${i.search}`,
797
+ method: "POST",
798
+ headers: {
799
+ "Content-Type": "application/json",
800
+ ...this.getCustomHeaders()
801
+ }
802
+ };
803
+ return new Promise((r, o) => {
804
+ const c = (void 0)(n, (l) => {
805
+ l.on("data", (a) => {
806
+ }), l.on("end", () => {
807
+ const a = l.statusCode || 0;
808
+ a >= 200 && a < 300 ? (this.logger.debug(`Successfully sent ${e.length} event(s)`), r()) : o(new Error(`HTTP error! status: ${a}`));
809
+ });
810
+ });
811
+ c.on("error", (l) => {
812
+ o(l);
813
+ }), c.write(JSON.stringify(e)), c.end();
814
+ });
815
+ }
816
+ constructUrl(e) {
817
+ const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", i = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "";
818
+ return `${this.trackingHost}/api/v1/s2s/event?token=${e}${t}${i}`;
819
+ }
820
+ getCustomHeaders() {
821
+ return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
822
+ }
823
+ }
824
+ class m {
825
+ constructor(e, t = "all", i = {}) {
826
+ this.instance = e, this.trackingType = t, this.options = i, document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", this.initialize.bind(this)) : this.initialize();
827
+ }
828
+ initialize() {
829
+ this.trackingType !== "none" && this.setupFormTracking();
830
+ }
831
+ setupFormTracking() {
832
+ var e;
833
+ this.formElements = this.trackingType === "tagged" ? document.querySelectorAll("form[data-um-form]") : document.querySelectorAll("form"), (e = this.formElements) == null || e.forEach((t) => {
834
+ t.addEventListener("submit", this.handleFormSubmit.bind(this));
835
+ });
836
+ }
837
+ handleFormSubmit(e) {
838
+ const t = e.target, i = this._getFormDetails(t);
839
+ this.instance.track("$form", R(i)), this.options.trackFieldChanges && this.trackFieldChanges(t);
840
+ }
841
+ trackFieldChanges(e) {
842
+ e.querySelectorAll("input, select, textarea").forEach((i) => {
843
+ i.addEventListener("change", (n) => {
844
+ const r = this._getFieldProps(n.target, 0);
845
+ this.instance.track("$form_field_change", R(r));
846
+ });
847
+ });
848
+ }
849
+ static getInstance(e, t = "all", i = {}) {
850
+ return m.instance || (m.instance = new m(e, t, i)), m.instance;
851
+ }
852
+ _getFormDetails(e) {
853
+ const t = {
854
+ form_id: e.id,
855
+ form_name: e.name || "",
856
+ form_action: e.action,
857
+ form_method: e.method,
858
+ form_class: e.className,
859
+ form_attributes: this._getElementAttributes(e)
860
+ }, i = e.querySelectorAll("input, select, textarea");
861
+ return Array.from(i).filter((r) => !r.classList.contains("um-no-capture")).forEach((r, o) => {
862
+ const c = this._getFieldProps(r, o);
863
+ Object.assign(t, c);
864
+ }), t;
865
+ }
866
+ _getFieldProps(e, t) {
867
+ const i = Object.keys(e.dataset).length ? JSON.stringify(e.dataset) : void 0, n = this.getSafeText(e);
868
+ return {
869
+ [`field_${t + 1}_tag`]: e.tagName.toLowerCase(),
870
+ [`field_${t + 1}_type`]: e instanceof HTMLInputElement ? e.type : void 0,
871
+ [`field_${t + 1}_data_attributes`]: i,
872
+ [`field_${t + 1}_id`]: e.id,
873
+ [`field_${t + 1}_value`]: n,
874
+ [`field_${t + 1}_class`]: e.className,
875
+ [`field_${t + 1}_name`]: e.name,
876
+ [`field_${t + 1}_attributes`]: this._getElementAttributes(e)
877
+ };
878
+ }
879
+ _getElementAttributes(e) {
880
+ const t = {};
881
+ for (let i = 0; i < e.attributes.length; i++) {
882
+ const n = e.attributes[i];
883
+ n.name !== "value" && !n.name.startsWith("data-") && (t[n.name] = n.value);
884
+ }
885
+ return t;
886
+ }
887
+ getSafeText(e) {
888
+ let t = "";
889
+ return "value" in e && e.type !== "password" ? t = e.value : e.hasChildNodes() ? t = Array.from(e.childNodes).filter(
890
+ (n) => n.nodeType === Node.TEXT_NODE
891
+ ).map((n) => n.textContent).join("") : t = e.textContent || "", this._scrubPotentiallySensitiveValues(t);
892
+ }
893
+ _scrubPotentiallySensitiveValues(e) {
894
+ return this._shouldCaptureValue(e) ? e : "<redacted>";
895
+ }
896
+ _shouldCaptureValue(e) {
897
+ return !(this._isNullish(e) || this._isString(e) && (e = this._trim(e), /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((e || "").replace(/[- ]/g, "")) || /(^\d{3}-?\d{2}-?\d{4}$)/.test(e)));
898
+ }
899
+ _isNullish(e) {
900
+ return e == null;
901
+ }
902
+ _isString(e) {
903
+ return typeof e == "string" || e instanceof String;
904
+ }
905
+ _trim(e) {
906
+ if (typeof String.prototype.trim == "function")
907
+ return e.trim();
908
+ let t = 0, i = e.length - 1;
909
+ const n = [
910
+ " ",
911
+ `
912
+ `,
913
+ "\r",
914
+ " ",
915
+ "\f",
916
+ "\v",
917
+ " ",
918
+ " ",
919
+ " ",
920
+ " ",
921
+ " ",
922
+ " ",
923
+ " ",
924
+ " ",
925
+ " ",
926
+ " ",
927
+ " ",
928
+ " ",
929
+ " ",
930
+ "\u2028",
931
+ "\u2029",
932
+ " ",
933
+ " ",
934
+ " "
935
+ ].join("");
936
+ for (; t <= i && n.indexOf(e[t]) > -1; )
937
+ t++;
938
+ for (; i >= t && n.indexOf(e[i]) > -1; )
939
+ i--;
940
+ return e.slice(t, i + 1);
941
+ }
942
+ }
943
+ class pe {
944
+ constructor(e) {
945
+ this.config = this.mergeConfig(e, I), this.logger = h(this.config.logLevel), this.namespace = e.namespace || "usermaven", this.transport = this.initializeTransport(this.config), this.persistence = this.initializePersistence(), this.retryQueue = new U(
946
+ this.transport,
947
+ this.config.maxSendAttempts || 3,
948
+ this.config.minSendTimeout || 1e3,
949
+ 10,
950
+ 200,
951
+ // Reduced interval to .2 second
952
+ this.logger
953
+ ), u() && this.initializeBrowserFeatures(), this.anonymousId = this.getOrCreateAnonymousId(), this.logger.info(`Usermaven client initialized for namespace: ${this.namespace}`);
954
+ }
955
+ initializeBrowserFeatures() {
956
+ if (this.cookieManager = new Q(this.config.cookieDomain), this.config.autocapture && w.enabledForProject(this.config.key) && (this.autoCapture = new w(this, this.config, this.logger), this.autoCapture.init()), this.config.formTracking) {
957
+ const e = this.config.formTracking === !0 ? "all" : this.config.formTracking;
958
+ this.formTracking = m.getInstance(this, e || "none", {
959
+ trackFieldChanges: !1
960
+ });
961
+ }
962
+ this.config.autoPageview && (this.pageviewTracking = new le(this)), this.config.crossDomainLinking && this.manageCrossDomainLinking(), this.config.rageClick && (this.rageClick = new de(this)), this.setupPageLeaveTracking();
963
+ }
964
+ /**
965
+ * Recursively merge the provided configuration with the existing defaultConfig
966
+ * @param config
967
+ * @param defaultConfig
968
+ */
969
+ mergeConfig(e, t) {
970
+ const i = JSON.parse(JSON.stringify(e));
971
+ let n = { ...t, ...i };
972
+ return Object.keys(t).forEach((r) => {
973
+ k(t[r]) && (n[r] = this.mergeConfig(e[r], t[r]));
974
+ }), n;
975
+ }
976
+ init(e) {
977
+ this.config = { ...this.config, ...e }, this.logger = h(this.config.logLevel), this.namespace = e.namespace || this.namespace, this.transport = this.initializeTransport(e), this.persistence = this.initializePersistence(), this.retryQueue = new U(
978
+ this.transport,
979
+ this.config.maxSendAttempts || 3,
980
+ this.config.minSendTimeout || 1e3,
981
+ 10,
982
+ 250,
983
+ // Reduced interval to .25 second
984
+ this.logger
985
+ ), u() && this.initializeBrowserFeatures(), this.anonymousId = this.getOrCreateAnonymousId(), this.logger.info(`Usermaven client reinitialized for namespace: ${this.namespace}`);
986
+ }
987
+ manageCrossDomainLinking() {
988
+ if (!this.config.crossDomainLinking || !this.config.domains)
989
+ return;
990
+ const e = this.config.domains.split(",").map((i) => i.trim()), t = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
991
+ document.addEventListener("click", (i) => {
992
+ var c;
993
+ const n = this.findClosestLink(i.target);
994
+ if (!n) return;
995
+ const r = n.getAttribute("href");
996
+ if (!r || !r.startsWith("http")) return;
997
+ const o = new URL(r);
998
+ if (o.hostname !== window.location.hostname && e.includes(o.hostname)) {
999
+ const l = (c = this.cookieManager) == null ? void 0 : c.get(t);
1000
+ l && (o.searchParams.append("_um", l), n.setAttribute("href", o.toString()));
1001
+ }
1002
+ }), this.logger.debug("Cross-domain linking initialized");
1003
+ }
1004
+ findClosestLink(e) {
1005
+ for (; e && e.tagName !== "A"; )
1006
+ e = e.parentElement;
1007
+ return e;
1008
+ }
1009
+ initializeTransport(e) {
1010
+ if (!u())
1011
+ return new fe(e.trackingHost, e);
1012
+ const t = "XMLHttpRequest" in window, i = typeof fetch < "u", n = typeof navigator < "u" && "sendBeacon" in navigator;
1013
+ if (e.useBeaconApi && n)
1014
+ return new ue(e.trackingHost, e, this.logger);
1015
+ if (e.forceUseFetch && i)
1016
+ return new L(e.trackingHost, e, this.logger);
1017
+ if (t)
1018
+ return new he(e.trackingHost, e, this.logger);
1019
+ if (i)
1020
+ return new L(e.trackingHost, e, this.logger);
1021
+ throw new Error("No suitable transport method available");
1022
+ }
1023
+ initializePersistence() {
1024
+ return this.config.disableEventPersistence || !u() ? new ge() : new V(`${this.namespace}_${this.config.key}`, this.logger);
1025
+ }
1026
+ getOrCreateAnonymousId() {
1027
+ var i, n;
1028
+ if (!u())
1029
+ return P();
1030
+ if (this.config.privacyPolicy === "strict" || this.config.cookiePolicy === "strict")
1031
+ return this.generateFingerprint();
1032
+ const e = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
1033
+ let t = (i = this.cookieManager) == null ? void 0 : i.get(e);
1034
+ if (!t) {
1035
+ if (this.config.crossDomainLinking) {
1036
+ const c = new URLSearchParams(window.location.search).get("_um"), a = window.location.hash.substring(1).split("~"), g = a.length > 1 ? a[1] : void 0;
1037
+ t = c || g || P();
1038
+ }
1039
+ t || (t = P());
1040
+ const r = 365 * 10;
1041
+ (n = this.cookieManager) == null || n.set(e, t, r, document.location.protocol !== "http:", !1);
1042
+ }
1043
+ return t;
1044
+ }
1045
+ generateFingerprint() {
1046
+ const e = navigator.userAgent, t = `${screen.width}x${screen.height}`, i = screen.colorDepth, n = Intl.DateTimeFormat().resolvedOptions().timeZone, r = `${e}|${t}|${i}|${n}`;
1047
+ return this.hashString(r);
1048
+ }
1049
+ hashString(e) {
1050
+ let t = 0;
1051
+ for (let i = 0; i < e.length; i++) {
1052
+ const n = e.charCodeAt(i);
1053
+ t = (t << 5) - t + n, t = t & t;
1054
+ }
1055
+ return t.toString(36);
1056
+ }
1057
+ async id(e, t = !1) {
1058
+ if (!k(e))
1059
+ throw new Error("User data must be an object");
1060
+ if (e.email && !ne(e.email))
1061
+ throw new Error("Invalid email provided");
1062
+ if (!e.id || !O(e.id))
1063
+ throw new Error("User ID must be a string");
1064
+ const i = e.id;
1065
+ if (this.persistence.set("userId", i), this.persistence.set("userProps", e), !t) {
1066
+ const n = {
1067
+ ...e,
1068
+ anonymous_id: this.anonymousId
1069
+ };
1070
+ await this.track("user_identify", n);
1071
+ }
1072
+ this.logger.info("User identified:", e);
1073
+ }
1074
+ track(e, t, i = !1) {
1075
+ this.trackInternal(e, t, i);
1076
+ }
1077
+ trackInternal(e, t, i = !1) {
1078
+ if (!O(e))
1079
+ throw new Error("Event name must be a string");
1080
+ if (t !== void 0 && (typeof t != "object" || t === null || Array.isArray(t)))
1081
+ throw new Error("Event payload must be a non-null object and not an array");
1082
+ const n = this.createEventPayload(e, t);
1083
+ try {
1084
+ if (i) {
1085
+ this.transport.send(n), this.logger.debug(`Event sent: ${e}`, [n]);
1086
+ return;
1087
+ }
1088
+ this.retryQueue.add(n), this.logger.debug(`Event tracked: ${e}`, [n]);
1089
+ } catch (r) {
1090
+ throw this.logger.error(`Failed to track event: ${e}`, r), new Error(`Failed to track event: ${e}`);
1091
+ }
1092
+ }
1093
+ rawTrack(e) {
1094
+ if (!k(e))
1095
+ throw new Error("Event payload must be an object");
1096
+ this.track("raw", e);
1097
+ }
1098
+ async group(e, t = !1) {
1099
+ if (!k(e))
1100
+ throw new Error("Company properties must be an object");
1101
+ if (!e.id || !e.name || !e.created_at)
1102
+ throw new Error("Company properties must include id, name, and created_at");
1103
+ this.persistence.set("companyProps", e), t || await this.track("group", e), this.logger.info("Company identified:", e);
1104
+ }
1105
+ createEventPayload(e, t) {
1106
+ const i = this.persistence.get("userProps") || {}, n = this.persistence.get("companyProps") || void 0, r = this.persistence.get("userId"), o = this.persistence.get("global_props") || {}, c = this.persistence.get(`props_${e}`) || {};
1107
+ let l = t || {};
1108
+ const a = {
1109
+ event_id: "",
1110
+ user: {
1111
+ anonymous_id: this.anonymousId,
1112
+ id: r,
1113
+ ...i
1114
+ },
1115
+ ...n && { company: n },
1116
+ ids: this.getThirdPartyIds(),
1117
+ utc_time: (/* @__PURE__ */ new Date()).toISOString(),
1118
+ local_tz_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
1119
+ api_key: this.config.key,
1120
+ src: "usermaven",
1121
+ event_type: e,
1122
+ namespace: this.namespace,
1123
+ ...o,
1124
+ ...c
1125
+ };
1126
+ if (e === "$autocapture") {
1127
+ const g = this.processAutocaptureAttributes(t || {});
1128
+ a.autocapture_attributes = g;
1129
+ } else
1130
+ Array.isArray(this.config.propertyBlacklist) && this.config.propertyBlacklist.forEach((g) => {
1131
+ delete l[g];
1132
+ }), a.event_attributes = l;
1133
+ return u() && (a.referer = document.referrer, a.url = window.location.href, a.page_title = document.title, a.doc_path = window.location.pathname, a.doc_host = window.location.hostname, a.doc_search = window.location.search, a.screen_resolution = `${window.screen.width}x${window.screen.height}`, a.vp_size = `${window.innerWidth}x${window.innerHeight}`, a.user_agent = navigator.userAgent, a.user_language = navigator.language, a.doc_encoding = document.characterSet, a.utm = this.getUtmParams()), a;
1134
+ }
1135
+ processAutocaptureAttributes(e) {
1136
+ let t = {};
1137
+ const i = e.$elements || [];
1138
+ return i.length && (t = { ...i[0] }), t.el_text = t.$el_text || "", t.event_type = e.$event_type || "", ["$ce_version", "$event_type", "$initial_referrer", "$initial_referring_domain", "$referrer", "$referring_domain", "$elements"].forEach((n) => {
1139
+ delete t[n];
1140
+ }), delete t.$el_text, delete t.nth_child, delete t.nth_of_type, t;
1141
+ }
1142
+ getCookie(e) {
1143
+ var t;
1144
+ return ((t = this.cookieManager) == null ? void 0 : t.get(e)) || null;
1145
+ }
1146
+ getThirdPartyIds() {
1147
+ const e = {};
1148
+ if (u()) {
1149
+ const t = this.getCookie("_fbp");
1150
+ t && (e.fbp = t);
1151
+ }
1152
+ return e;
1153
+ }
1154
+ getUtmParams() {
1155
+ const e = {}, t = oe(window.location.search);
1156
+ return ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"].forEach((n) => {
1157
+ t[n] && (e[n.replace("utm_", "")] = t[n]);
1158
+ }), e;
1159
+ }
1160
+ pageview() {
1161
+ u() ? this.track("pageview", {
1162
+ url: window.location.href,
1163
+ referrer: document.referrer,
1164
+ title: document.title
1165
+ }, !0) : this.logger.warn("Pageview tracking is not available in server-side environments");
1166
+ }
1167
+ setupPageLeaveTracking() {
1168
+ if (!u()) return;
1169
+ let e = !1, t = !1;
1170
+ const i = () => {
1171
+ !e && !t && (e = !0, this.track("$pageleave", {
1172
+ url: window.location.href,
1173
+ referrer: document.referrer,
1174
+ title: document.title
1175
+ }));
1176
+ };
1177
+ window.addEventListener("beforeunload", (r) => {
1178
+ t = !0, setTimeout(() => {
1179
+ t = !1;
1180
+ }, 100);
1181
+ }), document.addEventListener("visibilitychange", () => {
1182
+ document.visibilityState === "hidden" && !t && i();
1183
+ });
1184
+ const n = history.pushState;
1185
+ history.pushState = function() {
1186
+ return i(), n.apply(this, arguments);
1187
+ }, window.addEventListener("popstate", i);
1188
+ }
1189
+ getConfig() {
1190
+ return this.config;
1191
+ }
1192
+ getLogger() {
1193
+ return this.logger;
1194
+ }
1195
+ async reset(e = !1) {
1196
+ if (this.persistence.clear(), e && this.cookieManager) {
1197
+ const t = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
1198
+ this.cookieManager.delete(t), this.anonymousId = this.getOrCreateAnonymousId();
1199
+ }
1200
+ this.logger.info("core state reset", { resetAnonId: e, namespace: this.namespace });
1201
+ }
1202
+ set(e, t) {
1203
+ if (!k(e))
1204
+ throw new Error("Properties must be an object");
1205
+ const i = t == null ? void 0 : t.eventType, n = (t == null ? void 0 : t.persist) ?? !0;
1206
+ if (i) {
1207
+ let r = this.persistence.get(`props_${i}`) || {};
1208
+ r = { ...r, ...e }, this.persistence.set(`props_${i}`, r);
1209
+ } else {
1210
+ let r = this.persistence.get("global_props") || {};
1211
+ r = { ...r, ...e }, this.persistence.set("global_props", r);
1212
+ }
1213
+ n && this.persistence.save(), this.logger.debug("Properties set", {
1214
+ properties: e,
1215
+ eventType: i || "global",
1216
+ persist: n
1217
+ });
1218
+ }
1219
+ setUserId(e) {
1220
+ this.persistence.set("userId", e);
1221
+ let t = this.persistence.get("userProps") || {};
1222
+ t.id = e, this.persistence.set("userProps", t), this.persistence.save();
1223
+ }
1224
+ unset(e, t) {
1225
+ const i = t == null ? void 0 : t.eventType, n = (t == null ? void 0 : t.persist) ?? !0;
1226
+ if (i) {
1227
+ let r = this.persistence.get(`props_${i}`) || {};
1228
+ delete r[e], this.persistence.set(`props_${i}`, r);
1229
+ } else {
1230
+ let r = this.persistence.get("global_props") || {};
1231
+ delete r[e], this.persistence.set("global_props", r);
1232
+ }
1233
+ n && this.persistence.save(), this.logger.debug(`Property unset: ${e}`, `Event type: ${i || "global"}`);
1234
+ }
1235
+ }
1236
+ function me(s) {
1237
+ const e = JSON.parse(JSON.stringify(s)), t = S(e), i = { ...I, ...t };
1238
+ if (!i.key)
1239
+ throw new Error("API key is required!");
1240
+ if (!i.trackingHost)
1241
+ throw new Error("Tracking host is required!");
1242
+ return new pe(i);
1243
+ }
1244
+ function ye(s) {
1245
+ var n;
1246
+ const e = {
1247
+ key: s.getAttribute("data-key") || void 0,
1248
+ trackingHost: s.getAttribute("data-tracking-host") || "https://events.usermaven.com",
1249
+ logLevel: ae(s.getAttribute("data-log-level")),
1250
+ autocapture: s.getAttribute("data-autocapture") === "true",
1251
+ formTracking: s.getAttribute("data-form-tracking") === "true" ? "all" : !1,
1252
+ autoPageview: s.getAttribute("data-auto-pageview") === "true",
1253
+ useBeaconApi: s.getAttribute("data-use-beacon-api") === "true",
1254
+ forceUseFetch: s.getAttribute("data-force-use-fetch") === "true",
1255
+ gaHook: s.getAttribute("data-ga-hook") === "true",
1256
+ segmentHook: s.getAttribute("data-segment-hook") === "true",
1257
+ randomizeUrl: s.getAttribute("data-randomize-url") === "true",
1258
+ capture3rdPartyCookies: s.getAttribute("data-capture-3rd-party-cookies") === "false" ? !1 : void 0,
1259
+ idMethod: s.getAttribute("data-id-method") || void 0,
1260
+ privacyPolicy: s.getAttribute("data-privacy-policy") === "strict" ? "strict" : void 0,
1261
+ ipPolicy: s.getAttribute("data-ip-policy") || void 0,
1262
+ cookiePolicy: s.getAttribute("data-cookie-policy") || void 0,
1263
+ minSendTimeout: parseInt(s.getAttribute("data-min-send-timeout") || "", 10) || void 0,
1264
+ maxSendTimeout: parseInt(s.getAttribute("data-max-send-timeout") || "", 10) || void 0,
1265
+ maxSendAttempts: parseInt(s.getAttribute("data-max-send-attempts") || "", 10) || void 0,
1266
+ propertiesStringMaxLength: parseInt(s.getAttribute("data-properties-string-max-length") || "", 10) || null,
1267
+ propertyBlacklist: ((n = s.getAttribute("data-property-blacklist")) == null ? void 0 : n.split(",")) || void 0,
1268
+ exclude: s.getAttribute("data-exclude") || void 0,
1269
+ namespace: s.getAttribute("data-namespace") || void 0,
1270
+ crossDomainLinking: s.getAttribute("data-cross-domain-linking") !== "false",
1271
+ domains: s.getAttribute("data-domains") || void 0,
1272
+ maskAllText: s.getAttribute("data-mask-all-text") === "true",
1273
+ maskAllElementAttributes: s.getAttribute("data-mask-all-element-attributes") === "true"
1274
+ }, t = me(e), i = e.namespace || "usermaven";
1275
+ u() && t.pageview(), we(i, t);
1276
+ }
1277
+ function we(s, e) {
1278
+ let t = !1;
1279
+ const i = [], n = [];
1280
+ function r() {
1281
+ for (; i.length > 0; ) {
1282
+ const a = i.shift();
1283
+ a && window[s].apply(null, a);
1284
+ }
1285
+ }
1286
+ function o() {
1287
+ n.forEach((a) => a()), n.length = 0;
1288
+ }
1289
+ window[s] = function(...a) {
1290
+ const g = a[0];
1291
+ if (g === "onLoad") {
1292
+ typeof a[1] == "function" && (t ? a[1]() : n.push(a[1]));
1293
+ return;
1294
+ }
1295
+ if (!t) {
1296
+ i.push(a);
1297
+ return;
1298
+ }
1299
+ if (typeof e[g] == "function")
1300
+ return e[g].apply(e, a.slice(1));
1301
+ console.error(`Method ${g} not found on UsermavenClient`);
1302
+ };
1303
+ const c = `${s}Q`, l = window[c] || [];
1304
+ for (window[c] = l, l.push = function(...a) {
1305
+ return window[s].apply(null, a), Array.prototype.push.apply(this, a);
1306
+ }, setTimeout(() => {
1307
+ t = !0, r(), o(), console.log(`Usermaven client for namespace ${s} is ready`);
1308
+ }, 0); l.length > 0; ) {
1309
+ const a = l.shift();
1310
+ a && i.push(a);
1311
+ }
1312
+ }
1313
+ u() && function(s, e) {
1314
+ const t = s.currentScript;
1315
+ function i() {
1316
+ t && t.src.includes("lib.js") && ye(t);
1317
+ }
1318
+ typeof e < "u" && (s.readyState === "loading" ? s.addEventListener("DOMContentLoaded", i) : i());
1319
+ }(document, window);
1320
+ export {
1321
+ v as LogLevel,
1322
+ pe as UsermavenClient,
1323
+ me as usermavenClient
1324
+ };