@levo-so/insights 0.1.76 → 0.1.78

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,122 @@
1
+ import { getLevoError as s } from "@levo-so/core";
2
+ import { getAttributes as g } from "../utils/autocapture.js";
3
+ import { isRageClick as y } from "../utils/rageclick.js";
4
+ const w = (c) => {
5
+ let i = c, e = 0;
6
+ for (; i && e < 10; ) {
7
+ const o = i.getAttribute?.("href");
8
+ if (o)
9
+ return o;
10
+ i = i.parentElement, e++;
11
+ }
12
+ return null;
13
+ }, u = (c) => {
14
+ const i = c.closest("a[href]"), e = i?.getAttribute("href") || w(c);
15
+ if (!e) return { type: null, href: null };
16
+ if (i?.hasAttribute("download"))
17
+ return { type: "download", href: e };
18
+ if (e.startsWith("tel:")) return { type: "tel", href: e };
19
+ if (e.startsWith("mailto:")) return { type: "mailto", href: e };
20
+ if (e.startsWith("#")) return { type: "anchor", href: e };
21
+ try {
22
+ return {
23
+ type: new URL(e, window.location.origin).origin === window.location.origin ? "internal" : "external",
24
+ href: e
25
+ };
26
+ } catch (o) {
27
+ return console.warn("[insights] Failed to classify link", s(o)), { type: "internal", href: e };
28
+ }
29
+ }, _ = (c) => {
30
+ if (typeof window > "u") return () => {
31
+ };
32
+ let i = 0, e = null;
33
+ const o = (t, r = !1) => {
34
+ const n = t.target, l = "clientX" in t ? t.clientX : t.changedTouches?.[0]?.clientX ?? 0, m = "clientY" in t ? t.clientY : t.changedTouches?.[0]?.clientY ?? 0;
35
+ let a = {
36
+ hostname: window.location.hostname,
37
+ pathname: window.location.pathname,
38
+ page_title: document.title,
39
+ url: window.location.href,
40
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
41
+ event_type: r ? "dblclick" : "click",
42
+ button_type: "button" in t ? t.button : 0
43
+ };
44
+ return n instanceof HTMLElement && (a.rage_click = y(l, m, Date.now()), a = {
45
+ ...a,
46
+ ...g(n)
47
+ }), a;
48
+ }, k = (t, r) => {
49
+ try {
50
+ if (Date.now() - i < 300) return;
51
+ const n = o(t);
52
+ c.track("page.click", {
53
+ ...n,
54
+ href: r.href || void 0,
55
+ link_type: r.type,
56
+ is_navigation: !0
57
+ });
58
+ } catch (n) {
59
+ console.error("[insights] Failed to track navigation click", s(n));
60
+ }
61
+ }, d = (t, r = !1) => {
62
+ try {
63
+ if (!(t.target instanceof HTMLElement) || Date.now() - i < 300) return;
64
+ const n = o(t, r), l = u(t.target);
65
+ c.track("page.click", {
66
+ ...n,
67
+ href: l.href || void 0,
68
+ link_type: l.type || void 0
69
+ });
70
+ } catch (n) {
71
+ console.error("[insights] Failed to track click", s(n));
72
+ }
73
+ }, f = (t) => {
74
+ if (!(t.target instanceof HTMLElement)) return;
75
+ const r = u(t.target);
76
+ if (r.type === "external" || r.type === "download") {
77
+ k(t, r);
78
+ return;
79
+ }
80
+ if (e) {
81
+ clearTimeout(e), e = null;
82
+ return;
83
+ }
84
+ e = setTimeout(() => {
85
+ d(t, !1), e = null;
86
+ }, 250);
87
+ }, h = (t) => {
88
+ e && (clearTimeout(e), e = null), d(t, !0);
89
+ }, p = (t) => {
90
+ try {
91
+ if (!(t.target instanceof HTMLElement)) return;
92
+ i = Date.now();
93
+ const r = u(t.target);
94
+ if (r.type === "external" || r.type === "download") {
95
+ const l = o(t);
96
+ c.track("page.click", {
97
+ ...l,
98
+ href: r.href || void 0,
99
+ link_type: r.type,
100
+ is_navigation: !0,
101
+ is_touch: !0
102
+ });
103
+ return;
104
+ }
105
+ const n = o(t);
106
+ c.track("page.click", {
107
+ ...n,
108
+ href: r.href || void 0,
109
+ link_type: r.type || void 0,
110
+ is_touch: !0
111
+ });
112
+ } catch (r) {
113
+ console.error("[insights] Failed to track touch", s(r));
114
+ }
115
+ };
116
+ return document.addEventListener("click", f), document.addEventListener("dblclick", h), document.addEventListener("touchend", p, { passive: !0 }), () => {
117
+ document.removeEventListener("click", f), document.removeEventListener("dblclick", h), document.removeEventListener("touchend", p), e && clearTimeout(e);
118
+ };
119
+ };
120
+ export {
121
+ _ as initClicksTracker
122
+ };
@@ -0,0 +1,20 @@
1
+ import { getLevoError as p } from "@levo-so/core";
2
+ import { getPropertiesFromEvent as u } from "../utils/autocapture.js";
3
+ const s = (c) => {
4
+ if (typeof window > "u") return () => {
5
+ };
6
+ const t = (n) => (i) => {
7
+ try {
8
+ const e = u(i, n);
9
+ e && c.track("page.copy", e);
10
+ } catch (e) {
11
+ console.error(`[insights] Failed to track clipboard ${n}`, p(e));
12
+ }
13
+ }, r = t("copy"), o = t("cut");
14
+ return document.addEventListener("copy", r, { capture: !0 }), document.addEventListener("cut", o, { capture: !0 }), () => {
15
+ document.removeEventListener("copy", r, { capture: !0 }), document.removeEventListener("cut", o, { capture: !0 });
16
+ };
17
+ };
18
+ export {
19
+ s as initClipboardTracker
20
+ };
@@ -0,0 +1,28 @@
1
+ import { atom as c } from "nanostores";
2
+ import { STORAGE_KEYS as a } from "../constants/storageKeys.js";
3
+ import { $session as i, updateSession as l } from "../stores/session.js";
4
+ const s = c(null), g = (b) => {
5
+ if (typeof window > "u") return () => {
6
+ };
7
+ let t = sessionStorage.getItem(a.current_tab);
8
+ const { allTabs: n } = i.get();
9
+ t && n.includes(t) && (t = null), t || (t = `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`, sessionStorage.setItem(a.current_tab, t));
10
+ const e = t;
11
+ s.set(e), n.includes(e) || l({ allTabs: [...n, e] });
12
+ const r = () => {
13
+ if (!e) return;
14
+ const { allTabs: o } = i.get();
15
+ if (o.includes(e)) {
16
+ const u = o.filter((d) => d !== e);
17
+ l({ allTabs: u });
18
+ }
19
+ };
20
+ return window.addEventListener("beforeunload", r), () => {
21
+ window.removeEventListener("beforeunload", r), r(), s.set(null);
22
+ };
23
+ }, p = () => s.get();
24
+ export {
25
+ s as $currentTab,
26
+ p as getCurrentTab,
27
+ g as initCurrentTabTracker
28
+ };
@@ -0,0 +1,23 @@
1
+ import { getLevoError as u } from "@levo-so/core";
2
+ import { getPropertiesFromEvent as m } from "../utils/autocapture.js";
3
+ const p = (c) => {
4
+ if (typeof window > "u") return () => {
5
+ };
6
+ const r = (t) => (i) => {
7
+ try {
8
+ const e = m(i, t);
9
+ if (e) {
10
+ const s = t === "submit" ? "form.submit" : "form.change";
11
+ c.track(s, e);
12
+ }
13
+ } catch (e) {
14
+ console.error(`[insights] Failed to track form ${t}`, u(e));
15
+ }
16
+ }, o = r("change"), n = r("submit");
17
+ return document.addEventListener("change", o, { capture: !0 }), document.addEventListener("submit", n, { capture: !0 }), () => {
18
+ document.removeEventListener("change", o, { capture: !0 }), document.removeEventListener("submit", n, { capture: !0 });
19
+ };
20
+ };
21
+ export {
22
+ p as initFormsTracker
23
+ };
@@ -0,0 +1,47 @@
1
+ import { getLevoError as w } from "@levo-so/core";
2
+ import { $config as c } from "../stores/config.js";
3
+ import { $session as f } from "../stores/session.js";
4
+ const u = (p) => {
5
+ if (typeof window > "u") return () => {
6
+ };
7
+ const { page_id: r } = c.get();
8
+ let a = r || "", s = typeof window < "u" ? window.location.href : "";
9
+ const d = () => {
10
+ const { isIdentified: e } = f.get();
11
+ if (e)
12
+ try {
13
+ p.page({
14
+ resource: "page"
15
+ });
16
+ } catch (i) {
17
+ console.error("[insights] Failed to send page view", w(i));
18
+ }
19
+ };
20
+ if (r) {
21
+ const e = c.listen((i, o, t) => {
22
+ const { page_id: n } = i;
23
+ t === "page_id" && n && a !== n && (a = n, d());
24
+ });
25
+ return () => {
26
+ e();
27
+ };
28
+ } else {
29
+ const e = () => {
30
+ if (typeof window > "u") return;
31
+ const t = window.location.href;
32
+ t !== s && (s = t, d());
33
+ };
34
+ window.addEventListener("popstate", e);
35
+ const i = window.history.pushState, o = window.history.replaceState;
36
+ return window.history.pushState = function(...t) {
37
+ i.apply(this, t), e();
38
+ }, window.history.replaceState = function(...t) {
39
+ o.apply(this, t), e();
40
+ }, () => {
41
+ window.removeEventListener("popstate", e), window.history.pushState = i, window.history.replaceState = o;
42
+ };
43
+ }
44
+ };
45
+ export {
46
+ u as initPageTracker
47
+ };
@@ -0,0 +1,52 @@
1
+ import _ from "lodash-es/debounce";
2
+ import { map as b } from "nanostores";
3
+ const r = b({
4
+ depth: 0,
5
+ speedCategory: "read",
6
+ direction: "down"
7
+ }), Y = (h) => {
8
+ if (typeof window > "u") return () => {
9
+ };
10
+ let c = {
11
+ prevMilestone: -1,
12
+ // Use -1 to ensure first milestone (even 0) is tracked
13
+ prevScrollY: 0,
14
+ prevTime: Date.now()
15
+ };
16
+ const i = 5, u = 300, w = 250, o = () => {
17
+ const e = window.scrollY, f = document.documentElement.scrollHeight, v = window.innerHeight, d = f - v;
18
+ if (d <= 0) return;
19
+ const S = Math.round(e / d * 100), D = Math.max(0, Math.min(100, S)), t = Math.floor(D / i) * i, { prevMilestone: s, prevScrollY: g, prevTime: E } = c;
20
+ if (t === s) return;
21
+ const p = Date.now(), a = (p - E) / 1e3, C = Math.abs(e - g), M = a > 0 ? C / a : 0, T = t > s ? "down" : "up", H = M > u ? "scan" : "read";
22
+ r.set({
23
+ depth: t,
24
+ speedCategory: H,
25
+ direction: T
26
+ }), c = {
27
+ prevMilestone: t,
28
+ prevScrollY: e,
29
+ prevTime: p
30
+ };
31
+ }, n = _(o, w);
32
+ window.addEventListener("scroll", n);
33
+ let l = 0;
34
+ const m = r.listen((e) => {
35
+ e.depth !== l && (l = e.depth, h.track("page.scroll", {
36
+ depth: e.depth,
37
+ speed_category: e.speedCategory,
38
+ direction: e.direction
39
+ }));
40
+ });
41
+ return typeof window.requestIdleCallback == "function" ? window.requestIdleCallback(() => o()) : setTimeout(o, 0), () => {
42
+ window.removeEventListener("scroll", n), n.cancel(), m(), r.set({
43
+ depth: 0,
44
+ speedCategory: "read",
45
+ direction: "down"
46
+ });
47
+ };
48
+ };
49
+ export {
50
+ r as $scrollBehavior,
51
+ Y as initScrollBehaviorTracker
52
+ };
@@ -0,0 +1,27 @@
1
+ import r from "lodash-es/debounce";
2
+ import { atom as l } from "nanostores";
3
+ import { makeSafeText as s } from "../utils/autocapture.js";
4
+ const n = l(null), f = (c) => {
5
+ if (typeof window > "u") return () => {
6
+ };
7
+ const t = r(() => {
8
+ const e = window.getSelection();
9
+ if (e && e.rangeCount > 0) {
10
+ const o = e.toString().trim();
11
+ o && n.set(o);
12
+ }
13
+ }, 1e3);
14
+ document.addEventListener("selectionchange", t);
15
+ const i = n.listen((e) => {
16
+ e && c.track("page.selection", {
17
+ text: s(e)
18
+ });
19
+ });
20
+ return () => {
21
+ document.removeEventListener("selectionchange", t), t.cancel(), i(), n.set(null);
22
+ };
23
+ };
24
+ export {
25
+ n as $selectedText,
26
+ f as initTextSelectionTracker
27
+ };
@@ -0,0 +1,203 @@
1
+ const d = (t) => Object.prototype.toString.call(t) == "[object String]", E = (t, e) => t.indexOf(e) !== -1, l = (t) => t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""), b = (t) => t === void 0, S = (t) => t === null, m = (t) => b(t) || S(t), x = (t) => !!t && t?.nodeType === 3;
2
+ function T(t) {
3
+ return !!t && t?.nodeType === 1;
4
+ }
5
+ function k(t, e) {
6
+ return !!t && !!t?.tagName && t?.tagName.toLowerCase() === e.toLowerCase();
7
+ }
8
+ function A(t) {
9
+ return t ? l(t).split(/\s+/) : [];
10
+ }
11
+ function L(t) {
12
+ let e = "";
13
+ switch (typeof t?.className) {
14
+ case "string":
15
+ e = t?.className;
16
+ break;
17
+ // TODO: when is this ever used?
18
+ case "object":
19
+ e = (t?.className && "baseVal" in t.className ? (t?.className).baseVal : null) || t?.getAttribute("class") || "";
20
+ break;
21
+ default:
22
+ e = "";
23
+ }
24
+ return A(e);
25
+ }
26
+ const a = (t, e = 255) => m(t) ? "" : l(t).split(/(\s+)/).filter((n) => p(n)).join("").replace(/[\r\n]/g, " ").replace(/[ ]+/g, " ").substring(0, e), h = ["span", "strong", "em", "i", "b", "mark", "code", "small", "sub", "sup", "label"], g = (t) => {
27
+ let e = "";
28
+ if (v(t) && t?.childNodes && t?.childNodes.length) {
29
+ for (const n of t.childNodes)
30
+ x(n) && n.textContent && (e += a(n.textContent) ?? "");
31
+ if (!l(e)) {
32
+ const n = t.querySelectorAll(h.join(", "));
33
+ for (const s of n) {
34
+ const i = s.textContent;
35
+ i && (e += `${a(i)} `);
36
+ }
37
+ }
38
+ if (!l(e) && t instanceof HTMLElement) {
39
+ const n = t.innerText;
40
+ n && (e = a(n.substring(0, 500)));
41
+ }
42
+ }
43
+ return l(e);
44
+ }, $ = (t) => b(t.target) ? t?.srcElement || null : t?.target?.shadowRoot ? t?.composedPath()?.[0] || null : t?.target || null, R = (t, e) => {
45
+ if (!window || !t || k(t, "html") || !T(t))
46
+ return !1;
47
+ const n = window.getComputedStyle(t);
48
+ if (n && n.getPropertyValue("cursor") === "pointer" && e.type === "click")
49
+ return !0;
50
+ switch (t?.tagName.toLowerCase()) {
51
+ case "html":
52
+ return !1;
53
+ case "form":
54
+ return e.type === "submit";
55
+ case "input":
56
+ case "select":
57
+ case "textarea":
58
+ return ["change", "click"].includes(e.type);
59
+ default:
60
+ return e.type === "click";
61
+ }
62
+ }, _ = /* @__PURE__ */ new Set([
63
+ "password",
64
+ "passwd",
65
+ "pwd",
66
+ "creditcard",
67
+ "cardnumber",
68
+ "ccnum",
69
+ "ccnumber",
70
+ "cvv",
71
+ "cvc",
72
+ "csc",
73
+ "securitycode",
74
+ "ssn",
75
+ "socialsecurity",
76
+ "routingnumber",
77
+ "accountnumber",
78
+ "bankaccount",
79
+ "secretkey",
80
+ "apikey",
81
+ "accesstoken"
82
+ ]);
83
+ function v(t) {
84
+ if (E(L(t), "ph-include"))
85
+ return !0;
86
+ const e = t.type || "";
87
+ if (d(e))
88
+ switch (e.toLowerCase()) {
89
+ case "hidden":
90
+ return !1;
91
+ case "password":
92
+ return !1;
93
+ }
94
+ const n = t.name || t?.id || "";
95
+ if (d(n)) {
96
+ const s = n.toLowerCase().replace(/[^a-z]/g, "");
97
+ if (_.has(s))
98
+ return !1;
99
+ }
100
+ return !0;
101
+ }
102
+ const y = "(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})", F = new RegExp(`^(?:${y})$`), j = new RegExp(y), N = "\\d{3}-?\\d{2}-?\\d{4}", I = new RegExp(`^(${N})$`), P = new RegExp(`(${N})`), p = (t, e = !0) => !(m(t) || d(t) && (t = l(t), (e ? F : j).test((t || "").replace(/[- ]/g, "")) || (e ? I : P).test(t))), V = (t) => d(t) ? t.substring(0, 10) === "_ngcontent" || t.substring(0, 7) === "_nghost" : !1, W = (t) => {
103
+ let e = g(t);
104
+ return e = `${e} ${w(t)}`.trim(), p(e) ? e : "";
105
+ };
106
+ function w(t) {
107
+ let e = "";
108
+ if (t?.childNodes.length)
109
+ for (const n of t.childNodes) {
110
+ const s = n.tagName?.toLowerCase();
111
+ if (n && s && h.includes(s))
112
+ try {
113
+ const i = g(n);
114
+ e = `${e} ${i}`.trim(), n?.childNodes.length && (e = `${e} ${w(n)}`.trim());
115
+ } catch {
116
+ }
117
+ }
118
+ return e;
119
+ }
120
+ const D = (t) => {
121
+ const e = t.tagName?.toLowerCase(), n = e === "a" || e === "button" ? W(t) : g(t);
122
+ if (n) return { text: n, source: "text" };
123
+ const s = t.getAttribute("aria-label");
124
+ if (s) return { text: a(s), source: "aria-label" };
125
+ const i = t.getAttribute("title");
126
+ if (i) return { text: a(i), source: "title" };
127
+ const u = t.getAttribute("data-track-label");
128
+ if (u) return { text: a(u), source: "data-track-label" };
129
+ const o = t.querySelector("img[alt], svg[aria-label]");
130
+ if (o) {
131
+ const r = o.getAttribute("alt") || o.getAttribute("aria-label");
132
+ if (r) return { text: a(r), source: "alt" };
133
+ }
134
+ const f = t.getAttribute("placeholder");
135
+ if (f) return { text: a(f), source: "placeholder" };
136
+ if (t instanceof HTMLElement && t.innerText) {
137
+ const r = t.innerText.substring(0, 500);
138
+ if (r.trim())
139
+ return { text: a(r), source: "innerText" };
140
+ }
141
+ return { text: "", source: "none" };
142
+ }, M = ["input", "textarea", "select"], q = (t) => {
143
+ const e = t?.tagName?.toLowerCase(), n = {
144
+ element: e
145
+ }, s = D(t);
146
+ n.text = s.text, n.text_source = s.source;
147
+ const i = t.getAttribute("aria-label");
148
+ i && (n.aria_label = a(i));
149
+ const u = t.getAttribute("role");
150
+ u && (n.role = u);
151
+ const o = {};
152
+ for (const r of t.attributes)
153
+ (r.name.startsWith("data-track-") || r.name.startsWith("data-analytics-")) && (o[r.name] = a(r.value));
154
+ Object.keys(o).length && (n.tracking_data = o);
155
+ const f = Array.from(t.attributes).reduce(
156
+ (r, c) => {
157
+ if (p(c.value) && !V(c.name)) {
158
+ if (c.name === "class" || c.name.startsWith("data-track-") || c.name.startsWith("data-analytics-"))
159
+ return r;
160
+ r[c.name] = typeof c?.value == "string" ? a(c.value) : c.value;
161
+ }
162
+ return r;
163
+ },
164
+ {}
165
+ );
166
+ if (n.attributes = f, M.includes(e) || t?.getAttribute("contenteditable") === "true") {
167
+ let r;
168
+ t.matches('input[type="checkbox"], input[type="radio"]') ? r = t.checked : t.matches("input, select, textarea") && !t.matches('input[type="password"]') && (r = t.value), r !== void 0 && (n.value = typeof r == "string" || r === null ? a(r, 1024) : r);
169
+ let c = "";
170
+ n?.attributes.id && (c = a(
171
+ document.querySelector(`label[for="${n?.attributes.id}"]`)?.textContent?.trim() || ""
172
+ ));
173
+ const C = t.closest("label");
174
+ c || (c = a(C?.textContent?.trim() || "")), c && (n.label = c);
175
+ }
176
+ return n;
177
+ }, O = (t, e) => {
178
+ let n = $(t);
179
+ x(n) && (n = n.parentNode || null);
180
+ const s = ["copy", "cut"].includes(e);
181
+ if (n && (s || R(n, t))) {
182
+ const i = q(n);
183
+ if (s) {
184
+ const u = a(window?.getSelection()?.toString()), o = t?.type || "clipboard";
185
+ i.copy_text = u ?? "", i.copy_type = o;
186
+ }
187
+ return i;
188
+ }
189
+ return null;
190
+ };
191
+ export {
192
+ q as getAttributes,
193
+ W as getDirectAndNestedSpanText,
194
+ D as getElementTextWithFallback,
195
+ $ as getEventTarget,
196
+ O as getPropertiesFromEvent,
197
+ g as getSafeText,
198
+ V as isAngularStyleAttr,
199
+ x as isTextNode,
200
+ a as makeSafeText,
201
+ R as shouldCaptureDomEvent,
202
+ p as shouldCaptureValue
203
+ };
@@ -0,0 +1,13 @@
1
+ const t = () => {
2
+ if (typeof window > "u" || !("localStorage" in window))
3
+ return !1;
4
+ try {
5
+ const e = "__levo_test__";
6
+ return window.localStorage.setItem(e, "test"), window.localStorage.removeItem(e), !0;
7
+ } catch {
8
+ return !1;
9
+ }
10
+ };
11
+ export {
12
+ t as checkLocalStorageAvailable
13
+ };
@@ -0,0 +1,17 @@
1
+ import { pingEndpoint as n } from "./pingEndpoint.js";
2
+ const s = async (u) => {
3
+ const {
4
+ mode: t = "auto",
5
+ insightsUrl: e,
6
+ directInsightsUrl: r,
7
+ pingTimeout: i = 3e3,
8
+ debug: l = !1
9
+ } = u;
10
+ if (l)
11
+ return { mode: "proxy", url: e || "/debug-api" };
12
+ const o = Number.isFinite(i) && i >= 0 ? i : 3e3;
13
+ return t === "direct" ? { mode: "direct", url: r ?? null } : t === "proxy" || !r ? { mode: "proxy", url: e ?? null } : (e ? await n(`${e}/ping`, o) : !1) ? { mode: "proxy", url: e ?? null } : await n(`${r}/ping`, o) ? { mode: "direct", url: r } : { mode: "proxy", url: e ?? null };
14
+ };
15
+ export {
16
+ s as detectMode
17
+ };
@@ -0,0 +1,11 @@
1
+ const c = ({
2
+ deviceToken: t,
3
+ sessionToken: i,
4
+ mode: r
5
+ }) => {
6
+ const e = {};
7
+ return r === "direct" && (t && (e["Levo-Audience-Device"] = t), i && (e["Levo-Audience-Session"] = i)), e;
8
+ };
9
+ export {
10
+ c as getAuthHeaders
11
+ };
@@ -0,0 +1,20 @@
1
+ import { getVisitorSource as f } from "@analytics/visitor-source";
2
+ const a = () => {
3
+ if (typeof document > "u")
4
+ return {};
5
+ const {
6
+ type: t,
7
+ referrer: o,
8
+ data: r = {}
9
+ } = f({
10
+ referrer: document.referrer,
11
+ currentUrl: window.location.href,
12
+ mapper: null
13
+ }), n = Object.keys(r);
14
+ for (const e of n)
15
+ r[e] && Array.isArray(r[e]) && r[e].length > 0 && (r[e] = r[e]?.[0]);
16
+ return { type: t, referrer: o, data: r, raw: document.referrer };
17
+ };
18
+ export {
19
+ a as getReferrer
20
+ };
@@ -0,0 +1,66 @@
1
+ import h from "get-user-locale";
2
+ import m from "./isIncognito.js";
3
+ const l = () => {
4
+ const o = document.createElement("canvas"), n = o?.getContext("webgl") || o?.getContext("experimental-webgl");
5
+ if (!n)
6
+ return null;
7
+ const r = n?.getExtension("WEBGL_debug_renderer_info");
8
+ return r ? n?.getParameter(r.UNMASKED_RENDERER_WEBGL) : null;
9
+ }, u = async () => {
10
+ let o = "", n = "", r = !1, i = !1;
11
+ const e = {};
12
+ if (!window)
13
+ return {
14
+ locale: o,
15
+ timezone: n,
16
+ dark_mode: r,
17
+ private_mode: i,
18
+ properties: e
19
+ };
20
+ try {
21
+ ({ isPrivate: i } = await m());
22
+ } catch (t) {
23
+ console.error(t);
24
+ }
25
+ try {
26
+ r = window.matchMedia?.("(prefers-color-scheme: dark)").matches;
27
+ } catch (t) {
28
+ console.error(t);
29
+ }
30
+ try {
31
+ n = Intl.DateTimeFormat().resolvedOptions().timeZone;
32
+ } catch (t) {
33
+ console.error(t);
34
+ }
35
+ try {
36
+ o = h();
37
+ } catch (t) {
38
+ console.error(t);
39
+ }
40
+ if (navigator && "connection" in navigator) {
41
+ const t = navigator.connection || navigator?.mozConnection || navigator.webkitConnection;
42
+ e.network_type = t.effectiveType;
43
+ }
44
+ if (e.width = window?.innerWidth, e.height = window?.innerHeight, e.pixel_ratio = window?.devicePixelRatio, screen && (e.screen_width = screen?.width, e.screen_height = screen?.height, e.color_depth = screen?.colorDepth, e.orientation = screen?.orientation?.type), navigator && "getBattery" in navigator) {
45
+ const t = await navigator?.getBattery();
46
+ t && (e.battery_level = Number((t?.level * 100).toFixed(0)), e.battery_charging = t?.charging, e.battery_discharging_time = t?.dischargingTime, e.battery_full_charge_capacity = t?.fullChargeCapacity, e.battery_charging_time = t?.chargingTime);
47
+ }
48
+ navigator && "deviceMemory" in navigator && (e.device_memory = navigator?.deviceMemory);
49
+ const s = "ontouchstart" in window || typeof navigator?.maxTouchPoints < "u" && navigator?.maxTouchPoints > 0;
50
+ if (e.touch_supported = s, "hardwareConcurrency" in navigator && (e.hardware_concurrency = navigator?.hardwareConcurrency), navigator && "mediaDevices" in navigator) {
51
+ const c = await navigator?.mediaDevices?.enumerateDevices(), g = c.some((a) => a?.kind === "videoinput");
52
+ e.camera_supported = g;
53
+ const d = c.some((a) => a?.kind === "audioinput");
54
+ e.microphone_supported = d;
55
+ }
56
+ return e.gpu = l(), {
57
+ locale: o,
58
+ timezone: n,
59
+ dark_mode: r,
60
+ private_mode: i,
61
+ properties: e
62
+ };
63
+ };
64
+ export {
65
+ u as getUserProperties
66
+ };