@sailfish-ai/recorder 1.10.7 → 1.10.9

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 (35) hide show
  1. package/dist/chunks/{chunkSerializer-BuEZW3N4.js → chunkSerializer-B_szIq8O.js} +1 -1
  2. package/dist/chunks/chunkSerializer-B_szIq8O.js.br +0 -0
  3. package/dist/chunks/chunkSerializer-B_szIq8O.js.gz +0 -0
  4. package/dist/chunks/{chunkSerializer-DM9muyGb.js → chunkSerializer-DdlgLmEH.js} +1 -1
  5. package/dist/chunks/chunkSerializer-DdlgLmEH.js.br +0 -0
  6. package/dist/chunks/chunkSerializer-DdlgLmEH.js.gz +0 -0
  7. package/dist/chunks/{index-soHaKXF4.js → index-B8gnDRst.js} +254 -236
  8. package/dist/chunks/index-B8gnDRst.js.br +0 -0
  9. package/dist/chunks/index-B8gnDRst.js.gz +0 -0
  10. package/dist/chunks/{index-BlPJWz9y.js → index-w2Ted1rp.js} +451 -376
  11. package/dist/chunks/index-w2Ted1rp.js.br +0 -0
  12. package/dist/chunks/index-w2Ted1rp.js.gz +0 -0
  13. package/dist/inAppReportIssueModal/index.js +106 -42
  14. package/dist/inAppReportIssueModal/integrations.js +0 -3
  15. package/dist/inAppReportIssueModal/types.js +1 -0
  16. package/dist/inAppReportIssueModal/ui.js +15 -8
  17. package/dist/index.js +15 -4
  18. package/dist/recorder.cjs +2 -2
  19. package/dist/recorder.js +12 -11
  20. package/dist/recorder.js.br +0 -0
  21. package/dist/recorder.js.gz +0 -0
  22. package/dist/types/inAppReportIssueModal/index.d.ts +5 -1
  23. package/dist/types/inAppReportIssueModal/types.d.ts +1 -0
  24. package/dist/types/index.d.ts +1 -0
  25. package/dist/types/websocket.d.ts +4 -0
  26. package/dist/websocket.js +11 -0
  27. package/package.json +1 -1
  28. package/dist/chunks/chunkSerializer-BuEZW3N4.js.br +0 -0
  29. package/dist/chunks/chunkSerializer-BuEZW3N4.js.gz +0 -0
  30. package/dist/chunks/chunkSerializer-DM9muyGb.js.br +0 -0
  31. package/dist/chunks/chunkSerializer-DM9muyGb.js.gz +0 -0
  32. package/dist/chunks/index-BlPJWz9y.js.br +0 -0
  33. package/dist/chunks/index-BlPJWz9y.js.gz +0 -0
  34. package/dist/chunks/index-soHaKXF4.js.br +0 -0
  35. package/dist/chunks/index-soHaKXF4.js.gz +0 -0
@@ -1,5 +1,27 @@
1
- import e from "reconnecting-websocket";
2
- import { EventType as t } from "@sailfish-rrweb/types";
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ const e = require("reconnecting-websocket"), t = require("@sailfish-rrweb/types");
3
25
  function readDebugFlag() {
4
26
  var _a;
5
27
  try {
@@ -151,20 +173,27 @@ function buildBatches(e2, t2, n2) {
151
173
  function eventSize(e2) {
152
174
  return JSON.stringify(e2).length;
153
175
  }
154
- let S = Date.now;
155
176
  function withAppUrlMetadata(e2) {
156
177
  var _a;
157
178
  return { ...e2 ?? {}, appUrl: (e2 == null ? void 0 : e2.appUrl) ?? ((_a = window == null ? void 0 : window.location) == null ? void 0 : _a.href) };
158
179
  }
159
- /[1-9][0-9]{12}/.test(Date.now().toString()) || (S = () => (/* @__PURE__ */ new Date()).getTime());
160
- const v = readDebugFlag(), k = "per_session";
161
- let x = null, I = null, T = false, E = null, C = null, $ = "", F = "", M = false;
180
+ exports.nowTimestamp = Date.now, /[1-9][0-9]{12}/.test(Date.now().toString()) || (exports.nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime());
181
+ const S = readDebugFlag(), v = "per_session";
182
+ let k = null, x = null, I = false, T = null, E = null, C = "", $ = "", F = false;
183
+ const M = [];
184
+ function onNavigationChange(e2) {
185
+ M.push(e2);
186
+ }
162
187
  function _updateHrefCache() {
163
- $ = window.location.href, F = window.location.origin + window.location.pathname;
188
+ C = window.location.href, $ = window.location.origin + window.location.pathname;
189
+ for (const e2 of M) try {
190
+ e2();
191
+ } catch (e3) {
192
+ }
164
193
  }
165
194
  function ensureHrefCache() {
166
- if (M || "undefined" == typeof window) return;
167
- M = true, _updateHrefCache(), window.addEventListener("popstate", _updateHrefCache), window.addEventListener("hashchange", _updateHrefCache);
195
+ if (F || "undefined" == typeof window) return;
196
+ F = true, _updateHrefCache(), window.addEventListener("popstate", _updateHrefCache), window.addEventListener("hashchange", _updateHrefCache);
168
197
  const e2 = history.pushState;
169
198
  history.pushState = function(...t3) {
170
199
  e2.apply(this, t3), _updateHrefCache();
@@ -175,10 +204,10 @@ function ensureHrefCache() {
175
204
  };
176
205
  }
177
206
  function getCachedHref() {
178
- return $ || ("undefined" != typeof window ? window.location.href : "");
207
+ return C || ("undefined" != typeof window ? window.location.href : "");
179
208
  }
180
209
  function getCachedHrefNoQuery() {
181
- return F || ("undefined" != typeof window ? window.location.origin + window.location.pathname : "");
210
+ return $ || ("undefined" != typeof window ? window.location.origin + window.location.pathname : "");
182
211
  }
183
212
  const L = [];
184
213
  let A = null;
@@ -196,27 +225,27 @@ function _flushIDBQueue() {
196
225
  let R = false, D = null, P = null, _ = false;
197
226
  const B = "sailfish_funcspan_global_state";
198
227
  function wsSendPayload(e2) {
199
- if (!isWebSocketOpen(I)) return false;
200
- if (x) try {
201
- return x.postMessage({ type: "send", payload: e2 }), true;
228
+ if (!isWebSocketOpen(x)) return false;
229
+ if (k) try {
230
+ return k.postMessage({ type: "send", payload: e2 }), true;
202
231
  } catch {
203
232
  return false;
204
233
  }
205
234
  try {
206
- return I.send(JSON.stringify(e2)), true;
235
+ return x.send(JSON.stringify(e2)), true;
207
236
  } catch {
208
237
  return false;
209
238
  }
210
239
  }
211
240
  function wsSendRaw(e2) {
212
- if (!isWebSocketOpen(I)) return false;
213
- if (x) try {
214
- return x.postMessage({ type: "sendRaw", payload: e2 }), true;
241
+ if (!isWebSocketOpen(x)) return false;
242
+ if (k) try {
243
+ return k.postMessage({ type: "sendRaw", payload: e2 }), true;
215
244
  } catch {
216
245
  return false;
217
246
  }
218
247
  try {
219
- return I.send(e2), true;
248
+ return x.send(e2), true;
220
249
  } catch {
221
250
  return false;
222
251
  }
@@ -225,21 +254,21 @@ function saveGlobalFuncSpanState(e2, t2) {
225
254
  try {
226
255
  if ("undefined" == typeof localStorage) return;
227
256
  const n2 = { enabled: e2, expirationTimestampMs: t2, savedAt: Date.now() };
228
- localStorage.setItem(B, JSON.stringify(n2)), v && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
257
+ localStorage.setItem(B, JSON.stringify(n2)), S && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
229
258
  } catch (e3) {
230
- v && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
259
+ S && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
231
260
  }
232
261
  }
233
262
  function clearGlobalFuncSpanState() {
234
263
  try {
235
264
  if ("undefined" == typeof localStorage) return;
236
- localStorage.removeItem(B), v && console.log("[Sailfish] Cleared funcSpan state from localStorage");
265
+ localStorage.removeItem(B), S && console.log("[Sailfish] Cleared funcSpan state from localStorage");
237
266
  } catch (e2) {
238
- v && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
267
+ S && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
239
268
  }
240
269
  }
241
270
  function clearStaleFuncSpanState() {
242
- R = false, P = null, _ = false, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
271
+ R = false, P = null, _ = false, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
243
272
  }
244
273
  let j = false;
245
274
  function restoreFuncSpanState() {
@@ -251,14 +280,14 @@ function restoreFuncSpanState() {
251
280
  const e3 = localStorage.getItem(B);
252
281
  if (!e3) return null;
253
282
  const t2 = JSON.parse(e3);
254
- return v && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
283
+ return S && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
255
284
  } catch (e3) {
256
- return v && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
285
+ return S && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
257
286
  }
258
287
  })();
259
- if (e2 && e2.enabled) if (R = true, P = e2.expirationTimestampMs, _ = false, v && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: P }), null !== P) {
260
- Date.now() >= P ? (R = false, P = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : v && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
261
- } else v && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
288
+ if (e2 && e2.enabled) if (R = true, P = e2.expirationTimestampMs, _ = false, S && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: P }), null !== P) {
289
+ Date.now() >= P ? (R = false, P = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : S && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
290
+ } else S && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
262
291
  }
263
292
  function isWebSocketOpen(e2) {
264
293
  return (e2 == null ? void 0 : e2.readyState) === WebSocket.OPEN;
@@ -270,7 +299,7 @@ async function flushNotifyQueue() {
270
299
  n2.onsuccess = () => t2(n2.result), n2.onerror = () => t2([]);
271
300
  })) ?? [];
272
301
  })();
273
- if (isWebSocketOpen(I)) try {
302
+ if (isWebSocketOpen(x)) try {
274
303
  for (const t2 of e2) {
275
304
  if (!wsSendRaw(t2.value)) break;
276
305
  await deleteNotifyMessageById(t2.id);
@@ -279,9 +308,9 @@ async function flushNotifyQueue() {
279
308
  }
280
309
  }
281
310
  async function flushBufferedEvents() {
282
- if (isWebSocketOpen(I)) if (E) await E;
311
+ if (isWebSocketOpen(x)) if (T) await T;
283
312
  else {
284
- E = (async () => {
313
+ T = (async () => {
285
314
  var _a, _b;
286
315
  const e2 = await (async function getAllIndexedEvents() {
287
316
  return await withStore$1("readonly", (e3) => new Promise((t3) => {
@@ -296,7 +325,7 @@ async function flushBufferedEvents() {
296
325
  for (const e3 of Object.values(t2)) {
297
326
  const t3 = buildBatches(e3, (e4) => eventSize(e4.data), 52428800);
298
327
  for (const e4 of t3) {
299
- if (!isWebSocketOpen(I)) break;
328
+ if (!isWebSocketOpen(x)) break;
300
329
  const t4 = e4.map((e5) => (e5.data.appUrl || (e5.data.appUrl = getCachedHref()), e5.data)), n2 = e4.map((e5) => e5.id).filter((e5) => null != e5);
301
330
  try {
302
331
  wsSendPayload({ type: "events", events: t4, mapUuid: window.sfMapUuid }) && await deleteEventsByIds(n2);
@@ -306,51 +335,51 @@ async function flushBufferedEvents() {
306
335
  }
307
336
  })();
308
337
  try {
309
- await E;
338
+ await T;
310
339
  } finally {
311
- E = null;
340
+ T = null;
312
341
  }
313
342
  }
314
343
  }
315
344
  function sendEvent(e2) {
316
- e2.app_url || (e2.app_url = getCachedHref()), !T && isWebSocketOpen(I) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
345
+ e2.app_url || (e2.app_url = getCachedHref()), !I && isWebSocketOpen(x) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
317
346
  }
318
347
  function handleWsOpen() {
319
- v && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (R ? "ENABLED" : "DISABLED"))), (async () => {
348
+ S && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (R ? "ENABLED" : "DISABLED"))), (async () => {
320
349
  try {
321
- T = true, await flushNotifyQueue(), await flushBufferedEvents();
350
+ I = true, await flushNotifyQueue(), await flushBufferedEvents();
322
351
  } finally {
323
- T = false;
352
+ I = false;
324
353
  }
325
- null != C && clearInterval(C), C = window.setInterval(() => {
354
+ null != E && clearInterval(E), E = window.setInterval(() => {
326
355
  flushBufferedEvents();
327
356
  }, 2e3);
328
357
  })();
329
358
  }
330
359
  function handleWsClose() {
331
- null != C && (clearInterval(C), C = null), v && console.log("[Sailfish] WebSocket closed");
360
+ null != E && (clearInterval(E), E = null), S && console.log("[Sailfish] WebSocket closed");
332
361
  }
333
362
  function handleWsMessage(e2) {
334
363
  try {
335
364
  const t2 = JSON.parse(e2);
336
- if ("funcSpanTrackingControl" === t2.type) if (v && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== D && (window.clearTimeout(D), D = null), R = t2.enabled, _ = false, v && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
365
+ if ("funcSpanTrackingControl" === t2.type) if (S && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== D && (window.clearTimeout(D), D = null), R = t2.enabled, _ = false, S && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
337
366
  if (t2.expirationTimestampMs) {
338
367
  P = t2.expirationTimestampMs;
339
368
  const e3 = Date.now(), n2 = P - e3;
340
- v && console.log(`[Sailfish] Server expiration timestamp: ${P}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, P), D = window.setTimeout(() => {
341
- _ || (R = false, P = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), v && console.log("[Sailfish] Notified backend that function span tracking expired"));
342
- }, n2)) : (R = false, P = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Tracking already expired, not enabling"));
369
+ S && console.log(`[Sailfish] Server expiration timestamp: ${P}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, P), D = window.setTimeout(() => {
370
+ _ || (R = false, P = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), S && console.log("[Sailfish] Notified backend that function span tracking expired"));
371
+ }, n2)) : (R = false, P = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Tracking already expired, not enabling"));
343
372
  } else {
344
373
  const e3 = t2.timeoutSeconds || 3600;
345
374
  e3 > 0 && (P = Date.now() + 1e3 * e3, saveGlobalFuncSpanState(true, P), D = window.setTimeout(() => {
346
- _ || (R = false, P = null, clearGlobalFuncSpanState(), v && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), v && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
375
+ _ || (R = false, P = null, clearGlobalFuncSpanState(), S && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), S && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
347
376
  }, 1e3 * e3));
348
377
  }
349
378
  try {
350
379
  const e3 = getOrSetSessionId();
351
- wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), v && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
380
+ wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), S && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
352
381
  } catch (e3) {
353
- v && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
382
+ S && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
354
383
  }
355
384
  } else P = null, clearGlobalFuncSpanState();
356
385
  } catch (e3) {
@@ -362,8 +391,8 @@ function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
362
391
  const t3 = new URL(e2);
363
392
  return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
364
393
  })(t2);
365
- let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${a2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.10.7`;
366
- if (o2 && (r2 += `&envValue=${encodeURIComponent(o2)}`), x = s2 ? (function tryCreateWsWorker() {
394
+ let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${a2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.10.9`;
395
+ if (o2 && (r2 += `&envValue=${encodeURIComponent(o2)}`), k = s2 ? (function tryCreateWsWorker() {
367
396
  if ("undefined" == typeof Worker) return null;
368
397
  try {
369
398
  const e2 = new Blob(['\nvar ws = null;\nvar wsUrl = "";\nvar reconnectTimer = null;\nvar reconnectDelay = 1000;\nvar MAX_RECONNECT_DELAY = 30000;\nvar CONNECTION_TIMEOUT = 30000;\nvar queue = [];\nvar MAX_QUEUE = 500;\n\nfunction enqueue(str) {\n if (queue.length >= MAX_QUEUE) queue.shift();\n queue.push(str);\n}\n\nfunction drain() {\n while (queue.length > 0) {\n if (!ws || ws.readyState !== 1) break;\n try { ws.send(queue.shift()); } catch (e) { break; }\n }\n}\n\nfunction connect() {\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) return;\n try { ws = new WebSocket(wsUrl); } catch (e) { scheduleReconnect(); return; }\n var tid = setTimeout(function() { if (ws && ws.readyState === 0) ws.close(); }, CONNECTION_TIMEOUT);\n ws.onopen = function() {\n clearTimeout(tid);\n reconnectDelay = 1000;\n drain();\n postMessage({ type: "open" });\n };\n ws.onclose = function() {\n clearTimeout(tid);\n ws = null;\n postMessage({ type: "close" });\n scheduleReconnect();\n };\n ws.onerror = function() {};\n ws.onmessage = function(e) {\n postMessage({ type: "message", data: e.data });\n };\n}\n\nfunction scheduleReconnect() {\n if (reconnectTimer) return;\n reconnectTimer = setTimeout(function() {\n reconnectTimer = null;\n reconnectDelay = Math.min(reconnectDelay * 1.5, MAX_RECONNECT_DELAY);\n connect();\n }, reconnectDelay);\n}\n\nself.onmessage = function(e) {\n var msg = e.data;\n if (msg.type === "init") {\n wsUrl = msg.wsUrl;\n connect();\n } else if (msg.type === "send") {\n try {\n var s = JSON.stringify(msg.payload);\n if (ws && ws.readyState === 1) { ws.send(s); }\n else { enqueue(s); }\n } catch (e) {}\n } else if (msg.type === "sendRaw") {\n if (ws && ws.readyState === 1) {\n try { ws.send(msg.payload); } catch (e) { enqueue(msg.payload); }\n } else { enqueue(msg.payload); }\n } else if (msg.type === "close") {\n if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }\n if (ws) { ws.close(); ws = null; }\n }\n};\n'], { type: "application/javascript" }), t3 = URL.createObjectURL(e2), n3 = new Worker(t3);
@@ -371,84 +400,73 @@ function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
371
400
  } catch {
372
401
  return null;
373
402
  }
374
- })() : null, x) {
375
- const e2 = x, t3 = { readyState: WebSocket.CONNECTING, close: () => {
376
- t3.readyState = WebSocket.CLOSED, e2.postMessage({ type: "close" }), e2.terminate(), x = null, null != C && (clearInterval(C), C = null);
403
+ })() : null, k) {
404
+ const e2 = k, t3 = { readyState: WebSocket.CONNECTING, close: () => {
405
+ t3.readyState = WebSocket.CLOSED, e2.postMessage({ type: "close" }), e2.terminate(), k = null, null != E && (clearInterval(E), E = null);
377
406
  } };
378
- return I = t3, x.onmessage = (e3) => {
407
+ return x = t3, k.onmessage = (e3) => {
379
408
  const n3 = e3.data;
380
409
  "open" === n3.type ? (t3.readyState = WebSocket.OPEN, handleWsOpen()) : "close" === n3.type ? (t3.readyState = WebSocket.CLOSED, handleWsClose()) : "message" === n3.type && handleWsMessage(n3.data);
381
- }, x.onerror = () => {
382
- v && console.warn("[Sailfish] WebSocket worker error");
383
- }, x.postMessage({ type: "init", wsUrl: r2 }), v && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
410
+ }, k.onerror = () => {
411
+ S && console.warn("[Sailfish] WebSocket worker error");
412
+ }, k.postMessage({ type: "init", wsUrl: r2 }), S && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
384
413
  }
385
- v && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
414
+ S && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
386
415
  const l2 = new e(r2, [], { connectionTimeout: 3e4 }), c2 = { get readyState() {
387
416
  return l2.readyState;
388
417
  }, close: () => {
389
- l2.close(), null != C && (clearInterval(C), C = null);
418
+ l2.close(), null != E && (clearInterval(E), E = null);
390
419
  } };
391
- return I = c2, l2.addEventListener("open", () => handleWsOpen()), l2.addEventListener("close", () => handleWsClose()), l2.addEventListener("message", (e2) => handleWsMessage(e2.data)), c2;
420
+ return x = c2, l2.addEventListener("open", () => handleWsOpen()), l2.addEventListener("close", () => handleWsClose()), l2.addEventListener("message", (e2) => handleWsMessage(e2.data)), c2;
392
421
  }
393
422
  function sendMessage(e2) {
394
- "sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), T || !isWebSocketOpen(I) ? saveNotifyMessageToIDB(JSON.stringify(e2)) : wsSendPayload(e2) || saveNotifyMessageToIDB(JSON.stringify(e2));
423
+ "sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), I || !isWebSocketOpen(x) ? saveNotifyMessageToIDB(JSON.stringify(e2)) : wsSendPayload(e2) || saveNotifyMessageToIDB(JSON.stringify(e2));
395
424
  }
396
425
  function enableFunctionSpanTracking() {
397
- if (v && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), R = true, _ = true, P = null, null !== D && (window.clearTimeout(D), D = null), isWebSocketOpen(I)) {
398
- wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: k });
399
- } else v && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
426
+ if (S && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), R = true, _ = true, P = null, null !== D && (window.clearTimeout(D), D = null), isWebSocketOpen(x)) {
427
+ wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: v });
428
+ } else S && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
400
429
  }
401
430
  function disableFunctionSpanTracking() {
402
- if (v && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(I)) {
403
- wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType: k });
431
+ if (S && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(x)) {
432
+ wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType: v });
404
433
  } else console.warn("[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end");
405
- _ && (R = false, _ = false, P = null, v && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== D && (window.clearTimeout(D), D = null);
434
+ _ && (R = false, _ = false, P = null, S && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== D && (window.clearTimeout(D), D = null);
406
435
  }
407
436
  function isFunctionSpanTrackingEnabled() {
408
437
  return R;
409
438
  }
410
439
  function initializeFunctionSpanTrackingFromApi(e2) {
411
- e2 && !R ? (R = true, _ = false, P = null, v && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && R && (R = false, _ = false, P = null, v && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
440
+ e2 && !R ? (R = true, _ = false, P = null, S && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && R && (R = false, _ = false, P = null, S && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
412
441
  }
413
442
  function getFuncSpanHeader() {
414
443
  if (!R) return null;
415
444
  if (null !== P) {
416
- if (Date.now() >= P) return R = false, P = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
445
+ if (Date.now() >= P) return R = false, P = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
417
446
  }
418
447
  return { name: "X-Sf3-FunctionSpanCaptureOverride", value: "1-1-10-10-1-1.0-1-0-0" };
419
448
  }
420
- const O = Object.freeze(Object.defineProperty({ __proto__: null, clearStaleFuncSpanState, disableFunctionSpanTracking, enableFunctionSpanTracking, ensureHrefCache, flushBufferedEvents, getCachedHref, getCachedHrefNoQuery, getFuncSpanHeader, initializeFunctionSpanTrackingFromApi, initializeWebSocket, isFunctionSpanTrackingEnabled, restoreFuncSpanState, sendEvent, sendMessage }, Symbol.toStringTag, { value: "Module" }));
421
- let z = null, H = null;
422
- function identify(e2, t2 = {}, n2 = false) {
423
- const i2 = { type: "identify", userId: e2, traits: t2 };
424
- z && z.userId === e2 && JSON.stringify(z.traits) === JSON.stringify(t2) || (z = { userId: e2, traits: t2, overwrite: n2 }, sendMessage(i2));
425
- }
426
- function addOrUpdateMetadata(e2) {
427
- const t2 = { type: "addOrUpdateMetadata", metadata: e2 };
428
- H && JSON.stringify(H) === JSON.stringify(e2) || (H = e2, sendMessage(t2));
429
- }
430
- function trackingEvent(e2) {
431
- sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: S() });
432
- }
433
- let U = null;
434
- const q = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
449
+ const z = Object.freeze(Object.defineProperty({ __proto__: null, clearStaleFuncSpanState, disableFunctionSpanTracking, enableFunctionSpanTracking, ensureHrefCache, flushBufferedEvents, getCachedHref, getCachedHrefNoQuery, getFuncSpanHeader, initializeFunctionSpanTrackingFromApi, initializeWebSocket, isFunctionSpanTrackingEnabled, onNavigationChange, restoreFuncSpanState, sendEvent, sendMessage }, Symbol.toStringTag, { value: "Module" }));
450
+ let O = null, U = null;
451
+ let H = null;
452
+ const N = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
435
453
  function fetchAndSendIp(e2) {
436
- U !== e2 && (U = e2, (async () => {
437
- for (const e3 of q) try {
454
+ H !== e2 && (H = e2, (async () => {
455
+ for (const e3 of N) try {
438
456
  const t2 = new AbortController(), n2 = setTimeout(() => t2.abort(), 5e3), i2 = await fetch(e3, { signal: t2.signal });
439
457
  if (clearTimeout(n2), !i2.ok) continue;
440
458
  const o2 = await i2.json(), s2 = o2.ip || o2.origin || null;
441
- if (s2 && "string" == typeof s2 && s2.length <= 45) return void sendMessage({ type: "visitorIp", ip: s2, timestamp: S() });
459
+ if (s2 && "string" == typeof s2 && s2.length <= 45) return void sendMessage({ type: "visitorIp", ip: s2, timestamp: exports.nowTimestamp() });
442
460
  } catch {
443
461
  }
444
- U = null;
462
+ H = null;
445
463
  })().catch(() => {
446
- U = null;
464
+ H = null;
447
465
  }));
448
466
  }
449
- let N = null;
467
+ let q = null;
450
468
  async function getSourceMapModule() {
451
- return N || (N = await import("source-map-js")), N;
469
+ return q || (q = await import("source-map-js")), q;
452
470
  }
453
471
  const W = /* @__PURE__ */ new Map(), K = /(?:\(|\s|^)(https?:\/\/[^)\s]+|\/[^)\s]+|[^)\s]+)?\/?([^/]+\.js)(?:\?[^:)]*)?:(\d+):(\d+)/;
454
472
  async function getConsumerFor(e2, t2) {
@@ -658,7 +676,7 @@ async function initializeConsolePlugin(e2, n2) {
658
676
  const { name: o2, observer: s2 } = i2(e2);
659
677
  s2((e3) => {
660
678
  const i3 = e3, [s3, a2] = getCallerLocationFromTrace(i3 == null ? void 0 : i3.trace, 0), [r2, l2] = getCallerLocation(2), c2 = s3 ?? r2, d2 = a2 ?? l2, u2 = { ...i3, sourceFile: c2, sourceLine: d2 };
661
- sendEvent({ type: t.Plugin, timestamp: Date.now(), data: { plugin: o2, payload: u2 }, sessionId: n2, ...getUrlAndStoredUuids() });
679
+ sendEvent({ type: t.EventType.Plugin, timestamp: Date.now(), data: { plugin: o2, payload: u2 }, sessionId: n2, ...getUrlAndStoredUuids() });
662
680
  }, window, e2);
663
681
  }
664
682
  async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2 = false) {
@@ -688,14 +706,14 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
688
706
  Object.assign(e3, getUrlAndStoredUuids()), e3.sessionId = o2, n3.emit(e3);
689
707
  }, startHeavyWork = async () => {
690
708
  if (true === e2.enableFiberTracking) try {
691
- const { installFiberHook: e3, processExistingTree: t2 } = await import("./fiberHook-DGANQ2ma.js");
709
+ const { installFiberHook: e3, processExistingTree: t2 } = await Promise.resolve().then(() => require("./fiberHook-CEzmPkx_.js"));
692
710
  e3(), t2(), console.log("[Sailfish] React Fiber tracking enabled");
693
711
  } catch (e3) {
694
712
  console.warn("[Sailfish] Failed to enable Fiber tracking:", e3);
695
713
  }
696
714
  const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
697
715
  if (J = n4, await yieldToMain(), l2) {
698
- const { chunkedSnapshot: i3 } = await import("./chunkSerializer-BuEZW3N4.js"), o3 = n4.mirror;
716
+ const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-DdlgLmEH.js")), o3 = n4.mirror;
699
717
  let s3 = true;
700
718
  const a3 = [];
701
719
  n4({ emit(e3) {
@@ -703,7 +721,7 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
703
721
  }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: X, ...e2, recordDOM: false });
704
722
  const r3 = Date.now(), l3 = await i3(document, o3, { chunkSize: 500, maxChunkMs: 16, blockClass: e2.blockClass, blockSelector: e2.blockSelector, maskTextClass: e2.maskTextClass ?? X, maskTextSelector: e2.maskTextSelector });
705
723
  if (l3) {
706
- emitWithContext({ type: t.Meta, data: { href: window.location.href, width: document.documentElement.clientWidth || document.body.clientWidth, height: document.documentElement.clientHeight || document.body.clientHeight }, timestamp: r3 }), emitWithContext({ type: t.FullSnapshot, data: { node: l3, initialOffset: { left: void 0 !== window.pageXOffset ? window.pageXOffset : document.documentElement.scrollLeft, top: void 0 !== window.pageYOffset ? window.pageYOffset : document.documentElement.scrollTop } }, timestamp: r3 });
724
+ emitWithContext({ type: t.EventType.Meta, data: { href: window.location.href, width: document.documentElement.clientWidth || document.body.clientWidth, height: document.documentElement.clientHeight || document.body.clientHeight }, timestamp: r3 }), emitWithContext({ type: t.EventType.FullSnapshot, data: { node: l3, initialOffset: { left: void 0 !== window.pageXOffset ? window.pageXOffset : document.documentElement.scrollLeft, top: void 0 !== window.pageYOffset ? window.pageYOffset : document.documentElement.scrollTop } }, timestamp: r3 });
707
725
  for (const e3 of a3) emitWithContext(e3);
708
726
  s3 = false;
709
727
  } else console.warn("[Sailfish] chunkSnapshot serialization failed; session continues without initial DOM snapshot"), s3 = false;
@@ -741,11 +759,11 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
741
759
  zE_safe("messenger:set", "conversationTags", [`sailfish-session-${o2}`]);
742
760
  });
743
761
  const handleWidgetOpen = () => {
744
- J == null ? void 0 : J.addSailfishEvent(t.SailfishCustom, { action: "customer support chat opened", element_id: Z, provider: Y });
762
+ J == null ? void 0 : J.addSailfishEvent(t.EventType.SailfishCustom, { action: "customer support chat opened", element_id: Z, provider: Y });
745
763
  }, handleWidgetClose = () => {
746
- J == null ? void 0 : J.addSailfishEvent(t.SailfishCustom, { action: "customer support chat closed", element_id: Z, provider: Y });
764
+ J == null ? void 0 : J.addSailfishEvent(t.EventType.SailfishCustom, { action: "customer support chat closed", element_id: Z, provider: Y });
747
765
  }, handleUnreadMessages = (e3) => {
748
- J == null ? void 0 : J.addSailfishEvent(t.SailfishCustom, { action: "zendesk unreadmessages", element_id: Z, provider: Y });
766
+ J == null ? void 0 : J.addSailfishEvent(t.EventType.SailfishCustom, { action: "zendesk unreadmessages", element_id: Z, provider: Y });
749
767
  };
750
768
  suppressConsoleLogsDuringCall(() => {
751
769
  zE_safe("messenger:on", "open", handleWidgetOpen), zE_safe("messenger:on", "close", handleWidgetClose), zE_safe("messenger:on", "unreadMessages", handleUnreadMessages);
@@ -789,7 +807,7 @@ async function refreshIntegrationData(e2, t2) {
789
807
  }
790
808
  function populateSelectOptions(e2, t2, n2) {
791
809
  const i2 = document.createElement("option");
792
- i2.value = "", i2.disabled = true, i2.selected = !n2, i2.textContent = "Select...", i2.style.color = "#9ca3af", e2.innerHTML = "", e2.appendChild(i2), t2.forEach((t3) => {
810
+ i2.value = "", i2.selected = !n2, i2.textContent = "Select...", i2.style.color = "#9ca3af", e2.innerHTML = "", e2.appendChild(i2), t2.forEach((t3) => {
793
811
  const n3 = document.createElement("option");
794
812
  n3.value = t3.id || t3.value || t3, n3.textContent = t3.name || t3.label || t3, e2.appendChild(n3);
795
813
  }), n2 ? (e2.value = n2, e2.style.color = "") : e2.style.color = "#9ca3af";
@@ -812,7 +830,7 @@ function populatePriorityOptions(e2, t2, n2) {
812
830
  function populateSprintOptions(e2, t2, n2) {
813
831
  e2.innerHTML = "";
814
832
  const i2 = document.createElement("option");
815
- i2.value = "", i2.disabled = true, i2.selected = !n2, i2.textContent = "Select sprint...", i2.style.color = "#9ca3af", e2.appendChild(i2);
833
+ i2.value = "", i2.selected = !n2, i2.textContent = "Select sprint...", i2.style.color = "#9ca3af", e2.appendChild(i2);
816
834
  (t2 || []).filter((e3) => "active" === e3.state || "future" === e3.state).forEach((t3) => {
817
835
  const n3 = document.createElement("option");
818
836
  n3.value = String(t3.id), n3.textContent = t3.name || t3.id, e2.appendChild(n3);
@@ -846,7 +864,7 @@ function updateIssueTypeOptions(e2, t2) {
846
864
  const i2 = n2.issue_types || [];
847
865
  e2.innerHTML = "";
848
866
  const o2 = document.createElement("option");
849
- if (o2.value = "", o2.disabled = true, o2.textContent = "Select...", o2.style.color = "#9ca3af", e2.appendChild(o2), i2.forEach((t3) => {
867
+ if (o2.value = "", o2.textContent = "Select...", o2.style.color = "#9ca3af", e2.appendChild(o2), i2.forEach((t3) => {
850
868
  const n3 = document.createElement("option");
851
869
  n3.value = t3.id || t3.value || t3, n3.textContent = t3.name || t3.label || t3, e2.appendChild(n3);
852
870
  }), i2.length > 0) {
@@ -915,16 +933,21 @@ function setIsRecording(e2) {
915
933
  me = e2;
916
934
  }
917
935
  function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
918
- const s2 = o2 ? '<span style="color:#ef4444;">*</span>' : "", a2 = n2.filter((e3) => i2.includes(e3.id || e3.value || e3.name || e3)).map((e3) => e3.name || e3.value || e3).join(", ");
919
936
  return `
920
937
  <div style="position:relative;">
921
938
  <label for="${e2}" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">
922
- ${t2} ${s2}
939
+ ${t2} ${o2 ? '<span style="color:#ef4444;">*</span>' : ""}
923
940
  </label>
924
941
  <div class="sf-custom-multiselect" id="${e2}-container" data-field-id="${e2}" style="position:relative;">
925
- <div class="sf-multiselect-input" style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; background-color:white; cursor:pointer; min-height:38px; display:flex; align-items:center;" onclick="document.getElementById('${e2}-dropdown').style.display = document.getElementById('${e2}-dropdown').style.display === 'none' ? 'block' : 'none';">
926
- <span style="color:${a2 ? "#000" : "#9ca3af"}; flex:1;">${a2 || "Select..."}</span>
927
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" style="margin-left:8px;">
942
+ <div class="sf-multiselect-input" style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; background-color:white; cursor:pointer; min-height:38px; display:flex; align-items:center; flex-wrap:wrap; gap:4px;" onclick="document.getElementById('${e2}-dropdown').style.display = document.getElementById('${e2}-dropdown').style.display === 'none' ? 'block' : 'none';">
943
+ <span class="sf-multiselect-chips" style="display:flex; flex-wrap:wrap; gap:4px; flex:1;">${n2.filter((e3) => i2.includes(e3.id || e3.value || e3.name || e3)).map((e3) => {
944
+ const t3 = e3.id || e3.value || e3.name || e3;
945
+ return `<span class="sf-multiselect-chip" data-value="${t3}" style="display:inline-flex; align-items:center; gap:4px; background:#e5e7eb; color:#374151; padding:2px 8px; border-radius:16px; font-size:13px; white-space:nowrap;">
946
+ ${e3.name || e3.value || e3}
947
+ <span class="sf-multiselect-chip-remove" data-value="${t3}" style="cursor:pointer; display:inline-flex; align-items:center; font-size:16px; line-height:1; color:#6b7280;" onclick="event.stopPropagation();">&times;</span>
948
+ </span>`;
949
+ }).join("") || '<span style="color:#9ca3af;">Select...</span>'}</span>
950
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" style="margin-left:8px; flex-shrink:0;">
928
951
  <path d="M4 6L8 10L12 6" stroke="#64748B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
929
952
  </svg>
930
953
  </div>
@@ -943,25 +966,46 @@ function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
943
966
  `;
944
967
  }
945
968
  const he = { enabled: false, openModalExistingMode: { key: "e", requireCmdCtrl: false }, openModalCaptureNewMode: { key: "n", requireCmdCtrl: false }, closeModal: { key: "escape", requireCmdCtrl: false }, submitReport: { key: "enter", requireCmdCtrl: true }, startRecording: { key: "r", requireCmdCtrl: false }, stopRecording: { key: "escape", requireCmdCtrl: true } }, ye = { shortcuts: { ...he }, resolveSessionId: null, apiKey: null, backendApi: null, triageBaseUrl: "https://app.sailfishqa.com", deactivateIsolation: () => {
946
- }, integrationData: null };
947
- let be = null;
969
+ }, integrationData: null, showEngTicketFieldsDefault: false };
970
+ let be = null, we = false;
948
971
  function setupCustomMultiSelectListeners(e2, t2) {
949
972
  const n2 = document.getElementById(`${e2}-container`), i2 = document.getElementById(`${e2}-dropdown`);
950
973
  if (!n2 || !i2) return;
951
- i2.querySelectorAll(".sf-multiselect-option").forEach((e3) => {
952
- e3.addEventListener("click", (o2) => {
953
- o2.stopPropagation();
954
- const s2 = e3, a2 = "true" === s2.dataset.selected;
955
- s2.dataset.selected = String(!a2), s2.style.backgroundColor = a2 ? "" : "#e0f2fe";
956
- const r2 = [], l2 = [];
957
- i2.querySelectorAll(".sf-multiselect-option").forEach((e4) => {
958
- const t3 = e4;
959
- "true" === t3.dataset.selected && (r2.push(t3.dataset.value || ""), l2.push(t3.textContent || ""));
974
+ function updateChipsDisplay() {
975
+ const e3 = [], o2 = [];
976
+ i2.querySelectorAll(".sf-multiselect-option").forEach((t3) => {
977
+ var _a;
978
+ const n3 = t3;
979
+ if ("true" === n3.dataset.selected) {
980
+ const t4 = n3.dataset.value || "", i3 = ((_a = n3.textContent) == null ? void 0 : _a.trim()) || "";
981
+ e3.push(t4), o2.push(`<span class="sf-multiselect-chip" data-value="${t4}" style="display:inline-flex; align-items:center; gap:4px; background:#e5e7eb; color:#374151; padding:2px 8px; border-radius:16px; font-size:13px; white-space:nowrap;">
982
+ ${i3}
983
+ <span class="sf-multiselect-chip-remove" data-value="${t4}" style="cursor:pointer; display:inline-flex; align-items:center; font-size:16px; line-height:1; color:#6b7280;" onclick="event.stopPropagation();">&times;</span>
984
+ </span>`);
985
+ }
986
+ });
987
+ const s2 = n2.querySelector(".sf-multiselect-chips");
988
+ return s2 && (s2.innerHTML = o2.join("") || '<span style="color:#9ca3af;">Select...</span>', s2.querySelectorAll(".sf-multiselect-chip-remove").forEach((e4) => {
989
+ e4.addEventListener("click", (n3) => {
990
+ n3.stopPropagation();
991
+ const o3 = e4.dataset.value || "", s3 = i2.querySelector(`.sf-multiselect-option[data-value="${o3}"]`);
992
+ s3 && (s3.dataset.selected = "false", s3.style.backgroundColor = ""), updateChipsDisplay();
993
+ const a2 = [];
994
+ i2.querySelectorAll(".sf-multiselect-option").forEach((e5) => {
995
+ "true" === e5.dataset.selected && a2.push(e5.dataset.value || "");
996
+ }), t2(a2);
960
997
  });
961
- const c2 = n2.querySelector(".sf-multiselect-input span"), d2 = l2.join(", ");
962
- c2 && (c2.textContent = d2 || "Select...", c2.style.color = d2 ? "#000" : "#9ca3af"), t2(r2);
998
+ })), e3;
999
+ }
1000
+ i2.querySelectorAll(".sf-multiselect-option").forEach((e3) => {
1001
+ e3.addEventListener("click", (n3) => {
1002
+ n3.stopPropagation();
1003
+ const i3 = e3, o2 = "true" === i3.dataset.selected;
1004
+ i3.dataset.selected = String(!o2), i3.style.backgroundColor = o2 ? "" : "#e0f2fe";
1005
+ const s2 = updateChipsDisplay();
1006
+ t2(s2);
963
1007
  });
964
- }), document.addEventListener("click", (e3) => {
1008
+ }), updateChipsDisplay(), document.addEventListener("click", (e3) => {
965
1009
  const t3 = e3.target;
966
1010
  n2.contains(t3) || (i2.style.display = "none");
967
1011
  });
@@ -1064,7 +1108,7 @@ function renderDynamicFields(e2, t2) {
1064
1108
  style="${p2} appearance:none; cursor:pointer; background-color: white; ${s4 ? "" : "color: #9ca3af;"}"
1065
1109
  ${l2 ? "required" : ""}
1066
1110
  >
1067
- <option value="" disabled ${s4 ? "" : "selected"} style="color: #9ca3af;">Select ${o3.toLowerCase()}...</option>
1111
+ <option value="" ${s4 ? "" : "selected"} style="color: #9ca3af;">Select ${o3.toLowerCase()}...</option>
1068
1112
  ${e5}
1069
1113
  </select>
1070
1114
  </div>
@@ -1089,7 +1133,7 @@ function renderDynamicFields(e2, t2) {
1089
1133
  style="${p2} appearance:none; cursor:pointer; background-color: white; ${n4 ? "" : "color: #9ca3af;"}"
1090
1134
  ${l2 ? "required" : ""}
1091
1135
  >
1092
- <option value="" disabled ${n4 ? "" : "selected"} style="color: #9ca3af;">Select ${o3.toLowerCase()}...</option>
1136
+ <option value="" ${n4 ? "" : "selected"} style="color: #9ca3af;">Select ${o3.toLowerCase()}...</option>
1093
1137
  ${e5}
1094
1138
  </select>
1095
1139
  </div>
@@ -1151,7 +1195,7 @@ function generateEngTicketFieldsHTML() {
1151
1195
  if (!e2) return "";
1152
1196
  const t2 = "jira" === ((_a = e2.provider) == null ? void 0 : _a.toLowerCase());
1153
1197
  let n2 = "<div style='display:flex; flex-direction:column; gap:12px;'>";
1154
- return e2.teams && Array.isArray(e2.teams) && e2.teams.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-team" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Team\n </label>\n <select id="sf-eng-ticket-team"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" disabled selected style="color: #9ca3af;">Select team...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-project" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Project\n </label>\n <select id="sf-eng-ticket-project"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" disabled selected style="color: #9ca3af;">Select project...</option>\n </select>\n </div>\n ', t2 && (n2 += '\n <div>\n <label for="sf-eng-ticket-type" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Issue Type\n </label>\n <select id="sf-eng-ticket-type"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" disabled selected style="color: #9ca3af;">Select project first...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-priority" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Priority\n </label>\n <select id="sf-eng-ticket-priority"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white;">\n </select>\n </div>\n ', e2.labels && Array.isArray(e2.labels) && e2.labels.length > 0 && (n2 += renderCustomMultiSelect("sf-eng-ticket-labels", "Labels", e2.labels, ue.engTicketLabels, false)), t2 && e2.sprints && Array.isArray(e2.sprints) && e2.sprints.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-sprint" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Sprint\n </label>\n <select id="sf-eng-ticket-sprint"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" disabled selected style="color: #9ca3af;">Select sprint...</option>\n </select>\n </div>\n '), n2 += '\n <div id="sf-dynamic-fields-container" style="display: flex; flex-direction: column; gap: 12px;"></div>\n ', n2 += "</div>", n2;
1198
+ return e2.teams && Array.isArray(e2.teams) && e2.teams.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-team" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Team\n </label>\n <select id="sf-eng-ticket-team"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select team...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-project" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Project\n </label>\n <select id="sf-eng-ticket-project"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project...</option>\n </select>\n </div>\n ', t2 && (n2 += '\n <div>\n <label for="sf-eng-ticket-type" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Issue Type\n </label>\n <select id="sf-eng-ticket-type"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project first...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-priority" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Priority\n </label>\n <select id="sf-eng-ticket-priority"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white;">\n </select>\n </div>\n ', e2.labels && Array.isArray(e2.labels) && e2.labels.length > 0 && (n2 += renderCustomMultiSelect("sf-eng-ticket-labels", "Labels", e2.labels, ue.engTicketLabels, false)), t2 && e2.sprints && Array.isArray(e2.sprints) && e2.sprints.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-sprint" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Sprint\n </label>\n <select id="sf-eng-ticket-sprint"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select sprint...</option>\n </select>\n </div>\n '), n2 += '\n <div id="sf-dynamic-fields-container" style="display: flex; flex-direction: column; gap: 12px;"></div>\n ', n2 += "</div>", n2;
1155
1199
  }
1156
1200
  function getShortcutKeyCmdCtrlLabel() {
1157
1201
  return (function isMacPlatform() {
@@ -1171,8 +1215,8 @@ function getSessionIdSafely() {
1171
1215
  if (!ye.resolveSessionId) throw new Error("getSessionId not defined");
1172
1216
  return ye.resolveSessionId();
1173
1217
  }
1174
- function openReportIssueModal() {
1175
- me ? stopRecording() : (injectModalHTML(), be && document.body.appendChild(be));
1218
+ function openReportIssueModal(e2) {
1219
+ me ? stopRecording() : (we = (e2 == null ? void 0 : e2.showEngTicketFields) ?? ye.showEngTicketFieldsDefault, injectModalHTML(), be && document.body.appendChild(be));
1176
1220
  }
1177
1221
  function closeModal() {
1178
1222
  ye.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (be == null ? void 0 : be.parentNode) && be.parentNode.removeChild(be), be = null, me || (function resetState() {
@@ -1364,7 +1408,7 @@ function injectModalHTML(e2 = "lookback") {
1364
1408
  Create an Issue
1365
1409
  </label>
1366
1410
 
1367
- <label id="sf-create-eng-ticket-label" style="display:${ye.integrationData ? "flex" : "none"}; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
1411
+ <label id="sf-create-eng-ticket-label" style="display:${ye.integrationData && we ? "flex" : "none"}; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
1368
1412
  <input type="checkbox" id="sf-create-eng-ticket-checkbox" ${ue.createEngTicket ? "checked" : ""}
1369
1413
  style="width:16px; height:16px; accent-color:#295DBF; cursor:pointer;">
1370
1414
  Create an Eng Ticket
@@ -1386,7 +1430,7 @@ function injectModalHTML(e2 = "lookback") {
1386
1430
  </div>
1387
1431
 
1388
1432
  <!-- Engineering Ticket Fields (shown when create eng ticket is checked) -->
1389
- <div id="sf-eng-ticket-fields-container" style="display:${ue.createEngTicket ? "block" : "none"}; margin-top: ${ue.createIssue ? "12px" : "0"};">
1433
+ <div id="sf-eng-ticket-fields-container" style="display:${ue.createEngTicket && ye.integrationData ? "block" : "none"}; margin-top: ${ue.createIssue ? "12px" : "0"};">
1390
1434
  ${generateEngTicketFieldsHTML()}
1391
1435
  </div>
1392
1436
  </div>
@@ -1491,7 +1535,7 @@ function injectModalHTML(e2 = "lookback") {
1491
1535
  pe = e6;
1492
1536
  })(Date.now()), setIsRecording(true);
1493
1537
  try {
1494
- const { enableFunctionSpanTracking: e6 } = await Promise.resolve().then(() => O);
1538
+ const { enableFunctionSpanTracking: e6 } = await Promise.resolve().then(() => z);
1495
1539
  e6();
1496
1540
  } catch (e6) {
1497
1541
  console.error("[Report Issue] Failed to enable function span tracking:", e6);
@@ -1550,23 +1594,33 @@ function injectModalHTML(e2 = "lookback") {
1550
1594
  m2[e6] = parseInt(y2, 10);
1551
1595
  }
1552
1596
  closeModal(), (async function createTriageAndIssue(e6, t6, n4, i4, o4, s4, a4, r4, l4, c4, d4, u3) {
1553
- var _a2, _b;
1597
+ var _a2, _b, _c;
1554
1598
  try {
1555
1599
  showStatusModal(true);
1556
- const p3 = await createTriageAndIssueFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t6, n4, i4, o4, s4, a4, r4, l4, c4, d4, u3), f3 = (_b = (_a2 = p3 == null ? void 0 : p3.data) == null ? void 0 : _a2.createTriageAndIssueFromRecorder) == null ? void 0 : _b.id;
1557
- f3 ? showStatusModal(false, { type: "issue", id: f3 }) : (console.error("No Issue ID returned from backend."), showStatusModal(false, null));
1600
+ const p3 = await createTriageAndIssueFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t6, n4, i4, o4, s4, a4, r4, l4, c4, d4, u3);
1601
+ if ((_a2 = p3 == null ? void 0 : p3.errors) == null ? void 0 : _a2.length) {
1602
+ const e7 = p3.errors.map((e8) => e8.message).join("; ");
1603
+ return console.error("GraphQL error creating triage and issue:", e7), void showStatusModal(false, null, e7);
1604
+ }
1605
+ const f3 = (_c = (_b = p3 == null ? void 0 : p3.data) == null ? void 0 : _b.createTriageAndIssueFromRecorder) == null ? void 0 : _c.id;
1606
+ f3 ? showStatusModal(false, { type: "issue", id: f3 }) : (console.error("No Issue ID returned from backend."), showStatusModal(false, null, "No issue was created. Please try again."));
1558
1607
  } catch (e7) {
1559
- console.error("Error creating triage and issue:", e7), showStatusModal(false, null);
1608
+ console.error("Error creating triage and issue:", e7), showStatusModal(false, null, "Something went wrong. Please try again.");
1560
1609
  }
1561
1610
  })(`${n3}`, `${i3}`, e5, l3, c3, ue.createEngTicket, d3, u2, p2, f2, g2, m2);
1562
1611
  } else closeModal(), (async function createTriage(e6, t5, n4) {
1563
- var _a2, _b;
1612
+ var _a2, _b, _c;
1564
1613
  try {
1565
1614
  showStatusModal(true);
1566
- const i4 = await createTriageFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4), o3 = (_b = (_a2 = i4 == null ? void 0 : i4.data) == null ? void 0 : _a2.createTriageFromRecorder) == null ? void 0 : _b.id;
1567
- o3 ? showStatusModal(false, { type: "triage", id: o3 }) : (console.error("No Triage ID returned from backend."), showStatusModal(false, null));
1615
+ const i4 = await createTriageFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4);
1616
+ if ((_a2 = i4 == null ? void 0 : i4.errors) == null ? void 0 : _a2.length) {
1617
+ const e7 = i4.errors.map((e8) => e8.message).join("; ");
1618
+ return console.error("GraphQL error creating triage:", e7), void showStatusModal(false, null, e7);
1619
+ }
1620
+ const o3 = (_c = (_b = i4 == null ? void 0 : i4.data) == null ? void 0 : _b.createTriageFromRecorder) == null ? void 0 : _c.id;
1621
+ o3 ? showStatusModal(false, { type: "triage", id: o3 }) : (console.error("No Triage ID returned from backend."), showStatusModal(false, null, "No triage was created. Please try again."));
1568
1622
  } catch (e7) {
1569
- console.error("Error creating triage:", e7), showStatusModal(false, null);
1623
+ console.error("Error creating triage:", e7), showStatusModal(false, null, "Something went wrong. Please try again.");
1570
1624
  }
1571
1625
  })(`${n3}`, `${i3}`, e5);
1572
1626
  }
@@ -1579,8 +1633,10 @@ function injectModalHTML(e2 = "lookback") {
1579
1633
  const e4 = generateEngTicketFieldsHTML();
1580
1634
  e4 && (t3.innerHTML = e4, initializeEngTicketForm(), bindEngTicketListeners(), updateFormWithIntegrationData(ue), renderDynamicFields(ue.engTicketProject, ue.engTicketIssueType));
1581
1635
  }
1582
- const n2 = document.getElementById("sf-create-eng-ticket-label");
1583
- n2 && (n2.style.display = "flex");
1636
+ if (we) {
1637
+ const e4 = document.getElementById("sf-create-eng-ticket-label");
1638
+ e4 && (e4.style.display = "flex");
1639
+ }
1584
1640
  });
1585
1641
  }
1586
1642
  function initializeEngTicketForm() {
@@ -1668,7 +1724,7 @@ async function stopRecording() {
1668
1724
  fe = e2;
1669
1725
  })(Date.now()), setIsRecording(false), ge && (clearInterval(ge), setTimerInterval(null)), (_a = document.getElementById("sf-recording-indicator")) == null ? void 0 : _a.remove();
1670
1726
  try {
1671
- const { disableFunctionSpanTracking: e2 } = await Promise.resolve().then(() => O);
1727
+ const { disableFunctionSpanTracking: e2 } = await Promise.resolve().then(() => z);
1672
1728
  e2();
1673
1729
  } catch (e2) {
1674
1730
  console.error("[Report Issue] Failed to disable function span tracking:", e2);
@@ -1698,23 +1754,23 @@ async function stopRecording() {
1698
1754
  r2.disabled = false, r2.style.opacity = "1", r2.style.cursor = "pointer";
1699
1755
  })();
1700
1756
  }
1701
- function showStatusModal(e2, t2) {
1702
- !(function showTriageStatusModal(e3, t3, n2) {
1757
+ function showStatusModal(e2, t2, n2) {
1758
+ !(function showTriageStatusModal(e3, t3, n3, i2) {
1703
1759
  var _a;
1704
1760
  !(function removeExistingModals() {
1705
1761
  var _a2, _b;
1706
1762
  (_a2 = document.getElementById("sf-report-issue-modal")) == null ? void 0 : _a2.remove(), (_b = document.getElementById("sf-triage-status-modal")) == null ? void 0 : _b.remove();
1707
1763
  })();
1708
- const i2 = n2 ? `${ye.triageBaseUrl}/issues/${n2}?from=inAppReportIssue` : t3 ? `${ye.triageBaseUrl}/triage/${t3}?from=inAppReportIssue` : "", o2 = document.createElement("div");
1709
- o2.id = "sf-triage-status-modal", Object.assign(o2.style, { position: "fixed", inset: "0", zIndex: "9998", display: "flex", alignItems: "center", justifyContent: "center" });
1710
- const s2 = e3 ? "Reporting Issue..." : "Issue reported!", a2 = e3 ? '<p style="font-size:14px; color:#64748b; line-height:20px;">This may take ~10 seconds</p>' : "", r2 = e3 ? '<div style="display:flex; justify-content:center; align-items:center; padding: 40px 0;">\n <div style="width:24px; height:24px; border:2px solid #295dbf; border-top:2px solid white; border-radius:50%; animation:spin 1s linear infinite;"></div>\n </div>' : "", l2 = e3 ? "" : '<div id="sf-copied-status" style="display:none; font-size:12px; font-weight:500; color:white;\n background-color:#22c55e; padding:4px 8px; border-radius:6px; white-space:nowrap; align-items:center; gap:6px;">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path fill-rule="evenodd" clip-rule="evenodd" d="M21 7.5L9 19.5L3 13.5L5.25 11.25L9 15L18.75 5.25L21 7.5Z" fill="white"/>\n </svg>\n Copied\n </div>';
1711
- o2.innerHTML = `
1764
+ const o2 = !e3 && i2, s2 = n3 ? `${ye.triageBaseUrl}/issues/${n3}?from=inAppReportIssue` : t3 ? `${ye.triageBaseUrl}/triage/${t3}?from=inAppReportIssue` : "", a2 = document.createElement("div");
1765
+ a2.id = "sf-triage-status-modal", Object.assign(a2.style, { position: "fixed", inset: "0", zIndex: "9998", display: "flex", alignItems: "center", justifyContent: "center" });
1766
+ const r2 = e3 ? "Reporting Issue..." : o2 ? "Failed to report issue" : "Issue reported!", l2 = e3 ? '<p style="font-size:14px; color:#64748b; line-height:20px;">This may take ~10 seconds</p>' : o2 ? `<p style="font-size:14px; color:#ef4444; line-height:20px;">${i2}</p>` : "", c2 = e3 ? '<div style="display:flex; justify-content:center; align-items:center; padding: 40px 0;">\n <div style="width:24px; height:24px; border:2px solid #295dbf; border-top:2px solid white; border-radius:50%; animation:spin 1s linear infinite;"></div>\n </div>' : "", d2 = e3 ? "" : '<div id="sf-copied-status" style="display:none; font-size:12px; font-weight:500; color:white;\n background-color:#22c55e; padding:4px 8px; border-radius:6px; white-space:nowrap; align-items:center; gap:6px;">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path fill-rule="evenodd" clip-rule="evenodd" d="M21 7.5L9 19.5L3 13.5L5.25 11.25L9 15L18.75 5.25L21 7.5Z" fill="white"/>\n </svg>\n Copied\n </div>';
1767
+ a2.innerHTML = `
1712
1768
  <div style="position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:9998;"></div>
1713
1769
  <div id="sf-triage-card"
1714
1770
  style="position:relative; background:#fff; padding:24px; border-radius:12px; width:300px; max-width:90%;
1715
1771
  font-family:sans-serif; box-shadow:0 4px 20px rgba(0,0,0,0.15);
1716
1772
  z-index:9999; opacity:1; transition:opacity 300ms ease;">
1717
- <div style="position:absolute; top:24px; right:48px;">${l2}</div>
1773
+ <div style="position:absolute; top:24px; right:48px;">${d2}</div>
1718
1774
 
1719
1775
  <button id="sf-triage-modal-close"
1720
1776
  style="position:absolute; top:24px; right:16px; background:none; border:none; cursor:pointer;">
@@ -1724,11 +1780,11 @@ function showStatusModal(e2, t2) {
1724
1780
  </svg>
1725
1781
  </button>
1726
1782
 
1727
- <h2 style="font-size:18px; font-weight:600; margin-bottom:${e3 ? 8 : 40}px; line-height:28px;">${s2}</h2>
1728
- ${a2}
1729
- ${r2}
1783
+ <h2 style="font-size:18px; font-weight:600; margin-bottom:${e3 || o2 ? 8 : 40}px; line-height:28px;">${r2}</h2>
1784
+ ${l2}
1785
+ ${c2}
1730
1786
 
1731
- <div style="display:flex; justify-content:flex-end; align-items:center; gap:8px;">
1787
+ <div style="display:${o2 ? "none" : "flex"}; justify-content:flex-end; align-items:center; gap:8px;">
1732
1788
  <button id="sf-copy-triage-link"
1733
1789
  style="background:white; border:1px solid #e2e8f0; padding:8px 16px; border-radius:6px;
1734
1790
  font-size:14px; color: #0f172a; cursor:pointer;">
@@ -1749,27 +1805,27 @@ function showStatusModal(e2, t2) {
1749
1805
  <style>
1750
1806
  @keyframes spin { to { transform: rotate(360deg); } }
1751
1807
  </style>
1752
- `, document.body.appendChild(o2);
1753
- const c2 = o2.querySelector("#sf-triage-card");
1808
+ `, document.body.appendChild(a2);
1809
+ const u2 = a2.querySelector("#sf-triage-card");
1754
1810
  (_a = document.getElementById("sf-triage-modal-close")) == null ? void 0 : _a.addEventListener("click", () => {
1755
- fadeCardAndRemove(o2, c2, 300);
1811
+ fadeCardAndRemove(a2, u2, 300);
1756
1812
  });
1757
- const d2 = document.getElementById("sf-copy-triage-link"), u2 = document.getElementById("sf-view-triage-btn");
1758
- e3 ? (d2.disabled = true, d2.style.opacity = "0.4", d2.style.cursor = "not-allowed", u2.disabled = true, u2.style.opacity = "0.4", u2.style.cursor = "not-allowed") : (d2.disabled = false, d2.addEventListener("click", () => {
1759
- navigator.clipboard.writeText(i2).then(() => {
1813
+ const p2 = document.getElementById("sf-copy-triage-link"), f2 = document.getElementById("sf-view-triage-btn");
1814
+ e3 ? (p2.disabled = true, p2.style.opacity = "0.4", p2.style.cursor = "not-allowed", f2.disabled = true, f2.style.opacity = "0.4", f2.style.cursor = "not-allowed") : (p2.disabled = false, p2.addEventListener("click", () => {
1815
+ navigator.clipboard.writeText(s2).then(() => {
1760
1816
  const e4 = document.getElementById("sf-copied-status");
1761
1817
  e4 && (e4.style.display = "flex");
1762
1818
  });
1763
- }), u2.disabled = false, u2.addEventListener("click", () => {
1764
- (t3 || n2) && window.open(i2, "_blank");
1765
- }), setTimeout(() => fadeCardAndRemove(o2, c2, 300), 1e4));
1766
- })(e2, "triage" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, "issue" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0);
1819
+ }), f2.disabled = false, f2.addEventListener("click", () => {
1820
+ (t3 || n3) && window.open(s2, "_blank");
1821
+ }), o2 || setTimeout(() => fadeCardAndRemove(a2, u2, 300), 1e4));
1822
+ })(e2, "triage" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, "issue" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, n2);
1767
1823
  }
1768
1824
  function fadeCardAndRemove(e2, t2, n2 = 300) {
1769
1825
  t2.style.opacity = "0", t2.addEventListener("transitionend", () => e2.remove(), { once: true }), setTimeout(() => e2.remove(), n2 + 100);
1770
1826
  }
1771
- const we = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueContext: ye, openReportIssueModal, setupIssueReporting: function setupIssueReporting(e2) {
1772
- ye.apiKey = e2.apiKey, ye.backendApi = e2.backendApi, ye.resolveSessionId = e2.getSessionId, ye.integrationData = e2.integrationData || null, e2.customBaseUrl && (ye.triageBaseUrl = e2.customBaseUrl), ye.shortcuts = (function mergeShortcutsConfig(e3) {
1827
+ const Se = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueContext: ye, openReportIssueModal, setupIssueReporting: function setupIssueReporting(e2) {
1828
+ ye.apiKey = e2.apiKey, ye.backendApi = e2.backendApi, ye.resolveSessionId = e2.getSessionId, ye.integrationData = e2.integrationData || null, ye.showEngTicketFieldsDefault = e2.showEngTicketFieldsInReportIssueModalDefault ?? false, e2.customBaseUrl && (ye.triageBaseUrl = e2.customBaseUrl), ye.shortcuts = (function mergeShortcutsConfig(e3) {
1773
1829
  const t3 = { ...he };
1774
1830
  if (!e3) return t3;
1775
1831
  "boolean" == typeof e3.enabled && (t3.enabled = e3.enabled);
@@ -1801,13 +1857,13 @@ const we = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueCon
1801
1857
  return void (t3 && (e3.preventDefault(), t3.click()));
1802
1858
  }
1803
1859
  });
1804
- } }, Symbol.toStringTag, { value: "Module" })), Se = readDebugFlag(), ve = /* @__PURE__ */ new Map();
1860
+ } }, Symbol.toStringTag, { value: "Module" })), ve = readDebugFlag(), ke = /* @__PURE__ */ new Map();
1805
1861
  function getCachedRegex(e2, t2) {
1806
1862
  const n2 = `${e2}|${t2}`;
1807
- let i2 = ve.get(n2);
1808
- return i2 || (i2 = new RegExp(e2, t2), ve.set(n2, i2)), i2;
1863
+ let i2 = ke.get(n2);
1864
+ return i2 || (i2 = new RegExp(e2, t2), ke.set(n2, i2)), i2;
1809
1865
  }
1810
- const ke = new Set([".js", ".mjs", ".cjs", ".ts", ".css", ".scss", ".sass", ".less", ".styl", ".stylus", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".avif", ".bmp", ".ico", ".tiff", ".tif", ".heic", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".mp4", ".webm", ".ogv", ".mp3", ".wav", ".flac", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".json", ".xml", ".txt", ".zip", ".rar", ".gz", ".tar", ".7z", ".map", ".webmanifest"].map((e2) => e2.toLowerCase())), xe = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], Ie = [400, 403], Te = "CORS", Ee = 1, Ce = "authorization", $e = "Authorization", Fe = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {}, enableFiberTracking: false }, Me = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
1866
+ const xe = new Set([".js", ".mjs", ".cjs", ".ts", ".css", ".scss", ".sass", ".less", ".styl", ".stylus", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".avif", ".bmp", ".ico", ".tiff", ".tif", ".heic", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".mp4", ".webm", ".ogv", ".mp3", ".wav", ".flac", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".json", ".xml", ".txt", ".zip", ".rar", ".gz", ".tar", ".7z", ".map", ".webmanifest"].map((e2) => e2.toLowerCase())), Ie = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], Te = [400, 403], Ee = "CORS", Ce = "authorization", $e = "Authorization", Fe = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {}, enableFiberTracking: false }, Me = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
1811
1867
  function maskAuthorizationHeader(e2) {
1812
1868
  const t2 = e2[Ce] ? Ce : e2[$e] ? $e : null;
1813
1869
  if (!t2) return;
@@ -1825,7 +1881,7 @@ function trackDomainChangesOnce() {
1825
1881
  const n3 = window.location.href.split("?")[0];
1826
1882
  if (e3 || n3 !== t2) {
1827
1883
  t2 = n3;
1828
- const e4 = uuidv4(), i2 = sessionStorage.getItem("pageVisitUUID");
1884
+ const e4 = uuidv4(), i2 = sessionStorage.getItem("pageVisitUUID") ?? "";
1829
1885
  sessionStorage.setItem("pageVisitUUID", e4), sessionStorage.setItem("prevPageVisitUUID", i2), invalidateUrlCache();
1830
1886
  sendMessage({ type: "routeChange", data: { url: n3, timestamp: Date.now(), page_visit_uuid: e4, prev_page_visit_uuid: i2 } });
1831
1887
  }
@@ -1835,7 +1891,7 @@ function trackDomainChangesOnce() {
1835
1891
  clearTimeout(n3), n3 = setTimeout(() => e3(...i2), t3);
1836
1892
  };
1837
1893
  })(() => checkDomainChange(), 500);
1838
- checkDomainChange(true), e2.routeWatcherIntervalId = window.setInterval(n2, 1e3);
1894
+ onNavigationChange(() => checkDomainChange()), checkDomainChange(true), e2.routeWatcherIntervalId = window.setInterval(n2, 1e3);
1839
1895
  }
1840
1896
  function sendUserDeviceUuid() {
1841
1897
  sendMessage({ type: "userDeviceUuid", userDeviceUuid: (function getOrSetUserDeviceUuid() {
@@ -1858,7 +1914,7 @@ function handleVisibilityChange() {
1858
1914
  const e2 = document.visibilityState, t2 = Date.now();
1859
1915
  "visible" === e2 && getOrSetSessionId();
1860
1916
  try {
1861
- sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: t2, ...getUrlAndStoredUuids() } }), Se && console.log(`[Sailfish] Tab became ${e2}, sent visibility change event`);
1917
+ sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: t2, ...getUrlAndStoredUuids() } }), ve && console.log(`[Sailfish] Tab became ${e2}, sent visibility change event`);
1862
1918
  } catch (e3) {
1863
1919
  console.warn("[Sailfish] Failed to send visibility change event:", e3);
1864
1920
  }
@@ -1913,7 +1969,7 @@ function matchUrlWithWildcard(e2, t2) {
1913
1969
  });
1914
1970
  }
1915
1971
  function createSkipHeadersPropagationChecker(e2 = []) {
1916
- const t2 = [...xe, ...e2];
1972
+ const t2 = [...Ie, ...e2];
1917
1973
  return function shouldSkipHeadersPropagation(e3) {
1918
1974
  let n2;
1919
1975
  try {
@@ -1922,7 +1978,7 @@ function createSkipHeadersPropagationChecker(e2 = []) {
1922
1978
  return true;
1923
1979
  }
1924
1980
  const i2 = n2.pathname.toLowerCase(), o2 = i2.lastIndexOf(".");
1925
- return !(-1 === o2 || !ke.has(i2.slice(o2))) || !!matchUrlWithWildcard(e3, t2);
1981
+ return !(-1 === o2 || !xe.has(i2.slice(o2))) || !!matchUrlWithWildcard(e3, t2);
1926
1982
  };
1927
1983
  }
1928
1984
  function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
@@ -1957,7 +2013,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
1957
2013
  h2[e5] = t3;
1958
2014
  }) : h2 = { ...l3.headers }), m2 = l3.body;
1959
2015
  } catch (e5) {
1960
- Se && console.warn("[Sailfish] Failed to capture request data:", e5);
2016
+ ve && console.warn("[Sailfish] Failed to capture request data:", e5);
1961
2017
  }
1962
2018
  delete h2[n];
1963
2019
  const b2 = getFuncSpanHeader();
@@ -1970,16 +2026,16 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
1970
2026
  const l4 = getFuncSpanHeader();
1971
2027
  if (i5 instanceof Request) {
1972
2028
  const c4 = i5.clone(), d4 = new Headers(c4.headers);
1973
- d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), Se && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l4.name }));
2029
+ d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), ve && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l4.name }));
1974
2030
  const u4 = new Request(c4, { headers: d4 });
1975
2031
  return await e5.call(t3, u4, o4);
1976
2032
  }
1977
2033
  {
1978
2034
  const c4 = { ...o4 }, d4 = new Headers(o4.headers || {});
1979
- return d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), Se && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof i5 ? i5 : i5.href, header: l4.name })), c4.headers = d4, await e5.call(t3, i5, c4);
2035
+ return d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), ve && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof i5 ? i5 : i5.href, header: l4.name })), c4.headers = d4, await e5.call(t3, i5, c4);
1980
2036
  }
1981
2037
  })(e4, i4, s3, l3, c3, p2.page_visit_uuid, u3), w3 = false;
1982
- Ie.includes(b3.status) && (Se && console.log("Perform retry as status was fail:", b3), delete h2[n], b3 = await (async function retryWithoutPropagateHeaders(e5, t3, i5, o4) {
2038
+ Te.includes(b3.status) && (ve && console.log("Perform retry as status was fail:", b3), delete h2[n], b3 = await (async function retryWithoutPropagateHeaders(e5, t3, i5, o4) {
1983
2039
  try {
1984
2040
  let o5 = i5[0], s4 = i5[1] || {};
1985
2041
  if ("string" == typeof o5 || o5 instanceof URL) {
@@ -1995,7 +2051,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
1995
2051
  }
1996
2052
  return e5.apply(t3, i5);
1997
2053
  } catch (e6) {
1998
- throw Se && console.log(`Retry without ${n} for ${o4} also failed:`, e6), e6;
2054
+ throw ve && console.log(`Retry without ${n} for ${o4} also failed:`, e6), e6;
1999
2055
  }
2000
2056
  })(e4, i4, o3, d3), w3 = true);
2001
2057
  const S2 = Date.now(), v2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
@@ -2005,7 +2061,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2005
2061
  I2[t3] = e5;
2006
2062
  });
2007
2063
  } catch (e5) {
2008
- Se && console.warn("[Sailfish] Failed to capture response headers:", e5), I2 = null;
2064
+ ve && console.warn("[Sailfish] Failed to capture response headers:", e5), I2 = null;
2009
2065
  }
2010
2066
  const T2 = { type: 27, timestamp: S2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: S2, response_code: v2, success: k2, error: x2, method: f2, url: d3, retry_without_trace_id: w3, request_headers: h2, request_body: m2, response_headers: I2, response_body: null }, ...p2 }, sendEventWithBody = (e5) => {
2011
2067
  T2.data.response_body = e5, y2 ? y2.text().then((e6) => {
@@ -2083,7 +2139,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2083
2139
  return b3;
2084
2140
  } catch (t3) {
2085
2141
  const n2 = Date.now(), s4 = false, a3 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, r3 = t3.message || "Fetch request failed";
2086
- if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Te.toLowerCase()))) return e4.apply(i4, o3);
2142
+ if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Ee.toLowerCase()))) return e4.apply(i4, o3);
2087
2143
  let l4 = m2;
2088
2144
  if (y2) try {
2089
2145
  l4 = await y2.text();
@@ -2100,7 +2156,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2100
2156
  const S2 = h2 ?? y2 ?? true, v2 = getOrSetSessionId(), k2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
2101
2157
  if (k2.sessionId = v2, k2.apiKey = e2, k2.backendApi = t2, k2.serviceAdditionalMetadata = l2, k2.initialized && k2.sessionId === v2 && k2.ws && 1 === k2.ws.readyState) return void trackDomainChangesOnce();
2102
2158
  const x2 = { captureStreamingResponseBody: d2, captureResponseBodyMaxMb: u2, captureStreamPrefixKb: p2, captureStreamTimeoutMs: f2 };
2103
- k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
2159
+ sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
2104
2160
  const i3 = XMLHttpRequest.prototype.open, o3 = XMLHttpRequest.prototype.send, s3 = XMLHttpRequest.prototype.setRequestHeader, a3 = getOrSetSessionId(), r3 = createSkipHeadersPropagationChecker(e3);
2105
2161
  XMLHttpRequest.prototype.setRequestHeader = function(e4, t4) {
2106
2162
  return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4, s3.call(this, e4, t4);
@@ -2118,9 +2174,9 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2118
2174
  }
2119
2175
  const d3 = getFuncSpanHeader();
2120
2176
  if (d3) try {
2121
- this.setRequestHeader(d3.name, d3.value), Se && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: i4, header: d3.name });
2177
+ this.setRequestHeader(d3.name, d3.value), ve && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: i4, header: d3.name });
2122
2178
  } catch (e5) {
2123
- Se && console.warn(`[Sailfish] Could not set funcspan header for ${i4}`, e5);
2179
+ ve && console.warn(`[Sailfish] Could not set funcspan header for ${i4}`, e5);
2124
2180
  }
2125
2181
  const u3 = Date.now();
2126
2182
  let p3 = false;
@@ -2153,7 +2209,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2153
2209
  2 === t4.length && (i5[t4[0]] = t4[1]);
2154
2210
  });
2155
2211
  } catch (e6) {
2156
- Se && console.warn("[Sailfish] Failed to capture XHR response headers:", e6), i5 = null;
2212
+ ve && console.warn("[Sailfish] Failed to capture XHR response headers:", e6), i5 = null;
2157
2213
  }
2158
2214
  if (e5 >= 200 && e5 < 300) emitFinished(true, e5, "", n2, i5);
2159
2215
  else {
@@ -2165,7 +2221,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2165
2221
  emitFinished(false, e5, t4);
2166
2222
  }, { once: true }), o3.apply(this, e4);
2167
2223
  };
2168
- })(o2, x2), k2.xhrPatched = true), await yieldToMain(), k2.fetchPatched || (setupFetchInterceptor(o2, x2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(v2), k2.domEventsInit = true), await yieldToMain(), k2.consoleInit || (initializeConsolePlugin(Me, v2), k2.consoleInit = true), await yieldToMain(), k2.errorInit || (!(function initializeErrorInterceptor() {
2224
+ })(o2, x2), k2.xhrPatched = true), k2.fetchPatched || (setupFetchInterceptor(o2, x2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(v2), k2.domEventsInit = true), await yieldToMain(), k2.consoleInit || (initializeConsolePlugin(Me, v2), k2.consoleInit = true), await yieldToMain(), k2.errorInit || (!(function initializeErrorInterceptor() {
2169
2225
  window.addEventListener("error", (e3) => {
2170
2226
  captureError(e3.error || e3.message);
2171
2227
  }), window.addEventListener("unhandledrejection", (e3) => {
@@ -2175,10 +2231,10 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2175
2231
  m && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", t3));
2176
2232
  })({ apiKey: e2, backendApi: t2 }), !isFunctionSpanTrackingEnabled() || k2.ws && 1 === k2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, t2).then((e3) => {
2177
2233
  var _a2;
2178
- ((_a2 = e3.data) == null ? void 0 : _a2.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? Se && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), Se && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
2234
+ ((_a2 = e3.data) == null ? void 0 : _a2.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? ve && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), ve && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
2179
2235
  }).catch((e3) => {
2180
- Se && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
2181
- }), k2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...o2, ...xe], t2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), k2.sentDoNotPropagateOnce = true), (async function gatherAndCacheDeviceInfo() {
2236
+ ve && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
2237
+ }), k2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...o2, ...Ie], t2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), k2.sentDoNotPropagateOnce = true), (async function gatherAndCacheDeviceInfo() {
2182
2238
  sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
2183
2239
  })(), c2 && fetchAndSendIp(v2);
2184
2240
  try {
@@ -2221,67 +2277,29 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2221
2277
  console.error("Error starting recording:", e3);
2222
2278
  }
2223
2279
  }
2224
- const initRecorder = async (e2) => {
2280
+ exports.DEFAULT_CAPTURE_SETTINGS = Fe, exports.DEFAULT_CONSOLE_RECORDING_SETTINGS = Me, exports.STORAGE_VERSION = 1, exports.addOrUpdateMetadata = function addOrUpdateMetadata(e2) {
2281
+ const t2 = { type: "addOrUpdateMetadata", metadata: e2 };
2282
+ U && JSON.stringify(U) === JSON.stringify(e2) || (U = e2, sendMessage(t2));
2283
+ }, exports.buildBatches = buildBatches, exports.clearStaleFuncSpanState = clearStaleFuncSpanState, exports.createTriageAndIssueFromRecorder = createTriageAndIssueFromRecorder, exports.createTriageFromRecorder = createTriageFromRecorder, exports.disableFunctionSpanTracking = disableFunctionSpanTracking, exports.enableFunctionSpanTracking = enableFunctionSpanTracking, exports.ensureHrefCache = ensureHrefCache, exports.eventSize = eventSize, exports.fetchAndSendIp = fetchAndSendIp, exports.fetchCaptureSettings = fetchCaptureSettings, exports.fetchEngineeringTicketPlatformIntegrations = fetchEngineeringTicketPlatformIntegrations, exports.fetchFunctionSpanTrackingEnabled = fetchFunctionSpanTrackingEnabled, exports.flushBufferedEvents = flushBufferedEvents, exports.getCachedHref = getCachedHref, exports.getCachedHrefNoQuery = getCachedHrefNoQuery, exports.getFuncSpanHeader = getFuncSpanHeader, exports.getOrSetSessionId = getOrSetSessionId, exports.getUrlAndStoredUuids = getUrlAndStoredUuids, exports.identify = function identify(e2, t2 = {}, n2 = false) {
2284
+ const i2 = { type: "identify", userId: e2, traits: t2 };
2285
+ O && O.userId === e2 && JSON.stringify(O.traits) === JSON.stringify(t2) || (O = { userId: e2, traits: t2, overwrite: n2 }, sendMessage(i2));
2286
+ }, exports.initRecorder = async (e2) => {
2225
2287
  if ("undefined" == typeof window) return;
2226
2288
  const t2 = window.__sailfish_recorder || (window.__sailfish_recorder = {}), n2 = getOrSetSessionId();
2227
2289
  return clearPageVisitDataFromSessionStorage(), t2.initialized && t2.sessionId === n2 && t2.ws && 1 === t2.ws.readyState ? void 0 : (t2.initPromise || (t2.initPromise = (async () => {
2228
2290
  if (t2.hasLoggedInitOnce || (console.log("Initializing Sailfish Recorder (first run) …"), t2.hasLoggedInitOnce = true), await startRecording(e2), !t2.issueReportingInit) {
2229
- const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: s2 }] = await Promise.all([Promise.resolve().then(() => we), Promise.resolve().then(() => le)]);
2291
+ const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: s2 }] = await Promise.all([Promise.resolve().then(() => Se), Promise.resolve().then(() => le)]);
2230
2292
  let a2 = null;
2231
2293
  try {
2232
2294
  await o2(e2.apiKey, n3), a2 = s2();
2233
2295
  } catch (e3) {
2234
2296
  console.warn("[Sailfish] Failed to fetch integration data for issue reporting:", e3);
2235
2297
  }
2236
- i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData: a2 }), t2.issueReportingInit = true;
2298
+ i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData: a2, showEngTicketFieldsInReportIssueModalDefault: e2.showEngTicketFieldsInReportIssueModalDefault }), t2.issueReportingInit = true;
2237
2299
  }
2238
2300
  })().finally(() => {
2239
2301
  delete t2.initPromise;
2240
2302
  })), t2.initPromise);
2241
- };
2242
- export {
2243
- initializeRecording as A,
2244
- initializeWebSocket as B,
2245
- invalidateUrlCache as C,
2246
- Fe as D,
2247
- isFunctionSpanTrackingEnabled as E,
2248
- matchUrlWithWildcard as F,
2249
- S as G,
2250
- openReportIssueModal as H,
2251
- restoreFuncSpanState as I,
2252
- sendDomainsToNotPropagateHeaderTo as J,
2253
- sendEvent as K,
2254
- sendGraphQLRequest as L,
2255
- sendMessage as M,
2256
- startRecording as N,
2257
- startRecordingSession as O,
2258
- trackingEvent as P,
2259
- withAppUrlMetadata as Q,
2260
- Ee as S,
2261
- Me as a,
2262
- addOrUpdateMetadata as b,
2263
- buildBatches as c,
2264
- clearStaleFuncSpanState as d,
2265
- createTriageAndIssueFromRecorder as e,
2266
- createTriageFromRecorder as f,
2267
- disableFunctionSpanTracking as g,
2268
- enableFunctionSpanTracking as h,
2269
- ensureHrefCache as i,
2270
- eventSize as j,
2271
- fetchAndSendIp as k,
2272
- fetchCaptureSettings as l,
2273
- fetchEngineeringTicketPlatformIntegrations as m,
2274
- fetchFunctionSpanTrackingEnabled as n,
2275
- flushBufferedEvents as o,
2276
- getCachedHref as p,
2277
- getCachedHrefNoQuery as q,
2278
- getFuncSpanHeader as r,
2279
- getOrSetSessionId as s,
2280
- getUrlAndStoredUuids as t,
2281
- identify as u,
2282
- initRecorder as v,
2283
- initializeConsolePlugin as w,
2284
- initializeDomContentEvents as x,
2285
- yieldToMain as y,
2286
- initializeFunctionSpanTrackingFromApi as z
2287
- };
2303
+ }, exports.initializeConsolePlugin = initializeConsolePlugin, exports.initializeDomContentEvents = initializeDomContentEvents, exports.initializeFunctionSpanTrackingFromApi = initializeFunctionSpanTrackingFromApi, exports.initializeRecording = initializeRecording, exports.initializeWebSocket = initializeWebSocket, exports.invalidateUrlCache = invalidateUrlCache, exports.isFunctionSpanTrackingEnabled = isFunctionSpanTrackingEnabled, exports.matchUrlWithWildcard = matchUrlWithWildcard, exports.onNavigationChange = onNavigationChange, exports.openReportIssueModal = openReportIssueModal, exports.restoreFuncSpanState = restoreFuncSpanState, exports.sendDomainsToNotPropagateHeaderTo = sendDomainsToNotPropagateHeaderTo, exports.sendEvent = sendEvent, exports.sendGraphQLRequest = sendGraphQLRequest, exports.sendMessage = sendMessage, exports.startRecording = startRecording, exports.startRecordingSession = startRecordingSession, exports.trackingEvent = function trackingEvent(e2) {
2304
+ sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: exports.nowTimestamp() });
2305
+ }, exports.withAppUrlMetadata = withAppUrlMetadata, exports.yieldToMain = yieldToMain;