@usermaven/sdk-js 1.4.2 → 1.4.3-rc.88

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