@tracelog/lib 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -407
- package/dist/browser/tracelog.esm.js +1173 -771
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/cjs/app.d.ts +2 -0
- package/dist/cjs/app.d.ts.map +1 -1
- package/dist/cjs/app.js +5 -0
- package/dist/cjs/app.js.map +1 -1
- package/dist/cjs/constants/config.constants.d.ts +26 -1
- package/dist/cjs/constants/config.constants.d.ts.map +1 -1
- package/dist/cjs/constants/config.constants.js +30 -3
- package/dist/cjs/constants/config.constants.js.map +1 -1
- package/dist/cjs/constants/error.constants.d.ts +15 -0
- package/dist/cjs/constants/error.constants.d.ts.map +1 -1
- package/dist/cjs/constants/error.constants.js +19 -1
- package/dist/cjs/constants/error.constants.js.map +1 -1
- package/dist/cjs/handlers/click.handler.d.ts +15 -0
- package/dist/cjs/handlers/click.handler.d.ts.map +1 -1
- package/dist/cjs/handlers/click.handler.js +69 -0
- package/dist/cjs/handlers/click.handler.js.map +1 -1
- package/dist/cjs/handlers/error.handler.d.ts +7 -0
- package/dist/cjs/handlers/error.handler.d.ts.map +1 -1
- package/dist/cjs/handlers/error.handler.js +35 -0
- package/dist/cjs/handlers/error.handler.js.map +1 -1
- package/dist/cjs/handlers/page-view.handler.d.ts +1 -0
- package/dist/cjs/handlers/page-view.handler.d.ts.map +1 -1
- package/dist/cjs/handlers/page-view.handler.js +11 -0
- package/dist/cjs/handlers/page-view.handler.js.map +1 -1
- package/dist/cjs/handlers/performance.handler.js +5 -5
- package/dist/cjs/handlers/performance.handler.js.map +1 -1
- package/dist/cjs/handlers/viewport.handler.d.ts +44 -0
- package/dist/cjs/handlers/viewport.handler.d.ts.map +1 -0
- package/dist/cjs/handlers/viewport.handler.js +286 -0
- package/dist/cjs/handlers/viewport.handler.js.map +1 -0
- package/dist/cjs/managers/event.manager.d.ts +23 -3
- package/dist/cjs/managers/event.manager.d.ts.map +1 -1
- package/dist/cjs/managers/event.manager.js +166 -10
- package/dist/cjs/managers/event.manager.js.map +1 -1
- package/dist/cjs/managers/sender.manager.d.ts.map +1 -1
- package/dist/cjs/managers/sender.manager.js +12 -0
- package/dist/cjs/managers/sender.manager.js.map +1 -1
- package/dist/cjs/types/config.types.d.ts +9 -0
- package/dist/cjs/types/config.types.d.ts.map +1 -1
- package/dist/cjs/types/config.types.js.map +1 -1
- package/dist/cjs/types/event.types.d.ts +140 -16
- package/dist/cjs/types/event.types.d.ts.map +1 -1
- package/dist/cjs/types/event.types.js +23 -9
- package/dist/cjs/types/event.types.js.map +1 -1
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +2 -0
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/scroll.types.d.ts +16 -0
- package/dist/cjs/types/scroll.types.d.ts.map +1 -0
- package/dist/cjs/types/scroll.types.js +12 -0
- package/dist/cjs/types/scroll.types.js.map +1 -0
- package/dist/cjs/types/viewport.types.d.ts +55 -0
- package/dist/cjs/types/viewport.types.d.ts.map +1 -0
- package/dist/cjs/types/viewport.types.js +3 -0
- package/dist/cjs/types/viewport.types.js.map +1 -0
- package/dist/cjs/utils/validations/config-validations.utils.d.ts.map +1 -1
- package/dist/cjs/utils/validations/config-validations.utils.js +91 -0
- package/dist/cjs/utils/validations/config-validations.utils.js.map +1 -1
- package/dist/esm/app.d.ts +2 -0
- package/dist/esm/app.d.ts.map +1 -1
- package/dist/esm/app.js +5 -0
- package/dist/esm/app.js.map +1 -1
- package/dist/esm/constants/config.constants.d.ts +26 -1
- package/dist/esm/constants/config.constants.d.ts.map +1 -1
- package/dist/esm/constants/config.constants.js +28 -1
- package/dist/esm/constants/config.constants.js.map +1 -1
- package/dist/esm/constants/error.constants.d.ts +15 -0
- package/dist/esm/constants/error.constants.d.ts.map +1 -1
- package/dist/esm/constants/error.constants.js +18 -0
- package/dist/esm/constants/error.constants.js.map +1 -1
- package/dist/esm/handlers/click.handler.d.ts +15 -0
- package/dist/esm/handlers/click.handler.d.ts.map +1 -1
- package/dist/esm/handlers/click.handler.js +70 -1
- package/dist/esm/handlers/click.handler.js.map +1 -1
- package/dist/esm/handlers/error.handler.d.ts +7 -0
- package/dist/esm/handlers/error.handler.d.ts.map +1 -1
- package/dist/esm/handlers/error.handler.js +36 -1
- package/dist/esm/handlers/error.handler.js.map +1 -1
- package/dist/esm/handlers/page-view.handler.d.ts +1 -0
- package/dist/esm/handlers/page-view.handler.d.ts.map +1 -1
- package/dist/esm/handlers/page-view.handler.js +11 -0
- package/dist/esm/handlers/page-view.handler.js.map +1 -1
- package/dist/esm/handlers/performance.handler.js +5 -5
- package/dist/esm/handlers/performance.handler.js.map +1 -1
- package/dist/esm/handlers/viewport.handler.d.ts +44 -0
- package/dist/esm/handlers/viewport.handler.d.ts.map +1 -0
- package/dist/esm/handlers/viewport.handler.js +282 -0
- package/dist/esm/handlers/viewport.handler.js.map +1 -0
- package/dist/esm/managers/event.manager.d.ts +23 -3
- package/dist/esm/managers/event.manager.d.ts.map +1 -1
- package/dist/esm/managers/event.manager.js +167 -11
- package/dist/esm/managers/event.manager.js.map +1 -1
- package/dist/esm/managers/sender.manager.d.ts.map +1 -1
- package/dist/esm/managers/sender.manager.js +13 -1
- package/dist/esm/managers/sender.manager.js.map +1 -1
- package/dist/esm/types/config.types.d.ts +9 -0
- package/dist/esm/types/config.types.d.ts.map +1 -1
- package/dist/esm/types/config.types.js.map +1 -1
- package/dist/esm/types/event.types.d.ts +140 -16
- package/dist/esm/types/event.types.d.ts.map +1 -1
- package/dist/esm/types/event.types.js +23 -7
- package/dist/esm/types/event.types.js.map +1 -1
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/scroll.types.d.ts +16 -0
- package/dist/esm/types/scroll.types.d.ts.map +1 -0
- package/dist/esm/types/scroll.types.js +8 -0
- package/dist/esm/types/scroll.types.js.map +1 -0
- package/dist/esm/types/viewport.types.d.ts +55 -0
- package/dist/esm/types/viewport.types.d.ts.map +1 -0
- package/dist/esm/types/viewport.types.js +2 -0
- package/dist/esm/types/viewport.types.js.map +1 -0
- package/dist/esm/utils/validations/config-validations.utils.d.ts.map +1 -1
- package/dist/esm/utils/validations/config-validations.utils.js +92 -1
- package/dist/esm/utils/validations/config-validations.utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
const jt = 120, Yt = 8192, Kt = 10, qt = 10, Zt = 20, Jt = 1;
|
|
2
|
+
const er = 1e3, tr = 500, rr = 100;
|
|
3
|
+
const v = "data-tlog", Ue = [
|
|
4
4
|
"button",
|
|
5
5
|
"a",
|
|
6
6
|
'input[type="button"]',
|
|
@@ -32,7 +32,7 @@ const A = "data-tlog", Pe = [
|
|
|
32
32
|
".menu-item",
|
|
33
33
|
"[data-testid]",
|
|
34
34
|
'[tabindex="0"]'
|
|
35
|
-
],
|
|
35
|
+
], He = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], xe = [
|
|
36
36
|
"token",
|
|
37
37
|
"auth",
|
|
38
38
|
"key",
|
|
@@ -48,7 +48,7 @@ const A = "data-tlog", Pe = [
|
|
|
48
48
|
"code",
|
|
49
49
|
"otp"
|
|
50
50
|
];
|
|
51
|
-
const
|
|
51
|
+
const h = {
|
|
52
52
|
INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
|
|
53
53
|
INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
|
|
54
54
|
INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1",
|
|
@@ -58,8 +58,20 @@ const S = {
|
|
|
58
58
|
INVALID_GLOBAL_METADATA: "Global metadata must be an object",
|
|
59
59
|
INVALID_SENSITIVE_QUERY_PARAMS: "Sensitive query params must be an array of strings",
|
|
60
60
|
INVALID_PRIMARY_SCROLL_SELECTOR: "Primary scroll selector must be a non-empty string",
|
|
61
|
-
INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX: "Invalid CSS selector syntax for primaryScrollSelector"
|
|
62
|
-
|
|
61
|
+
INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX: "Invalid CSS selector syntax for primaryScrollSelector",
|
|
62
|
+
INVALID_PAGE_VIEW_THROTTLE: "Page view throttle must be a non-negative number",
|
|
63
|
+
INVALID_CLICK_THROTTLE: "Click throttle must be a non-negative number",
|
|
64
|
+
INVALID_MAX_SAME_EVENT_PER_MINUTE: "Max same event per minute must be a positive number",
|
|
65
|
+
INVALID_VIEWPORT_CONFIG: "Viewport config must be an object",
|
|
66
|
+
INVALID_VIEWPORT_ELEMENTS: "Viewport elements must be a non-empty array",
|
|
67
|
+
INVALID_VIEWPORT_ELEMENT: "Each viewport element must have a valid selector string",
|
|
68
|
+
INVALID_VIEWPORT_ELEMENT_ID: "Viewport element id must be a non-empty string",
|
|
69
|
+
INVALID_VIEWPORT_ELEMENT_NAME: "Viewport element name must be a non-empty string",
|
|
70
|
+
INVALID_VIEWPORT_THRESHOLD: "Viewport threshold must be a number between 0 and 1",
|
|
71
|
+
INVALID_VIEWPORT_MIN_DWELL_TIME: "Viewport minDwellTime must be a non-negative number",
|
|
72
|
+
INVALID_VIEWPORT_COOLDOWN_PERIOD: "Viewport cooldownPeriod must be a non-negative number",
|
|
73
|
+
INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS: "Viewport maxTrackedElements must be a positive number"
|
|
74
|
+
}, Fe = [
|
|
63
75
|
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
64
76
|
/javascript:/gi,
|
|
65
77
|
/on\w+\s*=/gi,
|
|
@@ -67,96 +79,95 @@ const S = {
|
|
|
67
79
|
/<embed\b[^>]*>/gi,
|
|
68
80
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
69
81
|
];
|
|
70
|
-
var
|
|
71
|
-
class
|
|
82
|
+
var q = /* @__PURE__ */ ((n) => (n.Localhost = "localhost:8080", n.Fail = "localhost:9999", n))(q || {}), w = /* @__PURE__ */ ((n) => (n.Mobile = "mobile", n.Tablet = "tablet", n.Desktop = "desktop", n.Unknown = "unknown", n))(w || {}), Z = /* @__PURE__ */ ((n) => (n.EVENT = "event", n.QUEUE = "queue", n))(Z || {});
|
|
83
|
+
class R extends Error {
|
|
72
84
|
constructor(e, t) {
|
|
73
|
-
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this,
|
|
85
|
+
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this, R);
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
|
-
var
|
|
77
|
-
function
|
|
78
|
-
return
|
|
88
|
+
var u = /* @__PURE__ */ ((n) => (n.PAGE_VIEW = "page_view", n.CLICK = "click", n.SCROLL = "scroll", n.SESSION_START = "session_start", n.SESSION_END = "session_end", n.CUSTOM = "custom", n.WEB_VITALS = "web_vitals", n.ERROR = "error", n.VIEWPORT_VISIBLE = "viewport_visible", n))(u || {}), H = /* @__PURE__ */ ((n) => (n.UP = "up", n.DOWN = "down", n))(H || {}), P = /* @__PURE__ */ ((n) => (n.JS_ERROR = "js_error", n.PROMISE_REJECTION = "promise_rejection", n))(P || {}), D = /* @__PURE__ */ ((n) => (n.QA = "qa", n))(D || {});
|
|
89
|
+
function nr(n) {
|
|
90
|
+
return n.type === u.SCROLL && "scroll_data" in n && n.scroll_data.is_primary === !0;
|
|
79
91
|
}
|
|
80
|
-
function
|
|
81
|
-
return
|
|
92
|
+
function sr(n) {
|
|
93
|
+
return n.type === u.SCROLL && "scroll_data" in n && n.scroll_data.is_primary === !1;
|
|
82
94
|
}
|
|
83
|
-
|
|
84
|
-
class O extends Error {
|
|
95
|
+
class V extends Error {
|
|
85
96
|
constructor(e, t, r) {
|
|
86
97
|
super(e), this.errorCode = t, this.layer = r, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
87
98
|
}
|
|
88
99
|
}
|
|
89
|
-
class
|
|
100
|
+
class E extends V {
|
|
90
101
|
constructor(e, t = "config") {
|
|
91
102
|
super(e, "APP_CONFIG_INVALID", t);
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
|
-
class
|
|
105
|
+
class Ge extends V {
|
|
95
106
|
constructor(e, t = "config") {
|
|
96
107
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
97
108
|
}
|
|
98
109
|
}
|
|
99
|
-
class
|
|
110
|
+
class he extends V {
|
|
100
111
|
constructor(e, t = "config") {
|
|
101
112
|
super(e, "SAMPLING_RATE_INVALID", t);
|
|
102
113
|
}
|
|
103
114
|
}
|
|
104
|
-
class
|
|
115
|
+
class M extends V {
|
|
105
116
|
constructor(e, t = "config") {
|
|
106
117
|
super(e, "INTEGRATION_INVALID", t);
|
|
107
118
|
}
|
|
108
119
|
}
|
|
109
|
-
class
|
|
120
|
+
class ir extends V {
|
|
110
121
|
constructor(e, t, r = "runtime") {
|
|
111
122
|
super(e, "INITIALIZATION_TIMEOUT", r), this.timeoutMs = t;
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
|
-
const
|
|
125
|
+
const We = (n, e) => {
|
|
115
126
|
if (e) {
|
|
116
127
|
if (e instanceof Error) {
|
|
117
128
|
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\(.*?:\d+:\d+\)/g, "");
|
|
118
|
-
return `[TraceLog] ${
|
|
119
|
-
}
|
|
120
|
-
return `[TraceLog] ${
|
|
121
|
-
}
|
|
122
|
-
return `[TraceLog] ${
|
|
123
|
-
},
|
|
124
|
-
const { error: r, data:
|
|
125
|
-
if (!(
|
|
126
|
-
if (
|
|
127
|
-
const c =
|
|
128
|
-
console[
|
|
129
|
-
} else
|
|
130
|
-
},
|
|
129
|
+
return `[TraceLog] ${n}: ${t}`;
|
|
130
|
+
}
|
|
131
|
+
return `[TraceLog] ${n}: ${e instanceof Error ? e.message : "Unknown error"}`;
|
|
132
|
+
}
|
|
133
|
+
return `[TraceLog] ${n}`;
|
|
134
|
+
}, a = (n, e, t) => {
|
|
135
|
+
const { error: r, data: s, showToClient: i = !1 } = t ?? {}, o = r ? We(e, r) : `[TraceLog] ${e}`, l = n === "error" ? "error" : n === "warn" ? "warn" : "log";
|
|
136
|
+
if (!(n === "debug" || n === "info" && !i))
|
|
137
|
+
if (s !== void 0) {
|
|
138
|
+
const c = Be(s);
|
|
139
|
+
console[l](o, c);
|
|
140
|
+
} else s !== void 0 ? console[l](o, s) : console[l](o);
|
|
141
|
+
}, Be = (n) => {
|
|
131
142
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
132
|
-
for (const [r,
|
|
143
|
+
for (const [r, s] of Object.entries(n)) {
|
|
133
144
|
const i = r.toLowerCase();
|
|
134
|
-
t.some((
|
|
145
|
+
t.some((o) => i.includes(o)) ? e[r] = "[REDACTED]" : e[r] = s;
|
|
135
146
|
}
|
|
136
147
|
return e;
|
|
137
148
|
};
|
|
138
|
-
let
|
|
139
|
-
const
|
|
140
|
-
typeof window < "u" && !
|
|
141
|
-
},
|
|
149
|
+
let J, we;
|
|
150
|
+
const Xe = () => {
|
|
151
|
+
typeof window < "u" && !J && (J = window.matchMedia("(pointer: coarse)"), we = window.matchMedia("(hover: none)"));
|
|
152
|
+
}, $e = () => {
|
|
142
153
|
try {
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
const e = window.innerWidth, t =
|
|
148
|
-
return e <= 767 ||
|
|
149
|
-
} catch (
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
},
|
|
154
|
+
const n = navigator;
|
|
155
|
+
if (n.userAgentData && typeof n.userAgentData.mobile == "boolean")
|
|
156
|
+
return n.userAgentData.platform && /ipad|tablet/i.test(n.userAgentData.platform) ? w.Tablet : n.userAgentData.mobile ? w.Mobile : w.Desktop;
|
|
157
|
+
Xe();
|
|
158
|
+
const e = window.innerWidth, t = J?.matches ?? !1, r = we?.matches ?? !1, s = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), l = /tablet|ipad|android(?!.*mobile)/.test(i);
|
|
159
|
+
return e <= 767 || o && s ? w.Mobile : e >= 768 && e <= 1024 || l || t && r && s ? w.Tablet : w.Desktop;
|
|
160
|
+
} catch (n) {
|
|
161
|
+
return a("warn", "Device detection failed, defaulting to desktop", { error: n }), w.Desktop;
|
|
162
|
+
}
|
|
163
|
+
}, y = "tlog", Ee = `${y}:qa_mode`, ze = `${y}:uid`, Qe = (n) => n ? `${y}:${n}:queue` : `${y}:queue`, je = (n) => n ? `${y}:${n}:session` : `${y}:session`, Ye = (n) => n ? `${y}:${n}:broadcast` : `${y}:broadcast`, ye = {
|
|
153
164
|
LCP: 4e3,
|
|
154
165
|
FCP: 1800,
|
|
155
166
|
CLS: 0.25,
|
|
156
167
|
INP: 200,
|
|
157
168
|
TTFB: 800,
|
|
158
169
|
LONG_TASK: 50
|
|
159
|
-
},
|
|
170
|
+
}, Ke = 1e3, le = [
|
|
160
171
|
// Email addresses
|
|
161
172
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
162
173
|
// US Phone numbers (various formats)
|
|
@@ -171,17 +182,17 @@ const Fe = () => {
|
|
|
171
182
|
/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,
|
|
172
183
|
// Passwords in connection strings (protocol://user:password@host)
|
|
173
184
|
/:\/\/[^:/]+:([^@]+)@/gi
|
|
174
|
-
], fe = 500, ge = 5e3,
|
|
175
|
-
if (sessionStorage.getItem(
|
|
185
|
+
], fe = 500, ge = 5e3, x = 50, qe = x * 2, Le = 1, Ze = 1e3, Je = 10, me = 5e3, et = 6e4, Se = "tlog_mode", tt = "qa", rt = () => {
|
|
186
|
+
if (sessionStorage.getItem(Ee) === "true")
|
|
176
187
|
return !0;
|
|
177
|
-
const e = new URLSearchParams(window.location.search), r = e.get(Se) ===
|
|
188
|
+
const e = new URLSearchParams(window.location.search), r = e.get(Se) === tt;
|
|
178
189
|
if (r) {
|
|
179
|
-
sessionStorage.setItem(
|
|
180
|
-
const
|
|
190
|
+
sessionStorage.setItem(Ee, "true"), e.delete(Se);
|
|
191
|
+
const s = e.toString(), i = `${window.location.pathname}${s ? "?" + s : ""}${window.location.hash}`;
|
|
181
192
|
try {
|
|
182
193
|
window.history.replaceState({}, "", i);
|
|
183
|
-
} catch (
|
|
184
|
-
|
|
194
|
+
} catch (o) {
|
|
195
|
+
a("warn", "History API not available, cannot replace URL", { error: o });
|
|
185
196
|
}
|
|
186
197
|
console.log(
|
|
187
198
|
"%c[TraceLog] QA Mode ACTIVE",
|
|
@@ -189,20 +200,20 @@ const Fe = () => {
|
|
|
189
200
|
);
|
|
190
201
|
}
|
|
191
202
|
return r;
|
|
192
|
-
},
|
|
193
|
-
const
|
|
194
|
-
return
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
203
|
+
}, _e = () => {
|
|
204
|
+
const n = new URLSearchParams(window.location.search), e = {};
|
|
205
|
+
return He.forEach((r) => {
|
|
206
|
+
const s = n.get(r);
|
|
207
|
+
if (s) {
|
|
197
208
|
const i = r.split("utm_")[1];
|
|
198
|
-
e[i] =
|
|
209
|
+
e[i] = s;
|
|
199
210
|
}
|
|
200
211
|
}), Object.keys(e).length ? e : void 0;
|
|
201
|
-
},
|
|
212
|
+
}, nt = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (n) => {
|
|
202
213
|
const e = Math.random() * 16 | 0;
|
|
203
|
-
return (
|
|
204
|
-
}),
|
|
205
|
-
const
|
|
214
|
+
return (n === "x" ? e : e & 3 | 8).toString(16);
|
|
215
|
+
}), st = () => {
|
|
216
|
+
const n = Date.now();
|
|
206
217
|
let e = "";
|
|
207
218
|
try {
|
|
208
219
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
@@ -211,169 +222,215 @@ const Fe = () => {
|
|
|
211
222
|
}
|
|
212
223
|
} catch {
|
|
213
224
|
}
|
|
214
|
-
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${
|
|
215
|
-
},
|
|
225
|
+
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${n}-${e}`;
|
|
226
|
+
}, Te = (n, e = !1) => {
|
|
216
227
|
try {
|
|
217
|
-
const t = new URL(
|
|
218
|
-
return r || e &&
|
|
228
|
+
const t = new URL(n), r = t.protocol === "https:", s = t.protocol === "http:";
|
|
229
|
+
return r || e && s;
|
|
219
230
|
} catch {
|
|
220
231
|
return !1;
|
|
221
232
|
}
|
|
222
|
-
},
|
|
223
|
-
if (
|
|
224
|
-
const
|
|
225
|
-
if (
|
|
233
|
+
}, it = (n) => {
|
|
234
|
+
if (n.integrations?.tracelog?.projectId) {
|
|
235
|
+
const s = new URL(window.location.href).hostname.split(".");
|
|
236
|
+
if (s.length === 0)
|
|
226
237
|
throw new Error("Invalid URL");
|
|
227
|
-
const i =
|
|
228
|
-
if (!
|
|
238
|
+
const i = n.integrations.tracelog.projectId, o = s.slice(-2).join("."), l = `https://${i}.${o}/collect`;
|
|
239
|
+
if (!Te(l))
|
|
229
240
|
throw new Error("Invalid URL");
|
|
230
|
-
return
|
|
241
|
+
return l;
|
|
231
242
|
}
|
|
232
|
-
const e =
|
|
243
|
+
const e = n.integrations?.custom?.collectApiUrl;
|
|
233
244
|
if (e) {
|
|
234
|
-
const t =
|
|
235
|
-
if (!
|
|
245
|
+
const t = n.integrations?.custom?.allowHttp ?? !1;
|
|
246
|
+
if (!Te(e, t))
|
|
236
247
|
throw new Error("Invalid URL");
|
|
237
248
|
return e;
|
|
238
249
|
}
|
|
239
250
|
return "";
|
|
240
|
-
},
|
|
251
|
+
}, ee = (n, e = []) => {
|
|
241
252
|
try {
|
|
242
|
-
const t = new URL(
|
|
253
|
+
const t = new URL(n), r = t.searchParams, s = [.../* @__PURE__ */ new Set([...xe, ...e])];
|
|
243
254
|
let i = !1;
|
|
244
|
-
const
|
|
245
|
-
return
|
|
246
|
-
r.has(c) && (r.delete(c), i = !0,
|
|
247
|
-
}), !i &&
|
|
255
|
+
const o = [];
|
|
256
|
+
return s.forEach((c) => {
|
|
257
|
+
r.has(c) && (r.delete(c), i = !0, o.push(c));
|
|
258
|
+
}), !i && n.includes("?") ? n : (t.search = r.toString(), t.toString());
|
|
248
259
|
} catch (t) {
|
|
249
|
-
return
|
|
260
|
+
return a("warn", "URL normalization failed, returning original", { error: t, data: { url: n.slice(0, 100) } }), n;
|
|
250
261
|
}
|
|
251
|
-
}, pe = (
|
|
252
|
-
if (!
|
|
262
|
+
}, pe = (n) => {
|
|
263
|
+
if (!n || typeof n != "string" || n.trim().length === 0)
|
|
253
264
|
return "";
|
|
254
|
-
let e =
|
|
255
|
-
|
|
265
|
+
let e = n;
|
|
266
|
+
n.length > 1e3 && (e = n.slice(0, Math.max(0, 1e3)));
|
|
256
267
|
let t = 0;
|
|
257
|
-
for (const
|
|
268
|
+
for (const s of Fe) {
|
|
258
269
|
const i = e;
|
|
259
|
-
e = e.replace(
|
|
270
|
+
e = e.replace(s, ""), i !== e && t++;
|
|
260
271
|
}
|
|
261
|
-
return t > 0 &&
|
|
272
|
+
return t > 0 && a("warn", "XSS patterns detected and removed", {
|
|
262
273
|
data: {
|
|
263
274
|
patternMatches: t,
|
|
264
|
-
originalValue:
|
|
275
|
+
originalValue: n.slice(0, 100)
|
|
265
276
|
}
|
|
266
277
|
}), e = e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'").replaceAll("/", "/"), e.trim();
|
|
267
|
-
},
|
|
268
|
-
if (e > 3 ||
|
|
278
|
+
}, te = (n, e = 0) => {
|
|
279
|
+
if (e > 3 || n == null)
|
|
269
280
|
return null;
|
|
270
|
-
if (typeof
|
|
271
|
-
return pe(
|
|
272
|
-
if (typeof
|
|
273
|
-
return !Number.isFinite(
|
|
274
|
-
if (typeof
|
|
275
|
-
return
|
|
276
|
-
if (Array.isArray(
|
|
277
|
-
return
|
|
278
|
-
if (typeof
|
|
279
|
-
const t = {},
|
|
280
|
-
for (const [i,
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
const c =
|
|
284
|
-
c !== null && (t[
|
|
281
|
+
if (typeof n == "string")
|
|
282
|
+
return pe(n);
|
|
283
|
+
if (typeof n == "number")
|
|
284
|
+
return !Number.isFinite(n) || n < -Number.MAX_SAFE_INTEGER || n > Number.MAX_SAFE_INTEGER ? 0 : n;
|
|
285
|
+
if (typeof n == "boolean")
|
|
286
|
+
return n;
|
|
287
|
+
if (Array.isArray(n))
|
|
288
|
+
return n.slice(0, 100).map((s) => te(s, e + 1)).filter((s) => s !== null);
|
|
289
|
+
if (typeof n == "object") {
|
|
290
|
+
const t = {}, s = Object.entries(n).slice(0, 20);
|
|
291
|
+
for (const [i, o] of s) {
|
|
292
|
+
const l = pe(i);
|
|
293
|
+
if (l) {
|
|
294
|
+
const c = te(o, e + 1);
|
|
295
|
+
c !== null && (t[l] = c);
|
|
285
296
|
}
|
|
286
297
|
}
|
|
287
298
|
return t;
|
|
288
299
|
}
|
|
289
300
|
return null;
|
|
290
|
-
},
|
|
291
|
-
if (typeof
|
|
301
|
+
}, ot = (n) => {
|
|
302
|
+
if (typeof n != "object" || n === null)
|
|
292
303
|
return {};
|
|
293
304
|
try {
|
|
294
|
-
const e =
|
|
305
|
+
const e = te(n);
|
|
295
306
|
return typeof e == "object" && e !== null ? e : {};
|
|
296
307
|
} catch (e) {
|
|
297
308
|
const t = e instanceof Error ? e.message : String(e);
|
|
298
309
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
299
310
|
}
|
|
300
|
-
},
|
|
301
|
-
if (
|
|
302
|
-
throw new
|
|
303
|
-
if (
|
|
304
|
-
if (
|
|
305
|
-
throw new
|
|
306
|
-
if (
|
|
307
|
-
throw new
|
|
308
|
-
if (
|
|
309
|
-
if (!Array.isArray(
|
|
310
|
-
throw new
|
|
311
|
-
for (const e of
|
|
311
|
+
}, at = (n) => {
|
|
312
|
+
if (n !== void 0 && (n === null || typeof n != "object"))
|
|
313
|
+
throw new E("Configuration must be an object", "config");
|
|
314
|
+
if (n) {
|
|
315
|
+
if (n.sessionTimeout !== void 0 && (typeof n.sessionTimeout != "number" || n.sessionTimeout < 3e4 || n.sessionTimeout > 864e5))
|
|
316
|
+
throw new Ge(h.INVALID_SESSION_TIMEOUT, "config");
|
|
317
|
+
if (n.globalMetadata !== void 0 && (typeof n.globalMetadata != "object" || n.globalMetadata === null))
|
|
318
|
+
throw new E(h.INVALID_GLOBAL_METADATA, "config");
|
|
319
|
+
if (n.integrations && ct(n.integrations), n.sensitiveQueryParams !== void 0) {
|
|
320
|
+
if (!Array.isArray(n.sensitiveQueryParams))
|
|
321
|
+
throw new E(h.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
322
|
+
for (const e of n.sensitiveQueryParams)
|
|
312
323
|
if (typeof e != "string")
|
|
313
|
-
throw new
|
|
314
|
-
}
|
|
315
|
-
if (
|
|
316
|
-
throw new
|
|
317
|
-
if (
|
|
318
|
-
throw new
|
|
319
|
-
if (
|
|
320
|
-
if (typeof
|
|
321
|
-
throw new
|
|
322
|
-
if (
|
|
324
|
+
throw new E("All sensitive query params must be strings", "config");
|
|
325
|
+
}
|
|
326
|
+
if (n.errorSampling !== void 0 && (typeof n.errorSampling != "number" || n.errorSampling < 0 || n.errorSampling > 1))
|
|
327
|
+
throw new he(h.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
328
|
+
if (n.samplingRate !== void 0 && (typeof n.samplingRate != "number" || n.samplingRate < 0 || n.samplingRate > 1))
|
|
329
|
+
throw new he(h.INVALID_SAMPLING_RATE, "config");
|
|
330
|
+
if (n.primaryScrollSelector !== void 0) {
|
|
331
|
+
if (typeof n.primaryScrollSelector != "string" || !n.primaryScrollSelector.trim())
|
|
332
|
+
throw new E(h.INVALID_PRIMARY_SCROLL_SELECTOR, "config");
|
|
333
|
+
if (n.primaryScrollSelector !== "window")
|
|
323
334
|
try {
|
|
324
|
-
document.querySelector(
|
|
335
|
+
document.querySelector(n.primaryScrollSelector);
|
|
325
336
|
} catch {
|
|
326
|
-
throw new
|
|
327
|
-
`${
|
|
337
|
+
throw new E(
|
|
338
|
+
`${h.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${n.primaryScrollSelector}"`,
|
|
328
339
|
"config"
|
|
329
340
|
);
|
|
330
341
|
}
|
|
331
342
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
+
if (n.pageViewThrottleMs !== void 0 && (typeof n.pageViewThrottleMs != "number" || n.pageViewThrottleMs < 0))
|
|
344
|
+
throw new E(h.INVALID_PAGE_VIEW_THROTTLE, "config");
|
|
345
|
+
if (n.clickThrottleMs !== void 0 && (typeof n.clickThrottleMs != "number" || n.clickThrottleMs < 0))
|
|
346
|
+
throw new E(h.INVALID_CLICK_THROTTLE, "config");
|
|
347
|
+
if (n.maxSameEventPerMinute !== void 0 && (typeof n.maxSameEventPerMinute != "number" || n.maxSameEventPerMinute <= 0))
|
|
348
|
+
throw new E(h.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
349
|
+
n.viewport !== void 0 && lt(n.viewport);
|
|
350
|
+
}
|
|
351
|
+
}, lt = (n) => {
|
|
352
|
+
if (typeof n != "object" || n === null)
|
|
353
|
+
throw new E(h.INVALID_VIEWPORT_CONFIG, "config");
|
|
354
|
+
if (!n.elements || !Array.isArray(n.elements))
|
|
355
|
+
throw new E(h.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
356
|
+
if (n.elements.length === 0)
|
|
357
|
+
throw new E(h.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
358
|
+
const e = /* @__PURE__ */ new Set();
|
|
359
|
+
for (const t of n.elements) {
|
|
360
|
+
if (!t.selector || typeof t.selector != "string" || !t.selector.trim())
|
|
361
|
+
throw new E(h.INVALID_VIEWPORT_ELEMENT, "config");
|
|
362
|
+
const r = t.selector.trim();
|
|
363
|
+
if (e.has(r))
|
|
364
|
+
throw new E(
|
|
365
|
+
`Duplicate viewport selector found: "${r}". Each selector should appear only once.`,
|
|
366
|
+
"config"
|
|
367
|
+
);
|
|
368
|
+
if (e.add(r), t.id !== void 0 && (typeof t.id != "string" || !t.id.trim()))
|
|
369
|
+
throw new E(h.INVALID_VIEWPORT_ELEMENT_ID, "config");
|
|
370
|
+
if (t.name !== void 0 && (typeof t.name != "string" || !t.name.trim()))
|
|
371
|
+
throw new E(h.INVALID_VIEWPORT_ELEMENT_NAME, "config");
|
|
372
|
+
}
|
|
373
|
+
if (n.threshold !== void 0 && (typeof n.threshold != "number" || n.threshold < 0 || n.threshold > 1))
|
|
374
|
+
throw new E(h.INVALID_VIEWPORT_THRESHOLD, "config");
|
|
375
|
+
if (n.minDwellTime !== void 0 && (typeof n.minDwellTime != "number" || n.minDwellTime < 0))
|
|
376
|
+
throw new E(h.INVALID_VIEWPORT_MIN_DWELL_TIME, "config");
|
|
377
|
+
if (n.cooldownPeriod !== void 0 && (typeof n.cooldownPeriod != "number" || n.cooldownPeriod < 0))
|
|
378
|
+
throw new E(h.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
379
|
+
if (n.maxTrackedElements !== void 0 && (typeof n.maxTrackedElements != "number" || n.maxTrackedElements <= 0))
|
|
380
|
+
throw new E(h.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
381
|
+
}, ct = (n) => {
|
|
382
|
+
if (n) {
|
|
383
|
+
if (n.tracelog && (!n.tracelog.projectId || typeof n.tracelog.projectId != "string" || n.tracelog.projectId.trim() === ""))
|
|
384
|
+
throw new M(h.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
385
|
+
if (n.custom) {
|
|
386
|
+
if (!n.custom.collectApiUrl || typeof n.custom.collectApiUrl != "string" || n.custom.collectApiUrl.trim() === "")
|
|
387
|
+
throw new M(h.INVALID_CUSTOM_API_URL, "config");
|
|
388
|
+
if (n.custom.allowHttp !== void 0 && typeof n.custom.allowHttp != "boolean")
|
|
389
|
+
throw new M("allowHttp must be a boolean", "config");
|
|
390
|
+
const e = n.custom.collectApiUrl.trim();
|
|
343
391
|
if (!e.startsWith("http://") && !e.startsWith("https://"))
|
|
344
|
-
throw new
|
|
345
|
-
if (!(
|
|
346
|
-
throw new
|
|
392
|
+
throw new M('Custom API URL must start with "http://" or "https://"', "config");
|
|
393
|
+
if (!(n.custom.allowHttp ?? !1) && e.startsWith("http://"))
|
|
394
|
+
throw new M(
|
|
347
395
|
"Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
|
|
348
396
|
"config"
|
|
349
397
|
);
|
|
350
398
|
}
|
|
351
|
-
if (
|
|
352
|
-
if (!
|
|
353
|
-
throw new
|
|
354
|
-
if (!
|
|
355
|
-
throw new
|
|
399
|
+
if (n.googleAnalytics) {
|
|
400
|
+
if (!n.googleAnalytics.measurementId || typeof n.googleAnalytics.measurementId != "string" || n.googleAnalytics.measurementId.trim() === "")
|
|
401
|
+
throw new M(h.INVALID_GOOGLE_ANALYTICS_ID, "config");
|
|
402
|
+
if (!n.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))
|
|
403
|
+
throw new M('Google Analytics measurement ID must start with "G-" or "UA-"', "config");
|
|
356
404
|
}
|
|
357
405
|
}
|
|
358
|
-
},
|
|
359
|
-
|
|
406
|
+
}, ut = (n) => {
|
|
407
|
+
at(n);
|
|
360
408
|
const e = {
|
|
361
|
-
...
|
|
362
|
-
sessionTimeout:
|
|
363
|
-
globalMetadata:
|
|
364
|
-
sensitiveQueryParams:
|
|
365
|
-
errorSampling:
|
|
366
|
-
samplingRate:
|
|
409
|
+
...n ?? {},
|
|
410
|
+
sessionTimeout: n?.sessionTimeout ?? 9e5,
|
|
411
|
+
globalMetadata: n?.globalMetadata ?? {},
|
|
412
|
+
sensitiveQueryParams: n?.sensitiveQueryParams ?? [],
|
|
413
|
+
errorSampling: n?.errorSampling ?? Le,
|
|
414
|
+
samplingRate: n?.samplingRate ?? 1,
|
|
415
|
+
pageViewThrottleMs: n?.pageViewThrottleMs ?? 1e3,
|
|
416
|
+
clickThrottleMs: n?.clickThrottleMs ?? 300,
|
|
417
|
+
maxSameEventPerMinute: n?.maxSameEventPerMinute ?? 60
|
|
367
418
|
};
|
|
368
419
|
return e.integrations?.custom && (e.integrations.custom = {
|
|
369
420
|
...e.integrations.custom,
|
|
370
421
|
allowHttp: e.integrations.custom.allowHttp ?? !1
|
|
422
|
+
}), e.viewport && (e.viewport = {
|
|
423
|
+
...e.viewport,
|
|
424
|
+
threshold: e.viewport.threshold ?? 0.5,
|
|
425
|
+
minDwellTime: e.viewport.minDwellTime ?? 2e3,
|
|
426
|
+
cooldownPeriod: e.viewport.cooldownPeriod ?? 6e4,
|
|
427
|
+
maxTrackedElements: e.viewport.maxTrackedElements ?? 100
|
|
371
428
|
}), e;
|
|
372
|
-
},
|
|
373
|
-
if (typeof
|
|
429
|
+
}, dt = (n) => {
|
|
430
|
+
if (typeof n == "string")
|
|
374
431
|
return !0;
|
|
375
|
-
if (typeof
|
|
376
|
-
const e = Object.entries(
|
|
432
|
+
if (typeof n == "object" && n !== null && !Array.isArray(n)) {
|
|
433
|
+
const e = Object.entries(n);
|
|
377
434
|
if (e.length > 20)
|
|
378
435
|
return !1;
|
|
379
436
|
for (const [, t] of e) {
|
|
@@ -386,10 +443,10 @@ const Fe = () => {
|
|
|
386
443
|
return !0;
|
|
387
444
|
}
|
|
388
445
|
return !1;
|
|
389
|
-
},
|
|
390
|
-
if (typeof
|
|
446
|
+
}, Me = (n, e = 0) => {
|
|
447
|
+
if (typeof n != "object" || n === null || e > 1)
|
|
391
448
|
return !1;
|
|
392
|
-
for (const t of Object.values(
|
|
449
|
+
for (const t of Object.values(n)) {
|
|
393
450
|
if (t == null)
|
|
394
451
|
continue;
|
|
395
452
|
const r = typeof t;
|
|
@@ -398,14 +455,14 @@ const Fe = () => {
|
|
|
398
455
|
if (t.length === 0)
|
|
399
456
|
continue;
|
|
400
457
|
if (typeof t[0] == "string") {
|
|
401
|
-
if (!t.every((
|
|
458
|
+
if (!t.every((o) => typeof o == "string"))
|
|
402
459
|
return !1;
|
|
403
|
-
} else if (!t.every((
|
|
460
|
+
} else if (!t.every((o) => dt(o)))
|
|
404
461
|
return !1;
|
|
405
462
|
continue;
|
|
406
463
|
}
|
|
407
464
|
if (r === "object" && e === 0) {
|
|
408
|
-
if (!
|
|
465
|
+
if (!Me(t, e + 1))
|
|
409
466
|
return !1;
|
|
410
467
|
continue;
|
|
411
468
|
}
|
|
@@ -413,27 +470,27 @@ const Fe = () => {
|
|
|
413
470
|
}
|
|
414
471
|
}
|
|
415
472
|
return !0;
|
|
416
|
-
},
|
|
473
|
+
}, ht = (n) => typeof n != "string" ? {
|
|
417
474
|
valid: !1,
|
|
418
475
|
error: "Event name must be a string"
|
|
419
|
-
} :
|
|
476
|
+
} : n.length === 0 ? {
|
|
420
477
|
valid: !1,
|
|
421
478
|
error: "Event name cannot be empty"
|
|
422
|
-
} :
|
|
479
|
+
} : n.length > 120 ? {
|
|
423
480
|
valid: !1,
|
|
424
481
|
error: "Event name is too long (max 120 characters)"
|
|
425
|
-
} :
|
|
482
|
+
} : n.includes("<") || n.includes(">") || n.includes("&") ? {
|
|
426
483
|
valid: !1,
|
|
427
484
|
error: "Event name contains invalid characters"
|
|
428
|
-
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(
|
|
485
|
+
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(n.toLowerCase()) ? {
|
|
429
486
|
valid: !1,
|
|
430
487
|
error: "Event name cannot be a reserved word"
|
|
431
|
-
} : { valid: !0 },
|
|
432
|
-
const r =
|
|
433
|
-
if (!
|
|
488
|
+
} : { valid: !0 }, Ie = (n, e, t) => {
|
|
489
|
+
const r = ot(e), s = `${t} "${n}" metadata error`;
|
|
490
|
+
if (!Me(r))
|
|
434
491
|
return {
|
|
435
492
|
valid: !1,
|
|
436
|
-
error: `${
|
|
493
|
+
error: `${s}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
437
494
|
};
|
|
438
495
|
let i;
|
|
439
496
|
try {
|
|
@@ -441,86 +498,86 @@ const Fe = () => {
|
|
|
441
498
|
} catch {
|
|
442
499
|
return {
|
|
443
500
|
valid: !1,
|
|
444
|
-
error: `${
|
|
501
|
+
error: `${s}: object contains circular references or cannot be serialized.`
|
|
445
502
|
};
|
|
446
503
|
}
|
|
447
504
|
if (i.length > 8192)
|
|
448
505
|
return {
|
|
449
506
|
valid: !1,
|
|
450
|
-
error: `${
|
|
507
|
+
error: `${s}: object is too large (max ${8192 / 1024} KB).`
|
|
451
508
|
};
|
|
452
509
|
if (Object.keys(r).length > 10)
|
|
453
510
|
return {
|
|
454
511
|
valid: !1,
|
|
455
|
-
error: `${
|
|
512
|
+
error: `${s}: object has too many keys (max 10 keys).`
|
|
456
513
|
};
|
|
457
|
-
for (const [
|
|
514
|
+
for (const [l, c] of Object.entries(r)) {
|
|
458
515
|
if (Array.isArray(c)) {
|
|
459
516
|
if (c.length > 10)
|
|
460
517
|
return {
|
|
461
518
|
valid: !1,
|
|
462
|
-
error: `${
|
|
519
|
+
error: `${s}: array property "${l}" is too large (max 10 items).`
|
|
463
520
|
};
|
|
464
|
-
for (const
|
|
465
|
-
if (typeof
|
|
521
|
+
for (const d of c)
|
|
522
|
+
if (typeof d == "string" && d.length > 500)
|
|
466
523
|
return {
|
|
467
524
|
valid: !1,
|
|
468
|
-
error: `${
|
|
525
|
+
error: `${s}: array property "${l}" contains strings that are too long (max 500 characters).`
|
|
469
526
|
};
|
|
470
527
|
}
|
|
471
528
|
if (typeof c == "string" && c.length > 1e3)
|
|
472
529
|
return {
|
|
473
530
|
valid: !1,
|
|
474
|
-
error: `${
|
|
531
|
+
error: `${s}: property "${l}" is too long (max 1000 characters).`
|
|
475
532
|
};
|
|
476
533
|
}
|
|
477
534
|
return {
|
|
478
535
|
valid: !0,
|
|
479
536
|
sanitizedMetadata: r
|
|
480
537
|
};
|
|
481
|
-
},
|
|
538
|
+
}, Et = (n, e, t) => {
|
|
482
539
|
if (Array.isArray(e)) {
|
|
483
|
-
const r = [],
|
|
540
|
+
const r = [], s = `${t} "${n}" metadata error`;
|
|
484
541
|
for (let i = 0; i < e.length; i++) {
|
|
485
|
-
const
|
|
486
|
-
if (typeof
|
|
542
|
+
const o = e[i];
|
|
543
|
+
if (typeof o != "object" || o === null || Array.isArray(o))
|
|
487
544
|
return {
|
|
488
545
|
valid: !1,
|
|
489
|
-
error: `${
|
|
546
|
+
error: `${s}: array item at index ${i} must be an object.`
|
|
490
547
|
};
|
|
491
|
-
const
|
|
492
|
-
if (!
|
|
548
|
+
const l = Ie(n, o, t);
|
|
549
|
+
if (!l.valid)
|
|
493
550
|
return {
|
|
494
551
|
valid: !1,
|
|
495
|
-
error: `${
|
|
552
|
+
error: `${s}: array item at index ${i} is invalid: ${l.error}`
|
|
496
553
|
};
|
|
497
|
-
|
|
554
|
+
l.sanitizedMetadata && r.push(l.sanitizedMetadata);
|
|
498
555
|
}
|
|
499
556
|
return {
|
|
500
557
|
valid: !0,
|
|
501
558
|
sanitizedMetadata: r
|
|
502
559
|
};
|
|
503
560
|
}
|
|
504
|
-
return
|
|
505
|
-
},
|
|
506
|
-
const t =
|
|
561
|
+
return Ie(n, e, t);
|
|
562
|
+
}, ft = (n, e) => {
|
|
563
|
+
const t = ht(n);
|
|
507
564
|
if (!t.valid)
|
|
508
|
-
return
|
|
565
|
+
return a("error", "Event name validation failed", {
|
|
509
566
|
showToClient: !0,
|
|
510
|
-
data: { eventName:
|
|
567
|
+
data: { eventName: n, error: t.error }
|
|
511
568
|
}), t;
|
|
512
569
|
if (!e)
|
|
513
570
|
return { valid: !0 };
|
|
514
|
-
const r =
|
|
515
|
-
return r.valid ||
|
|
571
|
+
const r = Et(n, e, "customEvent");
|
|
572
|
+
return r.valid || a("error", "Event metadata validation failed", {
|
|
516
573
|
showToClient: !0,
|
|
517
574
|
data: {
|
|
518
|
-
eventName:
|
|
575
|
+
eventName: n,
|
|
519
576
|
error: r.error
|
|
520
577
|
}
|
|
521
578
|
}), r;
|
|
522
579
|
};
|
|
523
|
-
class
|
|
580
|
+
class gt {
|
|
524
581
|
listeners = /* @__PURE__ */ new Map();
|
|
525
582
|
on(e, t) {
|
|
526
583
|
this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
|
|
@@ -528,14 +585,14 @@ class lt {
|
|
|
528
585
|
off(e, t) {
|
|
529
586
|
const r = this.listeners.get(e);
|
|
530
587
|
if (r) {
|
|
531
|
-
const
|
|
532
|
-
|
|
588
|
+
const s = r.indexOf(t);
|
|
589
|
+
s > -1 && r.splice(s, 1);
|
|
533
590
|
}
|
|
534
591
|
}
|
|
535
592
|
emit(e, t) {
|
|
536
593
|
const r = this.listeners.get(e);
|
|
537
|
-
r && r.forEach((
|
|
538
|
-
|
|
594
|
+
r && r.forEach((s) => {
|
|
595
|
+
s(t);
|
|
539
596
|
});
|
|
540
597
|
}
|
|
541
598
|
removeAllListeners() {
|
|
@@ -543,7 +600,7 @@ class lt {
|
|
|
543
600
|
}
|
|
544
601
|
}
|
|
545
602
|
const j = {};
|
|
546
|
-
class
|
|
603
|
+
class S {
|
|
547
604
|
get(e) {
|
|
548
605
|
return j[e];
|
|
549
606
|
}
|
|
@@ -554,7 +611,7 @@ class g {
|
|
|
554
611
|
return { ...j };
|
|
555
612
|
}
|
|
556
613
|
}
|
|
557
|
-
class
|
|
614
|
+
class mt extends S {
|
|
558
615
|
storeManager;
|
|
559
616
|
lastPermanentErrorLog = null;
|
|
560
617
|
constructor(e) {
|
|
@@ -562,10 +619,10 @@ class ct extends g {
|
|
|
562
619
|
}
|
|
563
620
|
getQueueStorageKey() {
|
|
564
621
|
const e = this.get("userId") || "anonymous";
|
|
565
|
-
return
|
|
622
|
+
return Qe(e);
|
|
566
623
|
}
|
|
567
624
|
sendEventsQueueSync(e) {
|
|
568
|
-
return this.shouldSkipSend() ? !0 : this.get("config")?.integrations?.custom?.collectApiUrl ===
|
|
625
|
+
return this.shouldSkipSend() ? !0 : this.get("config")?.integrations?.custom?.collectApiUrl === q.Fail ? (a("warn", "Fail mode: simulating network failure (sync)", {
|
|
569
626
|
data: { events: e.events.length }
|
|
570
627
|
}), !1) : this.sendQueueSyncInternal(e);
|
|
571
628
|
}
|
|
@@ -574,7 +631,7 @@ class ct extends g {
|
|
|
574
631
|
const r = await this.send(e);
|
|
575
632
|
return r ? (this.clearPersistedEvents(), t?.onSuccess?.(e.events.length, e.events, e)) : (this.persistEvents(e), t?.onFailure?.()), r;
|
|
576
633
|
} catch (r) {
|
|
577
|
-
return r instanceof
|
|
634
|
+
return r instanceof R ? (this.logPermanentError("Permanent error, not retrying", r), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(e), t?.onFailure?.(), !1);
|
|
578
635
|
}
|
|
579
636
|
}
|
|
580
637
|
async recoverPersistedEvents(e) {
|
|
@@ -587,11 +644,11 @@ class ct extends g {
|
|
|
587
644
|
const r = this.createRecoveryBody(t);
|
|
588
645
|
await this.send(r) ? (this.clearPersistedEvents(), e?.onSuccess?.(t.events.length, t.events, r)) : e?.onFailure?.();
|
|
589
646
|
} catch (t) {
|
|
590
|
-
if (t instanceof
|
|
647
|
+
if (t instanceof R) {
|
|
591
648
|
this.logPermanentError("Permanent error during recovery, clearing persisted events", t), this.clearPersistedEvents(), e?.onFailure?.();
|
|
592
649
|
return;
|
|
593
650
|
}
|
|
594
|
-
|
|
651
|
+
a("error", "Failed to recover persisted events", { error: t });
|
|
595
652
|
}
|
|
596
653
|
}
|
|
597
654
|
stop() {
|
|
@@ -599,17 +656,17 @@ class ct extends g {
|
|
|
599
656
|
async send(e) {
|
|
600
657
|
if (this.shouldSkipSend())
|
|
601
658
|
return this.simulateSuccessfulSend();
|
|
602
|
-
if (this.get("config")?.integrations?.custom?.collectApiUrl ===
|
|
603
|
-
return
|
|
659
|
+
if (this.get("config")?.integrations?.custom?.collectApiUrl === q.Fail)
|
|
660
|
+
return a("warn", "Fail mode: simulating network failure", {
|
|
604
661
|
data: { events: e.events.length }
|
|
605
662
|
}), !1;
|
|
606
|
-
const { url: r, payload:
|
|
663
|
+
const { url: r, payload: s } = this.prepareRequest(e);
|
|
607
664
|
try {
|
|
608
|
-
return (await this.sendWithTimeout(r,
|
|
665
|
+
return (await this.sendWithTimeout(r, s)).ok;
|
|
609
666
|
} catch (i) {
|
|
610
|
-
if (i instanceof
|
|
667
|
+
if (i instanceof R)
|
|
611
668
|
throw i;
|
|
612
|
-
return
|
|
669
|
+
return a("error", "Send request failed", {
|
|
613
670
|
error: i,
|
|
614
671
|
data: {
|
|
615
672
|
events: e.events.length,
|
|
@@ -619,7 +676,7 @@ class ct extends g {
|
|
|
619
676
|
}
|
|
620
677
|
}
|
|
621
678
|
async sendWithTimeout(e, t) {
|
|
622
|
-
const r = new AbortController(),
|
|
679
|
+
const r = new AbortController(), s = setTimeout(() => {
|
|
623
680
|
r.abort();
|
|
624
681
|
}, 1e4);
|
|
625
682
|
try {
|
|
@@ -634,18 +691,27 @@ class ct extends g {
|
|
|
634
691
|
}
|
|
635
692
|
});
|
|
636
693
|
if (!i.ok)
|
|
637
|
-
throw i.status >= 400 && i.status < 500 ? new
|
|
694
|
+
throw i.status >= 400 && i.status < 500 ? new R(`HTTP ${i.status}: ${i.statusText}`, i.status) : new Error(`HTTP ${i.status}: ${i.statusText}`);
|
|
638
695
|
return i;
|
|
639
696
|
} finally {
|
|
640
|
-
clearTimeout(
|
|
697
|
+
clearTimeout(s);
|
|
641
698
|
}
|
|
642
699
|
}
|
|
643
700
|
sendQueueSyncInternal(e) {
|
|
644
|
-
const { url: t, payload: r } = this.prepareRequest(e)
|
|
701
|
+
const { url: t, payload: r } = this.prepareRequest(e);
|
|
702
|
+
if (r.length > 65536)
|
|
703
|
+
return a("warn", "Payload exceeds sendBeacon limit, persisting for recovery", {
|
|
704
|
+
data: {
|
|
705
|
+
size: r.length,
|
|
706
|
+
limit: 65536,
|
|
707
|
+
events: e.events.length
|
|
708
|
+
}
|
|
709
|
+
}), this.persistEvents(e), !1;
|
|
710
|
+
const s = new Blob([r], { type: "application/json" });
|
|
645
711
|
if (!this.isSendBeaconAvailable())
|
|
646
|
-
return
|
|
647
|
-
const i = navigator.sendBeacon(t,
|
|
648
|
-
return i || (
|
|
712
|
+
return a("warn", "sendBeacon not available, persisting events for recovery"), this.persistEvents(e), !1;
|
|
713
|
+
const i = navigator.sendBeacon(t, s);
|
|
714
|
+
return i || (a("warn", "sendBeacon rejected request, persisting events for recovery"), this.persistEvents(e)), i;
|
|
649
715
|
}
|
|
650
716
|
prepareRequest(e) {
|
|
651
717
|
const t = {
|
|
@@ -666,7 +732,7 @@ class ct extends g {
|
|
|
666
732
|
if (t)
|
|
667
733
|
return JSON.parse(t);
|
|
668
734
|
} catch (e) {
|
|
669
|
-
|
|
735
|
+
a("warn", "Failed to parse persisted data", { error: e }), this.clearPersistedEvents();
|
|
670
736
|
}
|
|
671
737
|
return null;
|
|
672
738
|
}
|
|
@@ -694,7 +760,7 @@ class ct extends g {
|
|
|
694
760
|
}, r = this.getQueueStorageKey();
|
|
695
761
|
return this.storeManager.setItem(r, JSON.stringify(t)), !!this.storeManager.getItem(r);
|
|
696
762
|
} catch (t) {
|
|
697
|
-
return
|
|
763
|
+
return a("warn", "Failed to persist events", { error: t }), !1;
|
|
698
764
|
}
|
|
699
765
|
}
|
|
700
766
|
clearPersistedEvents() {
|
|
@@ -702,7 +768,7 @@ class ct extends g {
|
|
|
702
768
|
const e = this.getQueueStorageKey();
|
|
703
769
|
this.storeManager.removeItem(e);
|
|
704
770
|
} catch (e) {
|
|
705
|
-
|
|
771
|
+
a("warn", "Failed to clear persisted events", { error: e });
|
|
706
772
|
}
|
|
707
773
|
}
|
|
708
774
|
shouldSkipSend() {
|
|
@@ -717,35 +783,45 @@ class ct extends g {
|
|
|
717
783
|
}
|
|
718
784
|
logPermanentError(e, t) {
|
|
719
785
|
const r = Date.now();
|
|
720
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >=
|
|
786
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >= et) && (a("error", e, {
|
|
721
787
|
data: { status: t.statusCode, message: t.message }
|
|
722
788
|
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp: r });
|
|
723
789
|
}
|
|
724
790
|
}
|
|
725
|
-
class
|
|
791
|
+
class St extends S {
|
|
726
792
|
googleAnalytics;
|
|
727
793
|
dataSender;
|
|
728
794
|
emitter;
|
|
729
795
|
eventsQueue = [];
|
|
730
796
|
pendingEventsBuffer = [];
|
|
731
|
-
|
|
732
|
-
|
|
797
|
+
recentEventFingerprints = /* @__PURE__ */ new Map();
|
|
798
|
+
// Time-based deduplication cache
|
|
733
799
|
sendIntervalId = null;
|
|
734
800
|
rateLimitCounter = 0;
|
|
735
801
|
rateLimitWindowStart = 0;
|
|
802
|
+
perEventRateLimits = /* @__PURE__ */ new Map();
|
|
803
|
+
sessionEventCounts = {
|
|
804
|
+
total: 0,
|
|
805
|
+
[u.CLICK]: 0,
|
|
806
|
+
[u.PAGE_VIEW]: 0,
|
|
807
|
+
[u.CUSTOM]: 0,
|
|
808
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
809
|
+
[u.SCROLL]: 0
|
|
810
|
+
};
|
|
811
|
+
lastSessionId = null;
|
|
736
812
|
constructor(e, t = null, r = null) {
|
|
737
|
-
super(), this.googleAnalytics = t, this.dataSender = new
|
|
813
|
+
super(), this.googleAnalytics = t, this.dataSender = new mt(e), this.emitter = r;
|
|
738
814
|
}
|
|
739
815
|
async recoverPersistedEvents() {
|
|
740
816
|
await this.dataSender.recoverPersistedEvents({
|
|
741
817
|
onSuccess: (e, t, r) => {
|
|
742
818
|
if (t && t.length > 0) {
|
|
743
|
-
const
|
|
744
|
-
this.removeProcessedEvents(
|
|
819
|
+
const s = t.map((i) => i.id);
|
|
820
|
+
this.removeProcessedEvents(s), r && this.emitEventsQueue(r);
|
|
745
821
|
}
|
|
746
822
|
},
|
|
747
823
|
onFailure: () => {
|
|
748
|
-
|
|
824
|
+
a("warn", "Failed to recover persisted events");
|
|
749
825
|
}
|
|
750
826
|
});
|
|
751
827
|
}
|
|
@@ -753,76 +829,127 @@ class ut extends g {
|
|
|
753
829
|
type: e,
|
|
754
830
|
page_url: t,
|
|
755
831
|
from_page_url: r,
|
|
756
|
-
scroll_data:
|
|
832
|
+
scroll_data: s,
|
|
757
833
|
click_data: i,
|
|
758
|
-
custom_event:
|
|
759
|
-
web_vitals:
|
|
834
|
+
custom_event: o,
|
|
835
|
+
web_vitals: l,
|
|
760
836
|
error_data: c,
|
|
761
|
-
session_end_reason:
|
|
837
|
+
session_end_reason: d,
|
|
838
|
+
viewport_data: _
|
|
762
839
|
}) {
|
|
763
840
|
if (!e) {
|
|
764
|
-
|
|
841
|
+
a("error", "Event type is required - event will be ignored");
|
|
765
842
|
return;
|
|
766
843
|
}
|
|
767
|
-
|
|
768
|
-
|
|
844
|
+
const g = this.get("sessionId");
|
|
845
|
+
if (!g) {
|
|
846
|
+
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), a("warn", "Pending events buffer full - dropping oldest event", {
|
|
769
847
|
data: { maxBufferSize: 100 }
|
|
770
848
|
})), this.pendingEventsBuffer.push({
|
|
771
849
|
type: e,
|
|
772
850
|
page_url: t,
|
|
773
851
|
from_page_url: r,
|
|
774
|
-
scroll_data:
|
|
852
|
+
scroll_data: s,
|
|
775
853
|
click_data: i,
|
|
776
|
-
custom_event:
|
|
777
|
-
web_vitals:
|
|
854
|
+
custom_event: o,
|
|
855
|
+
web_vitals: l,
|
|
778
856
|
error_data: c,
|
|
779
|
-
session_end_reason:
|
|
857
|
+
session_end_reason: d,
|
|
858
|
+
viewport_data: _
|
|
780
859
|
});
|
|
781
860
|
return;
|
|
782
861
|
}
|
|
783
|
-
|
|
784
|
-
|
|
862
|
+
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = {
|
|
863
|
+
total: 0,
|
|
864
|
+
[u.CLICK]: 0,
|
|
865
|
+
[u.PAGE_VIEW]: 0,
|
|
866
|
+
[u.CUSTOM]: 0,
|
|
867
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
868
|
+
[u.SCROLL]: 0
|
|
869
|
+
});
|
|
870
|
+
const L = e === u.SESSION_START || e === u.SESSION_END;
|
|
871
|
+
if (!L && !this.checkRateLimit())
|
|
785
872
|
return;
|
|
786
|
-
const
|
|
787
|
-
|
|
788
|
-
|
|
873
|
+
const m = e;
|
|
874
|
+
if (!L) {
|
|
875
|
+
if (this.sessionEventCounts.total >= 1e3) {
|
|
876
|
+
a("warn", "Session event limit reached", {
|
|
877
|
+
data: {
|
|
878
|
+
type: m,
|
|
879
|
+
total: this.sessionEventCounts.total,
|
|
880
|
+
limit: 1e3
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
const A = this.getTypeLimitForEvent(m);
|
|
886
|
+
if (A) {
|
|
887
|
+
const Q = this.sessionEventCounts[m];
|
|
888
|
+
if (Q !== void 0 && Q >= A) {
|
|
889
|
+
a("warn", "Session event type limit reached", {
|
|
890
|
+
data: {
|
|
891
|
+
type: m,
|
|
892
|
+
count: Q,
|
|
893
|
+
limit: A
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
if (m === u.CUSTOM && o?.name) {
|
|
901
|
+
const A = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
902
|
+
if (!this.checkPerEventRateLimit(o.name, A))
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const Ve = m === u.SESSION_START, ke = t || this.get("pageUrl"), z = this.buildEventPayload({
|
|
906
|
+
type: m,
|
|
907
|
+
page_url: ke,
|
|
789
908
|
from_page_url: r,
|
|
790
|
-
scroll_data:
|
|
909
|
+
scroll_data: s,
|
|
791
910
|
click_data: i,
|
|
792
|
-
custom_event:
|
|
793
|
-
web_vitals:
|
|
911
|
+
custom_event: o,
|
|
912
|
+
web_vitals: l,
|
|
794
913
|
error_data: c,
|
|
795
|
-
session_end_reason:
|
|
914
|
+
session_end_reason: d,
|
|
915
|
+
viewport_data: _
|
|
796
916
|
});
|
|
797
|
-
if (!(!
|
|
798
|
-
if (
|
|
799
|
-
const
|
|
800
|
-
if (!
|
|
801
|
-
|
|
917
|
+
if (!(!L && !this.shouldSample())) {
|
|
918
|
+
if (Ve) {
|
|
919
|
+
const A = this.get("sessionId");
|
|
920
|
+
if (!A) {
|
|
921
|
+
a("error", "Session start event requires sessionId - event will be ignored");
|
|
802
922
|
return;
|
|
803
923
|
}
|
|
804
924
|
if (this.get("hasStartSession")) {
|
|
805
|
-
|
|
806
|
-
data: { sessionId:
|
|
925
|
+
a("warn", "Duplicate session_start detected", {
|
|
926
|
+
data: { sessionId: A }
|
|
807
927
|
});
|
|
808
928
|
return;
|
|
809
929
|
}
|
|
810
930
|
this.set("hasStartSession", !0);
|
|
811
931
|
}
|
|
812
|
-
if (!this.isDuplicateEvent(
|
|
813
|
-
if (this.get("mode") ===
|
|
932
|
+
if (!this.isDuplicateEvent(z)) {
|
|
933
|
+
if (this.get("mode") === D.QA && m === u.CUSTOM && o) {
|
|
814
934
|
console.log("[TraceLog] Event", {
|
|
815
|
-
name:
|
|
816
|
-
...
|
|
817
|
-
}), this.emitEvent(
|
|
935
|
+
name: o.name,
|
|
936
|
+
...o.metadata && { metadata: o.metadata }
|
|
937
|
+
}), this.emitEvent(z);
|
|
818
938
|
return;
|
|
819
939
|
}
|
|
820
|
-
this.addToQueue(
|
|
940
|
+
this.addToQueue(z), L || (this.sessionEventCounts.total++, this.sessionEventCounts[m] !== void 0 && this.sessionEventCounts[m]++);
|
|
821
941
|
}
|
|
822
942
|
}
|
|
823
943
|
}
|
|
824
944
|
stop() {
|
|
825
|
-
this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.pendingEventsBuffer = [], this.
|
|
945
|
+
this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
946
|
+
total: 0,
|
|
947
|
+
[u.CLICK]: 0,
|
|
948
|
+
[u.PAGE_VIEW]: 0,
|
|
949
|
+
[u.CUSTOM]: 0,
|
|
950
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
951
|
+
[u.SCROLL]: 0
|
|
952
|
+
}, this.lastSessionId = null, this.dataSender.stop();
|
|
826
953
|
}
|
|
827
954
|
async flushImmediately() {
|
|
828
955
|
return this.flushEvents(!1);
|
|
@@ -837,7 +964,7 @@ class ut extends g {
|
|
|
837
964
|
if (this.pendingEventsBuffer.length === 0)
|
|
838
965
|
return;
|
|
839
966
|
if (!this.get("sessionId")) {
|
|
840
|
-
|
|
967
|
+
a("warn", "Cannot flush pending events: session not initialized - keeping in buffer", {
|
|
841
968
|
data: { bufferedEventCount: this.pendingEventsBuffer.length }
|
|
842
969
|
});
|
|
843
970
|
return;
|
|
@@ -853,17 +980,17 @@ class ut extends g {
|
|
|
853
980
|
flushEvents(e) {
|
|
854
981
|
if (this.eventsQueue.length === 0)
|
|
855
982
|
return e ? !0 : Promise.resolve(!0);
|
|
856
|
-
const t = this.buildEventsPayload(), r = [...this.eventsQueue],
|
|
983
|
+
const t = this.buildEventsPayload(), r = [...this.eventsQueue], s = r.map((i) => i.id);
|
|
857
984
|
if (e) {
|
|
858
985
|
const i = this.dataSender.sendEventsQueueSync(t);
|
|
859
|
-
return i && (this.removeProcessedEvents(
|
|
986
|
+
return i && (this.removeProcessedEvents(s), this.clearSendInterval(), this.emitEventsQueue(t)), i;
|
|
860
987
|
} else
|
|
861
988
|
return this.dataSender.sendEventsQueue(t, {
|
|
862
989
|
onSuccess: () => {
|
|
863
|
-
this.removeProcessedEvents(
|
|
990
|
+
this.removeProcessedEvents(s), this.clearSendInterval(), this.emitEventsQueue(t);
|
|
864
991
|
},
|
|
865
992
|
onFailure: () => {
|
|
866
|
-
|
|
993
|
+
a("warn", "Async flush failed", {
|
|
867
994
|
data: { eventCount: r.length }
|
|
868
995
|
});
|
|
869
996
|
}
|
|
@@ -872,13 +999,13 @@ class ut extends g {
|
|
|
872
999
|
async sendEventsQueue() {
|
|
873
1000
|
if (!this.get("sessionId") || this.eventsQueue.length === 0)
|
|
874
1001
|
return;
|
|
875
|
-
const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((
|
|
1002
|
+
const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((s) => s.id);
|
|
876
1003
|
await this.dataSender.sendEventsQueue(e, {
|
|
877
1004
|
onSuccess: () => {
|
|
878
1005
|
this.removeProcessedEvents(r), this.emitEventsQueue(e);
|
|
879
1006
|
},
|
|
880
1007
|
onFailure: () => {
|
|
881
|
-
|
|
1008
|
+
a("warn", "Events send failed, keeping in queue", {
|
|
882
1009
|
data: { eventCount: t.length }
|
|
883
1010
|
});
|
|
884
1011
|
}
|
|
@@ -886,11 +1013,11 @@ class ut extends g {
|
|
|
886
1013
|
}
|
|
887
1014
|
buildEventsPayload() {
|
|
888
1015
|
const e = /* @__PURE__ */ new Map(), t = [];
|
|
889
|
-
for (const
|
|
890
|
-
const i = this.createEventSignature(
|
|
891
|
-
e.has(i) || t.push(i), e.set(i,
|
|
1016
|
+
for (const s of this.eventsQueue) {
|
|
1017
|
+
const i = this.createEventSignature(s);
|
|
1018
|
+
e.has(i) || t.push(i), e.set(i, s);
|
|
892
1019
|
}
|
|
893
|
-
const r = t.map((
|
|
1020
|
+
const r = t.map((s) => e.get(s)).filter((s) => !!s).sort((s, i) => s.timestamp - i.timestamp);
|
|
894
1021
|
return {
|
|
895
1022
|
user_id: this.get("userId"),
|
|
896
1023
|
session_id: this.get("sessionId"),
|
|
@@ -900,9 +1027,9 @@ class ut extends g {
|
|
|
900
1027
|
};
|
|
901
1028
|
}
|
|
902
1029
|
buildEventPayload(e) {
|
|
903
|
-
const t = e.type ===
|
|
1030
|
+
const t = e.type === u.SESSION_START, r = e.page_url ?? this.get("pageUrl");
|
|
904
1031
|
return {
|
|
905
|
-
id:
|
|
1032
|
+
id: st(),
|
|
906
1033
|
type: e.type,
|
|
907
1034
|
page_url: r,
|
|
908
1035
|
timestamp: Date.now(),
|
|
@@ -914,18 +1041,40 @@ class ut extends g {
|
|
|
914
1041
|
...e.web_vitals && { web_vitals: e.web_vitals },
|
|
915
1042
|
...e.error_data && { error_data: e.error_data },
|
|
916
1043
|
...e.session_end_reason && { session_end_reason: e.session_end_reason },
|
|
917
|
-
...
|
|
1044
|
+
...e.viewport_data && { viewport_data: e.viewport_data },
|
|
1045
|
+
...t && _e() && { utm: _e() }
|
|
918
1046
|
};
|
|
919
1047
|
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Checks if event is a duplicate using time-based cache
|
|
1050
|
+
* Tracks recent event fingerprints with timestamp-based cleanup
|
|
1051
|
+
*/
|
|
920
1052
|
isDuplicateEvent(e) {
|
|
921
|
-
const t = Date.now(), r = this.createEventFingerprint(e);
|
|
922
|
-
return
|
|
1053
|
+
const t = Date.now(), r = this.createEventFingerprint(e), s = this.recentEventFingerprints.get(r);
|
|
1054
|
+
return s && t - s < 500 ? (this.recentEventFingerprints.set(r, t), !0) : (this.recentEventFingerprints.set(r, t), this.recentEventFingerprints.size > 1e3 && this.pruneOldFingerprints(), this.recentEventFingerprints.size > 2e3 && (this.recentEventFingerprints.clear(), this.recentEventFingerprints.set(r, t), a("warn", "Event fingerprint cache exceeded hard limit, cleared", {
|
|
1055
|
+
data: { hardLimit: 2e3 }
|
|
1056
|
+
})), !1);
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Prunes old fingerprints from cache based on timestamp
|
|
1060
|
+
* Removes entries older than 10x the duplicate threshold (5 seconds)
|
|
1061
|
+
*/
|
|
1062
|
+
pruneOldFingerprints() {
|
|
1063
|
+
const e = Date.now(), t = 500 * 10;
|
|
1064
|
+
for (const [r, s] of this.recentEventFingerprints.entries())
|
|
1065
|
+
e - s > t && this.recentEventFingerprints.delete(r);
|
|
1066
|
+
a("debug", "Pruned old event fingerprints", {
|
|
1067
|
+
data: {
|
|
1068
|
+
remaining: this.recentEventFingerprints.size,
|
|
1069
|
+
cutoffMs: t
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
923
1072
|
}
|
|
924
1073
|
createEventFingerprint(e) {
|
|
925
1074
|
let t = `${e.type}_${e.page_url}`;
|
|
926
1075
|
if (e.click_data) {
|
|
927
|
-
const r = Math.round((e.click_data.x || 0) / 10) * 10,
|
|
928
|
-
t += `_click_${r}_${
|
|
1076
|
+
const r = Math.round((e.click_data.x || 0) / 10) * 10, s = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
1077
|
+
t += `_click_${r}_${s}`;
|
|
929
1078
|
}
|
|
930
1079
|
return e.scroll_data && (t += `_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`), e.custom_event && (t += `_custom_${e.custom_event.name}`), e.web_vitals && (t += `_vitals_${e.web_vitals.type}`), e.error_data && (t += `_error_${e.error_data.type}_${e.error_data.message}`), t;
|
|
931
1080
|
}
|
|
@@ -935,18 +1084,18 @@ class ut extends g {
|
|
|
935
1084
|
addToQueue(e) {
|
|
936
1085
|
if (this.eventsQueue.push(e), this.emitEvent(e), this.eventsQueue.length > 100) {
|
|
937
1086
|
const t = this.eventsQueue.findIndex(
|
|
938
|
-
(
|
|
1087
|
+
(s) => s.type !== u.SESSION_START && s.type !== u.SESSION_END
|
|
939
1088
|
), r = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
940
|
-
|
|
1089
|
+
a("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
941
1090
|
data: {
|
|
942
1091
|
maxLength: 100,
|
|
943
1092
|
currentLength: this.eventsQueue.length,
|
|
944
1093
|
removedEventType: r?.type,
|
|
945
|
-
wasCritical: r?.type ===
|
|
1094
|
+
wasCritical: r?.type === u.SESSION_START || r?.type === u.SESSION_END
|
|
946
1095
|
}
|
|
947
1096
|
});
|
|
948
1097
|
}
|
|
949
|
-
this.sendIntervalId || this.startSendInterval(), this.handleGoogleAnalyticsIntegration(e);
|
|
1098
|
+
this.sendIntervalId || this.startSendInterval(), this.eventsQueue.length >= 50 && this.sendEventsQueue(), this.handleGoogleAnalyticsIntegration(e);
|
|
950
1099
|
}
|
|
951
1100
|
startSendInterval() {
|
|
952
1101
|
this.sendIntervalId = window.setInterval(() => {
|
|
@@ -954,8 +1103,8 @@ class ut extends g {
|
|
|
954
1103
|
}, 1e4);
|
|
955
1104
|
}
|
|
956
1105
|
handleGoogleAnalyticsIntegration(e) {
|
|
957
|
-
if (this.googleAnalytics && e.type ===
|
|
958
|
-
if (this.get("mode") ===
|
|
1106
|
+
if (this.googleAnalytics && e.type === u.CUSTOM && e.custom_event) {
|
|
1107
|
+
if (this.get("mode") === D.QA)
|
|
959
1108
|
return;
|
|
960
1109
|
this.googleAnalytics.trackEvent(e.custom_event.name, e.custom_event.metadata ?? {});
|
|
961
1110
|
}
|
|
@@ -966,20 +1115,46 @@ class ut extends g {
|
|
|
966
1115
|
}
|
|
967
1116
|
checkRateLimit() {
|
|
968
1117
|
const e = Date.now();
|
|
969
|
-
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >=
|
|
1118
|
+
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 50 ? !1 : (this.rateLimitCounter++, !0);
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Checks per-event-name rate limiting to prevent infinite loops in user code
|
|
1122
|
+
* Tracks timestamps per event name and limits to maxSameEventPerMinute per minute
|
|
1123
|
+
*/
|
|
1124
|
+
checkPerEventRateLimit(e, t) {
|
|
1125
|
+
const r = Date.now(), i = (this.perEventRateLimits.get(e) ?? []).filter((o) => r - o < 6e4);
|
|
1126
|
+
return i.length >= t ? (a("warn", "Per-event rate limit exceeded for custom event", {
|
|
1127
|
+
data: {
|
|
1128
|
+
eventName: e,
|
|
1129
|
+
limit: t,
|
|
1130
|
+
window: `${6e4 / 1e3}s`
|
|
1131
|
+
}
|
|
1132
|
+
}), !1) : (i.push(r), this.perEventRateLimits.set(e, i), !0);
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Gets the per-session limit for a specific event type (Phase 3)
|
|
1136
|
+
*/
|
|
1137
|
+
getTypeLimitForEvent(e) {
|
|
1138
|
+
return {
|
|
1139
|
+
[u.CLICK]: 500,
|
|
1140
|
+
[u.PAGE_VIEW]: 100,
|
|
1141
|
+
[u.CUSTOM]: 500,
|
|
1142
|
+
[u.VIEWPORT_VISIBLE]: 200,
|
|
1143
|
+
[u.SCROLL]: 120
|
|
1144
|
+
}[e] ?? null;
|
|
970
1145
|
}
|
|
971
1146
|
removeProcessedEvents(e) {
|
|
972
1147
|
const t = new Set(e);
|
|
973
1148
|
this.eventsQueue = this.eventsQueue.filter((r) => !t.has(r.id));
|
|
974
1149
|
}
|
|
975
1150
|
emitEvent(e) {
|
|
976
|
-
this.emitter && this.emitter.emit(
|
|
1151
|
+
this.emitter && this.emitter.emit(Z.EVENT, e);
|
|
977
1152
|
}
|
|
978
1153
|
emitEventsQueue(e) {
|
|
979
|
-
this.emitter && this.emitter.emit(
|
|
1154
|
+
this.emitter && this.emitter.emit(Z.QUEUE, e);
|
|
980
1155
|
}
|
|
981
1156
|
}
|
|
982
|
-
class
|
|
1157
|
+
class _t {
|
|
983
1158
|
/**
|
|
984
1159
|
* Gets or creates a unique user ID for the given project.
|
|
985
1160
|
* The user ID is persisted in localStorage and reused across sessions.
|
|
@@ -989,14 +1164,14 @@ class dt {
|
|
|
989
1164
|
* @returns Persistent unique user ID
|
|
990
1165
|
*/
|
|
991
1166
|
static getId(e) {
|
|
992
|
-
const t =
|
|
1167
|
+
const t = ze, r = e.getItem(t);
|
|
993
1168
|
if (r)
|
|
994
1169
|
return r;
|
|
995
|
-
const
|
|
996
|
-
return e.setItem(t,
|
|
1170
|
+
const s = nt();
|
|
1171
|
+
return e.setItem(t, s), s;
|
|
997
1172
|
}
|
|
998
1173
|
}
|
|
999
|
-
class
|
|
1174
|
+
class Tt extends S {
|
|
1000
1175
|
storageManager;
|
|
1001
1176
|
eventManager;
|
|
1002
1177
|
projectId;
|
|
@@ -1011,18 +1186,18 @@ class ht extends g {
|
|
|
1011
1186
|
}
|
|
1012
1187
|
initCrossTabSync() {
|
|
1013
1188
|
if (typeof BroadcastChannel > "u") {
|
|
1014
|
-
|
|
1189
|
+
a("warn", "BroadcastChannel not supported");
|
|
1015
1190
|
return;
|
|
1016
1191
|
}
|
|
1017
1192
|
const e = this.getProjectId();
|
|
1018
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
1019
|
-
const { action: r, sessionId:
|
|
1020
|
-
if (
|
|
1193
|
+
this.broadcastChannel = new BroadcastChannel(Ye(e)), this.broadcastChannel.onmessage = (t) => {
|
|
1194
|
+
const { action: r, sessionId: s, timestamp: i, projectId: o } = t.data ?? {};
|
|
1195
|
+
if (o === e) {
|
|
1021
1196
|
if (r === "session_end") {
|
|
1022
1197
|
this.resetSessionState();
|
|
1023
1198
|
return;
|
|
1024
1199
|
}
|
|
1025
|
-
|
|
1200
|
+
s && typeof i == "number" && i > Date.now() - 5e3 && (this.set("sessionId", s), this.set("hasStartSession", !0), this.persistSession(s, i), this.isTracking && this.setupSessionTimeout());
|
|
1026
1201
|
}
|
|
1027
1202
|
};
|
|
1028
1203
|
}
|
|
@@ -1045,7 +1220,7 @@ class ht extends g {
|
|
|
1045
1220
|
timestamp: Date.now()
|
|
1046
1221
|
});
|
|
1047
1222
|
} catch (r) {
|
|
1048
|
-
|
|
1223
|
+
a("warn", "Failed to broadcast session end", { error: r, data: { sessionId: e, reason: t } });
|
|
1049
1224
|
}
|
|
1050
1225
|
}
|
|
1051
1226
|
cleanupCrossTabSync() {
|
|
@@ -1084,24 +1259,24 @@ class ht extends g {
|
|
|
1084
1259
|
this.storageManager.setItem(t, JSON.stringify(e));
|
|
1085
1260
|
}
|
|
1086
1261
|
getSessionStorageKey() {
|
|
1087
|
-
return
|
|
1262
|
+
return je(this.getProjectId());
|
|
1088
1263
|
}
|
|
1089
1264
|
getProjectId() {
|
|
1090
1265
|
return this.projectId;
|
|
1091
1266
|
}
|
|
1092
1267
|
startTracking() {
|
|
1093
1268
|
if (this.isTracking) {
|
|
1094
|
-
|
|
1269
|
+
a("warn", "Session tracking already active");
|
|
1095
1270
|
return;
|
|
1096
1271
|
}
|
|
1097
1272
|
const e = this.recoverSession(), t = e ?? this.generateSessionId(), r = !!e;
|
|
1098
1273
|
this.isTracking = !0;
|
|
1099
1274
|
try {
|
|
1100
1275
|
this.set("sessionId", t), this.persistSession(t), r || this.eventManager.track({
|
|
1101
|
-
type:
|
|
1276
|
+
type: u.SESSION_START
|
|
1102
1277
|
}), this.initCrossTabSync(), this.shareSession(t), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
1103
|
-
} catch (
|
|
1104
|
-
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null),
|
|
1278
|
+
} catch (s) {
|
|
1279
|
+
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), s;
|
|
1105
1280
|
}
|
|
1106
1281
|
}
|
|
1107
1282
|
generateSessionId() {
|
|
@@ -1143,13 +1318,13 @@ class ht extends g {
|
|
|
1143
1318
|
endSession(e) {
|
|
1144
1319
|
const t = this.get("sessionId");
|
|
1145
1320
|
if (!t) {
|
|
1146
|
-
|
|
1321
|
+
a("warn", "endSession called without active session", { data: { reason: e } }), this.resetSessionState(e);
|
|
1147
1322
|
return;
|
|
1148
1323
|
}
|
|
1149
1324
|
this.eventManager.track({
|
|
1150
|
-
type:
|
|
1325
|
+
type: u.SESSION_END,
|
|
1151
1326
|
session_end_reason: e
|
|
1152
|
-
}), this.eventManager.flushImmediatelySync() ||
|
|
1327
|
+
}), this.eventManager.flushImmediatelySync() || a("warn", "Sync flush failed during session end, events persisted for recovery", {
|
|
1153
1328
|
data: { reason: e, sessionId: t }
|
|
1154
1329
|
}), this.broadcastSessionEnd(t, e), this.resetSessionState(e);
|
|
1155
1330
|
}
|
|
@@ -1163,7 +1338,7 @@ class ht extends g {
|
|
|
1163
1338
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.set("hasStartSession", !1);
|
|
1164
1339
|
}
|
|
1165
1340
|
}
|
|
1166
|
-
class
|
|
1341
|
+
class pt extends S {
|
|
1167
1342
|
eventManager;
|
|
1168
1343
|
storageManager;
|
|
1169
1344
|
sessionManager = null;
|
|
@@ -1175,14 +1350,14 @@ class ft extends g {
|
|
|
1175
1350
|
if (this.isActive())
|
|
1176
1351
|
return;
|
|
1177
1352
|
if (this.destroyed) {
|
|
1178
|
-
|
|
1353
|
+
a("warn", "Cannot start tracking on destroyed handler");
|
|
1179
1354
|
return;
|
|
1180
1355
|
}
|
|
1181
1356
|
const e = this.get("config"), t = e?.integrations?.tracelog?.projectId ?? e?.integrations?.custom?.collectApiUrl ?? "default";
|
|
1182
1357
|
if (!t)
|
|
1183
1358
|
throw new Error("Cannot start session tracking: config not available");
|
|
1184
1359
|
try {
|
|
1185
|
-
this.sessionManager = new
|
|
1360
|
+
this.sessionManager = new Tt(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
1186
1361
|
} catch (r) {
|
|
1187
1362
|
if (this.sessionManager) {
|
|
1188
1363
|
try {
|
|
@@ -1191,7 +1366,7 @@ class ft extends g {
|
|
|
1191
1366
|
}
|
|
1192
1367
|
this.sessionManager = null;
|
|
1193
1368
|
}
|
|
1194
|
-
throw
|
|
1369
|
+
throw a("error", "Failed to start session tracking", { error: r }), r;
|
|
1195
1370
|
}
|
|
1196
1371
|
}
|
|
1197
1372
|
isActive() {
|
|
@@ -1207,11 +1382,12 @@ class ft extends g {
|
|
|
1207
1382
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0, this.set("hasStartSession", !1));
|
|
1208
1383
|
}
|
|
1209
1384
|
}
|
|
1210
|
-
class
|
|
1385
|
+
class It extends S {
|
|
1211
1386
|
eventManager;
|
|
1212
1387
|
onTrack;
|
|
1213
1388
|
originalPushState;
|
|
1214
1389
|
originalReplaceState;
|
|
1390
|
+
lastPageViewTime = 0;
|
|
1215
1391
|
constructor(e, t) {
|
|
1216
1392
|
super(), this.eventManager = e, this.onTrack = t;
|
|
1217
1393
|
}
|
|
@@ -1219,7 +1395,7 @@ class gt extends g {
|
|
|
1219
1395
|
this.trackInitialPageView(), window.addEventListener("popstate", this.trackCurrentPage, !0), window.addEventListener("hashchange", this.trackCurrentPage, !0), this.patchHistory("pushState"), this.patchHistory("replaceState");
|
|
1220
1396
|
}
|
|
1221
1397
|
stopTracking() {
|
|
1222
|
-
window.removeEventListener("popstate", this.trackCurrentPage, !0), window.removeEventListener("hashchange", this.trackCurrentPage, !0), this.originalPushState && (window.history.pushState = this.originalPushState), this.originalReplaceState && (window.history.replaceState = this.originalReplaceState);
|
|
1398
|
+
window.removeEventListener("popstate", this.trackCurrentPage, !0), window.removeEventListener("hashchange", this.trackCurrentPage, !0), this.originalPushState && (window.history.pushState = this.originalPushState), this.originalReplaceState && (window.history.replaceState = this.originalReplaceState), this.lastPageViewTime = 0;
|
|
1223
1399
|
}
|
|
1224
1400
|
patchHistory(e) {
|
|
1225
1401
|
const t = window.history[e];
|
|
@@ -1228,32 +1404,35 @@ class gt extends g {
|
|
|
1228
1404
|
};
|
|
1229
1405
|
}
|
|
1230
1406
|
trackCurrentPage = () => {
|
|
1231
|
-
const e = window.location.href, t =
|
|
1407
|
+
const e = window.location.href, t = ee(e, this.get("config").sensitiveQueryParams);
|
|
1232
1408
|
if (this.get("pageUrl") === t)
|
|
1233
1409
|
return;
|
|
1234
|
-
this.
|
|
1235
|
-
|
|
1410
|
+
const r = Date.now(), s = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
1411
|
+
if (r - this.lastPageViewTime < s)
|
|
1412
|
+
return;
|
|
1413
|
+
this.lastPageViewTime = r, this.onTrack();
|
|
1414
|
+
const i = this.get("pageUrl");
|
|
1236
1415
|
this.set("pageUrl", t);
|
|
1237
|
-
const
|
|
1416
|
+
const o = this.extractPageViewData();
|
|
1238
1417
|
this.eventManager.track({
|
|
1239
|
-
type:
|
|
1418
|
+
type: u.PAGE_VIEW,
|
|
1240
1419
|
page_url: this.get("pageUrl"),
|
|
1241
|
-
from_page_url:
|
|
1242
|
-
...
|
|
1420
|
+
from_page_url: i,
|
|
1421
|
+
...o && { page_view: o }
|
|
1243
1422
|
});
|
|
1244
1423
|
};
|
|
1245
1424
|
trackInitialPageView() {
|
|
1246
|
-
const e =
|
|
1247
|
-
this.eventManager.track({
|
|
1248
|
-
type:
|
|
1425
|
+
const e = ee(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
1426
|
+
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
1427
|
+
type: u.PAGE_VIEW,
|
|
1249
1428
|
page_url: e,
|
|
1250
1429
|
...t && { page_view: t }
|
|
1251
1430
|
}), this.onTrack();
|
|
1252
1431
|
}
|
|
1253
1432
|
extractPageViewData() {
|
|
1254
|
-
const { pathname: e, search: t, hash: r } = window.location, { referrer:
|
|
1255
|
-
return !
|
|
1256
|
-
...
|
|
1433
|
+
const { pathname: e, search: t, hash: r } = window.location, { referrer: s } = document, { title: i } = document;
|
|
1434
|
+
return !s && !i && !e && !t && !r ? void 0 : {
|
|
1435
|
+
...s && { referrer: s },
|
|
1257
1436
|
...i && { title: i },
|
|
1258
1437
|
...e && { pathname: e },
|
|
1259
1438
|
...t && { search: t },
|
|
@@ -1261,53 +1440,99 @@ class gt extends g {
|
|
|
1261
1440
|
};
|
|
1262
1441
|
}
|
|
1263
1442
|
}
|
|
1264
|
-
class
|
|
1443
|
+
class vt extends S {
|
|
1265
1444
|
eventManager;
|
|
1266
1445
|
clickHandler;
|
|
1446
|
+
lastClickTimes = /* @__PURE__ */ new Map();
|
|
1267
1447
|
constructor(e) {
|
|
1268
1448
|
super(), this.eventManager = e;
|
|
1269
1449
|
}
|
|
1270
1450
|
startTracking() {
|
|
1271
1451
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
1272
|
-
const t = e, r = t.target,
|
|
1273
|
-
if (!
|
|
1274
|
-
|
|
1452
|
+
const t = e, r = t.target, s = typeof HTMLElement < "u" && r instanceof HTMLElement ? r : typeof HTMLElement < "u" && r instanceof Node && r.parentElement instanceof HTMLElement ? r.parentElement : null;
|
|
1453
|
+
if (!s) {
|
|
1454
|
+
a("warn", "Click target not found or not an element");
|
|
1275
1455
|
return;
|
|
1276
1456
|
}
|
|
1277
|
-
if (this.shouldIgnoreElement(
|
|
1457
|
+
if (this.shouldIgnoreElement(s))
|
|
1458
|
+
return;
|
|
1459
|
+
const i = this.get("config")?.clickThrottleMs ?? 300;
|
|
1460
|
+
if (i > 0 && !this.checkClickThrottle(s, i))
|
|
1278
1461
|
return;
|
|
1279
|
-
const
|
|
1280
|
-
if (
|
|
1281
|
-
const
|
|
1282
|
-
if (
|
|
1283
|
-
const
|
|
1462
|
+
const o = this.findTrackingElement(s), l = this.getRelevantClickElement(s), c = this.calculateClickCoordinates(t, s);
|
|
1463
|
+
if (o) {
|
|
1464
|
+
const _ = this.extractTrackingData(o);
|
|
1465
|
+
if (_) {
|
|
1466
|
+
const g = this.createCustomEventData(_);
|
|
1284
1467
|
this.eventManager.track({
|
|
1285
|
-
type:
|
|
1468
|
+
type: u.CUSTOM,
|
|
1286
1469
|
custom_event: {
|
|
1287
|
-
name:
|
|
1288
|
-
...
|
|
1470
|
+
name: g.name,
|
|
1471
|
+
...g.value && { metadata: { value: g.value } }
|
|
1289
1472
|
}
|
|
1290
1473
|
});
|
|
1291
1474
|
}
|
|
1292
1475
|
}
|
|
1293
|
-
const
|
|
1476
|
+
const d = this.generateClickData(s, l, c);
|
|
1294
1477
|
this.eventManager.track({
|
|
1295
|
-
type:
|
|
1296
|
-
click_data:
|
|
1478
|
+
type: u.CLICK,
|
|
1479
|
+
click_data: d
|
|
1297
1480
|
});
|
|
1298
1481
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
1299
1482
|
}
|
|
1300
1483
|
stopTracking() {
|
|
1301
|
-
this.clickHandler && (window.removeEventListener("click", this.clickHandler, !0), this.clickHandler = void 0);
|
|
1484
|
+
this.clickHandler && (window.removeEventListener("click", this.clickHandler, !0), this.clickHandler = void 0), this.lastClickTimes.clear();
|
|
1302
1485
|
}
|
|
1303
1486
|
shouldIgnoreElement(e) {
|
|
1304
|
-
return e.hasAttribute(`${
|
|
1487
|
+
return e.hasAttribute(`${v}-ignore`) ? !0 : e.closest(`[${v}-ignore]`) !== null;
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Checks per-element click throttling to prevent double-clicks and rapid spam
|
|
1491
|
+
* Returns true if the click should be tracked, false if throttled
|
|
1492
|
+
*/
|
|
1493
|
+
checkClickThrottle(e, t) {
|
|
1494
|
+
const r = this.getElementSignature(e), s = Date.now(), i = this.lastClickTimes.get(r);
|
|
1495
|
+
return i !== void 0 && s - i < t ? (a("debug", "ClickHandler: Click suppressed by throttle", {
|
|
1496
|
+
data: {
|
|
1497
|
+
signature: r,
|
|
1498
|
+
throttleRemaining: t - (s - i)
|
|
1499
|
+
}
|
|
1500
|
+
}), !1) : (this.lastClickTimes.set(r, s), !0);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Creates a stable signature for an element to track throttling
|
|
1504
|
+
* Priority: id > data-testid > data-tlog-name > DOM path
|
|
1505
|
+
*/
|
|
1506
|
+
getElementSignature(e) {
|
|
1507
|
+
if (e.id)
|
|
1508
|
+
return `#${e.id}`;
|
|
1509
|
+
const t = e.getAttribute("data-testid");
|
|
1510
|
+
if (t)
|
|
1511
|
+
return `[data-testid="${t}"]`;
|
|
1512
|
+
const r = e.getAttribute(`${v}-name`);
|
|
1513
|
+
return r ? `[${v}-name="${r}"]` : this.getElementPath(e);
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Generates a DOM path for an element (e.g., "body>div>button")
|
|
1517
|
+
*/
|
|
1518
|
+
getElementPath(e) {
|
|
1519
|
+
const t = [];
|
|
1520
|
+
let r = e;
|
|
1521
|
+
for (; r && r !== document.body; ) {
|
|
1522
|
+
let s = r.tagName.toLowerCase();
|
|
1523
|
+
if (r.className) {
|
|
1524
|
+
const i = r.className.split(" ")[0];
|
|
1525
|
+
i && (s += `.${i}`);
|
|
1526
|
+
}
|
|
1527
|
+
t.unshift(s), r = r.parentElement;
|
|
1528
|
+
}
|
|
1529
|
+
return t.join(">") || "unknown";
|
|
1305
1530
|
}
|
|
1306
1531
|
findTrackingElement(e) {
|
|
1307
|
-
return e.hasAttribute(`${
|
|
1532
|
+
return e.hasAttribute(`${v}-name`) ? e : e.closest(`[${v}-name]`);
|
|
1308
1533
|
}
|
|
1309
1534
|
getRelevantClickElement(e) {
|
|
1310
|
-
for (const t of
|
|
1535
|
+
for (const t of Ue)
|
|
1311
1536
|
try {
|
|
1312
1537
|
if (e.matches(t))
|
|
1313
1538
|
return e;
|
|
@@ -1315,7 +1540,7 @@ class St extends g {
|
|
|
1315
1540
|
if (r)
|
|
1316
1541
|
return r;
|
|
1317
1542
|
} catch (r) {
|
|
1318
|
-
|
|
1543
|
+
a("warn", "Invalid selector in element search", { error: r, data: { selector: t } });
|
|
1319
1544
|
continue;
|
|
1320
1545
|
}
|
|
1321
1546
|
return e;
|
|
@@ -1324,11 +1549,11 @@ class St extends g {
|
|
|
1324
1549
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
1325
1550
|
}
|
|
1326
1551
|
calculateClickCoordinates(e, t) {
|
|
1327
|
-
const r = t.getBoundingClientRect(),
|
|
1328
|
-
return { x:
|
|
1552
|
+
const r = t.getBoundingClientRect(), s = e.clientX, i = e.clientY, o = r.width > 0 ? this.clamp((s - r.left) / r.width) : 0, l = r.height > 0 ? this.clamp((i - r.top) / r.height) : 0;
|
|
1553
|
+
return { x: s, y: i, relativeX: o, relativeY: l };
|
|
1329
1554
|
}
|
|
1330
1555
|
extractTrackingData(e) {
|
|
1331
|
-
const t = e.getAttribute(`${
|
|
1556
|
+
const t = e.getAttribute(`${v}-name`), r = e.getAttribute(`${v}-value`);
|
|
1332
1557
|
if (t)
|
|
1333
1558
|
return {
|
|
1334
1559
|
element: e,
|
|
@@ -1337,38 +1562,38 @@ class St extends g {
|
|
|
1337
1562
|
};
|
|
1338
1563
|
}
|
|
1339
1564
|
generateClickData(e, t, r) {
|
|
1340
|
-
const { x:
|
|
1565
|
+
const { x: s, y: i, relativeX: o, relativeY: l } = r, c = this.getRelevantText(e, t), d = this.extractElementAttributes(t);
|
|
1341
1566
|
return {
|
|
1342
|
-
x:
|
|
1567
|
+
x: s,
|
|
1343
1568
|
y: i,
|
|
1344
|
-
relativeX:
|
|
1345
|
-
relativeY:
|
|
1569
|
+
relativeX: o,
|
|
1570
|
+
relativeY: l,
|
|
1346
1571
|
tag: t.tagName.toLowerCase(),
|
|
1347
1572
|
...t.id && { id: t.id },
|
|
1348
1573
|
...t.className && { class: t.className },
|
|
1349
1574
|
...c && { text: c },
|
|
1350
|
-
...
|
|
1351
|
-
...
|
|
1352
|
-
...
|
|
1353
|
-
...
|
|
1354
|
-
...
|
|
1355
|
-
...Object.keys(
|
|
1575
|
+
...d.href && { href: d.href },
|
|
1576
|
+
...d.title && { title: d.title },
|
|
1577
|
+
...d.alt && { alt: d.alt },
|
|
1578
|
+
...d.role && { role: d.role },
|
|
1579
|
+
...d["aria-label"] && { ariaLabel: d["aria-label"] },
|
|
1580
|
+
...Object.keys(d).length > 0 && { dataAttributes: d }
|
|
1356
1581
|
};
|
|
1357
1582
|
}
|
|
1358
1583
|
sanitizeText(e) {
|
|
1359
1584
|
let t = e;
|
|
1360
|
-
for (const r of
|
|
1361
|
-
const
|
|
1362
|
-
t = t.replace(
|
|
1585
|
+
for (const r of le) {
|
|
1586
|
+
const s = new RegExp(r.source, r.flags);
|
|
1587
|
+
t = t.replace(s, "[REDACTED]");
|
|
1363
1588
|
}
|
|
1364
1589
|
return t;
|
|
1365
1590
|
}
|
|
1366
1591
|
getRelevantText(e, t) {
|
|
1367
|
-
const r = e.textContent?.trim() ?? "",
|
|
1368
|
-
if (!r && !
|
|
1592
|
+
const r = e.textContent?.trim() ?? "", s = t.textContent?.trim() ?? "";
|
|
1593
|
+
if (!r && !s)
|
|
1369
1594
|
return "";
|
|
1370
1595
|
let i = "";
|
|
1371
|
-
return r && r.length <= 255 ? i = r :
|
|
1596
|
+
return r && r.length <= 255 ? i = r : s.length <= 255 ? i = s : i = s.slice(0, 252) + "...", this.sanitizeText(i);
|
|
1372
1597
|
}
|
|
1373
1598
|
extractElementAttributes(e) {
|
|
1374
1599
|
const t = [
|
|
@@ -1383,9 +1608,9 @@ class St extends g {
|
|
|
1383
1608
|
"alt",
|
|
1384
1609
|
"role"
|
|
1385
1610
|
], r = {};
|
|
1386
|
-
for (const
|
|
1387
|
-
const i = e.getAttribute(
|
|
1388
|
-
i && (r[
|
|
1611
|
+
for (const s of t) {
|
|
1612
|
+
const i = e.getAttribute(s);
|
|
1613
|
+
i && (r[s] = i);
|
|
1389
1614
|
}
|
|
1390
1615
|
return r;
|
|
1391
1616
|
}
|
|
@@ -1396,7 +1621,7 @@ class St extends g {
|
|
|
1396
1621
|
};
|
|
1397
1622
|
}
|
|
1398
1623
|
}
|
|
1399
|
-
class
|
|
1624
|
+
class At extends S {
|
|
1400
1625
|
eventManager;
|
|
1401
1626
|
containers = [];
|
|
1402
1627
|
limitWarningLogged = !1;
|
|
@@ -1421,8 +1646,8 @@ class Et extends g {
|
|
|
1421
1646
|
const t = this.findScrollableElements();
|
|
1422
1647
|
if (t.length > 0) {
|
|
1423
1648
|
for (const r of t) {
|
|
1424
|
-
const
|
|
1425
|
-
this.setupScrollContainer(r,
|
|
1649
|
+
const s = this.getElementSelector(r);
|
|
1650
|
+
this.setupScrollContainer(r, s);
|
|
1426
1651
|
}
|
|
1427
1652
|
this.applyPrimaryScrollSelectorIfConfigured();
|
|
1428
1653
|
return;
|
|
@@ -1443,18 +1668,18 @@ class Et extends g {
|
|
|
1443
1668
|
if (!document.body)
|
|
1444
1669
|
return [];
|
|
1445
1670
|
const e = [], t = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
1446
|
-
acceptNode: (
|
|
1447
|
-
const i =
|
|
1671
|
+
acceptNode: (s) => {
|
|
1672
|
+
const i = s;
|
|
1448
1673
|
if (!i.isConnected || !i.offsetParent)
|
|
1449
1674
|
return NodeFilter.FILTER_SKIP;
|
|
1450
|
-
const
|
|
1451
|
-
return
|
|
1675
|
+
const o = getComputedStyle(i);
|
|
1676
|
+
return o.overflowY === "auto" || o.overflowY === "scroll" || o.overflow === "auto" || o.overflow === "scroll" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
1452
1677
|
}
|
|
1453
1678
|
});
|
|
1454
1679
|
let r;
|
|
1455
1680
|
for (; (r = t.nextNode()) && e.length < 10; ) {
|
|
1456
|
-
const
|
|
1457
|
-
this.isElementScrollable(
|
|
1681
|
+
const s = r;
|
|
1682
|
+
this.isElementScrollable(s) && e.push(s);
|
|
1458
1683
|
}
|
|
1459
1684
|
return e;
|
|
1460
1685
|
}
|
|
@@ -1465,7 +1690,7 @@ class Et extends g {
|
|
|
1465
1690
|
if (t.id)
|
|
1466
1691
|
return `#${t.id}`;
|
|
1467
1692
|
if (t.className && typeof t.className == "string") {
|
|
1468
|
-
const r = t.className.split(" ").filter((
|
|
1693
|
+
const r = t.className.split(" ").filter((s) => s.trim())[0];
|
|
1469
1694
|
if (r)
|
|
1470
1695
|
return `.${r}`;
|
|
1471
1696
|
}
|
|
@@ -1475,42 +1700,42 @@ class Et extends g {
|
|
|
1475
1700
|
return this.isWindowScrollable() ? e === window : this.containers.length === 0;
|
|
1476
1701
|
}
|
|
1477
1702
|
setupScrollContainer(e, t) {
|
|
1478
|
-
if (this.containers.some((
|
|
1703
|
+
if (this.containers.some((d) => d.element === e) || e !== window && !this.isElementScrollable(e))
|
|
1479
1704
|
return;
|
|
1480
|
-
const
|
|
1705
|
+
const s = () => {
|
|
1481
1706
|
this.get("suppressNextScroll") || (this.clearContainerTimer(c), c.debounceTimer = window.setTimeout(() => {
|
|
1482
|
-
const
|
|
1483
|
-
if (
|
|
1484
|
-
const
|
|
1485
|
-
this.processScrollEvent(c,
|
|
1707
|
+
const d = this.calculateScrollData(c);
|
|
1708
|
+
if (d) {
|
|
1709
|
+
const _ = Date.now();
|
|
1710
|
+
this.processScrollEvent(c, d, _);
|
|
1486
1711
|
}
|
|
1487
1712
|
c.debounceTimer = null;
|
|
1488
1713
|
}, 250));
|
|
1489
|
-
}, i = this.getScrollTop(e),
|
|
1714
|
+
}, i = this.getScrollTop(e), o = this.calculateScrollDepth(
|
|
1490
1715
|
i,
|
|
1491
1716
|
this.getScrollHeight(e),
|
|
1492
1717
|
this.getViewportHeight(e)
|
|
1493
|
-
),
|
|
1718
|
+
), l = this.determineIfPrimary(e), c = {
|
|
1494
1719
|
element: e,
|
|
1495
1720
|
selector: t,
|
|
1496
|
-
isPrimary:
|
|
1721
|
+
isPrimary: l,
|
|
1497
1722
|
lastScrollPos: i,
|
|
1498
|
-
lastDepth:
|
|
1499
|
-
lastDirection:
|
|
1723
|
+
lastDepth: o,
|
|
1724
|
+
lastDirection: H.DOWN,
|
|
1500
1725
|
lastEventTime: 0,
|
|
1501
|
-
maxDepthReached:
|
|
1726
|
+
maxDepthReached: o,
|
|
1502
1727
|
debounceTimer: null,
|
|
1503
|
-
listener:
|
|
1728
|
+
listener: s
|
|
1504
1729
|
};
|
|
1505
|
-
this.containers.push(c), e instanceof Window ? window.addEventListener("scroll",
|
|
1730
|
+
this.containers.push(c), e instanceof Window ? window.addEventListener("scroll", s, { passive: !0 }) : e.addEventListener("scroll", s, { passive: !0 });
|
|
1506
1731
|
}
|
|
1507
1732
|
processScrollEvent(e, t, r) {
|
|
1508
1733
|
if (!this.shouldEmitScrollEvent(e, t, r))
|
|
1509
1734
|
return;
|
|
1510
1735
|
e.lastEventTime = r, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
1511
|
-
const
|
|
1512
|
-
this.set("scrollEventCount",
|
|
1513
|
-
type:
|
|
1736
|
+
const s = this.get("scrollEventCount") ?? 0;
|
|
1737
|
+
this.set("scrollEventCount", s + 1), this.eventManager.track({
|
|
1738
|
+
type: u.SCROLL,
|
|
1514
1739
|
scroll_data: {
|
|
1515
1740
|
...t,
|
|
1516
1741
|
container_selector: e.selector,
|
|
@@ -1531,7 +1756,7 @@ class Et extends g {
|
|
|
1531
1756
|
return Math.abs(t - e.lastDepth) >= this.minDepthChange;
|
|
1532
1757
|
}
|
|
1533
1758
|
logLimitOnce() {
|
|
1534
|
-
this.limitWarningLogged || (this.limitWarningLogged = !0,
|
|
1759
|
+
this.limitWarningLogged || (this.limitWarningLogged = !0, a("warn", "Max scroll events per session reached", {
|
|
1535
1760
|
data: { limit: this.maxEventsPerSession }
|
|
1536
1761
|
}));
|
|
1537
1762
|
}
|
|
@@ -1545,23 +1770,23 @@ class Et extends g {
|
|
|
1545
1770
|
e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
|
|
1546
1771
|
}
|
|
1547
1772
|
getScrollDirection(e, t) {
|
|
1548
|
-
return e > t ?
|
|
1773
|
+
return e > t ? H.DOWN : H.UP;
|
|
1549
1774
|
}
|
|
1550
1775
|
calculateScrollDepth(e, t, r) {
|
|
1551
1776
|
if (t <= r)
|
|
1552
1777
|
return 0;
|
|
1553
|
-
const
|
|
1554
|
-
return Math.min(100, Math.max(0, Math.floor(e /
|
|
1778
|
+
const s = t - r;
|
|
1779
|
+
return Math.min(100, Math.max(0, Math.floor(e / s * 100)));
|
|
1555
1780
|
}
|
|
1556
1781
|
calculateScrollData(e) {
|
|
1557
|
-
const { element: t, lastScrollPos: r, lastEventTime:
|
|
1558
|
-
if (
|
|
1782
|
+
const { element: t, lastScrollPos: r, lastEventTime: s } = e, i = this.getScrollTop(t), o = Date.now(), l = Math.abs(i - r);
|
|
1783
|
+
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
1559
1784
|
return null;
|
|
1560
|
-
const c = this.getViewportHeight(t),
|
|
1561
|
-
return
|
|
1562
|
-
depth:
|
|
1563
|
-
direction:
|
|
1564
|
-
velocity:
|
|
1785
|
+
const c = this.getViewportHeight(t), d = this.getScrollHeight(t), _ = this.getScrollDirection(i, r), g = this.calculateScrollDepth(i, d, c), L = s > 0 ? o - s : 0, m = L > 0 ? Math.round(l / L * 1e3) : 0;
|
|
1786
|
+
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
1787
|
+
depth: g,
|
|
1788
|
+
direction: _,
|
|
1789
|
+
velocity: m,
|
|
1565
1790
|
max_depth_reached: e.maxDepthReached
|
|
1566
1791
|
};
|
|
1567
1792
|
}
|
|
@@ -1575,30 +1800,190 @@ class Et extends g {
|
|
|
1575
1800
|
return e instanceof Window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
1576
1801
|
}
|
|
1577
1802
|
isElementScrollable(e) {
|
|
1578
|
-
const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflowX === "auto" || t.overflowX === "scroll" || t.overflow === "auto" || t.overflow === "scroll",
|
|
1579
|
-
return r &&
|
|
1803
|
+
const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflowX === "auto" || t.overflowX === "scroll" || t.overflow === "auto" || t.overflow === "scroll", s = e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth;
|
|
1804
|
+
return r && s;
|
|
1580
1805
|
}
|
|
1581
1806
|
applyPrimaryScrollSelector(e) {
|
|
1582
1807
|
let t;
|
|
1583
1808
|
if (e === "window")
|
|
1584
1809
|
t = window;
|
|
1585
1810
|
else {
|
|
1586
|
-
const
|
|
1587
|
-
if (!(
|
|
1588
|
-
|
|
1811
|
+
const s = document.querySelector(e);
|
|
1812
|
+
if (!(s instanceof HTMLElement)) {
|
|
1813
|
+
a("warn", `Selector "${e}" did not match an HTMLElement`);
|
|
1589
1814
|
return;
|
|
1590
1815
|
}
|
|
1591
|
-
t =
|
|
1816
|
+
t = s;
|
|
1592
1817
|
}
|
|
1593
|
-
this.containers.forEach((
|
|
1594
|
-
this.updateContainerPrimary(
|
|
1595
|
-
}), !this.containers.some((
|
|
1818
|
+
this.containers.forEach((s) => {
|
|
1819
|
+
this.updateContainerPrimary(s, s.element === t);
|
|
1820
|
+
}), !this.containers.some((s) => s.element === t) && t instanceof HTMLElement && this.isElementScrollable(t) && this.setupScrollContainer(t, e);
|
|
1596
1821
|
}
|
|
1597
1822
|
updateContainerPrimary(e, t) {
|
|
1598
1823
|
e.isPrimary = t;
|
|
1599
1824
|
}
|
|
1600
1825
|
}
|
|
1601
|
-
class
|
|
1826
|
+
class wt extends S {
|
|
1827
|
+
eventManager;
|
|
1828
|
+
trackedElements = /* @__PURE__ */ new Map();
|
|
1829
|
+
observer = null;
|
|
1830
|
+
mutationObserver = null;
|
|
1831
|
+
mutationDebounceTimer = null;
|
|
1832
|
+
config = null;
|
|
1833
|
+
constructor(e) {
|
|
1834
|
+
super(), this.eventManager = e;
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Starts tracking viewport visibility for configured elements
|
|
1838
|
+
*/
|
|
1839
|
+
startTracking() {
|
|
1840
|
+
const e = this.get("config");
|
|
1841
|
+
if (this.config = e.viewport ?? null, !this.config?.elements || this.config.elements.length === 0)
|
|
1842
|
+
return;
|
|
1843
|
+
const t = this.config.threshold ?? 0.5, r = this.config.minDwellTime ?? 1e3;
|
|
1844
|
+
if (t < 0 || t > 1) {
|
|
1845
|
+
a("warn", "ViewportHandler: Invalid threshold, must be between 0 and 1");
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
if (r < 0) {
|
|
1849
|
+
a("warn", "ViewportHandler: Invalid minDwellTime, must be non-negative");
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
if (typeof IntersectionObserver > "u") {
|
|
1853
|
+
a("warn", "ViewportHandler: IntersectionObserver not supported in this browser");
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
this.observer = new IntersectionObserver(this.handleIntersection, {
|
|
1857
|
+
threshold: t
|
|
1858
|
+
}), this.observeElements(), this.setupMutationObserver();
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Stops tracking and cleans up resources
|
|
1862
|
+
*/
|
|
1863
|
+
stopTracking() {
|
|
1864
|
+
this.observer && (this.observer.disconnect(), this.observer = null), this.mutationObserver && (this.mutationObserver.disconnect(), this.mutationObserver = null), this.mutationDebounceTimer !== null && (window.clearTimeout(this.mutationDebounceTimer), this.mutationDebounceTimer = null);
|
|
1865
|
+
for (const e of this.trackedElements.values())
|
|
1866
|
+
e.timeoutId !== null && window.clearTimeout(e.timeoutId);
|
|
1867
|
+
this.trackedElements.clear();
|
|
1868
|
+
}
|
|
1869
|
+
/**
|
|
1870
|
+
* Query and observe all elements matching configured elements
|
|
1871
|
+
*/
|
|
1872
|
+
observeElements() {
|
|
1873
|
+
if (!this.config || !this.observer) return;
|
|
1874
|
+
const e = this.config.maxTrackedElements ?? 100;
|
|
1875
|
+
let t = this.trackedElements.size;
|
|
1876
|
+
for (const r of this.config.elements)
|
|
1877
|
+
try {
|
|
1878
|
+
const s = document.querySelectorAll(r.selector);
|
|
1879
|
+
for (const i of Array.from(s)) {
|
|
1880
|
+
if (t >= e) {
|
|
1881
|
+
a("warn", "ViewportHandler: Maximum tracked elements reached", {
|
|
1882
|
+
data: {
|
|
1883
|
+
limit: e,
|
|
1884
|
+
selector: r.selector,
|
|
1885
|
+
message: "Some elements will not be tracked. Consider more specific selectors."
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
i.hasAttribute(`${v}-ignore`) || this.trackedElements.has(i) || (this.trackedElements.set(i, {
|
|
1891
|
+
element: i,
|
|
1892
|
+
selector: r.selector,
|
|
1893
|
+
id: r.id,
|
|
1894
|
+
name: r.name,
|
|
1895
|
+
startTime: null,
|
|
1896
|
+
timeoutId: null,
|
|
1897
|
+
lastFiredTime: null
|
|
1898
|
+
}), this.observer?.observe(i), t++);
|
|
1899
|
+
}
|
|
1900
|
+
} catch (s) {
|
|
1901
|
+
a("warn", `ViewportHandler: Invalid selector "${r.selector}"`, { error: s });
|
|
1902
|
+
}
|
|
1903
|
+
a("debug", "ViewportHandler: Elements tracked", {
|
|
1904
|
+
data: { count: t, limit: e }
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Handles intersection events from IntersectionObserver
|
|
1909
|
+
*/
|
|
1910
|
+
handleIntersection = (e) => {
|
|
1911
|
+
if (!this.config) return;
|
|
1912
|
+
const t = this.config.minDwellTime ?? 1e3;
|
|
1913
|
+
for (const r of e) {
|
|
1914
|
+
const s = this.trackedElements.get(r.target);
|
|
1915
|
+
s && (r.isIntersecting ? s.startTime === null && (s.startTime = performance.now(), s.timeoutId = window.setTimeout(() => {
|
|
1916
|
+
this.fireViewportEvent(s, r.intersectionRatio);
|
|
1917
|
+
}, t)) : s.startTime !== null && (s.timeoutId !== null && (window.clearTimeout(s.timeoutId), s.timeoutId = null), s.startTime = null));
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
/**
|
|
1921
|
+
* Fires a viewport visible event
|
|
1922
|
+
*/
|
|
1923
|
+
fireViewportEvent(e, t) {
|
|
1924
|
+
if (e.startTime === null) return;
|
|
1925
|
+
const r = Math.round(performance.now() - e.startTime);
|
|
1926
|
+
if (e.element.hasAttribute("data-tlog-ignore"))
|
|
1927
|
+
return;
|
|
1928
|
+
const s = this.config?.cooldownPeriod ?? 6e4, i = Date.now();
|
|
1929
|
+
if (e.lastFiredTime !== null && i - e.lastFiredTime < s) {
|
|
1930
|
+
a("debug", "ViewportHandler: Event suppressed by cooldown period", {
|
|
1931
|
+
data: {
|
|
1932
|
+
selector: e.selector,
|
|
1933
|
+
cooldownRemaining: s - (i - e.lastFiredTime)
|
|
1934
|
+
}
|
|
1935
|
+
}), e.startTime = null, e.timeoutId = null;
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1938
|
+
const o = {
|
|
1939
|
+
selector: e.selector,
|
|
1940
|
+
dwellTime: r,
|
|
1941
|
+
visibilityRatio: t,
|
|
1942
|
+
...e.id !== void 0 && { id: e.id },
|
|
1943
|
+
...e.name !== void 0 && { name: e.name }
|
|
1944
|
+
};
|
|
1945
|
+
this.eventManager.track({
|
|
1946
|
+
type: u.VIEWPORT_VISIBLE,
|
|
1947
|
+
viewport_data: o
|
|
1948
|
+
}), e.startTime = null, e.timeoutId = null, e.lastFiredTime = i;
|
|
1949
|
+
}
|
|
1950
|
+
/**
|
|
1951
|
+
* Sets up MutationObserver to detect dynamically added elements
|
|
1952
|
+
*/
|
|
1953
|
+
setupMutationObserver() {
|
|
1954
|
+
if (!(!this.config || typeof MutationObserver > "u")) {
|
|
1955
|
+
if (!document.body) {
|
|
1956
|
+
a("warn", "ViewportHandler: document.body not available, skipping MutationObserver setup");
|
|
1957
|
+
return;
|
|
1958
|
+
}
|
|
1959
|
+
this.mutationObserver = new MutationObserver((e) => {
|
|
1960
|
+
let t = !1;
|
|
1961
|
+
for (const r of e)
|
|
1962
|
+
r.type === "childList" && (r.addedNodes.length > 0 && (t = !0), r.removedNodes.length > 0 && this.cleanupRemovedNodes(r.removedNodes));
|
|
1963
|
+
t && (this.mutationDebounceTimer !== null && window.clearTimeout(this.mutationDebounceTimer), this.mutationDebounceTimer = window.setTimeout(() => {
|
|
1964
|
+
this.observeElements(), this.mutationDebounceTimer = null;
|
|
1965
|
+
}, 100));
|
|
1966
|
+
}), this.mutationObserver.observe(document.body, {
|
|
1967
|
+
childList: !0,
|
|
1968
|
+
subtree: !0
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Cleans up tracking for removed DOM nodes
|
|
1974
|
+
*/
|
|
1975
|
+
cleanupRemovedNodes(e) {
|
|
1976
|
+
e.forEach((t) => {
|
|
1977
|
+
if (t.nodeType !== 1) return;
|
|
1978
|
+
const r = t, s = this.trackedElements.get(r);
|
|
1979
|
+
s && (s.timeoutId !== null && window.clearTimeout(s.timeoutId), this.observer?.unobserve(r), this.trackedElements.delete(r)), Array.from(this.trackedElements.keys()).filter((o) => r.contains(o)).forEach((o) => {
|
|
1980
|
+
const l = this.trackedElements.get(o);
|
|
1981
|
+
l && l.timeoutId !== null && window.clearTimeout(l.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
1982
|
+
});
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
class yt extends S {
|
|
1602
1987
|
isInitialized = !1;
|
|
1603
1988
|
async initialize() {
|
|
1604
1989
|
if (this.isInitialized)
|
|
@@ -1612,7 +1997,7 @@ class mt extends g {
|
|
|
1612
1997
|
}
|
|
1613
1998
|
await this.loadScript(e), this.configureGtag(e, t), this.isInitialized = !0;
|
|
1614
1999
|
} catch (r) {
|
|
1615
|
-
|
|
2000
|
+
a("error", "Google Analytics initialization failed", { error: r });
|
|
1616
2001
|
}
|
|
1617
2002
|
}
|
|
1618
2003
|
trackEvent(e, t) {
|
|
@@ -1621,7 +2006,7 @@ class mt extends g {
|
|
|
1621
2006
|
const r = Array.isArray(t) ? { items: t } : t;
|
|
1622
2007
|
window.gtag("event", e, r);
|
|
1623
2008
|
} catch (r) {
|
|
1624
|
-
|
|
2009
|
+
a("error", "Google Analytics event tracking failed", { error: r });
|
|
1625
2010
|
}
|
|
1626
2011
|
}
|
|
1627
2012
|
cleanup() {
|
|
@@ -1634,12 +2019,12 @@ class mt extends g {
|
|
|
1634
2019
|
}
|
|
1635
2020
|
async loadScript(e) {
|
|
1636
2021
|
return new Promise((t, r) => {
|
|
1637
|
-
const
|
|
1638
|
-
|
|
2022
|
+
const s = document.createElement("script");
|
|
2023
|
+
s.id = "tracelog-ga-script", s.async = !0, s.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, s.onload = () => {
|
|
1639
2024
|
t();
|
|
1640
|
-
},
|
|
2025
|
+
}, s.onerror = () => {
|
|
1641
2026
|
r(new Error("Failed to load Google Analytics script"));
|
|
1642
|
-
}, document.head.appendChild(
|
|
2027
|
+
}, document.head.appendChild(s);
|
|
1643
2028
|
});
|
|
1644
2029
|
}
|
|
1645
2030
|
configureGtag(e, t) {
|
|
@@ -1654,14 +2039,14 @@ class mt extends g {
|
|
|
1654
2039
|
`, document.head.appendChild(r);
|
|
1655
2040
|
}
|
|
1656
2041
|
}
|
|
1657
|
-
class
|
|
2042
|
+
class Lt {
|
|
1658
2043
|
storage;
|
|
1659
2044
|
sessionStorageRef;
|
|
1660
2045
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
1661
2046
|
fallbackSessionStorage = /* @__PURE__ */ new Map();
|
|
1662
2047
|
hasQuotaExceededError = !1;
|
|
1663
2048
|
constructor() {
|
|
1664
|
-
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage ||
|
|
2049
|
+
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage || a("warn", "localStorage not available, using memory fallback"), this.sessionStorageRef || a("warn", "sessionStorage not available, using memory fallback");
|
|
1665
2050
|
}
|
|
1666
2051
|
/**
|
|
1667
2052
|
* Retrieves an item from storage
|
|
@@ -1685,7 +2070,7 @@ class pt {
|
|
|
1685
2070
|
}
|
|
1686
2071
|
} catch (r) {
|
|
1687
2072
|
if (r instanceof DOMException && r.name === "QuotaExceededError")
|
|
1688
|
-
if (this.hasQuotaExceededError = !0,
|
|
2073
|
+
if (this.hasQuotaExceededError = !0, a("warn", "localStorage quota exceeded, attempting cleanup", {
|
|
1689
2074
|
data: { key: e, valueSize: t.length }
|
|
1690
2075
|
}), this.cleanupOldData())
|
|
1691
2076
|
try {
|
|
@@ -1694,13 +2079,13 @@ class pt {
|
|
|
1694
2079
|
return;
|
|
1695
2080
|
}
|
|
1696
2081
|
} catch (i) {
|
|
1697
|
-
|
|
2082
|
+
a("error", "localStorage quota exceeded even after cleanup - data will not persist", {
|
|
1698
2083
|
error: i,
|
|
1699
2084
|
data: { key: e, valueSize: t.length }
|
|
1700
2085
|
});
|
|
1701
2086
|
}
|
|
1702
2087
|
else
|
|
1703
|
-
|
|
2088
|
+
a("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
|
|
1704
2089
|
error: r,
|
|
1705
2090
|
data: { key: e, valueSize: t.length }
|
|
1706
2091
|
});
|
|
@@ -1734,7 +2119,7 @@ class pt {
|
|
|
1734
2119
|
this.storage.removeItem(t);
|
|
1735
2120
|
}), this.fallbackStorage.clear();
|
|
1736
2121
|
} catch (e) {
|
|
1737
|
-
|
|
2122
|
+
a("error", "Failed to clear storage", { error: e }), this.fallbackStorage.clear();
|
|
1738
2123
|
}
|
|
1739
2124
|
}
|
|
1740
2125
|
/**
|
|
@@ -1760,8 +2145,8 @@ class pt {
|
|
|
1760
2145
|
try {
|
|
1761
2146
|
const e = [], t = [];
|
|
1762
2147
|
for (let i = 0; i < this.storage.length; i++) {
|
|
1763
|
-
const
|
|
1764
|
-
|
|
2148
|
+
const o = this.storage.key(i);
|
|
2149
|
+
o?.startsWith("tracelog_") && (e.push(o), o.startsWith("tracelog_persisted_events_") && t.push(o));
|
|
1765
2150
|
}
|
|
1766
2151
|
if (t.length > 0)
|
|
1767
2152
|
return t.forEach((i) => {
|
|
@@ -1770,15 +2155,15 @@ class pt {
|
|
|
1770
2155
|
} catch {
|
|
1771
2156
|
}
|
|
1772
2157
|
}), !0;
|
|
1773
|
-
const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"],
|
|
1774
|
-
return
|
|
2158
|
+
const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], s = e.filter((i) => !r.some((o) => i.startsWith(o)));
|
|
2159
|
+
return s.length > 0 ? (s.slice(0, 5).forEach((o) => {
|
|
1775
2160
|
try {
|
|
1776
|
-
this.storage.removeItem(
|
|
2161
|
+
this.storage.removeItem(o);
|
|
1777
2162
|
} catch {
|
|
1778
2163
|
}
|
|
1779
2164
|
}), !0) : !1;
|
|
1780
2165
|
} catch (e) {
|
|
1781
|
-
return
|
|
2166
|
+
return a("error", "Failed to cleanup old data", { error: e }), !1;
|
|
1782
2167
|
}
|
|
1783
2168
|
}
|
|
1784
2169
|
/**
|
|
@@ -1815,7 +2200,7 @@ class pt {
|
|
|
1815
2200
|
return;
|
|
1816
2201
|
}
|
|
1817
2202
|
} catch (r) {
|
|
1818
|
-
r instanceof DOMException && r.name === "QuotaExceededError" &&
|
|
2203
|
+
r instanceof DOMException && r.name === "QuotaExceededError" && a("error", "sessionStorage quota exceeded - data will not persist", {
|
|
1819
2204
|
error: r,
|
|
1820
2205
|
data: { key: e, valueSize: t.length }
|
|
1821
2206
|
});
|
|
@@ -1832,7 +2217,7 @@ class pt {
|
|
|
1832
2217
|
this.fallbackSessionStorage.delete(e);
|
|
1833
2218
|
}
|
|
1834
2219
|
}
|
|
1835
|
-
class
|
|
2220
|
+
class Mt extends S {
|
|
1836
2221
|
eventManager;
|
|
1837
2222
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
1838
2223
|
observers = [];
|
|
@@ -1849,7 +2234,7 @@ class _t extends g {
|
|
|
1849
2234
|
try {
|
|
1850
2235
|
e.disconnect();
|
|
1851
2236
|
} catch (r) {
|
|
1852
|
-
|
|
2237
|
+
a("warn", "Failed to disconnect performance observer", { error: r, data: { observerIndex: t } });
|
|
1853
2238
|
}
|
|
1854
2239
|
}), this.observers.length = 0, this.reportedByNav.clear();
|
|
1855
2240
|
}
|
|
@@ -1857,7 +2242,7 @@ class _t extends g {
|
|
|
1857
2242
|
this.reportTTFB(), this.safeObserve(
|
|
1858
2243
|
"largest-contentful-paint",
|
|
1859
2244
|
(r) => {
|
|
1860
|
-
const
|
|
2245
|
+
const s = r.getEntries(), i = s[s.length - 1];
|
|
1861
2246
|
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
|
|
1862
2247
|
},
|
|
1863
2248
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
@@ -1867,14 +2252,14 @@ class _t extends g {
|
|
|
1867
2252
|
this.safeObserve(
|
|
1868
2253
|
"layout-shift",
|
|
1869
2254
|
(r) => {
|
|
1870
|
-
const
|
|
1871
|
-
|
|
2255
|
+
const s = this.getNavigationId();
|
|
2256
|
+
s !== t && (e = 0, t = s);
|
|
1872
2257
|
const i = r.getEntries();
|
|
1873
|
-
for (const
|
|
1874
|
-
if (
|
|
2258
|
+
for (const o of i) {
|
|
2259
|
+
if (o.hadRecentInput === !0)
|
|
1875
2260
|
continue;
|
|
1876
|
-
const
|
|
1877
|
-
e +=
|
|
2261
|
+
const l = typeof o.value == "number" ? o.value : 0;
|
|
2262
|
+
e += l;
|
|
1878
2263
|
}
|
|
1879
2264
|
this.sendVital({ type: "CLS", value: Number(e.toFixed(2)) });
|
|
1880
2265
|
},
|
|
@@ -1882,34 +2267,34 @@ class _t extends g {
|
|
|
1882
2267
|
), this.safeObserve(
|
|
1883
2268
|
"paint",
|
|
1884
2269
|
(r) => {
|
|
1885
|
-
for (const
|
|
1886
|
-
|
|
2270
|
+
for (const s of r.getEntries())
|
|
2271
|
+
s.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(s.startTime.toFixed(2)) });
|
|
1887
2272
|
},
|
|
1888
2273
|
{ type: "paint", buffered: !0 },
|
|
1889
2274
|
!0
|
|
1890
2275
|
), this.safeObserve(
|
|
1891
2276
|
"event",
|
|
1892
2277
|
(r) => {
|
|
1893
|
-
let
|
|
2278
|
+
let s = 0;
|
|
1894
2279
|
const i = r.getEntries();
|
|
1895
|
-
for (const
|
|
1896
|
-
const
|
|
1897
|
-
|
|
2280
|
+
for (const o of i) {
|
|
2281
|
+
const l = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
2282
|
+
s = Math.max(s, l);
|
|
1898
2283
|
}
|
|
1899
|
-
|
|
2284
|
+
s > 0 && this.sendVital({ type: "INP", value: Number(s.toFixed(2)) });
|
|
1900
2285
|
},
|
|
1901
2286
|
{ type: "event", buffered: !0 }
|
|
1902
2287
|
);
|
|
1903
2288
|
}
|
|
1904
2289
|
async initWebVitals() {
|
|
1905
2290
|
try {
|
|
1906
|
-
const { onLCP: e, onCLS: t, onFCP: r, onTTFB:
|
|
1907
|
-
const
|
|
1908
|
-
this.sendVital({ type:
|
|
2291
|
+
const { onLCP: e, onCLS: t, onFCP: r, onTTFB: s, onINP: i } = await Promise.resolve().then(() => Qt), o = (l) => (c) => {
|
|
2292
|
+
const d = Number(c.value.toFixed(2));
|
|
2293
|
+
this.sendVital({ type: l, value: d });
|
|
1909
2294
|
};
|
|
1910
|
-
e(
|
|
2295
|
+
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), r(o("FCP"), { reportAllChanges: !1 }), s(o("TTFB"), { reportAllChanges: !1 }), i(o("INP"), { reportAllChanges: !1 });
|
|
1911
2296
|
} catch (e) {
|
|
1912
|
-
|
|
2297
|
+
a("warn", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
1913
2298
|
}
|
|
1914
2299
|
}
|
|
1915
2300
|
reportTTFB() {
|
|
@@ -1920,7 +2305,7 @@ class _t extends g {
|
|
|
1920
2305
|
const t = e.responseStart;
|
|
1921
2306
|
typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(2)) });
|
|
1922
2307
|
} catch (e) {
|
|
1923
|
-
|
|
2308
|
+
a("warn", "Failed to report TTFB", { error: e });
|
|
1924
2309
|
}
|
|
1925
2310
|
}
|
|
1926
2311
|
observeLongTasks() {
|
|
@@ -1929,8 +2314,8 @@ class _t extends g {
|
|
|
1929
2314
|
(e) => {
|
|
1930
2315
|
const t = e.getEntries();
|
|
1931
2316
|
for (const r of t) {
|
|
1932
|
-
const
|
|
1933
|
-
i - this.lastLongTaskSentAt >=
|
|
2317
|
+
const s = Number(r.duration.toFixed(2)), i = Date.now();
|
|
2318
|
+
i - this.lastLongTaskSentAt >= Ke && (this.shouldSendVital("LONG_TASK", s) && this.trackWebVital("LONG_TASK", s), this.lastLongTaskSentAt = i);
|
|
1934
2319
|
}
|
|
1935
2320
|
},
|
|
1936
2321
|
{ type: "longtask", buffered: !0 }
|
|
@@ -1950,11 +2335,11 @@ class _t extends g {
|
|
|
1950
2335
|
}
|
|
1951
2336
|
trackWebVital(e, t) {
|
|
1952
2337
|
if (!Number.isFinite(t)) {
|
|
1953
|
-
|
|
2338
|
+
a("warn", "Invalid web vital value", { data: { type: e, value: t } });
|
|
1954
2339
|
return;
|
|
1955
2340
|
}
|
|
1956
2341
|
this.eventManager.track({
|
|
1957
|
-
type:
|
|
2342
|
+
type: u.WEB_VITALS,
|
|
1958
2343
|
web_vitals: {
|
|
1959
2344
|
type: e,
|
|
1960
2345
|
value: t
|
|
@@ -1969,7 +2354,7 @@ class _t extends g {
|
|
|
1969
2354
|
const t = e.startTime || performance.now(), r = Math.random().toString(36).substr(2, 5);
|
|
1970
2355
|
return `${t.toFixed(2)}_${window.location.pathname}_${r}`;
|
|
1971
2356
|
} catch (e) {
|
|
1972
|
-
return
|
|
2357
|
+
return a("warn", "Failed to get navigation ID", { error: e }), null;
|
|
1973
2358
|
}
|
|
1974
2359
|
}
|
|
1975
2360
|
isObserverSupported(e) {
|
|
@@ -1977,28 +2362,28 @@ class _t extends g {
|
|
|
1977
2362
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
1978
2363
|
return !t || t.includes(e);
|
|
1979
2364
|
}
|
|
1980
|
-
safeObserve(e, t, r,
|
|
2365
|
+
safeObserve(e, t, r, s = !1) {
|
|
1981
2366
|
try {
|
|
1982
2367
|
if (!this.isObserverSupported(e))
|
|
1983
2368
|
return !1;
|
|
1984
|
-
const i = new PerformanceObserver((
|
|
2369
|
+
const i = new PerformanceObserver((o, l) => {
|
|
1985
2370
|
try {
|
|
1986
|
-
t(
|
|
2371
|
+
t(o, l);
|
|
1987
2372
|
} catch (c) {
|
|
1988
|
-
|
|
2373
|
+
a("warn", "Observer callback failed", {
|
|
1989
2374
|
error: c,
|
|
1990
2375
|
data: { type: e }
|
|
1991
2376
|
});
|
|
1992
2377
|
}
|
|
1993
|
-
if (
|
|
2378
|
+
if (s)
|
|
1994
2379
|
try {
|
|
1995
|
-
|
|
2380
|
+
l.disconnect();
|
|
1996
2381
|
} catch {
|
|
1997
2382
|
}
|
|
1998
2383
|
});
|
|
1999
|
-
return i.observe(r ?? { type: e, buffered: !0 }),
|
|
2384
|
+
return i.observe(r ?? { type: e, buffered: !0 }), s || this.observers.push(i), !0;
|
|
2000
2385
|
} catch (i) {
|
|
2001
|
-
return
|
|
2386
|
+
return a("warn", "Failed to create performance observer", {
|
|
2002
2387
|
error: i,
|
|
2003
2388
|
data: { type: e }
|
|
2004
2389
|
}), !1;
|
|
@@ -2006,14 +2391,17 @@ class _t extends g {
|
|
|
2006
2391
|
}
|
|
2007
2392
|
shouldSendVital(e, t) {
|
|
2008
2393
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
2009
|
-
return
|
|
2394
|
+
return a("warn", "Invalid web vital value", { data: { type: e, value: t } }), !1;
|
|
2010
2395
|
const r = this.vitalThresholds[e];
|
|
2011
2396
|
return !(typeof r == "number" && t <= r);
|
|
2012
2397
|
}
|
|
2013
2398
|
}
|
|
2014
|
-
class
|
|
2399
|
+
class Nt extends S {
|
|
2015
2400
|
eventManager;
|
|
2016
2401
|
recentErrors = /* @__PURE__ */ new Map();
|
|
2402
|
+
errorBurstCounter = 0;
|
|
2403
|
+
burstWindowStart = 0;
|
|
2404
|
+
burstBackoffUntil = 0;
|
|
2017
2405
|
constructor(e) {
|
|
2018
2406
|
super(), this.eventManager = e;
|
|
2019
2407
|
}
|
|
@@ -2021,20 +2409,34 @@ class Tt extends g {
|
|
|
2021
2409
|
window.addEventListener("error", this.handleError), window.addEventListener("unhandledrejection", this.handleRejection);
|
|
2022
2410
|
}
|
|
2023
2411
|
stopTracking() {
|
|
2024
|
-
window.removeEventListener("error", this.handleError), window.removeEventListener("unhandledrejection", this.handleRejection), this.recentErrors.clear();
|
|
2412
|
+
window.removeEventListener("error", this.handleError), window.removeEventListener("unhandledrejection", this.handleRejection), this.recentErrors.clear(), this.errorBurstCounter = 0, this.burstWindowStart = 0, this.burstBackoffUntil = 0;
|
|
2025
2413
|
}
|
|
2414
|
+
/**
|
|
2415
|
+
* Checks sampling rate and burst detection (Phase 3)
|
|
2416
|
+
* Returns false if in cooldown period after burst detection
|
|
2417
|
+
*/
|
|
2026
2418
|
shouldSample() {
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2419
|
+
const e = Date.now();
|
|
2420
|
+
if (e < this.burstBackoffUntil)
|
|
2421
|
+
return !1;
|
|
2422
|
+
if (e - this.burstWindowStart > Ze && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > Je)
|
|
2423
|
+
return this.burstBackoffUntil = e + me, a("warn", "Error burst detected - entering cooldown", {
|
|
2424
|
+
data: {
|
|
2425
|
+
errorsInWindow: this.errorBurstCounter,
|
|
2426
|
+
cooldownMs: me
|
|
2427
|
+
}
|
|
2428
|
+
}), !1;
|
|
2429
|
+
const r = this.get("config")?.errorSampling ?? Le;
|
|
2430
|
+
return Math.random() < r;
|
|
2029
2431
|
}
|
|
2030
2432
|
handleError = (e) => {
|
|
2031
2433
|
if (!this.shouldSample())
|
|
2032
2434
|
return;
|
|
2033
2435
|
const t = this.sanitize(e.message || "Unknown error");
|
|
2034
|
-
this.shouldSuppressError(
|
|
2035
|
-
type:
|
|
2436
|
+
this.shouldSuppressError(P.JS_ERROR, t) || this.eventManager.track({
|
|
2437
|
+
type: u.ERROR,
|
|
2036
2438
|
error_data: {
|
|
2037
|
-
type:
|
|
2439
|
+
type: P.JS_ERROR,
|
|
2038
2440
|
message: t,
|
|
2039
2441
|
...e.filename && { filename: e.filename },
|
|
2040
2442
|
...e.lineno && { line: e.lineno },
|
|
@@ -2046,10 +2448,10 @@ class Tt extends g {
|
|
|
2046
2448
|
if (!this.shouldSample())
|
|
2047
2449
|
return;
|
|
2048
2450
|
const t = this.extractRejectionMessage(e.reason), r = this.sanitize(t);
|
|
2049
|
-
this.shouldSuppressError(
|
|
2050
|
-
type:
|
|
2451
|
+
this.shouldSuppressError(P.PROMISE_REJECTION, r) || this.eventManager.track({
|
|
2452
|
+
type: u.ERROR,
|
|
2051
2453
|
error_data: {
|
|
2052
|
-
type:
|
|
2454
|
+
type: P.PROMISE_REJECTION,
|
|
2053
2455
|
message: r
|
|
2054
2456
|
}
|
|
2055
2457
|
});
|
|
@@ -2069,33 +2471,33 @@ class Tt extends g {
|
|
|
2069
2471
|
}
|
|
2070
2472
|
sanitize(e) {
|
|
2071
2473
|
let t = e.length > fe ? e.slice(0, fe) + "..." : e;
|
|
2072
|
-
for (const r of
|
|
2073
|
-
const
|
|
2074
|
-
t = t.replace(
|
|
2474
|
+
for (const r of le) {
|
|
2475
|
+
const s = new RegExp(r.source, r.flags);
|
|
2476
|
+
t = t.replace(s, "[REDACTED]");
|
|
2075
2477
|
}
|
|
2076
2478
|
return t;
|
|
2077
2479
|
}
|
|
2078
2480
|
shouldSuppressError(e, t) {
|
|
2079
|
-
const r = Date.now(),
|
|
2080
|
-
return i && r - i < ge ? (this.recentErrors.set(
|
|
2481
|
+
const r = Date.now(), s = `${e}:${t}`, i = this.recentErrors.get(s);
|
|
2482
|
+
return i && r - i < ge ? (this.recentErrors.set(s, r), !0) : (this.recentErrors.set(s, r), this.recentErrors.size > qe ? (this.recentErrors.clear(), this.recentErrors.set(s, r), !1) : (this.recentErrors.size > x && this.pruneOldErrors(), !1));
|
|
2081
2483
|
}
|
|
2082
2484
|
pruneOldErrors() {
|
|
2083
2485
|
const e = Date.now();
|
|
2084
|
-
for (const [
|
|
2085
|
-
e - i > ge && this.recentErrors.delete(
|
|
2086
|
-
if (this.recentErrors.size <=
|
|
2486
|
+
for (const [s, i] of this.recentErrors.entries())
|
|
2487
|
+
e - i > ge && this.recentErrors.delete(s);
|
|
2488
|
+
if (this.recentErrors.size <= x)
|
|
2087
2489
|
return;
|
|
2088
|
-
const t = Array.from(this.recentErrors.entries()).sort((
|
|
2089
|
-
for (let
|
|
2090
|
-
const i = t[
|
|
2490
|
+
const t = Array.from(this.recentErrors.entries()).sort((s, i) => s[1] - i[1]), r = this.recentErrors.size - x;
|
|
2491
|
+
for (let s = 0; s < r; s += 1) {
|
|
2492
|
+
const i = t[s];
|
|
2091
2493
|
i && this.recentErrors.delete(i[0]);
|
|
2092
2494
|
}
|
|
2093
2495
|
}
|
|
2094
2496
|
}
|
|
2095
|
-
class
|
|
2497
|
+
class Rt extends S {
|
|
2096
2498
|
isInitialized = !1;
|
|
2097
2499
|
suppressNextScrollTimer = null;
|
|
2098
|
-
emitter = new
|
|
2500
|
+
emitter = new gt();
|
|
2099
2501
|
managers = {};
|
|
2100
2502
|
handlers = {};
|
|
2101
2503
|
integrations = {};
|
|
@@ -2104,10 +2506,10 @@ class It extends g {
|
|
|
2104
2506
|
}
|
|
2105
2507
|
async init(e = {}) {
|
|
2106
2508
|
if (!this.isInitialized) {
|
|
2107
|
-
this.managers.storage = new
|
|
2509
|
+
this.managers.storage = new Lt();
|
|
2108
2510
|
try {
|
|
2109
|
-
this.setupState(e), await this.setupIntegrations(), this.managers.event = new
|
|
2110
|
-
|
|
2511
|
+
this.setupState(e), await this.setupIntegrations(), this.managers.event = new St(this.managers.storage, this.integrations.googleAnalytics, this.emitter), this.initializeHandlers(), await this.managers.event.recoverPersistedEvents().catch((t) => {
|
|
2512
|
+
a("warn", "Failed to recover persisted events", { error: t });
|
|
2111
2513
|
}), this.isInitialized = !0;
|
|
2112
2514
|
} catch (t) {
|
|
2113
2515
|
this.destroy(!0);
|
|
@@ -2119,14 +2521,14 @@ class It extends g {
|
|
|
2119
2521
|
sendCustomEvent(e, t) {
|
|
2120
2522
|
if (!this.managers.event)
|
|
2121
2523
|
return;
|
|
2122
|
-
const { valid: r, error:
|
|
2524
|
+
const { valid: r, error: s, sanitizedMetadata: i } = ft(e, t);
|
|
2123
2525
|
if (!r) {
|
|
2124
|
-
if (this.get("mode") ===
|
|
2125
|
-
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${
|
|
2526
|
+
if (this.get("mode") === D.QA)
|
|
2527
|
+
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${s}`);
|
|
2126
2528
|
return;
|
|
2127
2529
|
}
|
|
2128
2530
|
this.managers.event.track({
|
|
2129
|
-
type:
|
|
2531
|
+
type: u.CUSTOM,
|
|
2130
2532
|
custom_event: {
|
|
2131
2533
|
name: e,
|
|
2132
2534
|
...i && { metadata: i }
|
|
@@ -2144,33 +2546,33 @@ class It extends g {
|
|
|
2144
2546
|
try {
|
|
2145
2547
|
t.stopTracking();
|
|
2146
2548
|
} catch (r) {
|
|
2147
|
-
|
|
2549
|
+
a("warn", "Failed to stop tracking", { error: r });
|
|
2148
2550
|
}
|
|
2149
2551
|
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.set("hasStartSession", !1), this.set("suppressNextScroll", !1), this.set("sessionId", null), this.isInitialized = !1, this.handlers = {});
|
|
2150
2552
|
}
|
|
2151
2553
|
setupState(e = {}) {
|
|
2152
2554
|
this.set("config", e);
|
|
2153
|
-
const t =
|
|
2555
|
+
const t = _t.getId(this.managers.storage);
|
|
2154
2556
|
this.set("userId", t);
|
|
2155
|
-
const r =
|
|
2557
|
+
const r = it(e);
|
|
2156
2558
|
this.set("collectApiUrl", r);
|
|
2157
|
-
const
|
|
2158
|
-
this.set("device",
|
|
2159
|
-
const i =
|
|
2559
|
+
const s = $e();
|
|
2560
|
+
this.set("device", s);
|
|
2561
|
+
const i = ee(window.location.href, e.sensitiveQueryParams);
|
|
2160
2562
|
this.set("pageUrl", i);
|
|
2161
|
-
const
|
|
2162
|
-
|
|
2563
|
+
const o = rt() ? D.QA : void 0;
|
|
2564
|
+
o && this.set("mode", o);
|
|
2163
2565
|
}
|
|
2164
2566
|
async setupIntegrations() {
|
|
2165
2567
|
if (this.get("config").integrations?.googleAnalytics?.measurementId?.trim())
|
|
2166
2568
|
try {
|
|
2167
|
-
this.integrations.googleAnalytics = new
|
|
2569
|
+
this.integrations.googleAnalytics = new yt(), await this.integrations.googleAnalytics.initialize();
|
|
2168
2570
|
} catch {
|
|
2169
2571
|
this.integrations.googleAnalytics = void 0;
|
|
2170
2572
|
}
|
|
2171
2573
|
}
|
|
2172
2574
|
initializeHandlers() {
|
|
2173
|
-
this.handlers.session = new
|
|
2575
|
+
this.handlers.session = new pt(
|
|
2174
2576
|
this.managers.storage,
|
|
2175
2577
|
this.managers.event
|
|
2176
2578
|
), this.handlers.session.startTracking();
|
|
@@ -2179,83 +2581,83 @@ class It extends g {
|
|
|
2179
2581
|
this.set("suppressNextScroll", !1);
|
|
2180
2582
|
}, 500);
|
|
2181
2583
|
};
|
|
2182
|
-
this.handlers.pageView = new
|
|
2183
|
-
|
|
2184
|
-
}), this.handlers.error = new
|
|
2584
|
+
this.handlers.pageView = new It(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new vt(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new At(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new Mt(this.managers.event), this.handlers.performance.startTracking().catch((t) => {
|
|
2585
|
+
a("warn", "Failed to start performance tracking", { error: t });
|
|
2586
|
+
}), this.handlers.error = new Nt(this.managers.event), this.handlers.error.startTracking(), this.get("config").viewport && (this.handlers.viewport = new wt(this.managers.event), this.handlers.viewport.startTracking());
|
|
2185
2587
|
}
|
|
2186
2588
|
}
|
|
2187
|
-
const
|
|
2188
|
-
let
|
|
2189
|
-
const
|
|
2589
|
+
const N = [];
|
|
2590
|
+
let f = null, b = !1, F = !1;
|
|
2591
|
+
const Ot = async (n) => {
|
|
2190
2592
|
if (typeof window > "u" || typeof document > "u")
|
|
2191
2593
|
throw new Error("[TraceLog] This library can only be used in a browser environment");
|
|
2192
|
-
if (!window.__traceLogDisabled && !
|
|
2193
|
-
|
|
2594
|
+
if (!window.__traceLogDisabled && !f && !b) {
|
|
2595
|
+
b = !0;
|
|
2194
2596
|
try {
|
|
2195
|
-
const e =
|
|
2597
|
+
const e = ut(n ?? {}), t = new Rt();
|
|
2196
2598
|
try {
|
|
2197
|
-
|
|
2198
|
-
t.on(i,
|
|
2199
|
-
}),
|
|
2200
|
-
const r = t.init(e),
|
|
2599
|
+
N.forEach(({ event: i, callback: o }) => {
|
|
2600
|
+
t.on(i, o);
|
|
2601
|
+
}), N.length = 0;
|
|
2602
|
+
const r = t.init(e), s = new Promise((i, o) => {
|
|
2201
2603
|
setTimeout(() => {
|
|
2202
|
-
|
|
2604
|
+
o(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
2203
2605
|
}, 1e4);
|
|
2204
2606
|
});
|
|
2205
|
-
await Promise.race([r,
|
|
2607
|
+
await Promise.race([r, s]), f = t;
|
|
2206
2608
|
} catch (r) {
|
|
2207
2609
|
try {
|
|
2208
2610
|
t.destroy(!0);
|
|
2209
|
-
} catch (
|
|
2210
|
-
|
|
2611
|
+
} catch (s) {
|
|
2612
|
+
a("error", "Failed to cleanup partially initialized app", { error: s });
|
|
2211
2613
|
}
|
|
2212
2614
|
throw r;
|
|
2213
2615
|
}
|
|
2214
2616
|
} catch (e) {
|
|
2215
|
-
throw
|
|
2617
|
+
throw f = null, e;
|
|
2216
2618
|
} finally {
|
|
2217
|
-
|
|
2619
|
+
b = !1;
|
|
2218
2620
|
}
|
|
2219
2621
|
}
|
|
2220
|
-
},
|
|
2221
|
-
if (!
|
|
2622
|
+
}, bt = (n, e) => {
|
|
2623
|
+
if (!f)
|
|
2222
2624
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
2223
|
-
if (
|
|
2625
|
+
if (F)
|
|
2224
2626
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
2225
|
-
|
|
2226
|
-
},
|
|
2227
|
-
if (!
|
|
2228
|
-
|
|
2627
|
+
f.sendCustomEvent(n, e);
|
|
2628
|
+
}, Ct = (n, e) => {
|
|
2629
|
+
if (!f || b) {
|
|
2630
|
+
N.push({ event: n, callback: e });
|
|
2229
2631
|
return;
|
|
2230
2632
|
}
|
|
2231
|
-
|
|
2232
|
-
},
|
|
2233
|
-
if (!
|
|
2234
|
-
const t =
|
|
2235
|
-
t !== -1 &&
|
|
2633
|
+
f.on(n, e);
|
|
2634
|
+
}, Pt = (n, e) => {
|
|
2635
|
+
if (!f) {
|
|
2636
|
+
const t = N.findIndex((r) => r.event === n && r.callback === e);
|
|
2637
|
+
t !== -1 && N.splice(t, 1);
|
|
2236
2638
|
return;
|
|
2237
2639
|
}
|
|
2238
|
-
|
|
2239
|
-
},
|
|
2240
|
-
if (
|
|
2640
|
+
f.off(n, e);
|
|
2641
|
+
}, Dt = () => f !== null, Vt = () => {
|
|
2642
|
+
if (F)
|
|
2241
2643
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
2242
|
-
if (!
|
|
2644
|
+
if (!f)
|
|
2243
2645
|
throw new Error("[TraceLog] App not initialized");
|
|
2244
|
-
|
|
2646
|
+
F = !0;
|
|
2245
2647
|
try {
|
|
2246
|
-
|
|
2247
|
-
} catch (
|
|
2248
|
-
|
|
2648
|
+
f.destroy(), f = null, b = !1, N.length = 0;
|
|
2649
|
+
} catch (n) {
|
|
2650
|
+
f = null, b = !1, N.length = 0, a("warn", "Error during destroy, forced cleanup completed", { error: n });
|
|
2249
2651
|
} finally {
|
|
2250
|
-
|
|
2652
|
+
F = !1;
|
|
2251
2653
|
}
|
|
2252
|
-
},
|
|
2654
|
+
}, or = {
|
|
2253
2655
|
WEB_VITALS_THRESHOLDS: ye
|
|
2254
2656
|
// Business thresholds for performance analysis
|
|
2255
|
-
},
|
|
2256
|
-
PII_PATTERNS:
|
|
2657
|
+
}, ar = {
|
|
2658
|
+
PII_PATTERNS: le
|
|
2257
2659
|
// Patterns for sensitive data protection
|
|
2258
|
-
},
|
|
2660
|
+
}, lr = {
|
|
2259
2661
|
LOW_ACTIVITY_EVENT_COUNT: 50,
|
|
2260
2662
|
HIGH_ACTIVITY_EVENT_COUNT: 1e3,
|
|
2261
2663
|
MIN_EVENTS_FOR_DYNAMIC_CALCULATION: 100,
|
|
@@ -2265,7 +2667,7 @@ const vt = async (s) => {
|
|
|
2265
2667
|
MIN_ENGAGED_SESSION_DURATION_MS: 30 * 1e3,
|
|
2266
2668
|
MIN_SCROLL_DEPTH_ENGAGEMENT: 25
|
|
2267
2669
|
// 25% scroll depth for engagement
|
|
2268
|
-
},
|
|
2670
|
+
}, cr = {
|
|
2269
2671
|
INACTIVITY_TIMEOUT_MS: 1800 * 1e3,
|
|
2270
2672
|
// 30min for analytics (vs 15min client)
|
|
2271
2673
|
SHORT_SESSION_THRESHOLD_MS: 30 * 1e3,
|
|
@@ -2273,20 +2675,20 @@ const vt = async (s) => {
|
|
|
2273
2675
|
LONG_SESSION_THRESHOLD_MS: 1800 * 1e3,
|
|
2274
2676
|
MAX_REALISTIC_SESSION_DURATION_MS: 480 * 60 * 1e3
|
|
2275
2677
|
// Filter outliers
|
|
2276
|
-
},
|
|
2678
|
+
}, ur = {
|
|
2277
2679
|
MOBILE_MAX_WIDTH: 768,
|
|
2278
2680
|
TABLET_MAX_WIDTH: 1024,
|
|
2279
2681
|
MOBILE_PERFORMANCE_FACTOR: 1.5,
|
|
2280
2682
|
// Mobile typically 1.5x slower
|
|
2281
2683
|
TABLET_PERFORMANCE_FACTOR: 1.2
|
|
2282
|
-
},
|
|
2684
|
+
}, dr = {
|
|
2283
2685
|
MIN_TEXT_LENGTH_FOR_ANALYSIS: 10,
|
|
2284
2686
|
MIN_CLICKS_FOR_HOT_ELEMENT: 10,
|
|
2285
2687
|
// Popular element threshold
|
|
2286
2688
|
MIN_SCROLL_COMPLETION_PERCENT: 80,
|
|
2287
2689
|
// Page consumption threshold
|
|
2288
2690
|
MIN_TIME_ON_PAGE_FOR_READ_MS: 15 * 1e3
|
|
2289
|
-
},
|
|
2691
|
+
}, hr = {
|
|
2290
2692
|
SIGNIFICANT_CHANGE_PERCENT: 20,
|
|
2291
2693
|
MAJOR_CHANGE_PERCENT: 50,
|
|
2292
2694
|
MIN_EVENTS_FOR_INSIGHT: 100,
|
|
@@ -2296,19 +2698,19 @@ const vt = async (s) => {
|
|
|
2296
2698
|
LOW_ERROR_RATE_PERCENT: 1,
|
|
2297
2699
|
HIGH_ERROR_RATE_PERCENT: 5,
|
|
2298
2700
|
CRITICAL_ERROR_RATE_PERCENT: 10
|
|
2299
|
-
},
|
|
2701
|
+
}, Er = {
|
|
2300
2702
|
SHORT_TERM_TREND_HOURS: 24,
|
|
2301
2703
|
MEDIUM_TERM_TREND_DAYS: 7,
|
|
2302
2704
|
LONG_TERM_TREND_DAYS: 30,
|
|
2303
2705
|
MIN_DATA_POINTS_FOR_TREND: 5,
|
|
2304
2706
|
WEEKLY_PATTERN_MIN_WEEKS: 4,
|
|
2305
2707
|
DAILY_PATTERN_MIN_DAYS: 14
|
|
2306
|
-
},
|
|
2708
|
+
}, fr = {
|
|
2307
2709
|
MIN_SEGMENT_SIZE: 10,
|
|
2308
2710
|
MIN_COHORT_SIZE: 5,
|
|
2309
2711
|
COHORT_ANALYSIS_DAYS: [1, 3, 7, 14, 30],
|
|
2310
2712
|
MIN_FUNNEL_EVENTS: 20
|
|
2311
|
-
},
|
|
2713
|
+
}, gr = {
|
|
2312
2714
|
DEFAULT_EVENTS_LIMIT: 5,
|
|
2313
2715
|
DEFAULT_SESSIONS_LIMIT: 5,
|
|
2314
2716
|
DEFAULT_PAGES_LIMIT: 5,
|
|
@@ -2316,260 +2718,260 @@ const vt = async (s) => {
|
|
|
2316
2718
|
MAX_TIME_RANGE_DAYS: 365,
|
|
2317
2719
|
ANALYTICS_BATCH_SIZE: 1e3
|
|
2318
2720
|
// For historical analysis
|
|
2319
|
-
},
|
|
2721
|
+
}, mr = {
|
|
2320
2722
|
ANOMALY_THRESHOLD_SIGMA: 2.5,
|
|
2321
2723
|
STRONG_ANOMALY_THRESHOLD_SIGMA: 3,
|
|
2322
2724
|
TRAFFIC_DROP_ALERT_PERCENT: -30,
|
|
2323
2725
|
TRAFFIC_SPIKE_ALERT_PERCENT: 200,
|
|
2324
2726
|
MIN_BASELINE_DAYS: 7,
|
|
2325
2727
|
MIN_EVENTS_FOR_ANOMALY_DETECTION: 50
|
|
2326
|
-
},
|
|
2728
|
+
}, Sr = {
|
|
2327
2729
|
PAGE_URL_EXCLUDED: "excluded",
|
|
2328
2730
|
PAGE_URL_UNKNOWN: "unknown"
|
|
2329
|
-
},
|
|
2330
|
-
init:
|
|
2331
|
-
event:
|
|
2332
|
-
on:
|
|
2333
|
-
off:
|
|
2334
|
-
isInitialized:
|
|
2335
|
-
destroy:
|
|
2731
|
+
}, _r = {
|
|
2732
|
+
init: Ot,
|
|
2733
|
+
event: bt,
|
|
2734
|
+
on: Ct,
|
|
2735
|
+
off: Pt,
|
|
2736
|
+
isInitialized: Dt,
|
|
2737
|
+
destroy: Vt
|
|
2336
2738
|
};
|
|
2337
|
-
var
|
|
2739
|
+
var re, Ne = -1, C = function(n) {
|
|
2338
2740
|
addEventListener("pageshow", (function(e) {
|
|
2339
|
-
e.persisted && (
|
|
2741
|
+
e.persisted && (Ne = e.timeStamp, n(e));
|
|
2340
2742
|
}), !0);
|
|
2341
|
-
},
|
|
2342
|
-
var
|
|
2343
|
-
if (
|
|
2344
|
-
},
|
|
2345
|
-
var
|
|
2346
|
-
return
|
|
2347
|
-
},
|
|
2348
|
-
var t =
|
|
2349
|
-
return
|
|
2350
|
-
},
|
|
2743
|
+
}, ce = function() {
|
|
2744
|
+
var n = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
2745
|
+
if (n && n.responseStart > 0 && n.responseStart < performance.now()) return n;
|
|
2746
|
+
}, B = function() {
|
|
2747
|
+
var n = ce();
|
|
2748
|
+
return n && n.activationStart || 0;
|
|
2749
|
+
}, p = function(n, e) {
|
|
2750
|
+
var t = ce(), r = "navigate";
|
|
2751
|
+
return Ne >= 0 ? r = "back-forward-cache" : t && (document.prerendering || B() > 0 ? r = "prerender" : document.wasDiscarded ? r = "restore" : t.type && (r = t.type.replace(/_/g, "-"))), { name: n, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: r };
|
|
2752
|
+
}, k = function(n, e, t) {
|
|
2351
2753
|
try {
|
|
2352
|
-
if (PerformanceObserver.supportedEntryTypes.includes(
|
|
2353
|
-
var r = new PerformanceObserver((function(
|
|
2754
|
+
if (PerformanceObserver.supportedEntryTypes.includes(n)) {
|
|
2755
|
+
var r = new PerformanceObserver((function(s) {
|
|
2354
2756
|
Promise.resolve().then((function() {
|
|
2355
|
-
e(
|
|
2757
|
+
e(s.getEntries());
|
|
2356
2758
|
}));
|
|
2357
2759
|
}));
|
|
2358
|
-
return r.observe(Object.assign({ type:
|
|
2760
|
+
return r.observe(Object.assign({ type: n, buffered: !0 }, t || {})), r;
|
|
2359
2761
|
}
|
|
2360
2762
|
} catch {
|
|
2361
2763
|
}
|
|
2362
|
-
},
|
|
2363
|
-
var
|
|
2364
|
-
return function(
|
|
2365
|
-
e.value >= 0 && (
|
|
2366
|
-
return
|
|
2367
|
-
})(e.value, t),
|
|
2764
|
+
}, I = function(n, e, t, r) {
|
|
2765
|
+
var s, i;
|
|
2766
|
+
return function(o) {
|
|
2767
|
+
e.value >= 0 && (o || r) && ((i = e.value - (s || 0)) || s === void 0) && (s = e.value, e.delta = i, e.rating = (function(l, c) {
|
|
2768
|
+
return l > c[1] ? "poor" : l > c[0] ? "needs-improvement" : "good";
|
|
2769
|
+
})(e.value, t), n(e));
|
|
2368
2770
|
};
|
|
2369
|
-
},
|
|
2771
|
+
}, ue = function(n) {
|
|
2370
2772
|
requestAnimationFrame((function() {
|
|
2371
2773
|
return requestAnimationFrame((function() {
|
|
2372
|
-
return
|
|
2774
|
+
return n();
|
|
2373
2775
|
}));
|
|
2374
2776
|
}));
|
|
2375
|
-
},
|
|
2777
|
+
}, X = function(n) {
|
|
2376
2778
|
document.addEventListener("visibilitychange", (function() {
|
|
2377
|
-
document.visibilityState === "hidden" &&
|
|
2779
|
+
document.visibilityState === "hidden" && n();
|
|
2378
2780
|
}));
|
|
2379
|
-
},
|
|
2781
|
+
}, de = function(n) {
|
|
2380
2782
|
var e = !1;
|
|
2381
2783
|
return function() {
|
|
2382
|
-
e || (
|
|
2784
|
+
e || (n(), e = !0);
|
|
2383
2785
|
};
|
|
2384
|
-
},
|
|
2786
|
+
}, O = -1, ve = function() {
|
|
2385
2787
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
2386
|
-
},
|
|
2387
|
-
document.visibilityState === "hidden" &&
|
|
2388
|
-
},
|
|
2389
|
-
addEventListener("visibilitychange",
|
|
2390
|
-
},
|
|
2391
|
-
removeEventListener("visibilitychange",
|
|
2392
|
-
},
|
|
2393
|
-
return
|
|
2788
|
+
}, W = function(n) {
|
|
2789
|
+
document.visibilityState === "hidden" && O > -1 && (O = n.type === "visibilitychange" ? n.timeStamp : 0, kt());
|
|
2790
|
+
}, Ae = function() {
|
|
2791
|
+
addEventListener("visibilitychange", W, !0), addEventListener("prerenderingchange", W, !0);
|
|
2792
|
+
}, kt = function() {
|
|
2793
|
+
removeEventListener("visibilitychange", W, !0), removeEventListener("prerenderingchange", W, !0);
|
|
2794
|
+
}, Re = function() {
|
|
2795
|
+
return O < 0 && (O = ve(), Ae(), C((function() {
|
|
2394
2796
|
setTimeout((function() {
|
|
2395
|
-
|
|
2797
|
+
O = ve(), Ae();
|
|
2396
2798
|
}), 0);
|
|
2397
2799
|
}))), { get firstHiddenTime() {
|
|
2398
|
-
return
|
|
2800
|
+
return O;
|
|
2399
2801
|
} };
|
|
2400
|
-
},
|
|
2802
|
+
}, $ = function(n) {
|
|
2401
2803
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
2402
|
-
return
|
|
2403
|
-
}), !0) :
|
|
2404
|
-
},
|
|
2405
|
-
e = e || {},
|
|
2406
|
-
var t, r =
|
|
2407
|
-
|
|
2408
|
-
|
|
2804
|
+
return n();
|
|
2805
|
+
}), !0) : n();
|
|
2806
|
+
}, ne = [1800, 3e3], Oe = function(n, e) {
|
|
2807
|
+
e = e || {}, $((function() {
|
|
2808
|
+
var t, r = Re(), s = p("FCP"), i = k("paint", (function(o) {
|
|
2809
|
+
o.forEach((function(l) {
|
|
2810
|
+
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime < r.firstHiddenTime && (s.value = Math.max(l.startTime - B(), 0), s.entries.push(l), t(!0)));
|
|
2409
2811
|
}));
|
|
2410
2812
|
}));
|
|
2411
|
-
i && (t =
|
|
2412
|
-
|
|
2413
|
-
|
|
2813
|
+
i && (t = I(n, s, ne, e.reportAllChanges), C((function(o) {
|
|
2814
|
+
s = p("FCP"), t = I(n, s, ne, e.reportAllChanges), ue((function() {
|
|
2815
|
+
s.value = performance.now() - o.timeStamp, t(!0);
|
|
2414
2816
|
}));
|
|
2415
2817
|
})));
|
|
2416
2818
|
}));
|
|
2417
|
-
},
|
|
2418
|
-
e = e || {},
|
|
2419
|
-
var t, r =
|
|
2420
|
-
c.forEach((function(
|
|
2421
|
-
if (!
|
|
2422
|
-
var
|
|
2423
|
-
|
|
2819
|
+
}, se = [0.1, 0.25], Ut = function(n, e) {
|
|
2820
|
+
e = e || {}, Oe(de((function() {
|
|
2821
|
+
var t, r = p("CLS", 0), s = 0, i = [], o = function(c) {
|
|
2822
|
+
c.forEach((function(d) {
|
|
2823
|
+
if (!d.hadRecentInput) {
|
|
2824
|
+
var _ = i[0], g = i[i.length - 1];
|
|
2825
|
+
s && d.startTime - g.startTime < 1e3 && d.startTime - _.startTime < 5e3 ? (s += d.value, i.push(d)) : (s = d.value, i = [d]);
|
|
2424
2826
|
}
|
|
2425
|
-
})),
|
|
2426
|
-
},
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
})),
|
|
2430
|
-
|
|
2827
|
+
})), s > r.value && (r.value = s, r.entries = i, t());
|
|
2828
|
+
}, l = k("layout-shift", o);
|
|
2829
|
+
l && (t = I(n, r, se, e.reportAllChanges), X((function() {
|
|
2830
|
+
o(l.takeRecords()), t(!0);
|
|
2831
|
+
})), C((function() {
|
|
2832
|
+
s = 0, r = p("CLS", 0), t = I(n, r, se, e.reportAllChanges), ue((function() {
|
|
2431
2833
|
return t();
|
|
2432
2834
|
}));
|
|
2433
2835
|
})), setTimeout(t, 0));
|
|
2434
2836
|
})));
|
|
2435
|
-
},
|
|
2436
|
-
|
|
2437
|
-
e.interactionId && (
|
|
2837
|
+
}, be = 0, Y = 1 / 0, U = 0, Ht = function(n) {
|
|
2838
|
+
n.forEach((function(e) {
|
|
2839
|
+
e.interactionId && (Y = Math.min(Y, e.interactionId), U = Math.max(U, e.interactionId), be = U ? (U - Y) / 7 + 1 : 0);
|
|
2438
2840
|
}));
|
|
2439
|
-
},
|
|
2440
|
-
return
|
|
2441
|
-
},
|
|
2442
|
-
"interactionCount" in performance ||
|
|
2443
|
-
},
|
|
2444
|
-
var
|
|
2445
|
-
return
|
|
2446
|
-
},
|
|
2447
|
-
if (
|
|
2448
|
-
return n
|
|
2449
|
-
})),
|
|
2450
|
-
var e =
|
|
2451
|
-
if (t ||
|
|
2452
|
-
if (t)
|
|
2841
|
+
}, Ce = function() {
|
|
2842
|
+
return re ? be : performance.interactionCount || 0;
|
|
2843
|
+
}, xt = function() {
|
|
2844
|
+
"interactionCount" in performance || re || (re = k("event", Ht, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
2845
|
+
}, T = [], G = /* @__PURE__ */ new Map(), Pe = 0, Ft = function() {
|
|
2846
|
+
var n = Math.min(T.length - 1, Math.floor((Ce() - Pe) / 50));
|
|
2847
|
+
return T[n];
|
|
2848
|
+
}, Gt = [], Wt = function(n) {
|
|
2849
|
+
if (Gt.forEach((function(s) {
|
|
2850
|
+
return s(n);
|
|
2851
|
+
})), n.interactionId || n.entryType === "first-input") {
|
|
2852
|
+
var e = T[T.length - 1], t = G.get(n.interactionId);
|
|
2853
|
+
if (t || T.length < 10 || n.duration > e.latency) {
|
|
2854
|
+
if (t) n.duration > t.latency ? (t.entries = [n], t.latency = n.duration) : n.duration === t.latency && n.startTime === t.entries[0].startTime && t.entries.push(n);
|
|
2453
2855
|
else {
|
|
2454
|
-
var r = { id:
|
|
2455
|
-
|
|
2856
|
+
var r = { id: n.interactionId, latency: n.duration, entries: [n] };
|
|
2857
|
+
G.set(r.id, r), T.push(r);
|
|
2456
2858
|
}
|
|
2457
|
-
|
|
2458
|
-
return i.latency -
|
|
2459
|
-
})),
|
|
2460
|
-
return
|
|
2859
|
+
T.sort((function(s, i) {
|
|
2860
|
+
return i.latency - s.latency;
|
|
2861
|
+
})), T.length > 10 && T.splice(10).forEach((function(s) {
|
|
2862
|
+
return G.delete(s.id);
|
|
2461
2863
|
}));
|
|
2462
2864
|
}
|
|
2463
2865
|
}
|
|
2464
|
-
},
|
|
2866
|
+
}, De = function(n) {
|
|
2465
2867
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
2466
|
-
return
|
|
2467
|
-
},
|
|
2468
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
2868
|
+
return n = de(n), document.visibilityState === "hidden" ? n() : (t = e(n), X(n)), t;
|
|
2869
|
+
}, ie = [200, 500], Bt = function(n, e) {
|
|
2870
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, $((function() {
|
|
2469
2871
|
var t;
|
|
2470
|
-
|
|
2471
|
-
var r,
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
var c =
|
|
2475
|
-
c && c.latency !==
|
|
2872
|
+
xt();
|
|
2873
|
+
var r, s = p("INP"), i = function(l) {
|
|
2874
|
+
De((function() {
|
|
2875
|
+
l.forEach(Wt);
|
|
2876
|
+
var c = Ft();
|
|
2877
|
+
c && c.latency !== s.value && (s.value = c.latency, s.entries = c.entries, r());
|
|
2476
2878
|
}));
|
|
2477
|
-
},
|
|
2478
|
-
r =
|
|
2479
|
-
i(
|
|
2480
|
-
})),
|
|
2481
|
-
|
|
2879
|
+
}, o = k("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
2880
|
+
r = I(n, s, ie, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), X((function() {
|
|
2881
|
+
i(o.takeRecords()), r(!0);
|
|
2882
|
+
})), C((function() {
|
|
2883
|
+
Pe = Ce(), T.length = 0, G.clear(), s = p("INP"), r = I(n, s, ie, e.reportAllChanges);
|
|
2482
2884
|
})));
|
|
2483
2885
|
})));
|
|
2484
|
-
},
|
|
2485
|
-
e = e || {},
|
|
2486
|
-
var t, r =
|
|
2487
|
-
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(
|
|
2488
|
-
|
|
2886
|
+
}, oe = [2500, 4e3], K = {}, Xt = function(n, e) {
|
|
2887
|
+
e = e || {}, $((function() {
|
|
2888
|
+
var t, r = Re(), s = p("LCP"), i = function(c) {
|
|
2889
|
+
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(d) {
|
|
2890
|
+
d.startTime < r.firstHiddenTime && (s.value = Math.max(d.startTime - B(), 0), s.entries = [d], t());
|
|
2489
2891
|
}));
|
|
2490
|
-
},
|
|
2491
|
-
if (
|
|
2492
|
-
t =
|
|
2493
|
-
var
|
|
2494
|
-
|
|
2892
|
+
}, o = k("largest-contentful-paint", i);
|
|
2893
|
+
if (o) {
|
|
2894
|
+
t = I(n, s, oe, e.reportAllChanges);
|
|
2895
|
+
var l = de((function() {
|
|
2896
|
+
K[s.id] || (i(o.takeRecords()), o.disconnect(), K[s.id] = !0, t(!0));
|
|
2495
2897
|
}));
|
|
2496
2898
|
["keydown", "click"].forEach((function(c) {
|
|
2497
2899
|
addEventListener(c, (function() {
|
|
2498
|
-
return
|
|
2900
|
+
return De(l);
|
|
2499
2901
|
}), { once: !0, capture: !0 });
|
|
2500
|
-
})),
|
|
2501
|
-
|
|
2502
|
-
|
|
2902
|
+
})), X(l), C((function(c) {
|
|
2903
|
+
s = p("LCP"), t = I(n, s, oe, e.reportAllChanges), ue((function() {
|
|
2904
|
+
s.value = performance.now() - c.timeStamp, K[s.id] = !0, t(!0);
|
|
2503
2905
|
}));
|
|
2504
2906
|
}));
|
|
2505
2907
|
}
|
|
2506
2908
|
}));
|
|
2507
|
-
},
|
|
2508
|
-
document.prerendering ?
|
|
2509
|
-
return
|
|
2909
|
+
}, ae = [800, 1800], $t = function n(e) {
|
|
2910
|
+
document.prerendering ? $((function() {
|
|
2911
|
+
return n(e);
|
|
2510
2912
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
2511
|
-
return
|
|
2913
|
+
return n(e);
|
|
2512
2914
|
}), !0) : setTimeout(e, 0);
|
|
2513
|
-
},
|
|
2915
|
+
}, zt = function(n, e) {
|
|
2514
2916
|
e = e || {};
|
|
2515
|
-
var t =
|
|
2516
|
-
|
|
2517
|
-
var
|
|
2518
|
-
|
|
2519
|
-
t =
|
|
2917
|
+
var t = p("TTFB"), r = I(n, t, ae, e.reportAllChanges);
|
|
2918
|
+
$t((function() {
|
|
2919
|
+
var s = ce();
|
|
2920
|
+
s && (t.value = Math.max(s.responseStart - B(), 0), t.entries = [s], r(!0), C((function() {
|
|
2921
|
+
t = p("TTFB", 0), (r = I(n, t, ae, e.reportAllChanges))(!0);
|
|
2520
2922
|
})));
|
|
2521
2923
|
}));
|
|
2522
2924
|
};
|
|
2523
|
-
const
|
|
2925
|
+
const Qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2524
2926
|
__proto__: null,
|
|
2525
|
-
CLSThresholds:
|
|
2526
|
-
FCPThresholds:
|
|
2527
|
-
INPThresholds:
|
|
2528
|
-
LCPThresholds:
|
|
2529
|
-
TTFBThresholds:
|
|
2530
|
-
onCLS:
|
|
2531
|
-
onFCP:
|
|
2532
|
-
onINP:
|
|
2533
|
-
onLCP:
|
|
2534
|
-
onTTFB:
|
|
2927
|
+
CLSThresholds: se,
|
|
2928
|
+
FCPThresholds: ne,
|
|
2929
|
+
INPThresholds: ie,
|
|
2930
|
+
LCPThresholds: oe,
|
|
2931
|
+
TTFBThresholds: ae,
|
|
2932
|
+
onCLS: Ut,
|
|
2933
|
+
onFCP: Oe,
|
|
2934
|
+
onINP: Bt,
|
|
2935
|
+
onLCP: Xt,
|
|
2936
|
+
onTTFB: zt
|
|
2535
2937
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2536
2938
|
export {
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2939
|
+
gr as ANALYTICS_QUERY_LIMITS,
|
|
2940
|
+
mr as ANOMALY_DETECTION,
|
|
2941
|
+
E as AppConfigValidationError,
|
|
2942
|
+
dr as CONTENT_ANALYTICS,
|
|
2943
|
+
ar as DATA_PROTECTION,
|
|
2944
|
+
ur as DEVICE_ANALYTICS,
|
|
2945
|
+
w as DeviceType,
|
|
2946
|
+
lr as ENGAGEMENT_THRESHOLDS,
|
|
2947
|
+
Z as EmitterEvent,
|
|
2948
|
+
P as ErrorType,
|
|
2949
|
+
u as EventType,
|
|
2950
|
+
hr as INSIGHT_THRESHOLDS,
|
|
2951
|
+
ir as InitializationTimeoutError,
|
|
2952
|
+
M as IntegrationValidationError,
|
|
2953
|
+
rr as MAX_ARRAY_LENGTH,
|
|
2954
|
+
qt as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
2955
|
+
Kt as MAX_CUSTOM_EVENT_KEYS,
|
|
2956
|
+
jt as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
2957
|
+
Yt as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
2958
|
+
Jt as MAX_METADATA_NESTING_DEPTH,
|
|
2959
|
+
Zt as MAX_NESTED_OBJECT_KEYS,
|
|
2960
|
+
er as MAX_STRING_LENGTH,
|
|
2961
|
+
tr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
2962
|
+
D as Mode,
|
|
2963
|
+
or as PERFORMANCE_CONFIG,
|
|
2964
|
+
R as PermanentError,
|
|
2965
|
+
fr as SEGMENTATION_ANALYTICS,
|
|
2966
|
+
cr as SESSION_ANALYTICS,
|
|
2967
|
+
Sr as SPECIAL_PAGE_URLS,
|
|
2968
|
+
he as SamplingRateValidationError,
|
|
2969
|
+
H as ScrollDirection,
|
|
2970
|
+
Ge as SessionTimeoutValidationError,
|
|
2971
|
+
q as SpecialApiUrl,
|
|
2972
|
+
Er as TEMPORAL_ANALYSIS,
|
|
2973
|
+
V as TraceLogValidationError,
|
|
2974
|
+
nr as isPrimaryScrollEvent,
|
|
2975
|
+
sr as isSecondaryScrollEvent,
|
|
2976
|
+
_r as tracelog
|
|
2575
2977
|
};
|