@tracelog/lib 0.9.0 → 0.11.0

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