@sphoro/bugcatch-web-sdk 0.18.0 → 0.19.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.
@@ -1,10 +1,10 @@
1
- var fe = (t) => {
1
+ var be = (t) => {
2
2
  throw TypeError(t);
3
3
  };
4
- var ht = (t, e, n) => e.has(t) || fe("Cannot " + n);
5
- var pe = (t, e, n) => e.has(t) ? fe("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n);
6
- var x = (t, e, n) => (ht(t, e, "access private method"), n);
7
- const Y = "[REDACTED]", ft = /* @__PURE__ */ new Set([
4
+ var xt = (t, e, n) => e.has(t) || be("Cannot " + n);
5
+ var xe = (t, e, n) => e.has(t) ? be("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n);
6
+ var x = (t, e, n) => (xt(t, e, "access private method"), n);
7
+ const Q = "[REDACTED]", kt = /* @__PURE__ */ new Set([
8
8
  "auth",
9
9
  "bearer",
10
10
  "session",
@@ -16,7 +16,7 @@ const Y = "[REDACTED]", ft = /* @__PURE__ */ new Set([
16
16
  "pwd",
17
17
  "sig",
18
18
  "codeverifier"
19
- ]), pt = [
19
+ ]), vt = [
20
20
  "token",
21
21
  "secret",
22
22
  "password",
@@ -28,7 +28,7 @@ const Y = "[REDACTED]", ft = /* @__PURE__ */ new Set([
28
28
  "privatekey",
29
29
  "accesskey",
30
30
  "authorization"
31
- ], gt = /* @__PURE__ */ new Set(["key", "code", "state", "nonce", "salt", "hash"]), Ae = [
31
+ ], It = /* @__PURE__ */ new Set(["key", "code", "state", "nonce", "salt", "hash"]), Ne = [
32
32
  /eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,
33
33
  // JWT
34
34
  /(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,
@@ -51,61 +51,61 @@ const Y = "[REDACTED]", ft = /* @__PURE__ */ new Set([
51
51
  // GitLab
52
52
  /shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g
53
53
  // Shopify
54
- ], mt = /\bBearer\s+[\w.~+/=-]{8,}/gi, wt = /^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;
55
- function je(t) {
54
+ ], Ct = /\bBearer\s+[\w.~+/=-]{8,}/gi, St = /^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;
55
+ function Ue(t) {
56
56
  try {
57
57
  return decodeURIComponent(t.replace(/\+/g, " "));
58
58
  } catch {
59
59
  return t;
60
60
  }
61
61
  }
62
- function bt(t) {
63
- return je(t).toLowerCase().replace(/[^a-z0-9]/g, "");
62
+ function Bt(t) {
63
+ return Ue(t).toLowerCase().replace(/[^a-z0-9]/g, "");
64
64
  }
65
- function yt(t) {
66
- return t.length >= 20 ? !0 : Ae.some((e) => (e.lastIndex = 0, e.test(t)));
65
+ function Et(t) {
66
+ return t.length >= 20 ? !0 : Ne.some((e) => (e.lastIndex = 0, e.test(t)));
67
67
  }
68
- function vt(t, e) {
69
- const n = bt(t);
68
+ function $t(t, e) {
69
+ const n = Bt(t);
70
70
  if (!n) return !1;
71
- if (ft.has(n)) return !0;
72
- for (const o of pt) if (n.includes(o)) return !0;
73
- return gt.has(n) ? yt(je(e)) : !1;
71
+ if (kt.has(n)) return !0;
72
+ for (const i of vt) if (n.includes(i)) return !0;
73
+ return It.has(n) ? Et(Ue(e)) : !1;
74
74
  }
75
- function G(t) {
75
+ function ie(t) {
76
76
  return t.split("&").map((e) => {
77
77
  const n = e.indexOf("=");
78
78
  if (n === -1) return e;
79
- const o = e.slice(0, n), r = e.slice(n + 1);
80
- return r && vt(o, r) ? `${o}=${Y}` : e;
79
+ const i = e.slice(0, n), r = e.slice(n + 1);
80
+ return r && $t(i, r) ? `${i}=${Q}` : e;
81
81
  }).join("&");
82
82
  }
83
- function Oe(t) {
83
+ function Pe(t) {
84
84
  let e = t;
85
- for (const n of Ae)
86
- n.lastIndex = 0, e = e.replace(n, Y);
85
+ for (const n of Ne)
86
+ n.lastIndex = 0, e = e.replace(n, Q);
87
87
  return e;
88
88
  }
89
- function Me(t) {
89
+ function De(t) {
90
90
  if (t == null) return t;
91
91
  let e = String(t);
92
92
  if (!e) return e;
93
- e = e.replace(wt, `$1${Y}@`);
93
+ e = e.replace(St, `$1${Q}@`);
94
94
  const n = e.indexOf("#");
95
- let o = n === -1 ? e : e.slice(0, n), r = n === -1 ? "" : e.slice(n);
96
- const i = o.indexOf("?");
97
- if (i !== -1 && (o = o.slice(0, i + 1) + G(o.slice(i + 1))), r.length > 1) {
95
+ let i = n === -1 ? e : e.slice(0, n), r = n === -1 ? "" : e.slice(n);
96
+ const o = i.indexOf("?");
97
+ if (o !== -1 && (i = i.slice(0, o + 1) + ie(i.slice(o + 1))), r.length > 1) {
98
98
  const a = r.slice(1), s = a.indexOf("?");
99
- s !== -1 ? r = `#${a.slice(0, s + 1)}${G(a.slice(s + 1))}` : a.includes("=") && (r = `#${G(a)}`);
99
+ s !== -1 ? r = `#${a.slice(0, s + 1)}${ie(a.slice(s + 1))}` : a.includes("=") && (r = `#${ie(a)}`);
100
100
  }
101
- return Oe(o + r);
101
+ return Pe(i + r);
102
102
  }
103
- function kt(t) {
103
+ function Tt(t) {
104
104
  if (t == null) return t;
105
105
  let e = String(t);
106
- return e && (e = e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g, (n) => Me(n)), e = e.replace(mt, `Bearer ${Y}`), Oe(e));
106
+ return e && (e = e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g, (n) => De(n)), e = e.replace(Ct, `Bearer ${Q}`), Pe(e));
107
107
  }
108
- function D(t) {
108
+ function z(t) {
109
109
  const e = [];
110
110
  return {
111
111
  push(n) {
@@ -120,41 +120,41 @@ function D(t) {
120
120
  }
121
121
  };
122
122
  }
123
- const ge = ["log", "info", "warn", "error", "debug"];
124
- function xt(t, { levels: e = ["warn", "error", "log", "info"] } = {}) {
123
+ const ke = ["log", "info", "warn", "error", "debug"];
124
+ function At(t, { levels: e = ["warn", "error", "log", "info"] } = {}) {
125
125
  const n = {};
126
- for (const o of ge)
127
- n[o] = console[o], e.includes(o) && (console[o] = (...r) => {
126
+ for (const i of ke)
127
+ n[i] = console[i], e.includes(i) && (console[i] = (...r) => {
128
128
  try {
129
129
  t.push({
130
- level: o,
131
- text: r.map(Re).join(" ").slice(0, 2e3),
130
+ level: i,
131
+ text: r.map(He).join(" ").slice(0, 2e3),
132
132
  at: (/* @__PURE__ */ new Date()).toISOString()
133
133
  });
134
134
  } catch {
135
135
  }
136
- n[o].apply(console, r);
136
+ n[i].apply(console, r);
137
137
  });
138
138
  return () => {
139
- for (const o of ge) console[o] = n[o];
139
+ for (const i of ke) console[i] = n[i];
140
140
  };
141
141
  }
142
- function It(t, { slowMs: e = 2e3 } = {}) {
143
- const n = window.fetch, o = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.send;
142
+ function jt(t, { slowMs: e = 2e3 } = {}) {
143
+ const n = window.fetch, i = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.send;
144
144
  return n && (window.fetch = async function(...a) {
145
- var f, p, d;
146
- const s = performance.now(), c = typeof a[0] == "string" ? a[0] : (f = a[0]) == null ? void 0 : f.url, l = ((p = a[1]) == null ? void 0 : p.method) || (typeof a[0] == "object" ? (d = a[0]) == null ? void 0 : d.method : "GET") || "GET";
145
+ var h, f, d;
146
+ const s = performance.now(), c = typeof a[0] == "string" ? a[0] : (h = a[0]) == null ? void 0 : h.url, l = ((f = a[1]) == null ? void 0 : f.method) || (typeof a[0] == "object" ? (d = a[0]) == null ? void 0 : d.method : "GET") || "GET";
147
147
  try {
148
148
  const u = await n.apply(this, a);
149
- return Q(t, { url: c, method: l, status: u.status, ms: Math.round(performance.now() - s), slowMs: e }), u;
149
+ return oe(t, { url: c, method: l, status: u.status, ms: Math.round(performance.now() - s), slowMs: e }), u;
150
150
  } catch (u) {
151
- throw Q(t, { url: c, method: l, status: 0, error: String((u == null ? void 0 : u.message) || u), ms: Math.round(performance.now() - s), slowMs: e }), u;
151
+ throw oe(t, { url: c, method: l, status: 0, error: String((u == null ? void 0 : u.message) || u), ms: Math.round(performance.now() - s), slowMs: e }), u;
152
152
  }
153
153
  }), XMLHttpRequest.prototype.open = function(a, s, ...c) {
154
- return this.__bc = { method: a, url: s, started: 0 }, o.call(this, a, s, ...c);
154
+ return this.__bc = { method: a, url: s, started: 0 }, i.call(this, a, s, ...c);
155
155
  }, XMLHttpRequest.prototype.send = function(...a) {
156
156
  return this.__bc && (this.__bc.started = performance.now(), this.addEventListener("loadend", () => {
157
- Q(t, {
157
+ oe(t, {
158
158
  url: this.__bc.url,
159
159
  method: this.__bc.method,
160
160
  status: this.status,
@@ -163,10 +163,10 @@ function It(t, { slowMs: e = 2e3 } = {}) {
163
163
  });
164
164
  })), r.apply(this, a);
165
165
  }, () => {
166
- n && (window.fetch = n), XMLHttpRequest.prototype.open = o, XMLHttpRequest.prototype.send = r;
166
+ n && (window.fetch = n), XMLHttpRequest.prototype.open = i, XMLHttpRequest.prototype.send = r;
167
167
  };
168
168
  }
169
- function Q(t, { url: e, method: n, status: o, ms: r, error: i, slowMs: a }) {
169
+ function oe(t, { url: e, method: n, status: i, ms: r, error: o, slowMs: a }) {
170
170
  try {
171
171
  t.push({
172
172
  // Scrubbed before it is buffered, not before it is sent: a credential
@@ -175,31 +175,31 @@ function Q(t, { url: e, method: n, status: o, ms: r, error: i, slowMs: a }) {
175
175
  // then truncate — truncating first would split a token into something
176
176
  // no pattern recognises, and the fragment would still be a fragment of
177
177
  // a live credential.
178
- url: Me(String(e)).slice(0, 500),
178
+ url: De(String(e)).slice(0, 500),
179
179
  method: n,
180
- status: o,
180
+ status: i,
181
181
  ms: r,
182
- error: i === void 0 ? void 0 : kt(i),
182
+ error: o === void 0 ? void 0 : Tt(o),
183
183
  // Flagged so triage can spot the interesting rows without reading everything.
184
- failed: o === 0 || o >= 400,
184
+ failed: i === 0 || i >= 400,
185
185
  slow: r >= a,
186
186
  at: (/* @__PURE__ */ new Date()).toISOString()
187
187
  });
188
188
  } catch {
189
189
  }
190
190
  }
191
- function St(t) {
192
- const e = (o) => {
193
- const r = String(o.message || "Error"), i = o.filename ? ` (${o.filename}:${o.lineno}:${o.colno})` : "";
191
+ function Ot(t) {
192
+ const e = (i) => {
193
+ const r = String(i.message || "Error"), o = i.filename ? ` (${i.filename}:${i.lineno}:${i.colno})` : "";
194
194
  t.push({
195
195
  level: "error",
196
- text: (/^uncaught/i.test(r) ? r : `Uncaught ${r}`) + i,
196
+ text: (/^uncaught/i.test(r) ? r : `Uncaught ${r}`) + o,
197
197
  at: (/* @__PURE__ */ new Date()).toISOString()
198
198
  });
199
- }, n = (o) => {
199
+ }, n = (i) => {
200
200
  t.push({
201
201
  level: "error",
202
- text: `Unhandled rejection: ${Re(o.reason)}`,
202
+ text: `Unhandled rejection: ${He(i.reason)}`,
203
203
  at: (/* @__PURE__ */ new Date()).toISOString()
204
204
  });
205
205
  };
@@ -207,8 +207,8 @@ function St(t) {
207
207
  window.removeEventListener("error", e), window.removeEventListener("unhandledrejection", n);
208
208
  };
209
209
  }
210
- async function me() {
211
- const t = Le();
210
+ async function ve() {
211
+ const t = _e();
212
212
  try {
213
213
  if (navigator.getBattery) {
214
214
  const e = await navigator.getBattery();
@@ -218,8 +218,8 @@ async function me() {
218
218
  }
219
219
  return t;
220
220
  }
221
- function Le() {
222
- var e, n, o, r, i, a, s, c, l;
221
+ function _e() {
222
+ var e, n, i, r, o, a, s, c, l;
223
223
  const t = window.navigator || {};
224
224
  return {
225
225
  userAgent: t.userAgent,
@@ -233,9 +233,9 @@ function Le() {
233
233
  screen: {
234
234
  width: (e = window.screen) == null ? void 0 : e.width,
235
235
  height: (n = window.screen) == null ? void 0 : n.height,
236
- availWidth: (o = window.screen) == null ? void 0 : o.availWidth,
236
+ availWidth: (i = window.screen) == null ? void 0 : i.availWidth,
237
237
  availHeight: (r = window.screen) == null ? void 0 : r.availHeight,
238
- colorDepth: (i = window.screen) == null ? void 0 : i.colorDepth,
238
+ colorDepth: (o = window.screen) == null ? void 0 : o.colorDepth,
239
239
  orientation: ((s = (a = window.screen) == null ? void 0 : a.orientation) == null ? void 0 : s.type) || null
240
240
  },
241
241
  devicePixelRatio: window.devicePixelRatio,
@@ -260,7 +260,7 @@ function Le() {
260
260
  prefersReducedMotion: ((l = window.matchMedia) == null ? void 0 : l.call(window, "(prefers-reduced-motion: reduce)").matches) || !1
261
261
  };
262
262
  }
263
- function Re(t) {
263
+ function He(t) {
264
264
  if (typeof t == "string") return t;
265
265
  if (t instanceof Error) return `${t.name}: ${t.message}`;
266
266
  try {
@@ -269,152 +269,192 @@ function Re(t) {
269
269
  return String(t);
270
270
  }
271
271
  }
272
- const Ct = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>', Bt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>', Et = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>', $t = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>', Tt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>', Ke = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>', Ue = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>', At = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>', Ne = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>', jt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>';
273
- function De(t, e) {
272
+ const hi = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>', Mt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>', Rt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>', Lt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>', Kt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>', ze = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>', qe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>', Nt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>', Fe = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>', Ut = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>';
273
+ function Xe(t, e) {
274
274
  console.warn(`[BugCatch] ${t}`, ...e ? [e] : []);
275
275
  const n = new Error("[BugCatch] part of the widget could not be loaded — check the connection and try again.");
276
276
  return e && (n.cause = e), n;
277
277
  }
278
- function _e(t) {
278
+ function We(t) {
279
279
  let e = null;
280
- return (...n) => (e || (e = t(...n).catch((o) => {
281
- throw e = null, o;
280
+ return (...n) => (e || (e = t(...n).catch((i) => {
281
+ throw e = null, i;
282
282
  })), e);
283
283
  }
284
- const we = _e(() => import("./bugcatch-panel.es.js").catch((t) => {
285
- throw De("the report panel could not be loaded.", t);
286
- })), _ = _e(() => import("./bugcatch-call.es.js").catch((t) => {
287
- throw De("the calling code could not be loaded.", t);
288
- })), Ot = {
289
- info: Ne,
290
- success: At,
291
- warning: jt,
292
- critical: Ke
284
+ const Ie = We(() => import("./bugcatch-panel.es.js").catch((t) => {
285
+ throw Xe("the report panel could not be loaded.", t);
286
+ })), q = We(() => import("./bugcatch-call.es.js").catch((t) => {
287
+ throw Xe("the calling code could not be loaded.", t);
288
+ })), Pt = {
289
+ info: Fe,
290
+ success: Nt,
291
+ warning: Ut,
292
+ critical: ze
293
293
  };
294
- function Mt(t, { where: e, onDismiss: n }) {
295
- const o = document.createElement("div");
296
- o.className = `notice tone-${t.tone} at-${e}`, o.setAttribute("role", "status");
297
- const r = document.createElement("span");
298
- r.className = "notice-ico", r.setAttribute("aria-hidden", "true"), r.innerHTML = Ot[t.tone] || Ne;
294
+ function Dt(t, { where: e, onDismiss: n }) {
299
295
  const i = document.createElement("div");
300
- i.className = "notice-text";
296
+ i.className = `notice tone-${t.tone} at-${e}`, i.setAttribute("role", "status");
297
+ const r = document.createElement("span");
298
+ r.className = "notice-ico", r.setAttribute("aria-hidden", "true"), r.innerHTML = Pt[t.tone] || Fe;
299
+ const o = document.createElement("div");
300
+ o.className = "notice-text";
301
301
  const a = document.createElement("strong");
302
- if (a.textContent = t.title, i.append(a), t.body) {
302
+ if (a.textContent = t.title, o.append(a), t.body) {
303
303
  const s = document.createElement("p");
304
- s.textContent = t.body, i.append(s);
304
+ s.textContent = t.body, o.append(s);
305
305
  }
306
306
  if (t.ctaHref && t.ctaLabel) {
307
307
  const s = document.createElement("a");
308
- s.className = "notice-cta", s.href = t.ctaHref, s.textContent = t.ctaLabel, /^https?:/i.test(t.ctaHref) && (s.target = "_blank", s.rel = "noopener noreferrer"), i.append(s);
308
+ s.className = "notice-cta", s.href = t.ctaHref, s.textContent = t.ctaLabel, /^https?:/i.test(t.ctaHref) && (s.target = "_blank", s.rel = "noopener noreferrer"), o.append(s);
309
309
  }
310
- if (o.append(r, i), t.dismissible && n) {
310
+ if (i.append(r, o), t.dismissible && n) {
311
311
  const s = document.createElement("button");
312
- s.type = "button", s.className = "notice-x", s.setAttribute("aria-label", "Dismiss this notice"), s.innerHTML = Ue, s.addEventListener("click", () => n(t)), o.append(s);
312
+ s.type = "button", s.className = "notice-x", s.setAttribute("aria-label", "Dismiss this notice"), s.innerHTML = qe, s.addEventListener("click", () => n(t)), i.append(s);
313
313
  }
314
- return o;
314
+ return i;
315
+ }
316
+ const Je = "#0e0e10", re = "#ffffff";
317
+ function Ye(t) {
318
+ const e = _t(t);
319
+ if (!e) return re;
320
+ const [n, i, r] = e.map((a) => {
321
+ const s = a / 255;
322
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
323
+ });
324
+ return 0.2126 * n + 0.7152 * i + 0.0722 * r > 0.179 ? Je : re;
325
+ }
326
+ function _t(t) {
327
+ const e = String(t || "").trim();
328
+ let n = /^#([0-9a-f]{3})$/i.exec(e);
329
+ return n ? [...n[1]].map((i) => parseInt(i + i, 16)) : (n = /^#([0-9a-f]{6})$/i.exec(e), n ? [0, 2, 4].map((i) => parseInt(n[1].slice(i, i + 2), 16)) : (n = /^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i.exec(e), n ? [n[1], n[2], n[3]].map(Number) : null));
315
330
  }
316
- const be = {
331
+ const Ce = {
317
332
  "bottom-right": "bottom:20px;right:20px;",
318
333
  "bottom-left": "bottom:20px;left:20px;",
319
334
  "top-right": "top:20px;right:20px;",
320
335
  "top-left": "top:20px;left:20px;"
321
- }, Pe = [
322
- { value: "light", label: "Light", icon: Et },
323
- { value: "dark", label: "Dark", icon: $t },
324
- { value: "auto", label: "System default", icon: Tt }
325
- ], He = "bugcatch:theme";
326
- function Lt() {
336
+ }, P = [
337
+ { value: "light", label: "Light", icon: Rt },
338
+ { value: "dark", label: "Dark", icon: Lt },
339
+ { value: "auto", label: "System default", icon: Kt }
340
+ ], Ve = "bugcatch:theme";
341
+ function Ht() {
327
342
  try {
328
- const t = localStorage.getItem(He);
329
- return Pe.some((e) => e.value === t) ? t : null;
343
+ const t = localStorage.getItem(Ve);
344
+ return P.some((e) => e.value === t) ? t : null;
330
345
  } catch {
331
346
  return null;
332
347
  }
333
348
  }
334
- function Rt(t) {
349
+ function zt(t) {
335
350
  try {
336
- localStorage.setItem(He, t);
351
+ localStorage.setItem(Ve, t);
337
352
  } catch {
338
353
  }
339
354
  }
340
- const Kt = (t) => `
355
+ const Se = `
356
+ --bc-bg: #151517;
357
+ --bc-elevated: #1c1c1f;
358
+ --bc-fg: #f3f2ef;
359
+ --bc-muted: #b3b0aa;
360
+ --bc-faint: #8f8c86;
361
+ --bc-border: #2c2c30;
362
+ --bc-subtle: #1f1f22;
363
+ --bc-stone: #26262a;
364
+ --bc-raised: #303035;
365
+ --bc-danger: #ff6b81;
366
+ --bc-ok: #4fd19a;
367
+ --bc-warn: #f2a54a;
368
+ --bc-info: #79a8ff;
369
+ --bc-brand-ink: #b3b0aa;
370
+ --bc-brand-mark: #a59cff;
371
+ --bc-shadow: 0 0 0 1px rgba(255,255,255,.08), 0 30px 70px -20px rgba(0,0,0,.8), 0 8px 20px -8px rgba(0,0,0,.5);
372
+ --bc-shadow-sm: 0 0 0 1px rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.4);
373
+ --bc-accent-soft: color-mix(in srgb, var(--bc-accent) 14%, var(--bc-bg));`, qt = (t) => `
341
374
  :host { all: initial; }
342
375
  :host {
343
- --bc-accent: ${t};
344
- --bc-on-accent: #fff;
345
- --bc-bg: #fff;
346
- --bc-elevated: #fff;
347
- --bc-fg: #14161c;
348
- --bc-muted: #5f6673;
349
- --bc-faint: #9aa1ad;
350
- --bc-border: #e6e8ee;
351
- --bc-subtle: #f4f5f8;
352
- --bc-raised: #fff;
353
- --bc-danger: #dc2626;
354
- --bc-ok: #059669;
355
- --bc-warn: #b45309;
376
+ --bc-accent: ${t || "var(--bc-fg)"};
377
+ --bc-on-accent: ${t ? Ye(t) : "var(--bc-bg)"};
378
+ /* The assistant's orb: BugCatch's own three colours, or the host's accent
379
+ with two lighter cuts of it, so the orb on their site is in their colour. */
380
+ --bc-o1: ${t ? `color-mix(in srgb, ${t} 32%, #fff)` : "#ffb3c9"};
381
+ --bc-o2: ${t || "#6a5cff"};
382
+ --bc-o3: ${t ? `color-mix(in srgb, ${t} 22%, #ffe7d1)` : "#ffd6a0"};
383
+ --bc-bg: #ffffff;
384
+ --bc-elevated: #ffffff;
385
+ --bc-fg: #0e0e10;
386
+ --bc-muted: #57544e;
387
+ --bc-faint: #75726c;
388
+ --bc-border: #e9e7e3;
389
+ --bc-subtle: #f6f5f3;
390
+ /* Warm stone: fields, chips and the selected track. */
391
+ --bc-stone: #f0efec;
392
+ --bc-raised: #ffffff;
393
+ --bc-danger: #c8233d;
394
+ --bc-ok: #0b7a55;
395
+ --bc-warn: #a4570a;
396
+ --bc-info: #2459d1;
356
397
  /* The lockup's own two colours, kept off --bc-accent on purpose: that one is
357
398
  the customer's brand, and this mark is ours. Values are the light cut of
358
399
  brand/sphoro-bugcatch-primary.svg, pulled up from near-black so the mark
359
400
  identifies itself without out-shouting the host's page. */
360
- --bc-brand-ink: #4b5563;
401
+ --bc-brand-ink: #57544e;
361
402
  --bc-brand-mark: #5647ee;
362
- --bc-shadow: 0 24px 64px rgba(10,12,16,.22), 0 4px 14px rgba(10,12,16,.08);
363
- --bc-shadow-sm: 0 1px 2px rgba(10,12,16,.06), 0 1px 1px rgba(10,12,16,.04);
364
- --bc-dur: 240ms;
403
+ --bc-shadow: 0 0 0 1px rgba(20,18,14,.06), 0 30px 70px -24px rgba(20,18,14,.30), 0 8px 20px -8px rgba(20,18,14,.10);
404
+ --bc-shadow-sm: 0 0 0 1px rgba(20,18,14,.06), 0 1px 2px rgba(20,18,14,.05);
405
+ --bc-dur: 220ms;
365
406
  --bc-ease: cubic-bezier(.22,1,.36,1);
407
+ /* Film grain over the orb, so it reads as light rather than a gradient. */
408
+ --bc-grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
366
409
  /* The system everything below is drawn from. Derived tokens are written in
367
410
  terms of the ones above, so a host that overrides --bc-accent or the
368
411
  palette gets a coherent result without touching these. */
369
- --bc-accent-soft: color-mix(in srgb, var(--bc-accent) 10%, var(--bc-bg));
370
- --bc-accent-line: color-mix(in srgb, var(--bc-accent) 32%, var(--bc-border));
371
- --bc-ring: 0 0 0 3px color-mix(in srgb, var(--bc-accent) 22%, transparent);
412
+ --bc-accent-soft: color-mix(in srgb, var(--bc-accent) 7%, var(--bc-bg));
413
+ --bc-accent-line: color-mix(in srgb, var(--bc-accent) 30%, var(--bc-border));
414
+ --bc-ring: 0 0 0 3px color-mix(in srgb, var(--bc-accent) 16%, transparent);
372
415
  --bc-r-sm: 8px;
373
416
  --bc-r-md: 12px;
374
- --bc-r-lg: 18px;
375
- --bc-r-xl: 22px;
417
+ --bc-r-lg: 16px;
418
+ --bc-r-xl: 20px;
376
419
  --bc-fs-xs: 11.5px;
377
420
  --bc-fs-sm: 12.5px;
378
421
  --bc-fs-md: 14px;
379
- --bc-fs-lg: 16px;
422
+ --bc-fs-lg: 15px;
380
423
  --bc-pad: 18px;
381
424
  }
382
- :host(.bc-dark) {
383
- --bc-bg: #14161c;
384
- --bc-elevated: #1c1f27;
385
- --bc-fg: #eef0f4;
386
- --bc-muted: #a3aab6;
387
- --bc-faint: #6f7682;
388
- --bc-border: #2a2e38;
389
- --bc-subtle: #1f222a;
390
- --bc-raised: #363d4b;
391
- --bc-warn: #f59e0b;
392
- --bc-brand-ink: #9aa1ad;
393
- --bc-brand-mark: #9b8fff;
394
- --bc-shadow: 0 24px 64px rgba(0,0,0,.6), 0 4px 14px rgba(0,0,0,.4);
395
- --bc-shadow-sm: 0 1px 2px rgba(0,0,0,.4);
396
- --bc-accent-soft: color-mix(in srgb, var(--bc-accent) 18%, var(--bc-bg));
425
+ :host(.bc-dark) {${Se}
397
426
  }
398
427
  @media (prefers-color-scheme: dark) {
399
- :host(.bc-auto) {
400
- --bc-bg: #14161c;
401
- --bc-elevated: #1c1f27;
402
- --bc-fg: #eef0f4;
403
- --bc-muted: #a3aab6;
404
- --bc-faint: #6f7682;
405
- --bc-border: #2a2e38;
406
- --bc-subtle: #1f222a;
407
- --bc-raised: #363d4b;
408
- --bc-warn: #f59e0b;
409
- --bc-brand-ink: #9aa1ad;
410
- --bc-brand-mark: #9b8fff;
411
- --bc-shadow: 0 24px 64px rgba(0,0,0,.6), 0 4px 14px rgba(0,0,0,.4);
412
- --bc-shadow-sm: 0 1px 2px rgba(0,0,0,.4);
413
- --bc-accent-soft: color-mix(in srgb, var(--bc-accent) 18%, var(--bc-bg));
428
+ :host(.bc-auto) {${Se}
414
429
  }
415
430
  }
416
431
 
417
432
  * { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif; }
433
+
434
+ /* ---------- the orb ----------
435
+ The assistant's face, on the launcher and at the top of every screen: three
436
+ blurred colour blobs turning slowly under a highlight and grain. Hue from
437
+ --bc-o1..3. Sized by whoever places it. */
438
+ .orb {
439
+ position: relative; display: block; flex: none; aspect-ratio: 1; border-radius: 50%;
440
+ background: var(--bc-o2); overflow: hidden; isolation: isolate;
441
+ box-shadow: inset -3px -5px 10px rgba(0,0,0,.22), inset 2px 3px 7px rgba(255,255,255,.35);
442
+ }
443
+ .orb::before {
444
+ content: ''; position: absolute; inset: -20%; border-radius: 50%; z-index: -1;
445
+ background:
446
+ radial-gradient(circle at 70% 72%, var(--bc-o3) 0%, transparent 44%),
447
+ radial-gradient(circle at 26% 66%, var(--bc-o1) 0%, transparent 48%),
448
+ radial-gradient(circle at 58% 30%, var(--bc-o2) 0%, transparent 62%);
449
+ filter: blur(3px);
450
+ animation: bc-orb-turn 18s linear infinite;
451
+ }
452
+ .orb::after {
453
+ content: ''; position: absolute; inset: 0; border-radius: 50%;
454
+ background: radial-gradient(circle at 34% 26%, rgba(255,255,255,.85) 0 5%, rgba(255,255,255,0) 30%), var(--bc-grain);
455
+ mix-blend-mode: soft-light;
456
+ }
457
+ @keyframes bc-orb-turn { to { transform: rotate(360deg); } }
418
458
  svg { width: 1em; height: 1em; display: block; }
419
459
  /* The hidden attribute has to actually hide. Nearly every element in here is given a
420
460
  display by a rule below, and any of them beats the attribute's own UA style
@@ -445,65 +485,50 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
445
485
  @keyframes bc-launcher-in { from { opacity: 0; transform: translateY(12px) scale(.86) } to { opacity: 1; transform: none } }
446
486
  @keyframes bc-item-in { from { opacity: 0; transform: translateY(8px) scale(.96) } to { opacity: 1; transform: none } }
447
487
 
448
- /* ---------- dock: theme switch stacked above the launcher ---------- */
488
+ /* ---------- dock: the launcher, and what is said beside it ---------- */
449
489
  .dock {
450
490
  position: fixed; z-index: 2147483000;
451
491
  display: flex; flex-direction: column; gap: 10px;
452
492
  }
453
493
  .dock[hidden] { display: none; }
454
- /* While the panel is open the switch rises above the scrim so it stays usable
455
- — the panel shares the shadow root, so a change re-themes the open form. */
494
+ /* While the panel is open the launcher rises above the scrim, so the button
495
+ that opened it is the button that closes it. */
456
496
  .dock.over { z-index: 2147483002; }
457
497
  .dock.at-right { align-items: flex-end; }
458
498
  .dock.at-left { align-items: flex-start; }
459
- /* Anchored to the top, "above the launcher" would be off-screen, so the
460
- switch goes under it and the launcher stays the outermost thing. */
499
+ /* Anchored to the top, "above the launcher" would be off-screen, so cards go
500
+ under it and the launcher stays the outermost thing. */
461
501
  .dock.at-top { flex-direction: column-reverse; }
462
502
 
463
- .themer {
464
- display: inline-flex; align-items: center; gap: 2px;
465
- padding: 3px; border-radius: 999px;
466
- background: var(--bc-elevated); border: 1px solid var(--bc-border);
467
- box-shadow: 0 6px 18px rgba(10,12,16,.14), 0 1px 3px rgba(10,12,16,.08);
468
- animation: bc-launcher-in 420ms var(--bc-ease) both;
469
- }
470
- .themer button {
471
- display: grid; place-items: center;
472
- width: 28px; height: 28px; padding: 0;
473
- border: none; border-radius: 999px; background: transparent;
474
- color: var(--bc-muted); cursor: pointer;
475
- transition: background var(--bc-dur) var(--bc-ease), color var(--bc-dur) var(--bc-ease), transform 140ms var(--bc-ease);
476
- }
477
- .themer button svg { font-size: 15px; }
478
- .themer button:hover { background: var(--bc-subtle); color: var(--bc-fg); }
479
- .themer button:active { transform: scale(.92); }
480
- .themer button[aria-pressed="true"] { background: var(--bc-accent); color: var(--bc-on-accent); }
481
- .themer button[aria-pressed="true"]:hover { background: var(--bc-accent); filter: brightness(1.06); }
482
-
483
- /* ---------- launcher ---------- */
503
+ /* ---------- launcher ----------
504
+ A pill with the assistant's orb in it: ink by default, the host's colour when
505
+ they set one. The shadow is neutral, never tinted, so a bright brand colour
506
+ does not glow on somebody's checkout. */
484
507
  .launcher {
485
508
  position: relative;
486
- display: inline-flex; align-items: center; gap: 9px;
487
- height: 48px; padding: 0 20px 0 16px; border: none; border-radius: 999px;
509
+ display: inline-flex; align-items: center; gap: 10px;
510
+ height: 46px; padding: 0 18px 0 7px; border: none; border-radius: 999px;
488
511
  background: var(--bc-accent); color: var(--bc-on-accent);
489
- font-size: var(--bc-fs-md); font-weight: 620; line-height: 1; letter-spacing: -.01em;
512
+ font-size: var(--bc-fs-md); font-weight: 560; line-height: 1; letter-spacing: -.01em;
490
513
  cursor: pointer;
491
- box-shadow: 0 10px 28px color-mix(in srgb, var(--bc-accent) 34%, rgba(10,12,16,.2)), 0 2px 6px rgba(10,12,16,.16);
492
- transition: transform var(--bc-dur) var(--bc-ease), box-shadow var(--bc-dur) var(--bc-ease), filter 160ms linear, padding var(--bc-dur) var(--bc-ease);
514
+ box-shadow: 0 1px 2px rgba(0,0,0,.18), 0 10px 26px -8px rgba(0,0,0,.36);
515
+ transition: transform var(--bc-dur) var(--bc-ease), box-shadow var(--bc-dur) var(--bc-ease), filter 160ms linear;
493
516
  animation: bc-launcher-in 420ms var(--bc-ease) both;
494
517
  }
495
- /* Two glyphs in one box: the bubble when closed, a chevron when open, turned
518
+ /* Two faces in one circle: the orb when closed, a chevron when open, turned
496
519
  into each other so the button reads as the panel's own handle. */
497
- .launcher .ico { position: relative; width: 20px; height: 20px; flex: none; }
520
+ .launcher .ico { position: relative; width: 32px; height: 32px; flex: none; }
498
521
  .launcher .ico > span {
499
- position: absolute; inset: 0;
522
+ position: absolute; inset: 0; display: grid; place-items: center; border-radius: 50%;
500
523
  transition: transform 320ms var(--bc-ease), opacity 200ms ease;
501
524
  }
502
- .launcher .ico svg { width: 20px; height: 20px; }
525
+ .launcher .ico .orb { width: 32px; }
526
+ .launcher .ico .when-open { background: color-mix(in srgb, var(--bc-on-accent) 14%, transparent); }
527
+ .launcher .ico svg { width: 18px; height: 18px; }
503
528
  .launcher .ico .when-open { opacity: 0; transform: rotate(-90deg) scale(.6); }
504
529
  .launcher[aria-expanded="true"] .ico .when-closed { opacity: 0; transform: rotate(90deg) scale(.6); }
505
530
  .launcher[aria-expanded="true"] .ico .when-open { opacity: 1; transform: none; }
506
- .launcher:hover { transform: translateY(-2px); filter: brightness(1.06); }
531
+ .launcher:hover { transform: translateY(-1px); box-shadow: 0 1px 2px rgba(0,0,0,.18), 0 14px 30px -8px rgba(0,0,0,.42); }
507
532
  .launcher:active { transform: translateY(0) scale(.97); transition-duration: 90ms; }
508
533
  .launcher:focus-visible { outline-offset: 3px; }
509
534
  .launcher[hidden] { display: none; }
@@ -526,11 +551,11 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
526
551
  In this sheet because the card beside the button exists before the panel's
527
552
  does. The tone is a colour and an icon; the site's accent is the info one. */
528
553
  .notice {
529
- --tone: var(--bc-accent);
554
+ --tone: var(--bc-info);
530
555
  display: flex; align-items: flex-start; gap: 10px;
531
- padding: 12px 12px 12px 14px; border-radius: var(--bc-r-md);
532
- background: color-mix(in srgb, var(--tone) 7%, var(--bc-elevated));
533
- border: 1px solid color-mix(in srgb, var(--tone) 28%, var(--bc-border));
556
+ padding: 11px 10px 11px 12px; border-radius: var(--bc-r-md);
557
+ background: var(--bc-subtle);
558
+ border: 1px solid var(--bc-border);
534
559
  color: var(--bc-fg);
535
560
  font-size: var(--bc-fs-sm); line-height: 1.45; text-align: left;
536
561
  animation: bc-item-in 240ms var(--bc-ease) both;
@@ -538,33 +563,48 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
538
563
  .notice.tone-success { --tone: var(--bc-ok); }
539
564
  .notice.tone-warning { --tone: var(--bc-warn); }
540
565
  .notice.tone-critical { --tone: var(--bc-danger); }
541
- .notice-ico { flex: none; color: var(--tone); font-size: 16px; margin-top: 1px; }
566
+ /* The tone is the icon's colour and a wash behind it — enough to tell a delay
567
+ from a fix at a glance, without a coloured card shouting over the form. */
568
+ .notice-ico {
569
+ flex: none; display: grid; place-items: center; width: 22px; height: 22px; margin-top: -1px;
570
+ border-radius: 7px; font-size: 14px;
571
+ color: var(--tone); background: color-mix(in srgb, var(--tone) 13%, transparent);
572
+ }
542
573
  .notice-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
543
- .notice-text strong { display: block; font-weight: 650; letter-spacing: -.005em; }
574
+ .notice-text strong { display: block; font-weight: 600; letter-spacing: -.005em; }
544
575
  .notice-text p { margin: 2px 0 0; color: var(--bc-muted); white-space: pre-line; }
545
576
  .notice-cta {
546
- display: inline-block; margin-top: 6px;
547
- color: var(--tone); font-weight: 620; text-decoration: none;
577
+ display: inline-flex; align-items: center; gap: 4px; margin-top: 6px;
578
+ color: var(--bc-fg); font-weight: 600; text-decoration: underline;
579
+ text-decoration-color: color-mix(in srgb, var(--bc-fg) 30%, transparent); text-underline-offset: 3px;
548
580
  }
549
- .notice-cta:hover { text-decoration: underline; text-underline-offset: 2px; }
581
+ .notice-cta:hover { text-decoration-color: currentColor; }
550
582
  .notice-x {
551
583
  flex: none; display: grid; place-items: center;
552
- width: 26px; height: 26px; margin: -4px -4px 0 0; padding: 0;
584
+ width: 24px; height: 24px; margin: -2px -2px 0 0; padding: 0;
553
585
  border: 0; border-radius: 999px; background: transparent;
554
- color: var(--bc-muted); cursor: pointer;
586
+ color: var(--bc-faint); cursor: pointer;
555
587
  }
556
- .notice-x:hover { background: color-mix(in srgb, var(--tone) 12%, transparent); color: var(--bc-fg); }
557
- .notice-x svg { font-size: 14px; }
588
+ .notice-x:hover { background: color-mix(in srgb, var(--bc-fg) 7%, transparent); color: var(--bc-fg); }
589
+ .notice-x svg { font-size: 13px; }
558
590
  /* Beside the button it floats over somebody else's page: opaque, lifted, and
559
591
  never taller than a glance. The whole text is in the panel. */
560
592
  .notice.at-launcher {
561
593
  width: min(320px, calc(100vw - 40px));
562
- box-shadow: 0 10px 28px rgba(10,12,16,.14), 0 1px 3px rgba(10,12,16,.08);
594
+ background: var(--bc-elevated); border-color: transparent;
595
+ box-shadow: var(--bc-shadow);
596
+ padding: 13px 12px 13px 13px;
563
597
  }
564
598
  .notice.at-launcher .notice-text p {
565
599
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
566
600
  }
567
- .notice.at-panel { margin-bottom: 10px; }
601
+ /* In the panel they are a stack of short lines above the form, not a wall:
602
+ the body is held to two lines, and the whole of it was beside the button. */
603
+ .notice.at-panel { margin-bottom: 8px; padding: 9px 8px 9px 10px; }
604
+ .notice.at-panel .notice-text p {
605
+ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
606
+ }
607
+ .notice.at-panel .notice-cta { margin-top: 3px; }
568
608
 
569
609
  /* The dock sits in a corner of a page the widget does not own. On a notched
570
610
  phone that corner is under the home indicator, and in landscape it is under
@@ -584,25 +624,12 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
584
624
  .dock.over { display: none; }
585
625
  }
586
626
  @media (pointer: coarse) {
587
- /* The theme switch's buttons are small glyphs whose boxes cannot grow without
588
- moving the launcher under them, so each keeps its size and gets an
589
- invisible target drawn around it instead. */
590
- .themer button { position: relative; }
591
- .themer button::after {
592
- content: '';
593
- position: absolute;
594
- inset: -8px;
595
- }
596
- /* The themer's three buttons sit side by side, so their expanders would
597
- overlap each other without a gap to grow into. */
598
- .themer { gap: 4px; }
599
627
  .notice-x { width: 36px; height: 36px; margin: -9px -8px -6px 0; }
600
628
  }
601
629
  /* Hover is a lie on a touchscreen: it latches on tap and stays. The launcher's
602
630
  lift in particular was left applied after the panel closed. */
603
631
  @media (hover: none) {
604
632
  .launcher:hover { transform: none; filter: none; }
605
- .themer button:hover { transform: none; }
606
633
  }
607
634
 
608
635
  /* ---------- while the panel's code is on its way ----------
@@ -628,99 +655,100 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
628
655
  .loadfail button[data-act="retry"] { text-decoration: underline; text-underline-offset: 2px; }
629
656
  .loadfail button svg { font-size: 13px; margin: 0; }
630
657
  `;
631
- function Ut(t) {
658
+ function Ft(t) {
632
659
  const e = document.createElement("div");
633
660
  e.setAttribute("data-bugcatch", "widget");
634
- let n = Lt() || Nt(t.config.theme);
635
- e.className = ye(n);
636
- const o = e.attachShadow({ mode: "open" }), r = document.createElement("style");
637
- r.textContent = Kt(t.config.accent || "#4F46E5"), o.appendChild(r);
638
- const i = be[t.config.widgetPosition] ? t.config.widgetPosition : "bottom-right", a = document.createElement("div");
639
- a.className = `dock ${i.includes("right") ? "at-right" : "at-left"}` + (i.startsWith("top") ? " at-top" : ""), a.style.cssText = be[i];
640
- const s = document.createElement("div");
641
- s.className = "themer", s.setAttribute("role", "group"), s.setAttribute("aria-label", "Report widget theme"), s.innerHTML = Pe.map((w) => `<button type="button" data-theme="${w.value}" title="${w.label}" aria-label="${w.label}" aria-pressed="${w.value === n}">${w.icon}</button>`).join(""), s.addEventListener("click", (w) => {
642
- const k = w.target.closest("button[data-theme]");
643
- !k || k.dataset.theme === n || (n = k.dataset.theme, e.className = ye(n), Rt(n), s.querySelectorAll("button").forEach((B) => {
644
- B.setAttribute("aria-pressed", String(B.dataset.theme === n));
645
- }));
646
- });
647
- const c = document.createElement("button");
648
- c.className = "launcher", c.type = "button", c.innerHTML = `<span class="ico" aria-hidden="true"><span class="when-closed">${Ct}</span><span class="when-open">${Bt}</span></span><span>Report a bug</span>`, c.setAttribute("aria-haspopup", "dialog"), c.setAttribute("aria-expanded", "false");
661
+ let n = Ht() || Xt(t.config.theme);
662
+ e.className = Be(n);
663
+ const i = e.attachShadow({ mode: "open" }), r = document.createElement("style");
664
+ r.textContent = qt(t.config.accent || null), i.appendChild(r);
665
+ const o = Ce[t.config.widgetPosition] ? t.config.widgetPosition : "bottom-right", a = document.createElement("div");
666
+ a.className = `dock ${o.includes("right") ? "at-right" : "at-left"}` + (o.startsWith("top") ? " at-top" : ""), a.style.cssText = Ce[o];
667
+ const s = {
668
+ current: () => n,
669
+ label: () => P.find((g) => g.value === n).label,
670
+ cycle() {
671
+ const g = P[(P.findIndex((b) => b.value === n) + 1) % P.length];
672
+ return n = g.value, e.className = Be(n), zt(n), g;
673
+ }
674
+ }, c = document.createElement("button");
675
+ c.className = "launcher", c.type = "button", c.innerHTML = `<span class="ico" aria-hidden="true"><span class="when-closed"><span class="orb"></span></span><span class="when-open">${Mt}</span></span><span>Report a bug</span>`, c.setAttribute("aria-haspopup", "dialog"), c.setAttribute("aria-expanded", "false");
649
676
  let l = null;
650
677
  c.addEventListener("click", () => {
651
678
  if (l) {
652
679
  l.close();
653
680
  return;
654
681
  }
655
- l = f();
682
+ l = h();
656
683
  });
657
- function f() {
658
- S(), v();
659
- let w = null, k = !1;
684
+ function h() {
685
+ I(), p();
686
+ let g = null, b = !1;
660
687
  const B = () => {
661
- k = !0, c.removeAttribute("aria-busy"), l = null;
662
- }, b = {
663
- close: () => w ? w.close() : B(),
664
- destroy: () => w ? w.destroy() : B()
688
+ b = !0, c.removeAttribute("aria-busy"), l = null;
689
+ }, y = {
690
+ close: () => g ? g.close() : B(),
691
+ destroy: () => g ? g.destroy() : B()
665
692
  };
666
- return c.setAttribute("aria-busy", "true"), we(t.config.chunkBase).then(({ openPanel: y }) => {
667
- k || (c.removeAttribute("aria-busy"), a.classList.add("over"), c.setAttribute("aria-expanded", "true"), w = y({
668
- root: o,
693
+ return c.setAttribute("aria-busy", "true"), Ie(t.config.chunkBase).then(({ openPanel: C }) => {
694
+ b || (c.removeAttribute("aria-busy"), a.classList.add("over"), c.setAttribute("aria-expanded", "true"), g = C({
695
+ root: i,
669
696
  host: e,
670
697
  dock: a,
671
698
  client: t,
672
699
  preloadCall: u,
700
+ themeControls: s,
673
701
  onClose: () => {
674
702
  l = null, a.classList.remove("over"), c.setAttribute("aria-expanded", "false");
675
703
  }
676
704
  }));
677
705
  }, () => {
678
- k || (B(), $());
679
- }), b;
706
+ b || (B(), $());
707
+ }), y;
680
708
  }
681
- const p = () => {
682
- we(t.config.chunkBase).catch(() => {
709
+ const f = () => {
710
+ Ie(t.config.chunkBase).catch(() => {
683
711
  });
684
712
  };
685
- for (const w of ["pointerenter", "touchstart", "focus"])
686
- c.addEventListener(w, p, { once: !0, passive: !0 });
687
- const d = ve(p);
713
+ for (const g of ["pointerenter", "touchstart", "focus"])
714
+ c.addEventListener(g, f, { once: !0, passive: !0 });
715
+ const d = Ee(f);
688
716
  function u() {
689
- _(t.config.chunkBase).catch(() => {
717
+ q(t.config.chunkBase).catch(() => {
690
718
  });
691
719
  }
692
- let g = null;
720
+ let m = null;
693
721
  function $() {
694
- S(), g = document.createElement("div"), g.className = "msg err loadfail", g.setAttribute("role", "alert"), g.innerHTML = `${Ke}<span>The report form didn't load. Check your connection and try again.</span><button type="button" data-act="retry">Try again</button><button type="button" data-act="dismiss" aria-label="Dismiss">${Ue}</button>`, g.querySelector('[data-act="retry"]').addEventListener("click", () => {
695
- c.focus(), l || (l = f());
696
- }), g.querySelector('[data-act="dismiss"]').addEventListener("click", () => {
697
- c.focus(), S();
698
- }), a.prepend(g);
699
- }
700
- function S() {
701
- g == null || g.remove(), g = null;
702
- }
703
- let h = null;
704
- function I(w) {
705
- v(), h = Mt(w, {
722
+ I(), m = document.createElement("div"), m.className = "msg err loadfail", m.setAttribute("role", "alert"), m.innerHTML = `${ze}<span>The report form didn't load. Check your connection and try again.</span><button type="button" data-act="retry">Try again</button><button type="button" data-act="dismiss" aria-label="Dismiss">${qe}</button>`, m.querySelector('[data-act="retry"]').addEventListener("click", () => {
723
+ c.focus(), l || (l = h());
724
+ }), m.querySelector('[data-act="dismiss"]').addEventListener("click", () => {
725
+ c.focus(), I();
726
+ }), a.prepend(m);
727
+ }
728
+ function I() {
729
+ m == null || m.remove(), m = null;
730
+ }
731
+ let v = null;
732
+ function T(g) {
733
+ p(), v = Dt(g, {
706
734
  where: "launcher",
707
- onDismiss: (k) => {
708
- t.dismissAnnouncement(k), c.focus(), v();
735
+ onDismiss: (b) => {
736
+ t.dismissAnnouncement(b), c.focus(), p();
709
737
  }
710
- }), g ? g.after(h) : a.prepend(h);
738
+ }), m ? m.after(v) : a.prepend(v);
711
739
  }
712
- function v() {
713
- h == null || h.remove(), h = null;
740
+ function p() {
741
+ v == null || v.remove(), v = null;
714
742
  }
715
- const C = t.config.announcements === !1 ? () => {
716
- } : ve(() => {
717
- t.announcements().then((w) => {
718
- const k = w.find((B) => B.placement === "launcher");
719
- k && !l && e.isConnected && I(k);
743
+ const k = t.config.announcements === !1 ? () => {
744
+ } : Ee(() => {
745
+ t.announcements().then((g) => {
746
+ const b = g.find((B) => B.placement === "launcher");
747
+ b && !l && e.isConnected && T(b);
720
748
  }).catch(() => {
721
749
  });
722
750
  });
723
- return a.append(s, c), o.appendChild(a), document.body.appendChild(e), t.widgetControls = {
751
+ return a.append(c), i.appendChild(a), document.body.appendChild(e), t.widgetControls = {
724
752
  open: () => {
725
753
  l || c.click();
726
754
  },
@@ -729,34 +757,34 @@ function Ut(t) {
729
757
  },
730
758
  isOpen: () => !!l
731
759
  }, () => {
732
- d(), C(), l == null || l.destroy(), e.remove(), t.widgetControls = null;
760
+ d(), k(), l == null || l.destroy(), e.remove(), t.widgetControls = null;
733
761
  };
734
762
  }
735
- function Nt(t) {
763
+ function Xt(t) {
736
764
  return t === "dark" || t === "light" ? t : "auto";
737
765
  }
738
- function ye(t) {
766
+ function Be(t) {
739
767
  return t === "dark" ? "bc-dark" : t === "light" ? "bc-light" : "bc-auto";
740
768
  }
741
- function ve(t) {
769
+ function Ee(t) {
742
770
  let e = () => {
743
771
  };
744
772
  const n = () => {
745
773
  if (typeof requestIdleCallback == "function") {
746
- const o = requestIdleCallback(t, { timeout: 5e3 });
747
- e = () => cancelIdleCallback(o);
774
+ const i = requestIdleCallback(t, { timeout: 5e3 });
775
+ e = () => cancelIdleCallback(i);
748
776
  } else {
749
- const o = setTimeout(t, 1500);
750
- e = () => clearTimeout(o);
777
+ const i = setTimeout(t, 1500);
778
+ e = () => clearTimeout(i);
751
779
  }
752
780
  };
753
781
  return document.readyState === "complete" ? n() : (window.addEventListener("load", n, { once: !0 }), e = () => window.removeEventListener("load", n)), () => e();
754
782
  }
755
- const Dt = "Too many requests are being sent from here at the moment. Please try again in a minute.";
756
- function L(t) {
757
- return t || Dt;
783
+ const Wt = "Too many requests are being sent from here at the moment. Please try again in a minute.";
784
+ function N(t) {
785
+ return t || Wt;
758
786
  }
759
- const _t = typeof window < "u" && window.fetch ? window.fetch.bind(window) : null, Pt = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.open : null, Ht = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.send : null, zt = [
787
+ const Jt = typeof window < "u" && window.fetch ? window.fetch.bind(window) : null, Yt = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.open : null, Vt = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.send : null, Zt = [
760
788
  "image/png",
761
789
  "image/jpeg",
762
790
  "image/webp",
@@ -777,27 +805,27 @@ const _t = typeof window < "u" && window.fetch ? window.fetch.bind(window) : nul
777
805
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
778
806
  "application/vnd.ms-excel",
779
807
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
780
- ], ke = [
808
+ ], $e = [
781
809
  "image/png",
782
810
  "image/jpeg",
783
811
  "image/webp",
784
812
  "video/webm",
785
813
  "video/mp4"
786
- ], oo = () => {
814
+ ], fi = () => {
787
815
  var t;
788
816
  return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getUserMedia && typeof MediaRecorder < "u");
789
- }, io = () => {
817
+ }, pi = () => {
790
818
  var t;
791
819
  return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getDisplayMedia && typeof MediaRecorder < "u");
792
- }, ro = () => {
820
+ }, gi = () => {
793
821
  var t;
794
822
  return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getDisplayMedia);
795
823
  };
796
- function ee(t, e = zt) {
824
+ function ae(t, e = Zt) {
797
825
  const n = String(t || "").split(";")[0].trim().toLowerCase();
798
826
  return e.includes(n) ? n : null;
799
827
  }
800
- async function ao() {
828
+ async function mi() {
801
829
  const t = await navigator.mediaDevices.getDisplayMedia({
802
830
  video: { frameRate: 1 },
803
831
  audio: !1
@@ -805,268 +833,268 @@ async function ao() {
805
833
  try {
806
834
  const e = t.getVideoTracks()[0], n = document.createElement("video");
807
835
  n.srcObject = t, n.muted = !0, n.playsInline = !0, await n.play(), await new Promise((s) => requestAnimationFrame(() => requestAnimationFrame(s)));
808
- const { width: o, height: r } = e.getSettings(), i = document.createElement("canvas");
809
- i.width = o || n.videoWidth, i.height = r || n.videoHeight, i.getContext("2d").drawImage(n, 0, 0, i.width, i.height);
810
- const a = await new Promise((s) => i.toBlob(s, "image/png"));
836
+ const { width: i, height: r } = e.getSettings(), o = document.createElement("canvas");
837
+ o.width = i || n.videoWidth, o.height = r || n.videoHeight, o.getContext("2d").drawImage(n, 0, 0, o.width, o.height);
838
+ const a = await new Promise((s) => o.toBlob(s, "image/png"));
811
839
  if (!a) throw new Error("The browser returned an empty screenshot.");
812
840
  return { blob: a, mime: "image/png", kind: "SCREENSHOT" };
813
841
  } finally {
814
842
  t.getTracks().forEach((e) => e.stop());
815
843
  }
816
844
  }
817
- async function so({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
818
- const o = await navigator.mediaDevices.getDisplayMedia({
845
+ async function wi({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
846
+ const i = await navigator.mediaDevices.getDisplayMedia({
819
847
  video: { frameRate: 15 },
820
848
  audio: !1
821
- }), r = ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"].find((u) => MediaRecorder.isTypeSupported(u)) || "video/webm", i = new MediaRecorder(o, { mimeType: r, videoBitsPerSecond: 25e5 }), a = [];
822
- i.ondataavailable = (u) => {
849
+ }), r = ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"].find((u) => MediaRecorder.isTypeSupported(u)) || "video/webm", o = new MediaRecorder(i, { mimeType: r, videoBitsPerSecond: 25e5 }), a = [];
850
+ o.ondataavailable = (u) => {
823
851
  u.data.size && a.push(u.data);
824
- }, i.start(1e3);
852
+ }, o.start(1e3);
825
853
  const s = Date.now(), c = setInterval(() => e == null ? void 0 : e(Math.floor((Date.now() - s) / 1e3)), 500), l = () => {
826
- clearInterval(c), clearTimeout(d), o.getTracks().forEach((u) => u.stop());
827
- }, f = new Promise((u) => {
828
- i.onstop = () => {
854
+ clearInterval(c), clearTimeout(d), i.getTracks().forEach((u) => u.stop());
855
+ }, h = new Promise((u) => {
856
+ o.onstop = () => {
829
857
  l(), u(new Blob(a, { type: r }));
830
858
  };
831
- }), p = () => {
832
- i.state !== "inactive" && i.stop(), n == null || n();
859
+ }), f = () => {
860
+ o.state !== "inactive" && o.stop(), n == null || n();
833
861
  };
834
- o.getVideoTracks()[0].addEventListener("ended", p);
835
- const d = setTimeout(p, t);
862
+ i.getVideoTracks()[0].addEventListener("ended", f);
863
+ const d = setTimeout(f, t);
836
864
  return {
837
865
  mime: r,
838
866
  maxMs: t,
839
867
  async stop() {
840
- return clearTimeout(d), i.state !== "inactive" && i.stop(), { blob: await f, mime: r, kind: "VIDEO" };
868
+ return clearTimeout(d), o.state !== "inactive" && o.stop(), { blob: await h, mime: r, kind: "VIDEO" };
841
869
  },
842
870
  cancel() {
843
- l(), i.state !== "inactive" && i.stop();
871
+ l(), o.state !== "inactive" && o.stop();
844
872
  }
845
873
  };
846
874
  }
847
- async function co({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
848
- const o = await navigator.mediaDevices.getUserMedia({ audio: !0 }), r = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4", "audio/ogg"].find((u) => MediaRecorder.isTypeSupported(u)) || "", i = new MediaRecorder(o, r ? { mimeType: r } : void 0), a = [];
849
- i.ondataavailable = (u) => {
875
+ async function yi({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
876
+ const i = await navigator.mediaDevices.getUserMedia({ audio: !0 }), r = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4", "audio/ogg"].find((u) => MediaRecorder.isTypeSupported(u)) || "", o = new MediaRecorder(i, r ? { mimeType: r } : void 0), a = [];
877
+ o.ondataavailable = (u) => {
850
878
  u.data.size && a.push(u.data);
851
- }, i.start(1e3);
879
+ }, o.start(1e3);
852
880
  const s = Date.now(), c = setInterval(() => e == null ? void 0 : e(Math.floor((Date.now() - s) / 1e3)), 500), l = () => {
853
- clearInterval(c), clearTimeout(d), o.getTracks().forEach((u) => u.stop());
854
- }, f = new Promise((u) => {
855
- i.onstop = () => {
856
- l(), u(new Blob(a, { type: i.mimeType || r }));
881
+ clearInterval(c), clearTimeout(d), i.getTracks().forEach((u) => u.stop());
882
+ }, h = new Promise((u) => {
883
+ o.onstop = () => {
884
+ l(), u(new Blob(a, { type: o.mimeType || r }));
857
885
  };
858
886
  }), d = setTimeout(() => {
859
- i.state !== "inactive" && i.stop(), n == null || n();
887
+ o.state !== "inactive" && o.stop(), n == null || n();
860
888
  }, t);
861
889
  return {
862
- mime: i.mimeType || r,
890
+ mime: o.mimeType || r,
863
891
  maxMs: t,
864
892
  async stop() {
865
- clearTimeout(d), i.state !== "inactive" && i.stop();
866
- const u = await f;
867
- return { blob: u, mime: u.type || i.mimeType || r, kind: "AUDIO" };
893
+ clearTimeout(d), o.state !== "inactive" && o.stop();
894
+ const u = await h;
895
+ return { blob: u, mime: u.type || o.mimeType || r, kind: "AUDIO" };
868
896
  },
869
897
  cancel() {
870
- l(), i.state !== "inactive" && i.stop();
898
+ l(), o.state !== "inactive" && o.stop();
871
899
  }
872
900
  };
873
901
  }
874
- async function Ft({ apiBase: t, apiKey: e, blob: n, mime: o, onProgress: r }) {
902
+ async function Gt({ apiBase: t, apiKey: e, blob: n, mime: i, onProgress: r }) {
875
903
  var l;
876
- const i = ee(o || n.type);
877
- if (!i)
878
- throw new Error(`[BugCatch] ${o || n.type || "that file"} can't be attached.`);
879
- const a = await _t(`${t}/ingest/presign`, {
904
+ const o = ae(i || n.type);
905
+ if (!o)
906
+ throw new Error(`[BugCatch] ${i || n.type || "that file"} can't be attached.`);
907
+ const a = await Jt(`${t}/ingest/presign`, {
880
908
  method: "POST",
881
909
  headers: { "Content-Type": "application/json", "X-BugCatch-Key": e },
882
- body: JSON.stringify({ mime: i })
910
+ body: JSON.stringify({ mime: o })
883
911
  });
884
912
  if (a.status === 429) {
885
- let f = "";
913
+ let h = "";
886
914
  try {
887
- f = ((l = await a.json()) == null ? void 0 : l.message) || "";
915
+ h = ((l = await a.json()) == null ? void 0 : l.message) || "";
888
916
  } catch {
889
917
  }
890
- throw new Error(`[BugCatch] ${L(typeof f == "string" ? f : "")}`);
918
+ throw new Error(`[BugCatch] ${N(typeof h == "string" ? h : "")}`);
891
919
  }
892
920
  if (!a.ok) throw new Error(`[BugCatch] could not start the upload (HTTP ${a.status}).`);
893
921
  const { key: s, uploadUrl: c } = await a.json();
894
- return await Xt(c, n, i, r), { storageKey: s, mime: i };
922
+ return await Qt(c, n, o, r), { storageKey: s, mime: o };
895
923
  }
896
- function Xt(t, e, n, o) {
897
- return new Promise((r, i) => {
924
+ function Qt(t, e, n, i) {
925
+ return new Promise((r, o) => {
898
926
  const a = new XMLHttpRequest();
899
- Pt.call(a, "PUT", t, !0), a.setRequestHeader("Content-Type", n), a.upload.onprogress = (s) => {
900
- s.lengthComputable && (o == null || o(s.loaded / s.total));
927
+ Yt.call(a, "PUT", t, !0), a.setRequestHeader("Content-Type", n), a.upload.onprogress = (s) => {
928
+ s.lengthComputable && (i == null || i(s.loaded / s.total));
901
929
  }, a.onload = () => {
902
- a.status >= 200 && a.status < 300 ? r() : i(new Error(`[BugCatch] upload failed (HTTP ${a.status}).`));
903
- }, a.onerror = () => i(new Error(
930
+ a.status >= 200 && a.status < 300 ? r() : o(new Error(`[BugCatch] upload failed (HTTP ${a.status}).`));
931
+ }, a.onerror = () => o(new Error(
904
932
  "[BugCatch] the browser blocked the upload to storage. If this is a new environment, the media bucket is probably missing its CORS policy."
905
- )), a.onabort = () => i(new Error("[BugCatch] upload cancelled.")), Ht.call(a, e);
933
+ )), a.onabort = () => o(new Error("[BugCatch] upload cancelled.")), Vt.call(a, e);
906
934
  });
907
935
  }
908
- function lo(t) {
936
+ function bi(t) {
909
937
  return t < 1024 ? `${t} B` : t < 1024 * 1024 ? `${(t / 1024).toFixed(0)} KB` : `${(t / 1024 / 1024).toFixed(1)} MB`;
910
938
  }
911
- function uo(t) {
939
+ function xi(t) {
912
940
  const e = Math.floor(t / 60), n = t % 60;
913
941
  return `${e}:${String(n).padStart(2, "0")}`;
914
942
  }
915
- const X = "bugcatch.watch", xe = [2e3, 5e3, 15e3, 3e4, 6e4], qt = 5e3;
916
- let U = null;
917
- function Wt(t) {
918
- U = t || null;
943
+ const Y = "bugcatch.watch", Te = [2e3, 5e3, 15e3, 3e4, 6e4], en = 5e3;
944
+ let _ = null;
945
+ function tn(t) {
946
+ _ = t || null;
919
947
  }
920
- const se = () => U ? `${X}:${U}` : X;
921
- function ce() {
922
- return U ? `?projectId=${encodeURIComponent(U)}` : "";
948
+ const fe = () => _ ? `${Y}:${_}` : Y;
949
+ function ee() {
950
+ return _ ? `?projectId=${encodeURIComponent(_)}` : "";
923
951
  }
924
952
  function E() {
925
953
  try {
926
954
  const t = window.localStorage;
927
- return (t == null ? void 0 : t.getItem(se())) || (t == null ? void 0 : t.getItem(X)) || null;
955
+ return (t == null ? void 0 : t.getItem(fe())) || (t == null ? void 0 : t.getItem(Y)) || null;
928
956
  } catch {
929
957
  return null;
930
958
  }
931
959
  }
932
- function te(t) {
960
+ function se(t) {
933
961
  var e;
934
962
  if (t)
935
963
  try {
936
- (e = window.localStorage) == null || e.setItem(se(), t);
964
+ (e = window.localStorage) == null || e.setItem(fe(), t);
937
965
  } catch {
938
966
  }
939
967
  }
940
- function M() {
968
+ function K() {
941
969
  var t, e;
942
970
  try {
943
- (t = window.localStorage) == null || t.removeItem(se()), (e = window.localStorage) == null || e.removeItem(X);
971
+ (t = window.localStorage) == null || t.removeItem(fe()), (e = window.localStorage) == null || e.removeItem(Y);
944
972
  } catch {
945
973
  }
946
- ze();
974
+ Ze();
947
975
  }
948
- const q = "bugcatch.unread";
949
- function Jt(t) {
976
+ const V = "bugcatch.unread";
977
+ function nn(t) {
950
978
  return [(t == null ? void 0 : t.bugId) || "report", (t == null ? void 0 : t.kind) || "status", (t == null ? void 0 : t.at) || ""].join("|");
951
979
  }
952
- function N() {
980
+ function H() {
953
981
  var t;
954
982
  try {
955
- const e = (t = window.localStorage) == null ? void 0 : t.getItem(q), n = e ? JSON.parse(e) : [];
956
- return Array.isArray(n) ? n.filter((o) => o && typeof o.id == "string") : [];
983
+ const e = (t = window.localStorage) == null ? void 0 : t.getItem(V), n = e ? JSON.parse(e) : [];
984
+ return Array.isArray(n) ? n.filter((i) => i && typeof i.id == "string") : [];
957
985
  } catch {
958
986
  return [];
959
987
  }
960
988
  }
961
- function V(t) {
989
+ function te(t) {
962
990
  var e, n;
963
991
  try {
964
- t.length ? (e = window.localStorage) == null || e.setItem(q, JSON.stringify(t)) : (n = window.localStorage) == null || n.removeItem(q);
992
+ t.length ? (e = window.localStorage) == null || e.setItem(V, JSON.stringify(t)) : (n = window.localStorage) == null || n.removeItem(V);
965
993
  } catch {
966
994
  }
967
995
  }
968
- function Yt(t) {
969
- const e = { ...t, id: Jt(t) }, n = N().filter((o) => o.id !== e.id);
970
- return n.push(e), V(n.slice(-20)), e;
996
+ function on(t) {
997
+ const e = { ...t, id: nn(t) }, n = H().filter((i) => i.id !== e.id);
998
+ return n.push(e), te(n.slice(-20)), e;
971
999
  }
972
- function Vt(t) {
973
- const e = N().filter((n) => n.id !== t);
974
- return V(e), e;
1000
+ function rn(t) {
1001
+ const e = H().filter((n) => n.id !== t);
1002
+ return te(e), e;
975
1003
  }
976
- function Zt(t) {
977
- const e = N().filter((n) => n.bugId !== t);
978
- return V(e), e;
1004
+ function an(t) {
1005
+ const e = H().filter((n) => n.bugId !== t);
1006
+ return te(e), e;
979
1007
  }
980
- function ze() {
981
- return V([]), [];
1008
+ function Ze() {
1009
+ return te([]), [];
982
1010
  }
983
- function Gt(t, e) {
984
- let n = t, o = n.indexOf(`
1011
+ function sn(t, e) {
1012
+ let n = t, i = n.indexOf(`
985
1013
 
986
1014
  `);
987
- for (; o !== -1; ) {
988
- const r = n.slice(0, o);
989
- n = n.slice(o + 2);
990
- const i = r.split(`
1015
+ for (; i !== -1; ) {
1016
+ const r = n.slice(0, i);
1017
+ n = n.slice(i + 2);
1018
+ const o = r.split(`
991
1019
  `).filter((a) => a.startsWith("data:")).map((a) => a.slice(5).trim()).join(`
992
1020
  `);
993
- if (i)
1021
+ if (o)
994
1022
  try {
995
- e(JSON.parse(i));
1023
+ e(JSON.parse(o));
996
1024
  } catch {
997
1025
  }
998
- o = n.indexOf(`
1026
+ i = n.indexOf(`
999
1027
 
1000
1028
  `);
1001
1029
  }
1002
1030
  return n;
1003
1031
  }
1004
- async function Qt({ apiBase: t }) {
1032
+ async function cn({ apiBase: t }) {
1005
1033
  const e = E();
1006
1034
  if (!e) return { reporter: null, reports: [] };
1007
- const n = await fetch(`${t}/ingest/watch/reports${ce()}`, {
1035
+ const n = await fetch(`${t}/ingest/watch/reports${ee()}`, {
1008
1036
  headers: { Authorization: `Bearer ${e}` }
1009
1037
  });
1010
1038
  if (n.status === 401)
1011
- return M(), { reporter: null, reports: [] };
1039
+ return K(), { reporter: null, reports: [] };
1012
1040
  if (!n.ok) throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);
1013
1041
  return n.json();
1014
1042
  }
1015
- async function en({ apiBase: t, bugId: e }) {
1043
+ async function ln({ apiBase: t, bugId: e }) {
1016
1044
  const n = E();
1017
1045
  if (!n) return null;
1018
- const o = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}${ce()}`, {
1046
+ const i = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}${ee()}`, {
1019
1047
  headers: { Authorization: `Bearer ${n}` }
1020
1048
  });
1021
- if (o.status === 401)
1022
- return M(), null;
1023
- if (o.status === 404) return null;
1024
- if (!o.ok) throw new Error(`[BugCatch] could not load that report (HTTP ${o.status})`);
1025
- return o.json();
1049
+ if (i.status === 401)
1050
+ return K(), null;
1051
+ if (i.status === 404) return null;
1052
+ if (!i.ok) throw new Error(`[BugCatch] could not load that report (HTTP ${i.status})`);
1053
+ return i.json();
1026
1054
  }
1027
- async function tn({ apiBase: t, bugId: e, body: n, attachments: o }) {
1055
+ async function un({ apiBase: t, bugId: e, body: n, attachments: i }) {
1028
1056
  const r = E();
1029
1057
  if (!r) throw new Error("[BugCatch] nothing filed from this browser yet.");
1030
- const i = await fetch(
1058
+ const o = await fetch(
1031
1059
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,
1032
1060
  {
1033
1061
  method: "POST",
1034
1062
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${r}` },
1035
1063
  body: JSON.stringify({
1036
1064
  ...n ? { body: n } : {},
1037
- ...o != null && o.length ? { attachments: o } : {}
1065
+ ...i != null && i.length ? { attachments: i } : {}
1038
1066
  })
1039
1067
  }
1040
1068
  );
1041
- if (i.status === 401)
1042
- throw M(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1043
- if (!i.ok) {
1069
+ if (o.status === 401)
1070
+ throw K(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1071
+ if (!o.ok) {
1044
1072
  let a = "";
1045
1073
  try {
1046
- const s = await i.json();
1074
+ const s = await o.json();
1047
1075
  a = Array.isArray(s.message) ? s.message.join(", ") : s.message || "";
1048
1076
  } catch {
1049
1077
  }
1050
- throw i.status === 429 ? new Error(L(a)) : new Error(a || `[BugCatch] could not send that (HTTP ${i.status}).`);
1078
+ throw o.status === 429 ? new Error(N(a)) : new Error(a || `[BugCatch] could not send that (HTTP ${o.status}).`);
1051
1079
  }
1052
- return i.json();
1080
+ return o.json();
1053
1081
  }
1054
- async function nn({ apiBase: t, apiKey: e, projectId: n }) {
1055
- const o = { agent: !1, live: !1 };
1082
+ async function dn({ apiBase: t, apiKey: e, projectId: n }) {
1083
+ const i = { agent: !1, live: !1 };
1056
1084
  try {
1057
1085
  const r = await fetch(
1058
1086
  `${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,
1059
1087
  { headers: { "X-BugCatch-Key": e } }
1060
1088
  );
1061
- if (!r.ok) return o;
1062
- const i = await r.json();
1063
- return i != null && i.available ? i.kinds && typeof i.kinds == "object" ? { agent: !1, live: !!i.kinds.live } : { agent: !1, live: i.kind === "live" } : o;
1089
+ if (!r.ok) return i;
1090
+ const o = await r.json();
1091
+ return o != null && o.available ? o.kinds && typeof o.kinds == "object" ? { agent: !1, live: !!o.kinds.live } : { agent: !1, live: o.kind === "live" } : i;
1064
1092
  } catch {
1065
- return o;
1093
+ return i;
1066
1094
  }
1067
1095
  }
1068
- async function on({ apiBase: t, apiKey: e, token: n, payload: o, watchToken: r }) {
1069
- const i = await fetch(`${t}/ingest/calls`, {
1096
+ async function hn({ apiBase: t, apiKey: e, token: n, payload: i, watchToken: r }) {
1097
+ const o = await fetch(`${t}/ingest/calls`, {
1070
1098
  method: "POST",
1071
1099
  headers: {
1072
1100
  "Content-Type": "application/json",
@@ -1079,199 +1107,206 @@ async function on({ apiBase: t, apiKey: e, token: n, payload: o, watchToken: r }
1079
1107
  },
1080
1108
  // The watch token this browser holds, so the one filing hands back covers
1081
1109
  // the reports it already could — see withHeldToken in index.js.
1082
- body: JSON.stringify(r ? { ...o, watchToken: r } : o)
1110
+ body: JSON.stringify(r ? { ...i, watchToken: r } : i)
1083
1111
  });
1084
- if (!i.ok) {
1112
+ if (!o.ok) {
1085
1113
  let a = "";
1086
1114
  try {
1087
- const c = await i.json();
1115
+ const c = await o.json();
1088
1116
  a = Array.isArray(c.message) ? c.message.join(", ") : c.message || "";
1089
1117
  } catch {
1090
1118
  }
1091
1119
  const s = new Error(
1092
- i.status === 429 ? L(a) : a || `[BugCatch] the call could not be started (HTTP ${i.status}).`
1120
+ o.status === 429 ? N(a) : a || `[BugCatch] the call could not be started (HTTP ${o.status}).`
1093
1121
  );
1094
- throw s.status = i.status, s;
1122
+ throw s.status = o.status, s;
1095
1123
  }
1096
- return i.json();
1124
+ return o.json();
1097
1125
  }
1098
- async function Ie({ apiBase: t, bugId: e }) {
1126
+ async function Ae({ apiBase: t, bugId: e }) {
1099
1127
  const n = E();
1100
1128
  if (!n) return !1;
1101
1129
  try {
1102
- const o = await fetch(
1130
+ const i = await fetch(
1103
1131
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,
1104
1132
  { headers: { Authorization: `Bearer ${n}` } }
1105
1133
  );
1106
- if (!o.ok) return !1;
1107
- const r = await o.json();
1134
+ if (!i.ok) return !1;
1135
+ const r = await i.json();
1108
1136
  return !!(r != null && r.offered);
1109
1137
  } catch {
1110
1138
  return !1;
1111
1139
  }
1112
1140
  }
1113
- async function rn({ apiBase: t, bugId: e }) {
1141
+ async function fn({ apiBase: t, bugId: e }) {
1114
1142
  const n = E();
1115
1143
  if (!n) throw new Error("[BugCatch] nothing filed from this browser yet.");
1116
- const o = await fetch(
1144
+ const i = await fetch(
1117
1145
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,
1118
1146
  { method: "POST", headers: { Authorization: `Bearer ${n}` } }
1119
1147
  );
1120
- if (o.status === 401)
1121
- throw M(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1122
- if (!o.ok) {
1148
+ if (i.status === 401)
1149
+ throw K(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1150
+ if (!i.ok) {
1123
1151
  let r = "";
1124
1152
  try {
1125
- const i = await o.json();
1126
- r = Array.isArray(i.message) ? i.message.join(", ") : i.message || "";
1153
+ const o = await i.json();
1154
+ r = Array.isArray(o.message) ? o.message.join(", ") : o.message || "";
1127
1155
  } catch {
1128
1156
  }
1129
- throw new Error(r || `[BugCatch] the call could not be started (HTTP ${o.status}).`);
1157
+ throw new Error(r || `[BugCatch] the call could not be started (HTTP ${i.status}).`);
1130
1158
  }
1131
- return o.json();
1159
+ return i.json();
1132
1160
  }
1133
- async function an({ apiBase: t, bugId: e, callId: n }) {
1134
- const o = E();
1135
- if (o)
1161
+ async function pn({ apiBase: t, bugId: e, callId: n }) {
1162
+ const i = E();
1163
+ if (i)
1136
1164
  try {
1137
1165
  await fetch(
1138
1166
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,
1139
- { method: "POST", headers: { Authorization: `Bearer ${o}` } }
1167
+ { method: "POST", headers: { Authorization: `Bearer ${i}` } }
1140
1168
  );
1141
1169
  } catch {
1142
1170
  }
1143
1171
  }
1144
- async function sn({ apiBase: t, bugId: e, callId: n }) {
1145
- const o = E();
1146
- if (!o) throw new Error("[BugCatch] nothing filed from this browser yet.");
1172
+ async function gn({ apiBase: t, bugId: e, callId: n }) {
1173
+ const i = E();
1174
+ if (!i) throw new Error("[BugCatch] nothing filed from this browser yet.");
1147
1175
  const r = await fetch(
1148
1176
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,
1149
- { method: "POST", headers: { Authorization: `Bearer ${o}` } }
1177
+ { method: "POST", headers: { Authorization: `Bearer ${i}` } }
1150
1178
  );
1151
1179
  if (r.status === 401)
1152
- throw M(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1180
+ throw K(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
1153
1181
  if (r.status === 409)
1154
1182
  throw new Error("[BugCatch] that call is no longer ringing.");
1155
1183
  if (!r.ok) {
1156
- let i = "";
1184
+ let o = "";
1157
1185
  try {
1158
1186
  const a = await r.json();
1159
- i = Array.isArray(a.message) ? a.message.join(", ") : a.message || "";
1187
+ o = Array.isArray(a.message) ? a.message.join(", ") : a.message || "";
1160
1188
  } catch {
1161
1189
  }
1162
- throw new Error(i || `[BugCatch] the call could not be answered (HTTP ${r.status}).`);
1190
+ throw new Error(o || `[BugCatch] the call could not be answered (HTTP ${r.status}).`);
1163
1191
  }
1164
1192
  return r.json();
1165
1193
  }
1166
- async function Se({ apiBase: t, bugId: e, callId: n }) {
1167
- const o = E();
1168
- if (o)
1194
+ async function je({ apiBase: t, bugId: e, callId: n }) {
1195
+ const i = E();
1196
+ if (i)
1169
1197
  try {
1170
1198
  await fetch(
1171
1199
  `${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,
1172
- { method: "POST", headers: { Authorization: `Bearer ${o}` } }
1200
+ { method: "POST", headers: { Authorization: `Bearer ${i}` } }
1173
1201
  );
1174
1202
  } catch {
1175
1203
  }
1176
1204
  }
1177
- function cn({ apiBase: t, onUpdate: e }) {
1178
- let n = !0, o = 0, r = null;
1179
- async function i() {
1205
+ function mn({ apiBase: t, onUpdate: e }) {
1206
+ let n = !0, i = 0, r = null;
1207
+ async function o() {
1180
1208
  const a = E();
1181
1209
  if (!a) throw new Error("nothing filed from this browser yet");
1182
1210
  r = new AbortController();
1183
- const s = await fetch(`${t}/ingest/watch/stream${ce()}`, {
1211
+ const s = await fetch(`${t}/ingest/watch/stream${ee()}`, {
1184
1212
  headers: { Authorization: `Bearer ${a}`, Accept: "text/event-stream" },
1185
1213
  signal: r.signal
1186
1214
  });
1187
1215
  if (s.status === 401)
1188
- throw n = !1, M(), new Error("subscription no longer valid");
1216
+ throw n = !1, K(), new Error("subscription no longer valid");
1189
1217
  if (!s.ok || !s.body) throw new Error(`stream failed (${s.status})`);
1190
- const c = Date.now(), l = s.body.getReader(), f = new TextDecoder();
1191
- let p = "";
1218
+ const c = Date.now(), l = s.body.getReader(), h = new TextDecoder();
1219
+ let f = "";
1192
1220
  try {
1193
1221
  for (; ; ) {
1194
1222
  const { value: d, done: u } = await l.read();
1195
1223
  if (u) break;
1196
- p += f.decode(d, { stream: !0 }), p = Gt(p, (g) => {
1197
- if (g.type !== "ping")
1224
+ f += h.decode(d, { stream: !0 }), f = sn(f, (m) => {
1225
+ if (m.type !== "ping")
1198
1226
  try {
1199
- e(g);
1227
+ e(m);
1200
1228
  } catch {
1201
1229
  }
1202
1230
  });
1203
1231
  }
1204
1232
  } finally {
1205
- Date.now() - c >= qt && (o = 0);
1233
+ Date.now() - c >= en && (i = 0);
1206
1234
  }
1207
1235
  }
1208
1236
  return (async () => {
1209
1237
  for (; n; ) {
1210
1238
  try {
1211
- await i();
1239
+ await o();
1212
1240
  } catch (s) {
1213
1241
  if ((s == null ? void 0 : s.name) === "AbortError") return;
1214
1242
  }
1215
1243
  if (!n) return;
1216
- const a = xe[Math.min(o, xe.length - 1)];
1217
- o += 1, await new Promise((s) => setTimeout(s, a));
1244
+ const a = Te[Math.min(i, Te.length - 1)];
1245
+ i += 1, await new Promise((s) => setTimeout(s, a));
1218
1246
  }
1219
1247
  })(), () => {
1220
1248
  n = !1, r == null || r.abort(), r = null;
1221
1249
  };
1222
1250
  }
1223
- const ln = {
1251
+ const wn = {
1224
1252
  OPEN: "is open",
1225
1253
  IN_PROGRESS: "is being worked on",
1226
1254
  RESOLVED: "has been fixed",
1227
1255
  CLOSED: "has been closed"
1228
- }, un = {
1256
+ }, yn = {
1229
1257
  status: null,
1230
1258
  // falls back to the host's configured accent
1231
- severity: "#e8912a",
1232
- assignment: "#4da3ff",
1233
- reply: "#35b87f"
1259
+ severity: "#f2a54a",
1260
+ assignment: "#79a8ff",
1261
+ reply: "#4fd19a"
1262
+ }, j = {
1263
+ bg: "#111113",
1264
+ fg: "#f3f2ef",
1265
+ muted: "#b3b0aa",
1266
+ faint: "#8f8c86",
1267
+ ring: "rgba(255,255,255,.09)",
1268
+ brand: "#a59cff"
1234
1269
  };
1235
- function Ce(t) {
1236
- return t != null && t.summary ? t.summary : `Your report ${ln[t == null ? void 0 : t.status] || "was updated"}`;
1270
+ function Oe(t) {
1271
+ return t != null && t.summary ? t.summary : `Your report ${wn[t == null ? void 0 : t.status] || "was updated"}`;
1237
1272
  }
1238
- function dn(t) {
1273
+ function bn(t) {
1239
1274
  var e;
1240
1275
  return (t == null ? void 0 : t.kind) === "reply" && ((e = t.reply) != null && e.body) ? `${t.reply.author ? `${t.reply.author}: ` : ""}${t.reply.body}` : (t == null ? void 0 : t.title) || "";
1241
1276
  }
1242
- function hn(t) {
1277
+ function xn(t) {
1243
1278
  const e = Date.parse(t || "");
1244
1279
  if (!Number.isFinite(e)) return "";
1245
1280
  const n = Math.round((Date.now() - e) / 6e4);
1246
1281
  if (n < 1) return "just now";
1247
1282
  if (n < 60) return `${n}m ago`;
1248
- const o = Math.round(n / 60);
1249
- if (o < 24) return `${o}h ago`;
1250
- const r = Math.round(o / 24);
1283
+ const i = Math.round(n / 60);
1284
+ if (i < 24) return `${i}h ago`;
1285
+ const r = Math.round(i / 24);
1251
1286
  return r === 1 ? "yesterday" : `${r}d ago`;
1252
1287
  }
1253
- function fn() {
1288
+ function kn() {
1254
1289
  var t;
1255
1290
  try {
1256
- const e = document.querySelector('[data-bugcatch="widget"]'), n = (t = e == null ? void 0 : e.shadowRoot) == null ? void 0 : t.querySelector(".dock"), o = (n == null ? void 0 : n.getBoundingClientRect().height) || 0;
1257
- return o ? Math.round(o) + 12 : 0;
1291
+ const e = document.querySelector('[data-bugcatch="widget"]'), n = (t = e == null ? void 0 : e.shadowRoot) == null ? void 0 : t.querySelector(".dock"), i = (n == null ? void 0 : n.getBoundingClientRect().height) || 0;
1292
+ return i ? Math.round(i) + 12 : 0;
1258
1293
  } catch {
1259
1294
  return 0;
1260
1295
  }
1261
1296
  }
1262
- function pn({
1263
- accent: t = "#4F46E5",
1297
+ function vn({
1298
+ accent: t = null,
1264
1299
  position: e = "bottom-right",
1265
1300
  onRead: n = null,
1266
- onReadAll: o = null,
1301
+ onReadAll: i = null,
1267
1302
  onCall: r = null
1268
1303
  } = {}) {
1269
- const [i, a] = String(e).split("-"), s = i === "top", c = a === "left", l = /* @__PURE__ */ new Map();
1270
- let f = null, p = null;
1304
+ const [o, a] = String(e).split("-"), s = o === "top", c = a === "left", l = /* @__PURE__ */ new Map();
1305
+ let h = null, f = null;
1271
1306
  function d() {
1272
- return f != null && f.isConnected || (f = document.createElement("div"), f.setAttribute("data-bugcatch", "updates"), f.style.cssText = [
1307
+ return h != null && h.isConnected || (h = document.createElement("div"), h.setAttribute("data-bugcatch", "updates"), h.style.cssText = [
1273
1308
  "position:fixed",
1274
- `${s ? "top" : "bottom"}:${20 + fn()}px`,
1309
+ `${s ? "top" : "bottom"}:${20 + kn()}px`,
1275
1310
  `${c ? "left" : "right"}:20px`,
1276
1311
  // Under the widget's dock and its panel scrim, both of which are higher.
1277
1312
  // A notification is worth interrupting a page for, not the report being
@@ -1284,81 +1319,86 @@ function pn({
1284
1319
  "width:min(320px,calc(100vw - 40px))",
1285
1320
  // The gaps between cards belong to the page underneath.
1286
1321
  "pointer-events:none"
1287
- ].join(";"), document.body.appendChild(f)), f;
1322
+ ].join(";"), document.body.appendChild(h)), h;
1288
1323
  }
1289
- function u(h) {
1290
- if (!h._bcShown) {
1291
- h.remove();
1324
+ function u(p) {
1325
+ if (!p._bcShown) {
1326
+ p.remove();
1292
1327
  return;
1293
1328
  }
1294
- h.style.opacity = "0", h.style.transform = `translateY(${s ? -8 : 8}px)`, setTimeout(() => h.remove(), 250);
1295
- }
1296
- function g(h, I) {
1297
- const v = document.createElement("button");
1298
- return v.type = "button", v.textContent = h, v.style.cssText = [
1299
- "padding:5px 11px",
1300
- `border:${I ? "0" : "1px solid rgba(236,238,242,.24)"}`,
1301
- "border-radius:6px",
1302
- `background:${I ? t : "transparent"}`,
1303
- `color:${I ? "#fff" : "#eceef2"}`,
1304
- "font:600 12px/1.4 inherit",
1329
+ p.style.opacity = "0", p.style.transform = `translateY(${s ? -8 : 8}px)`, setTimeout(() => p.remove(), 250);
1330
+ }
1331
+ const m = t || re, $ = t ? Ye(t) : Je;
1332
+ function I(p, k) {
1333
+ const g = document.createElement("button");
1334
+ return g.type = "button", g.textContent = p, g.style.cssText = [
1335
+ "padding:6px 12px",
1336
+ "border:0",
1337
+ `box-shadow:${k ? "none" : `inset 0 0 0 1px ${j.ring}`}`,
1338
+ "border-radius:999px",
1339
+ `background:${k ? m : "rgba(255,255,255,.06)"}`,
1340
+ `color:${k ? $ : j.fg}`,
1341
+ "font:560 12px/1.4 inherit",
1305
1342
  "cursor:pointer",
1306
1343
  "white-space:nowrap"
1307
- ].join(";"), v;
1344
+ ].join(";"), g;
1308
1345
  }
1309
- function $(h) {
1310
- var b;
1311
- const I = document.createElement("div");
1312
- I.setAttribute("role", "status"), I.style.cssText = [
1346
+ function v(p) {
1347
+ var L;
1348
+ const k = document.createElement("div");
1349
+ k.setAttribute("role", "status"), k.style.cssText = [
1313
1350
  "box-sizing:border-box",
1314
1351
  "width:100%",
1315
- "padding:12px 14px",
1316
- "border-radius:10px",
1317
- "background:#1b1e26",
1318
- "color:#eceef2",
1352
+ "padding:13px 14px",
1353
+ "border-radius:14px",
1354
+ `background:${j.bg}`,
1355
+ `color:${j.fg}`,
1319
1356
  'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',
1320
- "box-shadow:0 12px 30px rgba(0,0,0,0.45)",
1321
- `border-left:3px solid ${un[h == null ? void 0 : h.kind] || t}`,
1357
+ `box-shadow:0 0 0 1px ${j.ring},0 20px 44px -12px rgba(0,0,0,.55),0 4px 12px rgba(0,0,0,.25)`,
1322
1358
  "opacity:0",
1323
1359
  `transform:translateY(${s ? -8 : 8}px)`,
1324
1360
  "transition:opacity .2s ease,transform .2s ease",
1325
1361
  "pointer-events:auto"
1326
1362
  ].join(";");
1327
- const v = document.createElement("div");
1328
- v.style.cssText = "font-weight:600;margin-bottom:2px", v.textContent = Ce(h);
1363
+ const g = document.createElement("div");
1364
+ g.style.cssText = "display:flex;align-items:baseline;gap:8px;font-weight:600;margin-bottom:2px";
1365
+ const b = document.createElement("span");
1366
+ b.setAttribute("aria-hidden", "true"), b.style.cssText = `flex:none;width:7px;height:7px;border-radius:50%;transform:translateY(-1px);background:${yn[p == null ? void 0 : p.kind] || t || j.brand}`;
1367
+ const B = document.createElement("span");
1368
+ B.textContent = Oe(p), g.append(b, B);
1369
+ const y = document.createElement("div");
1370
+ y.style.cssText = (p == null ? void 0 : p.kind) === "reply" ? `color:${j.muted};padding-left:15px;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden` : `color:${j.muted};padding-left:15px`, y.textContent = bn(p);
1329
1371
  const C = document.createElement("div");
1330
- C.style.cssText = (h == null ? void 0 : h.kind) === "reply" ? "color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden" : "color:#a4abba", C.textContent = dn(h);
1331
- const w = document.createElement("div");
1332
- w.style.cssText = "display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";
1333
- const k = document.createElement("span");
1334
- k.style.cssText = "color:#7b8394;font-size:11px;margin-right:auto", k.textContent = hn(h == null ? void 0 : h.at);
1335
- const B = g("Mark as read", !1);
1336
- if (B.setAttribute("aria-label", `Mark as read: ${Ce(h)}`), B.addEventListener("click", () => n == null ? void 0 : n(h.id)), w.append(k, B), (b = h == null ? void 0 : h.call) != null && b.offered && typeof r == "function") {
1337
- const y = g("Talk it through", !0);
1338
- y.addEventListener("click", () => r(h)), w.insertBefore(y, B);
1372
+ C.style.cssText = "display:flex;align-items:center;gap:8px;margin-top:10px;padding-left:15px;flex-wrap:wrap";
1373
+ const A = document.createElement("span");
1374
+ A.style.cssText = `color:${j.faint};font-size:11px;margin-right:auto`, A.textContent = xn(p == null ? void 0 : p.at);
1375
+ const S = I("Mark as read", !1);
1376
+ if (S.setAttribute("aria-label", `Mark as read: ${Oe(p)}`), S.addEventListener("click", () => n == null ? void 0 : n(p.id)), C.append(A, S), (L = p == null ? void 0 : p.call) != null && L.offered && typeof r == "function") {
1377
+ const ye = I("Talk it through", !0);
1378
+ ye.addEventListener("click", () => r(p)), C.insertBefore(ye, S);
1339
1379
  }
1340
- return I.append(v, C, w), I;
1380
+ return k.append(g, y, C), k;
1341
1381
  }
1342
- function S(h) {
1343
- const I = document.createElement("div");
1344
- I.style.cssText = [
1382
+ function T(p) {
1383
+ const k = document.createElement("div");
1384
+ k.style.cssText = [
1345
1385
  "box-sizing:border-box",
1346
1386
  "width:100%",
1347
1387
  "display:flex",
1348
1388
  "align-items:center",
1349
1389
  "gap:8px",
1350
- "padding:8px 12px",
1351
- "border-radius:10px",
1352
- "background:#1b1e26",
1353
- "color:#a4abba",
1390
+ "padding:8px 10px 8px 14px",
1391
+ "border-radius:999px",
1392
+ `background:${j.bg}`,
1393
+ `color:${j.muted}`,
1354
1394
  'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',
1355
- "box-shadow:0 12px 30px rgba(0,0,0,0.45)",
1395
+ `box-shadow:0 0 0 1px ${j.ring},0 12px 30px -10px rgba(0,0,0,.5)`,
1356
1396
  "pointer-events:auto"
1357
1397
  ].join(";");
1358
- const v = document.createElement("span");
1359
- v.style.cssText = "margin-right:auto", v.textContent = `${h} more update${h === 1 ? "" : "s"}`;
1360
- const C = g("Mark all as read", !1);
1361
- return C.style.cssText += ";padding:4px 9px", C.addEventListener("click", () => o == null ? void 0 : o()), I.append(v, C), I;
1398
+ const g = document.createElement("span");
1399
+ g.style.cssText = "margin-right:auto", g.textContent = `${p} more update${p === 1 ? "" : "s"}`;
1400
+ const b = I("Mark all as read", !1);
1401
+ return b.style.cssText += ";padding:4px 9px", b.addEventListener("click", () => i == null ? void 0 : i()), k.append(g, b), k;
1362
1402
  }
1363
1403
  return {
1364
1404
  /**
@@ -1368,51 +1408,51 @@ function pn({
1368
1408
  * corner the reporter's eye is already trained on — so the stack grows away
1369
1409
  * from the launcher rather than over it.
1370
1410
  */
1371
- render(h) {
1372
- const I = Array.isArray(h) ? h : [];
1373
- if (!I.length) {
1374
- for (const y of l.values()) u(y);
1375
- l.clear(), p == null || p.remove(), p = null, f == null || f.remove(), f = null;
1411
+ render(p) {
1412
+ const k = Array.isArray(p) ? p : [];
1413
+ if (!k.length) {
1414
+ for (const S of l.values()) u(S);
1415
+ l.clear(), f == null || f.remove(), f = null, h == null || h.remove(), h = null;
1376
1416
  return;
1377
1417
  }
1378
- const v = I.slice(-3), C = new Set(v.map((y) => y.id)), w = d();
1379
- for (const [y, T] of l)
1380
- C.has(y) || (u(T), l.delete(y));
1381
- const k = [];
1382
- for (const y of v) {
1383
- if (l.has(y.id)) continue;
1384
- const T = $(y);
1385
- l.set(y.id, T), k.push(T);
1418
+ const g = k.slice(-3), b = new Set(g.map((S) => S.id)), B = d();
1419
+ for (const [S, L] of l)
1420
+ b.has(S) || (u(L), l.delete(S));
1421
+ const y = [];
1422
+ for (const S of g) {
1423
+ if (l.has(S.id)) continue;
1424
+ const L = v(S);
1425
+ l.set(S.id, L), y.push(L);
1386
1426
  }
1387
- const B = s ? [...v].reverse() : v;
1388
- for (const y of B) w.appendChild(l.get(y.id));
1389
- const b = I.length - v.length;
1390
- b > 0 ? (p == null || p.remove(), p = S(b), s ? w.appendChild(p) : w.insertBefore(p, w.firstChild)) : (p == null || p.remove(), p = null), requestAnimationFrame(() => {
1391
- for (const y of k)
1392
- y.isConnected && (y._bcShown = !0, y.style.opacity = "1", y.style.transform = "translateY(0)");
1427
+ const C = s ? [...g].reverse() : g;
1428
+ for (const S of C) B.appendChild(l.get(S.id));
1429
+ const A = k.length - g.length;
1430
+ A > 0 ? (f == null || f.remove(), f = T(A), s ? B.appendChild(f) : B.insertBefore(f, B.firstChild)) : (f == null || f.remove(), f = null), requestAnimationFrame(() => {
1431
+ for (const S of y)
1432
+ S.isConnected && (S._bcShown = !0, S.style.opacity = "1", S.style.transform = "translateY(0)");
1393
1433
  });
1394
1434
  },
1395
1435
  destroy() {
1396
- l.clear(), p = null, f == null || f.remove(), f = null;
1436
+ l.clear(), f = null, h == null || h.remove(), h = null;
1397
1437
  }
1398
1438
  };
1399
1439
  }
1400
- async function gn({ apiBase: t, apiKey: e, projectId: n, sessionToken: o }) {
1440
+ async function In({ apiBase: t, apiKey: e, projectId: n, sessionToken: i }) {
1401
1441
  try {
1402
1442
  const r = await fetch(
1403
1443
  `${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,
1404
- { headers: le(e, o) }
1444
+ { headers: pe(e, i) }
1405
1445
  );
1406
1446
  if (!r.ok) return [];
1407
- const i = await r.json();
1408
- return Array.isArray(i == null ? void 0 : i.issues) ? i.issues : [];
1447
+ const o = await r.json();
1448
+ return Array.isArray(o == null ? void 0 : o.issues) ? o.issues : [];
1409
1449
  } catch {
1410
1450
  return [];
1411
1451
  }
1412
1452
  }
1413
- async function mn({ apiBase: t, apiKey: e, projectId: n, q: o, sessionToken: r, signal: i }) {
1453
+ async function Cn({ apiBase: t, apiKey: e, projectId: n, q: i, sessionToken: r, signal: o }) {
1414
1454
  try {
1415
- const a = `${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`, s = await fetch(a, { headers: le(e, r), signal: i });
1455
+ const a = `${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(i)}`, s = await fetch(a, { headers: pe(e, r), signal: o });
1416
1456
  if (!s.ok) return [];
1417
1457
  const c = await s.json();
1418
1458
  return Array.isArray(c == null ? void 0 : c.issues) ? c.issues : [];
@@ -1420,102 +1460,116 @@ async function mn({ apiBase: t, apiKey: e, projectId: n, q: o, sessionToken: r,
1420
1460
  return [];
1421
1461
  }
1422
1462
  }
1423
- async function wn({
1463
+ async function Sn({
1424
1464
  apiBase: t,
1425
1465
  apiKey: e,
1426
1466
  projectId: n,
1427
- bugId: o,
1467
+ bugId: i,
1428
1468
  reporterEmail: r,
1429
- reporterName: i,
1469
+ reporterName: o,
1430
1470
  metadata: a,
1431
1471
  logs: s,
1432
1472
  sessionToken: c
1433
1473
  }) {
1434
- const l = E(), f = await fetch(
1435
- `${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,
1474
+ const l = E(), h = await fetch(
1475
+ `${t}/ingest/known-issues/${encodeURIComponent(i)}/join`,
1436
1476
  {
1437
1477
  method: "POST",
1438
- headers: le(e, c),
1478
+ headers: pe(e, c),
1439
1479
  body: JSON.stringify({
1440
1480
  projectId: n,
1441
1481
  reporterEmail: r,
1442
- reporterName: i,
1482
+ reporterName: o,
1443
1483
  metadata: a,
1444
1484
  logs: s,
1445
1485
  ...l ? { watchToken: l } : {}
1446
1486
  })
1447
1487
  }
1448
1488
  );
1449
- if (!f.ok) throw new Error(await bn(f));
1450
- const p = await f.json();
1451
- return p != null && p.watchToken && te(p.watchToken), p;
1489
+ if (!h.ok) throw new Error(await Bn(h));
1490
+ const f = await h.json();
1491
+ return f != null && f.watchToken && se(f.watchToken), f;
1452
1492
  }
1453
- function le(t, e) {
1493
+ function pe(t, e) {
1454
1494
  return {
1455
1495
  "Content-Type": "application/json",
1456
1496
  "X-BugCatch-Key": t,
1457
1497
  ...e ? { "X-BugCatch-Session": e } : {}
1458
1498
  };
1459
1499
  }
1460
- async function bn(t) {
1500
+ async function Bn(t) {
1461
1501
  let e = "";
1462
1502
  try {
1463
1503
  const n = await t.json();
1464
1504
  e = Array.isArray(n.message) ? n.message.join(", ") : n.message || "";
1465
1505
  } catch {
1466
1506
  }
1467
- return t.status === 429 ? L(e) : e || `Could not add you to this issue (HTTP ${t.status})`;
1507
+ return t.status === 429 ? N(e) : e || `Could not add you to this issue (HTTP ${t.status})`;
1508
+ }
1509
+ async function En({ apiBase: t, bugId: e, score: n, comment: i }) {
1510
+ const r = E();
1511
+ if (!r) throw new Error("This browser cannot access that report.");
1512
+ const o = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/rating${ee()}`, {
1513
+ method: "POST",
1514
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${r}` },
1515
+ body: JSON.stringify({ score: n, ...i ? { comment: i } : {} })
1516
+ }), a = await o.json().catch(() => ({}));
1517
+ if (!o.ok) {
1518
+ const s = Array.isArray(a.message) ? a.message.join(", ") : a.message;
1519
+ throw new Error(s || "Could not send your rating. Please try again.");
1520
+ }
1521
+ return a;
1468
1522
  }
1469
- async function yn({ apiBase: t, bugId: e, ...n }) {
1470
- const o = E();
1471
- if (!o) throw new Error("This browser cannot access that report.");
1523
+ async function $n({ apiBase: t, bugId: e, ...n }) {
1524
+ const i = E();
1525
+ if (!i) throw new Error("This browser cannot access that report.");
1472
1526
  const r = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`, {
1473
1527
  method: "POST",
1474
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${o}` },
1528
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${i}` },
1475
1529
  body: JSON.stringify(n)
1476
- }), i = await r.json().catch(() => ({}));
1477
- if (!r.ok) throw new Error(i.message || "Could not record feedback. Please refresh and try again.");
1478
- return i;
1530
+ }), o = await r.json().catch(() => ({}));
1531
+ if (!r.ok) throw new Error(o.message || "Could not record feedback. Please refresh and try again.");
1532
+ return o;
1479
1533
  }
1480
- const vn = "bugcatch.session.", ue = (t) => `${vn}${t}`, de = /* @__PURE__ */ new Map();
1481
- function j(t) {
1534
+ const Tn = "bugcatch.session.", ge = (t) => `${Tn}${t}`, me = /* @__PURE__ */ new Map();
1535
+ function M(t) {
1482
1536
  var e;
1483
1537
  if (!t) return null;
1484
1538
  try {
1485
- const n = (e = window.localStorage) == null ? void 0 : e.getItem(ue(t));
1539
+ const n = (e = window.localStorage) == null ? void 0 : e.getItem(ge(t));
1486
1540
  if (n) {
1487
- const o = JSON.parse(n);
1488
- if (o != null && o.token) return o;
1541
+ const i = JSON.parse(n);
1542
+ if (i != null && i.token) return i;
1489
1543
  }
1490
1544
  } catch {
1491
1545
  }
1492
- return de.get(t) || null;
1546
+ return me.get(t) || null;
1493
1547
  }
1494
- function kn(t, e) {
1495
- var o;
1548
+ function An(t, e) {
1549
+ var i;
1496
1550
  if (!t || !(e != null && e.token)) return;
1497
1551
  const n = {
1498
1552
  token: e.token,
1499
1553
  email: e.email || null,
1500
1554
  name: e.name || null
1501
1555
  };
1502
- de.set(t, n);
1556
+ me.set(t, n);
1503
1557
  try {
1504
- (o = window.localStorage) == null || o.setItem(ue(t), JSON.stringify(n));
1558
+ (i = window.localStorage) == null || i.setItem(ge(t), JSON.stringify(n));
1505
1559
  } catch {
1506
1560
  }
1507
1561
  }
1508
- function ne(t) {
1562
+ function ce(t) {
1509
1563
  var e;
1510
1564
  if (t) {
1511
- de.delete(t);
1565
+ me.delete(t);
1512
1566
  try {
1513
- (e = window.localStorage) == null || e.removeItem(ue(t));
1567
+ (e = window.localStorage) == null || e.removeItem(ge(t));
1514
1568
  } catch {
1515
1569
  }
1516
1570
  }
1517
1571
  }
1518
- function Z({ apiKey: t, token: e }) {
1572
+ function ne({ apiKey: t, token: e }) {
1519
1573
  return {
1520
1574
  "Content-Type": "application/json",
1521
1575
  "X-BugCatch-Key": t,
@@ -1525,24 +1579,24 @@ function Z({ apiKey: t, token: e }) {
1525
1579
  ...e ? { "X-BugCatch-Session": e } : {}
1526
1580
  };
1527
1581
  }
1528
- async function Fe(t) {
1582
+ async function Ge(t) {
1529
1583
  let e = "";
1530
1584
  try {
1531
1585
  const n = await t.json();
1532
1586
  e = Array.isArray(n.message) ? n.message.join(", ") : n.message || "";
1533
1587
  } catch {
1534
1588
  }
1535
- return t.status === 429 ? L(e) : e || `Request failed (HTTP ${t.status})`;
1589
+ return t.status === 429 ? N(e) : e || `Request failed (HTTP ${t.status})`;
1536
1590
  }
1537
- async function xn({ apiBase: t, apiKey: e, projectId: n, token: o }) {
1591
+ async function jn({ apiBase: t, apiKey: e, projectId: n, token: i }) {
1538
1592
  const r = { mode: "off", signedIn: null, signedOutReason: null };
1539
1593
  try {
1540
- const i = await fetch(
1594
+ const o = await fetch(
1541
1595
  `${t}/ingest/login?projectId=${encodeURIComponent(n)}`,
1542
- { headers: Z({ apiKey: e, token: o }) }
1596
+ { headers: ne({ apiKey: e, token: i }) }
1543
1597
  );
1544
- if (!i.ok) return r;
1545
- const a = await i.json();
1598
+ if (!o.ok) return r;
1599
+ const a = await o.json();
1546
1600
  return {
1547
1601
  mode: a.mode === "optional" || a.mode === "required" ? a.mode : "off",
1548
1602
  signedIn: a.signedIn || null,
@@ -1552,52 +1606,52 @@ async function xn({ apiBase: t, apiKey: e, projectId: n, token: o }) {
1552
1606
  return r;
1553
1607
  }
1554
1608
  }
1555
- async function In({ apiBase: t, apiKey: e, projectId: n, email: o, name: r }) {
1556
- const i = await fetch(`${t}/ingest/login/start`, {
1609
+ async function On({ apiBase: t, apiKey: e, projectId: n, email: i, name: r }) {
1610
+ const o = await fetch(`${t}/ingest/login/start`, {
1557
1611
  method: "POST",
1558
- headers: Z({ apiKey: e }),
1559
- body: JSON.stringify({ projectId: n, email: o, ...r ? { name: r } : {} })
1612
+ headers: ne({ apiKey: e }),
1613
+ body: JSON.stringify({ projectId: n, email: i, ...r ? { name: r } : {} })
1560
1614
  });
1561
- if (!i.ok) throw new Error(await Fe(i));
1562
- return i.json();
1615
+ if (!o.ok) throw new Error(await Ge(o));
1616
+ return o.json();
1563
1617
  }
1564
- async function Sn({ apiBase: t, apiKey: e, projectId: n, email: o, code: r }) {
1565
- const i = await fetch(`${t}/ingest/login`, {
1618
+ async function Mn({ apiBase: t, apiKey: e, projectId: n, email: i, code: r }) {
1619
+ const o = await fetch(`${t}/ingest/login`, {
1566
1620
  method: "POST",
1567
- headers: Z({ apiKey: e }),
1568
- body: JSON.stringify({ projectId: n, email: o, code: r })
1621
+ headers: ne({ apiKey: e }),
1622
+ body: JSON.stringify({ projectId: n, email: i, code: r })
1569
1623
  });
1570
- if (!i.ok) throw new Error(await Fe(i));
1571
- const a = await i.json(), s = { token: a.sessionToken, email: a.email, name: a.name };
1572
- return kn(n, s), s;
1624
+ if (!o.ok) throw new Error(await Ge(o));
1625
+ const a = await o.json(), s = { token: a.sessionToken, email: a.email, name: a.name };
1626
+ return An(n, s), s;
1573
1627
  }
1574
- async function Cn({ apiBase: t, apiKey: e, projectId: n, token: o }) {
1575
- if (ne(n), !o) return { signedOut: !0 };
1628
+ async function Rn({ apiBase: t, apiKey: e, projectId: n, token: i }) {
1629
+ if (ce(n), !i) return { signedOut: !0 };
1576
1630
  try {
1577
1631
  await fetch(`${t}/ingest/logout`, {
1578
1632
  method: "POST",
1579
- headers: Z({ apiKey: e, token: o }),
1633
+ headers: ne({ apiKey: e, token: i }),
1580
1634
  body: JSON.stringify({ projectId: n })
1581
1635
  });
1582
1636
  } catch {
1583
1637
  }
1584
1638
  return { signedOut: !0 };
1585
1639
  }
1586
- let Xe = !1;
1640
+ let Qe = !1;
1587
1641
  if (typeof window < "u" && window.addEventListener)
1588
1642
  for (const t of ["pointerdown", "keydown", "touchstart"])
1589
1643
  window.addEventListener(t, () => {
1590
- Xe = !0;
1644
+ Qe = !0;
1591
1645
  }, {
1592
1646
  once: !0,
1593
1647
  capture: !0,
1594
1648
  passive: !0
1595
1649
  });
1596
- function Bn() {
1597
- return Xe;
1650
+ function Ln() {
1651
+ return Qe;
1598
1652
  }
1599
- const En = 2e4, qe = 120, oe = 200;
1600
- function We(t) {
1653
+ const Kn = 2e4, et = 120, le = 200;
1654
+ function tt(t) {
1601
1655
  if (typeof t != "string" || !t.trim() || t.length > 400) return null;
1602
1656
  try {
1603
1657
  return new RegExp(t.trim(), "gi");
@@ -1605,194 +1659,194 @@ function We(t) {
1605
1659
  return null;
1606
1660
  }
1607
1661
  }
1608
- const Je = (t) => String(t).replace(/\s+/g, " ").trim().slice(0, qe);
1609
- function Ye(t, e) {
1662
+ const nt = (t) => String(t).replace(/\s+/g, " ").trim().slice(0, et);
1663
+ function it(t, e) {
1610
1664
  const n = t && t.normalize;
1611
1665
  if (n === "phone") {
1612
- const o = e.replace(/\D/g, "");
1613
- return o.length === 10 ? o : o.length === 12 && o.startsWith("91") ? o.slice(2) : o.length === 11 && o.startsWith("0") ? o.slice(1) : e;
1666
+ const i = e.replace(/\D/g, "");
1667
+ return i.length === 10 ? i : i.length === 12 && i.startsWith("91") ? i.slice(2) : i.length === 11 && i.startsWith("0") ? i.slice(1) : e;
1614
1668
  }
1615
1669
  return n === "upper" ? e.toUpperCase() : e;
1616
1670
  }
1617
- function Ve(t) {
1671
+ function ot(t) {
1618
1672
  const e = t.length > 1 && t[1] !== void 0 ? t[1] : t[0];
1619
- return typeof e != "string" || !e.trim() ? null : { value: Je(e), start: t.index, end: t.index + t[0].length };
1673
+ return typeof e != "string" || !e.trim() ? null : { value: nt(e), start: t.index, end: t.index + t[0].length };
1620
1674
  }
1621
- function $n(t, e) {
1675
+ function Nn(t, e) {
1622
1676
  return ((t.slice(e.start, e.valueStart) + t.slice(e.valueEnd, e.end)).match(/[a-z]/gi) || []).length;
1623
1677
  }
1624
- const Tn = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[A-Za-z0-9][\w-]{5,40}/gi, Be = /[\w-]/;
1625
- function ho(t, e) {
1626
- const n = (t || []).filter((d) => d && d.scan !== !1 && d.pattern), o = [], r = [], i = (e || []).map((d) => typeof d == "string" ? d.slice(0, En) : "");
1627
- i.forEach((d, u) => {
1628
- d && n.forEach((g, $) => {
1629
- const S = We(g.pattern);
1630
- if (!S) return;
1631
- let h, I = 0;
1632
- for (S.lastIndex = 0; (h = S.exec(d)) !== null && !(++I > oe); ) {
1633
- if (h[0] === "") {
1634
- S.lastIndex += 1;
1678
+ const Un = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[A-Za-z0-9][\w-]{5,40}/gi, Me = /[\w-]/;
1679
+ function ki(t, e) {
1680
+ const n = (t || []).filter((d) => d && d.scan !== !1 && d.pattern), i = [], r = [], o = (e || []).map((d) => typeof d == "string" ? d.slice(0, Kn) : "");
1681
+ o.forEach((d, u) => {
1682
+ d && n.forEach((m, $) => {
1683
+ const I = tt(m.pattern);
1684
+ if (!I) return;
1685
+ let v, T = 0;
1686
+ for (I.lastIndex = 0; (v = I.exec(d)) !== null && !(++T > le); ) {
1687
+ if (v[0] === "") {
1688
+ I.lastIndex += 1;
1635
1689
  continue;
1636
1690
  }
1637
- const v = Ve(h);
1638
- if (!v) continue;
1639
- const C = h.length > 1 && h[1] !== void 0 ? h[1] : h[0], w = h.index + Math.max(0, h[0].indexOf(C)), k = {
1691
+ const p = ot(v);
1692
+ if (!p) continue;
1693
+ const k = v.length > 1 && v[1] !== void 0 ? v[1] : v[0], g = v.index + Math.max(0, v[0].indexOf(k)), b = {
1640
1694
  block: u,
1641
1695
  order: $,
1642
- key: g.key,
1643
- label: g.label,
1644
- value: Ye(g, v.value),
1645
- start: v.start,
1646
- end: v.end,
1647
- valueStart: w,
1648
- valueEnd: w + C.length
1696
+ key: m.key,
1697
+ label: m.label,
1698
+ value: it(m, p.value),
1699
+ start: p.start,
1700
+ end: p.end,
1701
+ valueStart: g,
1702
+ valueEnd: g + k.length
1649
1703
  };
1650
- k.weight = $n(d, k), o.push(k);
1704
+ b.weight = Nn(d, b), i.push(b);
1651
1705
  }
1652
1706
  });
1653
1707
  });
1654
- const a = o.filter((d) => !o.some((u) => u !== d && u.block === d.block && u.key !== d.key && u.valueStart <= d.valueStart && u.valueEnd >= d.valueEnd && u.weight > d.weight)), s = /* @__PURE__ */ new Map();
1708
+ const a = i.filter((d) => !i.some((u) => u !== d && u.block === d.block && u.key !== d.key && u.valueStart <= d.valueStart && u.valueEnd >= d.valueEnd && u.weight > d.weight)), s = /* @__PURE__ */ new Map();
1655
1709
  for (const d of a) {
1656
1710
  const u = d.value.toLowerCase();
1657
1711
  s.has(u) || s.set(u, { value: d.value, keys: /* @__PURE__ */ new Map() });
1658
- const g = s.get(u);
1659
- g.keys.has(d.key) || g.keys.set(d.key, { key: d.key, label: d.label, order: d.order });
1712
+ const m = s.get(u);
1713
+ m.keys.has(d.key) || m.keys.set(d.key, { key: d.key, label: d.label, order: d.order });
1660
1714
  }
1661
- const c = [], l = [], f = /* @__PURE__ */ new Map();
1715
+ const c = [], l = [], h = /* @__PURE__ */ new Map();
1662
1716
  for (const d of s.values()) {
1663
- const u = [...d.keys.values()].sort((S, h) => S.order - h.order);
1717
+ const u = [...d.keys.values()].sort((I, v) => I.order - v.order);
1664
1718
  if (u.length > 1) {
1665
- l.push({ value: d.value, kinds: u.map(({ key: S, label: h }) => ({ key: S, label: h })) });
1719
+ l.push({ value: d.value, kinds: u.map(({ key: I, label: v }) => ({ key: I, label: v })) });
1666
1720
  continue;
1667
1721
  }
1668
- const [{ key: g, label: $ }] = u;
1669
- f.has(g) || f.set(g, []), f.get(g).push({ key: g, label: $, value: d.value });
1722
+ const [{ key: m, label: $ }] = u;
1723
+ h.has(m) || h.set(m, []), h.get(m).push({ key: m, label: $, value: d.value });
1670
1724
  }
1671
- for (const d of f.values())
1725
+ for (const d of h.values())
1672
1726
  if (d.length === 1) c.push(d[0]);
1673
1727
  else for (const u of d) l.push({ value: u.value, kinds: [{ key: u.key, label: u.label }] });
1674
- const p = new Set(s.keys());
1675
- return i.forEach((d, u) => {
1728
+ const f = new Set(s.keys());
1729
+ return o.forEach((d, u) => {
1676
1730
  if (!d) return;
1677
- const g = o.filter((I) => I.block === u), $ = new RegExp(Tn.source, "gi");
1678
- let S, h = 0;
1679
- for (; (S = $.exec(d)) !== null && ++h <= oe; ) {
1680
- const I = S.index, v = I + S[0].length;
1681
- if (g.some((y) => I < y.end && v > y.start)) continue;
1682
- const C = d[I - 1] || "", w = d[v] || "";
1683
- if (Be.test(C) || Be.test(w) || C === "/" || C === "@" || w === "@" || C === "." || w === "." && /\w/.test(d[v + 1] || "") || !/\d/.test(S[0])) continue;
1684
- const k = Je(S[0]), B = k.toLowerCase();
1685
- if (p.has(B)) continue;
1686
- const b = (t || []).filter((y) => y && An(y, k)).map(({ key: y, label: T }) => ({ key: y, label: T }));
1687
- b.length && (p.add(B), r.push({ value: k, kinds: b }));
1731
+ const m = i.filter((T) => T.block === u), $ = new RegExp(Un.source, "gi");
1732
+ let I, v = 0;
1733
+ for (; (I = $.exec(d)) !== null && ++v <= le; ) {
1734
+ const T = I.index, p = T + I[0].length;
1735
+ if (m.some((C) => T < C.end && p > C.start)) continue;
1736
+ const k = d[T - 1] || "", g = d[p] || "";
1737
+ if (Me.test(k) || Me.test(g) || k === "/" || k === "@" || g === "@" || k === "." || g === "." && /\w/.test(d[p + 1] || "") || !/\d/.test(I[0])) continue;
1738
+ const b = nt(I[0]), B = b.toLowerCase();
1739
+ if (f.has(B)) continue;
1740
+ const y = (t || []).filter((C) => C && Pn(C, b)).map(({ key: C, label: A }) => ({ key: C, label: A }));
1741
+ y.length && (f.add(B), r.push({ value: b, kinds: y }));
1688
1742
  }
1689
1743
  }), { found: c, conflicts: l, loose: r };
1690
1744
  }
1691
- function An(t, e) {
1745
+ function Pn(t, e) {
1692
1746
  const n = typeof e == "string" ? e.trim() : "";
1693
- if (!n || n.length > qe) return null;
1694
- const o = We(t && (t.valuePattern || t.pattern));
1695
- if (!o) return null;
1696
- let r, i = 0;
1697
- for (o.lastIndex = 0; (r = o.exec(n)) !== null && !(++i > oe); ) {
1747
+ if (!n || n.length > et) return null;
1748
+ const i = tt(t && (t.valuePattern || t.pattern));
1749
+ if (!i) return null;
1750
+ let r, o = 0;
1751
+ for (i.lastIndex = 0; (r = i.exec(n)) !== null && !(++o > le); ) {
1698
1752
  if (r[0] === "") {
1699
- o.lastIndex += 1;
1753
+ i.lastIndex += 1;
1700
1754
  continue;
1701
1755
  }
1702
1756
  const a = r.index + r[0].length === n.length, s = r.index === 0 || r.index === 1;
1703
1757
  if (a && s) {
1704
- const c = Ve(r);
1705
- if (c) return Ye(t, c.value);
1758
+ const c = ot(r);
1759
+ if (c) return it(t, c.value);
1706
1760
  }
1707
1761
  }
1708
1762
  return null;
1709
1763
  }
1710
- async function jn({ apiBase: t, apiKey: e, projectId: n }) {
1711
- const o = { policy: "off", fields: [] };
1764
+ async function Dn({ apiBase: t, apiKey: e, projectId: n }) {
1765
+ const i = { policy: "off", fields: [] };
1712
1766
  try {
1713
1767
  const r = await fetch(
1714
1768
  `${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,
1715
1769
  { headers: { "X-BugCatch-Key": e } }
1716
1770
  );
1717
- if (!r.ok) return o;
1718
- const i = await r.json(), a = i.policy === "optional" || i.policy === "required" ? i.policy : "off", s = Array.isArray(i.fields) ? i.fields : [];
1719
- return s.length ? { policy: a, fields: s } : o;
1771
+ if (!r.ok) return i;
1772
+ const o = await r.json(), a = o.policy === "optional" || o.policy === "required" ? o.policy : "off", s = Array.isArray(o.fields) ? o.fields : [];
1773
+ return s.length ? { policy: a, fields: s } : i;
1720
1774
  } catch {
1721
- return o;
1775
+ return i;
1722
1776
  }
1723
1777
  }
1724
- const fo = /Did this answer your question\?/i;
1725
- async function On({ apiBase: t, apiKey: e, projectId: n }) {
1778
+ const vi = /Did this answer your question\?/i;
1779
+ async function _n({ apiBase: t, apiKey: e, projectId: n }) {
1726
1780
  try {
1727
- const o = await fetch(
1781
+ const i = await fetch(
1728
1782
  `${t}/ingest/agent-issues?projectId=${encodeURIComponent(n)}`,
1729
1783
  { headers: { "X-BugCatch-Key": e } }
1730
1784
  );
1731
- if (!o.ok) return [];
1732
- const r = await o.json();
1733
- return (Array.isArray(r == null ? void 0 : r.issues) ? r.issues : []).filter((i) => i && typeof i.key == "string" && typeof i.title == "string").map((i) => ({ key: i.key, title: i.title, hint: typeof i.hint == "string" ? i.hint : "" }));
1785
+ if (!i.ok) return [];
1786
+ const r = await i.json();
1787
+ return (Array.isArray(r == null ? void 0 : r.issues) ? r.issues : []).filter((o) => o && typeof o.key == "string" && typeof o.title == "string").map((o) => ({ key: o.key, title: o.title, hint: typeof o.hint == "string" ? o.hint : "" }));
1734
1788
  } catch {
1735
1789
  return [];
1736
1790
  }
1737
1791
  }
1738
- const Mn = 5 * 6e4, Ze = "bugcatch:announcements:seen", Ln = 40, Rn = ["info", "success", "warning", "critical"], Ge = (t) => `bugcatch:announcements:${t}`;
1739
- async function Kn({
1792
+ const Hn = 5 * 6e4, rt = "bugcatch:announcements:seen", zn = 40, qn = ["info", "success", "warning", "critical"], at = (t) => `bugcatch:announcements:${t}`;
1793
+ async function Fn({
1740
1794
  apiBase: t,
1741
1795
  apiKey: e,
1742
1796
  projectId: n,
1743
- fresh: o = !1
1797
+ fresh: i = !1
1744
1798
  }) {
1745
1799
  var r;
1746
- if (!o) {
1747
- const i = zn(n);
1748
- if (i) return i;
1800
+ if (!i) {
1801
+ const o = Gn(n);
1802
+ if (o) return o;
1749
1803
  }
1750
1804
  try {
1751
- const i = await fetch(
1805
+ const o = await fetch(
1752
1806
  `${t}/ingest/announcements?projectId=${encodeURIComponent(n)}`,
1753
1807
  { headers: { "X-BugCatch-Key": e } }
1754
- ), a = i.ok ? Hn((r = await i.json()) == null ? void 0 : r.announcements) : [];
1755
- return Fn(n, a), a;
1808
+ ), a = o.ok ? Zn((r = await o.json()) == null ? void 0 : r.announcements) : [];
1809
+ return Qn(n, a), a;
1756
1810
  } catch {
1757
1811
  return [];
1758
1812
  }
1759
1813
  }
1760
- function Un(t, { on: e = _n(), seen: n = et() } = {}) {
1761
- return (t || []).filter((o) => Pn(o, e) && !(o.dismissible && n.includes(Qe(o))));
1814
+ function Xn(t, { on: e = Yn(), seen: n = ct() } = {}) {
1815
+ return (t || []).filter((i) => Vn(i, e) && !(i.dismissible && n.includes(st(i))));
1762
1816
  }
1763
- function Nn(t) {
1817
+ function Wn(t) {
1764
1818
  if (!(!(t != null && t.id) || !t.dismissible))
1765
1819
  try {
1766
- const e = Qe(t), n = [...et().filter((o) => o !== e), e];
1767
- localStorage.setItem(Ze, JSON.stringify(n.slice(-Ln)));
1820
+ const e = st(t), n = [...ct().filter((i) => i !== e), e];
1821
+ localStorage.setItem(rt, JSON.stringify(n.slice(-zn)));
1768
1822
  } catch {
1769
1823
  }
1770
1824
  }
1771
- function Dn(t) {
1825
+ function Jn(t) {
1772
1826
  return typeof t != "string" || !t || t.startsWith("//") ? null : t.startsWith("/") || /^(https?:\/\/|mailto:)./i.test(t) ? t : null;
1773
1827
  }
1774
- function _n(t = /* @__PURE__ */ new Date()) {
1828
+ function Yn(t = /* @__PURE__ */ new Date()) {
1775
1829
  const e = (n) => String(n).padStart(2, "0");
1776
1830
  return `${t.getFullYear()}-${e(t.getMonth() + 1)}-${e(t.getDate())}`;
1777
1831
  }
1778
- function Pn(t, e) {
1832
+ function Vn(t, e) {
1779
1833
  return !(t.startsOn && e < t.startsOn || t.endsOn && e > t.endsOn);
1780
1834
  }
1781
- function Qe(t) {
1835
+ function st(t) {
1782
1836
  return `${t.id}#${t.revision || 0}`;
1783
1837
  }
1784
- function Hn(t) {
1838
+ function Zn(t) {
1785
1839
  return (Array.isArray(t) ? t : []).filter((e) => e && typeof e.id == "string" && typeof e.title == "string" && e.title.trim()).map((e) => {
1786
- const n = e.placement === "launcher" ? "launcher" : "panel", o = Dn(e.ctaHref);
1840
+ const n = e.placement === "launcher" ? "launcher" : "panel", i = Jn(e.ctaHref);
1787
1841
  return {
1788
1842
  id: e.id,
1789
1843
  revision: Number.isInteger(e.revision) ? e.revision : 0,
1790
1844
  title: e.title,
1791
1845
  body: typeof e.body == "string" ? e.body : "",
1792
- tone: Rn.includes(e.tone) ? e.tone : "info",
1846
+ tone: qn.includes(e.tone) ? e.tone : "info",
1793
1847
  // Both halves, or neither, as the API saves them.
1794
- ctaLabel: o && typeof e.ctaLabel == "string" ? e.ctaLabel : "",
1795
- ctaHref: o && typeof e.ctaLabel == "string" ? o : "",
1848
+ ctaLabel: i && typeof e.ctaLabel == "string" ? e.ctaLabel : "",
1849
+ ctaHref: i && typeof e.ctaLabel == "string" ? i : "",
1796
1850
  placement: n,
1797
1851
  dismissible: n === "launcher" || e.dismissible !== !1,
1798
1852
  startsOn: typeof e.startsOn == "string" ? e.startsOn : "",
@@ -1800,150 +1854,150 @@ function Hn(t) {
1800
1854
  };
1801
1855
  });
1802
1856
  }
1803
- function et() {
1857
+ function ct() {
1804
1858
  try {
1805
- const t = JSON.parse(localStorage.getItem(Ze) || "[]");
1859
+ const t = JSON.parse(localStorage.getItem(rt) || "[]");
1806
1860
  return Array.isArray(t) ? t.filter((e) => typeof e == "string") : [];
1807
1861
  } catch {
1808
1862
  return [];
1809
1863
  }
1810
1864
  }
1811
- function zn(t) {
1865
+ function Gn(t) {
1812
1866
  try {
1813
- const e = JSON.parse(localStorage.getItem(Ge(t)) || "null");
1867
+ const e = JSON.parse(localStorage.getItem(at(t)) || "null");
1814
1868
  if (!e || !Array.isArray(e.list) || typeof e.at != "number") return null;
1815
1869
  const n = Date.now() - e.at;
1816
- return n >= 0 && n < Mn ? e.list : null;
1870
+ return n >= 0 && n < Hn ? e.list : null;
1817
1871
  } catch {
1818
1872
  return null;
1819
1873
  }
1820
1874
  }
1821
- function Fn(t, e) {
1875
+ function Qn(t, e) {
1822
1876
  try {
1823
- localStorage.setItem(Ge(t), JSON.stringify({ at: Date.now(), list: e }));
1877
+ localStorage.setItem(at(t), JSON.stringify({ at: Date.now(), list: e }));
1824
1878
  } catch {
1825
1879
  }
1826
1880
  }
1827
- const W = 120, Xn = 500, J = 30, qn = 1e3, he = {
1881
+ const Z = 120, ei = 500, G = 30, ti = 1e3, we = {
1828
1882
  loanId: ["loanId", "loanNumber"],
1829
1883
  applicationId: ["applicationId"],
1830
1884
  customerNumber: ["customerNumber", "customerId"]
1831
- }, Wn = /[\u0000-\u001f\u007f]/;
1832
- function Jn(t) {
1885
+ }, ni = /[\u0000-\u001f\u007f]/;
1886
+ function ii(t) {
1833
1887
  if (typeof t == "number") return Number.isFinite(t) ? String(t) : null;
1834
1888
  if (typeof t != "string") return null;
1835
1889
  const e = t.trim();
1836
- return !e || e.length > W || Wn.test(e) ? null : e;
1890
+ return !e || e.length > Z || ni.test(e) ? null : e;
1837
1891
  }
1838
- function A(t) {
1892
+ function O(t) {
1839
1893
  return t === null ? "null" : Array.isArray(t) ? "an array" : typeof t == "object" ? "an object" : `a ${typeof t}`;
1840
1894
  }
1841
- function ie(t, e, n, o, r) {
1842
- for (const i of n) {
1843
- if (!(i in t) || t[i] === void 0 || t[i] === null || t[i] === "") continue;
1844
- const a = Jn(t[i]);
1895
+ function ue(t, e, n, i, r) {
1896
+ for (const o of n) {
1897
+ if (!(o in t) || t[o] === void 0 || t[o] === null || t[o] === "") continue;
1898
+ const a = ii(t[o]);
1845
1899
  if (a) return a;
1846
- const s = t[i];
1847
- r(typeof s == "string" && s.trim().length > W ? `${o}.${i} is longer than ${W} characters and was dropped — pass the identifier itself, not a sentence or a URL.` : `${o}.${i} should be a string or number, got ${A(s)} — it was dropped.`);
1900
+ const s = t[o];
1901
+ r(typeof s == "string" && s.trim().length > Z ? `${i}.${o} is longer than ${Z} characters and was dropped — pass the identifier itself, not a sentence or a URL.` : `${i}.${o} should be a string or number, got ${O(s)} — it was dropped.`);
1848
1902
  }
1849
1903
  return null;
1850
1904
  }
1851
- function tt(t) {
1905
+ function lt(t) {
1852
1906
  if (t === null || typeof t == "boolean") return { ok: !0, value: t };
1853
1907
  if (typeof t == "number") return Number.isFinite(t) ? { ok: !0, value: t } : { ok: !1 };
1854
- if (typeof t == "string") return { ok: !0, value: t.slice(0, Xn) };
1908
+ if (typeof t == "string") return { ok: !0, value: t.slice(0, ei) };
1855
1909
  if (typeof t == "object")
1856
1910
  try {
1857
1911
  const e = JSON.stringify(t);
1858
- if (e && e.length <= qn) return { ok: !0, value: JSON.parse(e) };
1912
+ if (e && e.length <= ti) return { ok: !0, value: JSON.parse(e) };
1859
1913
  } catch {
1860
1914
  }
1861
1915
  return { ok: !1 };
1862
1916
  }
1863
- const nt = ["email", "name", "phone"], Yn = /* @__PURE__ */ new Set(["id", "userId", ...nt, ...Object.values(he).flat()]);
1864
- function Ee(t, e = () => {
1917
+ const ut = ["email", "name", "phone"], oi = /* @__PURE__ */ new Set(["id", "userId", ...ut, ...Object.values(we).flat()]);
1918
+ function Re(t, e = () => {
1865
1919
  }) {
1866
1920
  if (t == null) return null;
1867
1921
  if (typeof t != "object" || Array.isArray(t))
1868
- return e(`identify() takes an object like { id, email, name } or null, got ${A(t)} — ignored.`), null;
1922
+ return e(`identify() takes an object like { id, email, name } or null, got ${O(t)} — ignored.`), null;
1869
1923
  const n = {};
1870
1924
  try {
1871
- const o = ie(t, "id", ["id", "userId"], "identify()", e);
1872
- o && (n.id = o);
1873
- for (const i of nt) {
1874
- const a = t[i];
1925
+ const i = ue(t, "id", ["id", "userId"], "identify()", e);
1926
+ i && (n.id = i);
1927
+ for (const o of ut) {
1928
+ const a = t[o];
1875
1929
  if (a == null || a === "") continue;
1876
- if (i === "phone" && typeof a == "number" && Number.isFinite(a)) {
1930
+ if (o === "phone" && typeof a == "number" && Number.isFinite(a)) {
1877
1931
  n.phone = String(a);
1878
1932
  continue;
1879
1933
  }
1880
1934
  if (typeof a != "string") {
1881
- e(`identify().${i} should be a string, got ${A(a)} — it was dropped.`);
1935
+ e(`identify().${o} should be a string, got ${O(a)} — it was dropped.`);
1882
1936
  continue;
1883
1937
  }
1884
- const s = a.trim().slice(0, i === "name" ? 200 : W);
1885
- s && (i === "email" && !s.includes("@") && e(`identify().email "${s}" does not look like an email address — reports cannot be threaded or followed up without one.`), n[i] = s);
1938
+ const s = a.trim().slice(0, o === "name" ? 200 : Z);
1939
+ s && (o === "email" && !s.includes("@") && e(`identify().email "${s}" does not look like an email address — reports cannot be threaded or followed up without one.`), n[o] = s);
1886
1940
  }
1887
- for (const [i, a] of Object.entries(he)) {
1888
- const s = ie(t, i, a, "identify()", e);
1889
- s && (n[i] = s);
1941
+ for (const [o, a] of Object.entries(we)) {
1942
+ const s = ue(t, o, a, "identify()", e);
1943
+ s && (n[o] = s);
1890
1944
  }
1891
1945
  let r = 0;
1892
- for (const [i, a] of Object.entries(t)) {
1893
- if (Yn.has(i) || a === void 0 || typeof a == "function") continue;
1894
- if (r >= J) {
1895
- e(`identify() was given more than ${J} extra fields; the rest were dropped.`);
1946
+ for (const [o, a] of Object.entries(t)) {
1947
+ if (oi.has(o) || a === void 0 || typeof a == "function") continue;
1948
+ if (r >= G) {
1949
+ e(`identify() was given more than ${G} extra fields; the rest were dropped.`);
1896
1950
  break;
1897
1951
  }
1898
- const s = tt(a);
1952
+ const s = lt(a);
1899
1953
  if (!s.ok) {
1900
- e(`identify().${i} could not be sent (${A(a)} too large or not serialisable) — dropped.`);
1954
+ e(`identify().${o} could not be sent (${O(a)} too large or not serialisable) — dropped.`);
1901
1955
  continue;
1902
1956
  }
1903
- n[i] = s.value, r += 1;
1957
+ n[o] = s.value, r += 1;
1904
1958
  }
1905
1959
  } catch {
1906
1960
  }
1907
1961
  return !n.id && !n.email && e("identify() was called without an id or email — reports will not be attributed to anyone, and nothing can be looked up by user."), n;
1908
1962
  }
1909
- function $e(t, e, n = () => {
1963
+ function Le(t, e, n = () => {
1910
1964
  }) {
1911
1965
  if (e === null) return {};
1912
- const o = { ...t || {} };
1913
- if (e === void 0) return o;
1966
+ const i = { ...t || {} };
1967
+ if (e === void 0) return i;
1914
1968
  if (typeof e != "object" || Array.isArray(e))
1915
- return n(`setContext() takes an object like { loanId, screen } or null, got ${A(e)} — ignored.`), o;
1969
+ return n(`setContext() takes an object like { loanId, screen } or null, got ${O(e)} — ignored.`), i;
1916
1970
  try {
1917
1971
  const r = /* @__PURE__ */ new Map();
1918
- for (const [i, a] of Object.entries(he)) for (const s of a) r.set(s, i);
1919
- for (const [i, a] of Object.entries(e)) {
1920
- const s = r.get(i);
1972
+ for (const [o, a] of Object.entries(we)) for (const s of a) r.set(s, o);
1973
+ for (const [o, a] of Object.entries(e)) {
1974
+ const s = r.get(o);
1921
1975
  if (a == null) {
1922
- delete o[s || i];
1976
+ delete i[s || o];
1923
1977
  continue;
1924
1978
  }
1925
1979
  if (s) {
1926
- const l = ie({ [i]: a }, s, [i], "setContext()", n);
1927
- l ? o[s] = l : delete o[s];
1980
+ const l = ue({ [o]: a }, s, [o], "setContext()", n);
1981
+ l ? i[s] = l : delete i[s];
1928
1982
  continue;
1929
1983
  }
1930
1984
  if (typeof a == "function") continue;
1931
- if (!(i in o) && Object.keys(o).length >= J) {
1932
- n(`setContext() holds at most ${J} keys; "${i}" was dropped.`);
1985
+ if (!(o in i) && Object.keys(i).length >= G) {
1986
+ n(`setContext() holds at most ${G} keys; "${o}" was dropped.`);
1933
1987
  continue;
1934
1988
  }
1935
- const c = tt(a);
1989
+ const c = lt(a);
1936
1990
  if (!c.ok) {
1937
- n(`setContext().${i} could not be sent (${A(a)} too large or not serialisable) — dropped.`);
1991
+ n(`setContext().${o} could not be sent (${O(a)} too large or not serialisable) — dropped.`);
1938
1992
  continue;
1939
1993
  }
1940
- o[i] = c.value;
1994
+ i[o] = c.value;
1941
1995
  }
1942
1996
  } catch {
1943
1997
  }
1944
- return o;
1998
+ return i;
1945
1999
  }
1946
- const ot = [
2000
+ const dt = [
1947
2001
  "apiBase",
1948
2002
  "apiKey",
1949
2003
  "projectId",
@@ -1981,7 +2035,7 @@ const ot = [
1981
2035
  "buildId",
1982
2036
  "chunkBase",
1983
2037
  "announcements"
1984
- ], Vn = [
2038
+ ], ri = [
1985
2039
  "beforeSend",
1986
2040
  "onUpdate",
1987
2041
  "onCallState",
@@ -1990,35 +2044,35 @@ const ot = [
1990
2044
  "onAssistantPhase",
1991
2045
  "onError"
1992
2046
  ];
1993
- function Zn(t) {
2047
+ function ai(t) {
1994
2048
  const e = t.toLowerCase().replace(/[-_]/g, "");
1995
- return ot.find((n) => n.toLowerCase() === e) || null;
2049
+ return dt.find((n) => n.toLowerCase() === e) || null;
1996
2050
  }
1997
- const Te = /^(your[_-]|<|xxx|todo|changeme)/i, Gn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1998
- function Qn(t, { pageHost: e = "" } = {}) {
1999
- const n = [], o = [];
2051
+ const Ke = /^(your[_-]|<|xxx|todo|changeme)/i, si = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2052
+ function ci(t, { pageHost: e = "" } = {}) {
2053
+ const n = [], i = [];
2000
2054
  if (!t || typeof t != "object")
2001
- return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."), { errors: n, warnings: o };
2002
- const { apiKey: r, projectId: i, apiBase: a } = t;
2003
- r ? typeof r != "string" ? n.push(`apiKey must be a string, got ${A(r)}.`) : Te.test(r) ? n.push(`apiKey is still the placeholder "${r}" — paste the key you saved when you created it.`) : Gn.test(r) ? o.push("apiKey looks like a project id — did you swap apiKey and projectId?") : r.startsWith("bc_") || o.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.') : n.push("apiKey is required — create one under Workspace Settings → API Keys."), i ? typeof i != "string" ? n.push(`projectId must be a string, got ${A(i)}.`) : Te.test(i) ? n.push(`projectId is still the placeholder "${i}".`) : i.startsWith("bc_") ? o.push("projectId looks like an API key — did you swap apiKey and projectId?") : /\s/.test(i) && o.push("projectId contains whitespace — check it was copied cleanly.") : n.push("projectId is required — copy it from Project Settings → Web SDK."), a == null ? !e || /^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e) || o.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL.") : (typeof a != "string" || !/^https?:\/\//.test(a)) && o.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(a)}.`);
2055
+ return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."), { errors: n, warnings: i };
2056
+ const { apiKey: r, projectId: o, apiBase: a } = t;
2057
+ r ? typeof r != "string" ? n.push(`apiKey must be a string, got ${O(r)}.`) : Ke.test(r) ? n.push(`apiKey is still the placeholder "${r}" — paste the key you saved when you created it.`) : si.test(r) ? i.push("apiKey looks like a project id — did you swap apiKey and projectId?") : r.startsWith("bc_") || i.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.') : n.push("apiKey is required — create one under Workspace Settings → API Keys."), o ? typeof o != "string" ? n.push(`projectId must be a string, got ${O(o)}.`) : Ke.test(o) ? n.push(`projectId is still the placeholder "${o}".`) : o.startsWith("bc_") ? i.push("projectId looks like an API key — did you swap apiKey and projectId?") : /\s/.test(o) && i.push("projectId contains whitespace — check it was copied cleanly.") : n.push("projectId is required — copy it from Project Settings → Web SDK."), a == null ? !e || /^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e) || i.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL.") : (typeof a != "string" || !/^https?:\/\//.test(a)) && i.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(a)}.`);
2004
2058
  for (const s of Object.keys(t)) {
2005
- if (ot.includes(s)) continue;
2006
- const c = Zn(s);
2007
- o.push(c ? `unknown option "${s}" — did you mean "${c}"?` : `unknown option "${s}" is ignored.`);
2059
+ if (dt.includes(s)) continue;
2060
+ const c = ai(s);
2061
+ i.push(c ? `unknown option "${s}" — did you mean "${c}"?` : `unknown option "${s}" is ignored.`);
2008
2062
  }
2009
- for (const s of Vn) {
2063
+ for (const s of ri) {
2010
2064
  const c = t[s];
2011
- c != null && typeof c != "function" && o.push(`${s} should be a function, got ${A(c)} — it will not be called.`);
2065
+ c != null && typeof c != "function" && i.push(`${s} should be a function, got ${O(c)} — it will not be called.`);
2012
2066
  }
2013
- return { errors: n, warnings: o };
2067
+ return { errors: n, warnings: i };
2014
2068
  }
2015
- function eo(t) {
2069
+ function li(t) {
2016
2070
  return typeof t == "string" ? t.replace(/\/+$/, "") : t;
2017
2071
  }
2018
- const K = {
2072
+ const D = {
2019
2073
  name: "@sphoro/bugcatch-web-sdk",
2020
- version: "0.18.0"
2021
- }, R = {
2074
+ version: "0.19.0"
2075
+ }, U = {
2022
2076
  apiBase: "http://localhost:3000",
2023
2077
  apiKey: null,
2024
2078
  projectId: null,
@@ -2032,7 +2086,9 @@ const K = {
2032
2086
  widgetPosition: "bottom-right",
2033
2087
  // 'auto' follows the visitor's system setting; 'light' / 'dark' pin it.
2034
2088
  theme: "auto",
2035
- accent: "#4F46E5",
2089
+ // null is ink: black buttons on light, white on dark (accent.js). Any CSS
2090
+ // colour makes the buttons, the launcher and the assistant's orb that colour.
2091
+ accent: null,
2036
2092
  // Draw what the project's team is telling visitors — written on the Widget
2037
2093
  // announcements settings page — in the panel, and beside the button for the
2038
2094
  // ones written for that. false draws nothing; announcements() still answers,
@@ -2100,15 +2156,15 @@ const K = {
2100
2156
  // printed either way.
2101
2157
  debug: !1
2102
2158
  };
2103
- function to(t) {
2159
+ function ui(t) {
2104
2160
  const e = E();
2105
2161
  return e ? { ...t, watchToken: e } : t;
2106
2162
  }
2107
- var m, P, rt, O, at, re, H, z, ae, st, ct, lt, F, ut;
2108
- class it {
2163
+ var w, F, ft, R, pt, de, X, W, he, gt, mt, wt, J, yt;
2164
+ class ht {
2109
2165
  constructor() {
2110
- pe(this, m);
2111
- this.config = { ...R }, this.started = !1, this.teardown = [], this.consoleBuffer = D(R.consoleLimit), this.networkBuffer = D(R.networkLimit), this.stopWatching = null, this.notifier = null, this.call = null, this.callStarting = !1, this.ringing = null, this.listeners = /* @__PURE__ */ new Map(), this.context = {}, this.warned = /* @__PURE__ */ new Set(), this.phases = /* @__PURE__ */ new Map();
2166
+ xe(this, w);
2167
+ this.config = { ...U }, this.started = !1, this.teardown = [], this.consoleBuffer = z(U.consoleLimit), this.networkBuffer = z(U.networkLimit), this.stopWatching = null, this.notifier = null, this.call = null, this.callStarting = !1, this.ringing = null, this.listeners = /* @__PURE__ */ new Map(), this.context = {}, this.warned = /* @__PURE__ */ new Set(), this.phases = /* @__PURE__ */ new Map();
2112
2168
  }
2113
2169
  /** A misconfiguration, said once. Always printed — it is what saves a day of guessing. */
2114
2170
  warn(e) {
@@ -2121,14 +2177,14 @@ class it {
2121
2177
  init(e = {}) {
2122
2178
  if (this.started)
2123
2179
  return console.warn("[BugCatch] init() called twice — ignoring the second call."), this;
2124
- const { errors: n, warnings: o } = Qn(e, {
2180
+ const { errors: n, warnings: i } = ci(e, {
2125
2181
  pageHost: typeof location < "u" ? location.hostname : ""
2126
2182
  });
2127
2183
  if (n.length) throw new Error(`[BugCatch] ${n[0]}`);
2128
- for (const i of o) this.warn(i);
2184
+ for (const o of i) this.warn(o);
2129
2185
  const r = this.config.user;
2130
- return this.config = { ...R, ...e, apiBase: eo(e.apiBase ?? R.apiBase) }, this.config.user = e.user !== void 0 ? Ee(e.user, (i) => this.warn(i.replace("identify()", "init({ user })"))) : r || null, e.context && this.setContext(e.context), this.consoleBuffer = D(this.config.consoleLimit), this.networkBuffer = D(this.config.networkLimit), this.config.captureConsole && this.teardown.push(xt(this.consoleBuffer)), this.config.captureNetwork && this.teardown.push(It(this.networkBuffer)), this.config.captureErrors && this.teardown.push(St(this.consoleBuffer)), Wt(this.config.projectId), this.config.widget && this.teardown.push(Ut(this)), this.config.updates && E() && (this.startWatching(), queueMicrotask(() => x(this, m, O).call(this))), this.started = !0, x(this, m, rt).call(this), this.debugLog("initialised", {
2131
- version: K.version,
2186
+ return this.config = { ...U, ...e, apiBase: li(e.apiBase ?? U.apiBase) }, this.config.user = e.user !== void 0 ? Re(e.user, (o) => this.warn(o.replace("identify()", "init({ user })"))) : r || null, e.context && this.setContext(e.context), this.consoleBuffer = z(this.config.consoleLimit), this.networkBuffer = z(this.config.networkLimit), this.config.captureConsole && this.teardown.push(At(this.consoleBuffer)), this.config.captureNetwork && this.teardown.push(jt(this.networkBuffer)), this.config.captureErrors && this.teardown.push(Ot(this.consoleBuffer)), tn(this.config.projectId), this.config.widget && this.teardown.push(Ft(this)), this.config.updates && E() && (this.startWatching(), queueMicrotask(() => x(this, w, R).call(this))), this.started = !0, x(this, w, ft).call(this), this.debugLog("initialised", {
2187
+ version: D.version,
2132
2188
  apiBase: this.config.apiBase,
2133
2189
  projectId: this.config.projectId,
2134
2190
  user: this.config.user,
@@ -2141,26 +2197,26 @@ class it {
2141
2197
  */
2142
2198
  startWatching() {
2143
2199
  if (this.stopWatching) return this;
2144
- this.stopWatching = cn({
2200
+ this.stopWatching = mn({
2145
2201
  apiBase: this.config.apiBase,
2146
2202
  onUpdate: (n) => {
2147
2203
  if (n != null && n.incomingCall) {
2148
- x(this, m, lt).call(this, n);
2204
+ x(this, w, wt).call(this, n);
2149
2205
  return;
2150
2206
  }
2151
2207
  if (n != null && n.callWithdrawn) {
2152
- x(this, m, F).call(this, n.callWithdrawn.callId);
2208
+ x(this, w, J).call(this, n.callWithdrawn.callId);
2153
2209
  return;
2154
2210
  }
2155
- const o = Yt(n);
2156
- typeof this.config.onUpdate == "function" && this.config.onUpdate(o), this.emit("update", o), x(this, m, O).call(this);
2211
+ const i = on(n);
2212
+ typeof this.config.onUpdate == "function" && this.config.onUpdate(i), this.emit("update", i), x(this, w, R).call(this);
2157
2213
  }
2158
2214
  }), this.teardown.push(() => {
2159
2215
  var n;
2160
2216
  return (n = this.stopWatching) == null ? void 0 : n.call(this);
2161
- }), this.teardown.push(() => x(this, m, F).call(this));
2217
+ }), this.teardown.push(() => x(this, w, J).call(this));
2162
2218
  const e = (n) => {
2163
- (n.key === q || n.key === null) && x(this, m, O).call(this);
2219
+ (n.key === V || n.key === null) && x(this, w, R).call(this);
2164
2220
  };
2165
2221
  return window.addEventListener("storage", e), this.teardown.push(() => window.removeEventListener("storage", e)), this;
2166
2222
  }
@@ -2177,18 +2233,18 @@ class it {
2177
2233
  on(e, n) {
2178
2234
  if (typeof n != "function") return () => {
2179
2235
  };
2180
- const o = this.listeners.get(e) || /* @__PURE__ */ new Set();
2181
- return o.add(n), this.listeners.set(e, o), () => this.off(e, n);
2236
+ const i = this.listeners.get(e) || /* @__PURE__ */ new Set();
2237
+ return i.add(n), this.listeners.set(e, i), () => this.off(e, n);
2182
2238
  }
2183
2239
  off(e, n) {
2184
- var o;
2185
- return (o = this.listeners.get(e)) == null || o.delete(n), this;
2240
+ var i;
2241
+ return (i = this.listeners.get(e)) == null || i.delete(n), this;
2186
2242
  }
2187
2243
  /** Notify listeners; one that throws must not stop the rest. */
2188
2244
  emit(e, n) {
2189
- for (const o of this.listeners.get(e) || [])
2245
+ for (const i of this.listeners.get(e) || [])
2190
2246
  try {
2191
- o(n);
2247
+ i(n);
2192
2248
  } catch (r) {
2193
2249
  console.error(`[BugCatch] a '${e}' listener threw:`, r);
2194
2250
  }
@@ -2204,7 +2260,7 @@ class it {
2204
2260
  * Each carries the `id` the mark-read calls take.
2205
2261
  */
2206
2262
  unreadUpdates() {
2207
- return N();
2263
+ return H();
2208
2264
  }
2209
2265
  /**
2210
2266
  * Mark one update read. It stops being shown, here and on the next load.
@@ -2217,7 +2273,7 @@ class it {
2217
2273
  * knows when its reader has seen one, so it has to say.
2218
2274
  */
2219
2275
  markUpdateRead(e) {
2220
- return Vt(e), x(this, m, O).call(this), this;
2276
+ return rn(e), x(this, w, R).call(this), this;
2221
2277
  }
2222
2278
  /**
2223
2279
  * Mark everything about one report read.
@@ -2226,11 +2282,31 @@ class it {
2226
2282
  * the thread opens; an integration with its own report view should too.
2227
2283
  */
2228
2284
  markReportRead(e) {
2229
- return Zt(e), x(this, m, O).call(this), this;
2285
+ return an(e), x(this, w, R).call(this), this;
2230
2286
  }
2231
2287
  /** Mark everything read. The "clear all" behind your own notification list. */
2232
2288
  markUpdatesRead() {
2233
- return ze(), x(this, m, O).call(this), this;
2289
+ return Ze(), x(this, w, R).call(this), this;
2290
+ }
2291
+ /**
2292
+ * Tell the team whether their fix worked. STILL_HAPPENING reopens the report
2293
+ * and re-sends this browser's context with it.
2294
+ */
2295
+ async verifyFix(e, { result: n, resolvedAt: i, note: r }) {
2296
+ const o = n === "STILL_HAPPENING" ? await x(this, w, W).call(this, {}) : {};
2297
+ return $n({ apiBase: this.config.apiBase, bugId: e, result: n, resolvedAt: i, note: r, metadata: o.metadata, logs: o.logs });
2298
+ }
2299
+ /**
2300
+ * Rate how a settled report was handled, 1 to 5, five best.
2301
+ *
2302
+ * await BugCatch.rate(report.id, { score: 4, comment: 'Quick, thanks' });
2303
+ *
2304
+ * Only once the report is RESOLVED or CLOSED, on a project that asks for
2305
+ * ratings — `myReport(id).ratingAsked` says whether it does. Rating again
2306
+ * replaces the earlier score rather than adding a second one.
2307
+ */
2308
+ async rate(e, { score: n, comment: i } = {}) {
2309
+ return En({ apiBase: this.config.apiBase, bugId: e, score: n, comment: i });
2234
2310
  }
2235
2311
  /**
2236
2312
  * One report in full, with its timeline — every step from filing to now.
@@ -2240,13 +2316,9 @@ class it {
2240
2316
  *
2241
2317
  * Resolves to null when this browser cannot prove it filed that report.
2242
2318
  */
2243
- async verifyFix(e, { result: n, resolvedAt: o, note: r }) {
2244
- const i = n === "STILL_HAPPENING" ? await x(this, m, z).call(this, {}) : {};
2245
- return yn({ apiBase: this.config.apiBase, bugId: e, result: n, resolvedAt: o, note: r, metadata: i.metadata, logs: i.logs });
2246
- }
2247
2319
  async myReport(e) {
2248
- const n = await en({ apiBase: this.config.apiBase, bugId: e });
2249
- return x(this, m, at).call(this, e, n == null ? void 0 : n.assistant), n;
2320
+ const n = await ln({ apiBase: this.config.apiBase, bugId: e });
2321
+ return x(this, w, pt).call(this, e, n == null ? void 0 : n.assistant), n;
2250
2322
  }
2251
2323
  /**
2252
2324
  * Write back on a report this browser filed.
@@ -2261,8 +2333,8 @@ class it {
2261
2333
  * integration rendering its own can too. Resolves to the stored message, so
2262
2334
  * the caller renders what the server kept rather than what it hoped it sent.
2263
2335
  */
2264
- replyToReport(e, { body: n, attachments: o } = {}) {
2265
- return tn({ apiBase: this.config.apiBase, bugId: e, body: n, attachments: o });
2336
+ replyToReport(e, { body: n, attachments: i } = {}) {
2337
+ return un({ apiBase: this.config.apiBase, bugId: e, body: n, attachments: i });
2266
2338
  }
2267
2339
  /**
2268
2340
  * Whether this visitor can report something by talking about it instead.
@@ -2315,7 +2387,7 @@ class it {
2315
2387
  async callKinds() {
2316
2388
  var n;
2317
2389
  const e = { agent: !1, live: !1 };
2318
- return !this.config.voice || !((n = this.config.user) != null && n.email) ? e : this.kinds !== void 0 ? this.kinds : (this.kinds = await nn({
2390
+ return !this.config.voice || !((n = this.config.user) != null && n.email) ? e : this.kinds !== void 0 ? this.kinds : (this.kinds = await dn({
2319
2391
  apiBase: this.config.apiBase,
2320
2392
  apiKey: this.config.apiKey,
2321
2393
  projectId: this.config.projectId
@@ -2336,7 +2408,7 @@ class it {
2336
2408
  * for either of them to be asking about.
2337
2409
  */
2338
2410
  canCall(e) {
2339
- return this.config.voice ? Ie({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
2411
+ return this.config.voice ? Ae({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
2340
2412
  }
2341
2413
  /**
2342
2414
  * Ring the team.
@@ -2379,7 +2451,7 @@ class it {
2379
2451
  try {
2380
2452
  if (!await this.callKind())
2381
2453
  throw new Error((n = this.config.user) != null && n.email ? "[BugCatch] calling is not available on this project." : "[BugCatch] a call needs to know who is calling — call identify() with an email first.");
2382
- return await x(this, m, ct).call(this, e);
2454
+ return await x(this, w, mt).call(this, e);
2383
2455
  } finally {
2384
2456
  this.callStarting = !1;
2385
2457
  }
@@ -2402,7 +2474,7 @@ class it {
2402
2474
  * For a host application drawing its own button. The widget asks this itself.
2403
2475
  */
2404
2476
  canCallTeam(e) {
2405
- return this.config.voice ? Ie({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
2477
+ return this.config.voice ? Ae({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
2406
2478
  }
2407
2479
  /**
2408
2480
  * End the call in progress, of either kind. Does nothing when there is not
@@ -2424,7 +2496,7 @@ class it {
2424
2496
  * nothing to look up in either case.
2425
2497
  */
2426
2498
  myReports() {
2427
- return Qt({ apiBase: this.config.apiBase });
2499
+ return cn({ apiBase: this.config.apiBase });
2428
2500
  }
2429
2501
  /** True when this browser has filed something, so a "your reports" entry
2430
2502
  * point can be hidden until it would show anything. */
@@ -2437,7 +2509,7 @@ class it {
2437
2509
  */
2438
2510
  forgetReports() {
2439
2511
  var e;
2440
- return (e = this.stopWatching) == null || e.call(this), this.stopWatching = null, this.endCall(), M(), x(this, m, O).call(this), this;
2512
+ return (e = this.stopWatching) == null || e.call(this), this.stopWatching = null, this.endCall(), K(), x(this, w, R).call(this), this;
2441
2513
  }
2442
2514
  /**
2443
2515
  * Attach the signed-in user so reports say who hit the bug.
@@ -2454,7 +2526,7 @@ class it {
2454
2526
  * Pass null to forget them again on sign-out.
2455
2527
  */
2456
2528
  identify(e) {
2457
- const n = Ee(e, (o) => this.warn(o));
2529
+ const n = Re(e, (i) => this.warn(i));
2458
2530
  return e != null && !n ? this : (this.config.user = n, this.debugLog("identify", n), this);
2459
2531
  }
2460
2532
  /**
@@ -2471,7 +2543,7 @@ class it {
2471
2543
  * outrank the same field on identify(); anything else is readable metadata.
2472
2544
  */
2473
2545
  setContext(e) {
2474
- return this.context = $e(this.context, e, (n) => this.warn(n)), this.debugLog("context", this.context), this;
2546
+ return this.context = Le(this.context, e, (n) => this.warn(n)), this.debugLog("context", this.context), this;
2475
2547
  }
2476
2548
  /** What setContext() currently holds (a copy). */
2477
2549
  getContext() {
@@ -2505,61 +2577,61 @@ class it {
2505
2577
  * through the API — so this is also what you call when you drive the SDK
2506
2578
  * yourself with `widget: false`.
2507
2579
  */
2508
- async uploadAttachment(e, n, o) {
2580
+ async uploadAttachment(e, n, i) {
2509
2581
  if (!this.started) throw new Error("[BugCatch] call init() first.");
2510
- return Ft({
2582
+ return Gt({
2511
2583
  apiBase: this.config.apiBase,
2512
2584
  apiKey: this.config.apiKey,
2513
2585
  blob: e,
2514
2586
  mime: n || (e == null ? void 0 : e.type),
2515
- onProgress: o
2587
+ onProgress: i
2516
2588
  });
2517
2589
  }
2518
2590
  /** File a bug with everything captured so far. */
2519
2591
  async report({
2520
2592
  title: e,
2521
2593
  description: n = "",
2522
- priority: o = "MEDIUM",
2594
+ priority: i = "MEDIUM",
2523
2595
  metadata: r = {},
2524
- attachments: i = [],
2596
+ attachments: o = [],
2525
2597
  references: a = [],
2526
2598
  context: s = null,
2527
2599
  issue: c = null
2528
2600
  } = {}) {
2529
- var S, h, I, v, C, w, k, B;
2601
+ var I, v, T, p, k, g, b, B;
2530
2602
  if (!this.started) throw new Error("[BugCatch] call init() first.");
2531
2603
  if (typeof e != "string" || !e.trim()) throw new Error("[BugCatch] a title is required.");
2532
- ["LOW", "MEDIUM", "HIGH", "CRITICAL"].includes(String(o).toUpperCase()) || (this.warn(`priority "${o}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`), o = "MEDIUM");
2533
- const l = (i || []).filter((b) => (b == null ? void 0 : b.storageKey) && ee(b.mime, ke)).map((b) => ({
2534
- type: b.type === "VIDEO" ? "VIDEO" : "SCREENSHOT",
2535
- storageKey: b.storageKey,
2536
- mime: ee(b.mime, ke)
2537
- })), f = (Array.isArray(a) ? a : []).filter((b) => b && typeof b.key == "string" && b.key && (typeof b.value == "string" || typeof b.value == "number")).map((b) => ({ key: b.key.slice(0, 64), value: String(b.value).trim().slice(0, 120) })).filter((b) => b.value);
2538
- Array.isArray(a) && f.length < a.length && this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");
2539
- let p = await x(this, m, z).call(this, {
2604
+ ["LOW", "MEDIUM", "HIGH", "CRITICAL"].includes(String(i).toUpperCase()) || (this.warn(`priority "${i}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`), i = "MEDIUM");
2605
+ const l = (o || []).filter((y) => (y == null ? void 0 : y.storageKey) && ae(y.mime, $e)).map((y) => ({
2606
+ type: y.type === "VIDEO" ? "VIDEO" : "SCREENSHOT",
2607
+ storageKey: y.storageKey,
2608
+ mime: ae(y.mime, $e)
2609
+ })), h = (Array.isArray(a) ? a : []).filter((y) => y && typeof y.key == "string" && y.key && (typeof y.value == "string" || typeof y.value == "number")).map((y) => ({ key: y.key.slice(0, 64), value: String(y.value).trim().slice(0, 120) })).filter((y) => y.value);
2610
+ Array.isArray(a) && h.length < a.length && this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");
2611
+ let f = await x(this, w, W).call(this, {
2540
2612
  title: e.trim(),
2541
2613
  description: typeof n == "string" ? n : String(n ?? ""),
2542
- priority: String(o).toUpperCase(),
2614
+ priority: String(i).toUpperCase(),
2543
2615
  metadata: r,
2544
2616
  media: l,
2545
- references: f,
2617
+ references: h,
2546
2618
  context: s,
2547
2619
  issue: typeof c == "string" && c ? c.slice(0, 32) : null
2548
2620
  });
2549
- const d = x(this, m, ae).call(this, p);
2621
+ const d = x(this, w, he).call(this, f);
2550
2622
  if (d === !1) return { cancelled: !0 };
2551
- p = d, this.debugLog("sending report", {
2552
- title: p.title,
2553
- user: (S = p.metadata) == null ? void 0 : S.user,
2554
- context: (h = p.metadata) == null ? void 0 : h.context,
2555
- references: p.references,
2556
- console: (C = (v = (I = p.logs) == null ? void 0 : I.console) == null ? void 0 : v.entries) == null ? void 0 : C.length,
2557
- network: (B = (k = (w = p.logs) == null ? void 0 : w.network) == null ? void 0 : k.entries) == null ? void 0 : B.length
2623
+ f = d, this.debugLog("sending report", {
2624
+ title: f.title,
2625
+ user: (I = f.metadata) == null ? void 0 : I.user,
2626
+ context: (v = f.metadata) == null ? void 0 : v.context,
2627
+ references: f.references,
2628
+ console: (k = (p = (T = f.logs) == null ? void 0 : T.console) == null ? void 0 : p.entries) == null ? void 0 : k.length,
2629
+ network: (B = (b = (g = f.logs) == null ? void 0 : g.network) == null ? void 0 : b.entries) == null ? void 0 : B.length
2558
2630
  });
2559
- const u = j(this.config.projectId);
2560
- let g;
2631
+ const u = M(this.config.projectId);
2632
+ let m;
2561
2633
  try {
2562
- g = await fetch(`${this.config.apiBase}/ingest/bugs`, {
2634
+ m = await fetch(`${this.config.apiBase}/ingest/bugs`, {
2563
2635
  method: "POST",
2564
2636
  headers: {
2565
2637
  "Content-Type": "application/json",
@@ -2570,25 +2642,25 @@ class it {
2570
2642
  // reporter would undo the requirement.
2571
2643
  ...u != null && u.token ? { "X-BugCatch-Session": u.token } : {}
2572
2644
  },
2573
- body: JSON.stringify(to(p))
2645
+ body: JSON.stringify(ui(f))
2574
2646
  });
2575
- } catch (b) {
2576
- const y = new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);
2577
- throw y.cause = b, x(this, m, H).call(this, "report", y), y;
2647
+ } catch (y) {
2648
+ const C = new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);
2649
+ throw C.cause = y, x(this, w, X).call(this, "report", C), C;
2578
2650
  }
2579
- if (g.status === 401 && u && ne(this.config.projectId), !g.ok) {
2580
- let b = "";
2651
+ if (m.status === 401 && u && ce(this.config.projectId), !m.ok) {
2652
+ let y = "";
2581
2653
  try {
2582
- const T = await g.json();
2583
- b = Array.isArray(T.message) ? T.message.join(", ") : T.message || "";
2654
+ const A = await m.json();
2655
+ y = Array.isArray(A.message) ? A.message.join(", ") : A.message || "";
2584
2656
  } catch {
2585
2657
  }
2586
- g.status === 401 && !u && (b || (b = "the apiKey was not accepted")), g.status === 403 && (b || (b = "the apiKey is not allowed to report to this projectId"));
2587
- const y = g.status === 429 ? new Error(`[BugCatch] ${L(b)}`) : new Error(`[BugCatch] report failed (HTTP ${g.status})${b ? ": " + b : ""}`);
2588
- throw y.status = g.status, x(this, m, H).call(this, "report", y), y;
2658
+ m.status === 401 && !u && (y || (y = "the apiKey was not accepted")), m.status === 403 && (y || (y = "the apiKey is not allowed to report to this projectId"));
2659
+ const C = m.status === 429 ? new Error(`[BugCatch] ${N(y)}`) : new Error(`[BugCatch] report failed (HTTP ${m.status})${y ? ": " + y : ""}`);
2660
+ throw C.status = m.status, x(this, w, X).call(this, "report", C), C;
2589
2661
  }
2590
- const $ = await g.json();
2591
- return x(this, m, re).call(this, $, { title: p.title ?? e.trim(), via: "form" }), $.watchToken && (te($.watchToken), this.config.updates && this.startWatching()), $;
2662
+ const $ = await m.json();
2663
+ return x(this, w, de).call(this, $, { title: f.title ?? e.trim(), via: "form" }), $.watchToken && (se($.watchToken), this.config.updates && this.startWatching()), $;
2592
2664
  }
2593
2665
  /**
2594
2666
  * What this project asks of the person reporting, and who this browser is
@@ -2607,11 +2679,11 @@ class it {
2607
2679
  */
2608
2680
  loginState() {
2609
2681
  var e;
2610
- return xn({
2682
+ return jn({
2611
2683
  apiBase: this.config.apiBase,
2612
2684
  apiKey: this.config.apiKey,
2613
2685
  projectId: this.config.projectId,
2614
- token: (e = j(this.config.projectId)) == null ? void 0 : e.token
2686
+ token: (e = M(this.config.projectId)) == null ? void 0 : e.token
2615
2687
  });
2616
2688
  }
2617
2689
  /**
@@ -2630,7 +2702,7 @@ class it {
2630
2702
  * whether that form should have an identifier box on it.
2631
2703
  */
2632
2704
  referenceFields() {
2633
- return this.refFields ? this.refFields : (this.refFields = jn({
2705
+ return this.refFields ? this.refFields : (this.refFields = Dn({
2634
2706
  apiBase: this.config.apiBase,
2635
2707
  apiKey: this.config.apiKey,
2636
2708
  projectId: this.config.projectId
@@ -2652,7 +2724,7 @@ class it {
2652
2724
  * itself; cached for the life of the page.
2653
2725
  */
2654
2726
  agentIssues() {
2655
- return this.agentIssueList ? this.agentIssueList : (this.agentIssueList = On({
2727
+ return this.agentIssueList ? this.agentIssueList : (this.agentIssueList = _n({
2656
2728
  apiBase: this.config.apiBase,
2657
2729
  apiKey: this.config.apiKey,
2658
2730
  projectId: this.config.projectId
@@ -2673,12 +2745,12 @@ class it {
2673
2745
  * `widget: false` or `announcements: false`. Empty on every failure.
2674
2746
  */
2675
2747
  async announcements() {
2676
- const e = await Kn({
2748
+ const e = await Fn({
2677
2749
  apiBase: this.config.apiBase,
2678
2750
  apiKey: this.config.apiKey,
2679
2751
  projectId: this.config.projectId
2680
2752
  });
2681
- return Un(e);
2753
+ return Xn(e);
2682
2754
  }
2683
2755
  /**
2684
2756
  * Stop showing an announcement in this browser, until the team uses "Show it
@@ -2686,7 +2758,7 @@ class it {
2686
2758
  * is left alone.
2687
2759
  */
2688
2760
  dismissAnnouncement(e) {
2689
- Nn(e);
2761
+ Wn(e);
2690
2762
  }
2691
2763
  /**
2692
2764
  * Who this browser is signed in as on this project, from storage alone.
@@ -2698,7 +2770,7 @@ class it {
2698
2770
  * the server. Use loginState() where that matters.
2699
2771
  */
2700
2772
  signedInAs() {
2701
- const e = j(this.config.projectId);
2773
+ const e = M(this.config.projectId);
2702
2774
  return e ? { email: e.email, name: e.name } : null;
2703
2775
  }
2704
2776
  /**
@@ -2713,14 +2785,14 @@ class it {
2713
2785
  * address, which is all a reply-to has ever needed to be worth.
2714
2786
  */
2715
2787
  signIn(e, { name: n } = {}) {
2716
- var o;
2717
- return In({
2788
+ var i;
2789
+ return On({
2718
2790
  apiBase: this.config.apiBase,
2719
2791
  apiKey: this.config.apiKey,
2720
2792
  projectId: this.config.projectId,
2721
2793
  email: e,
2722
2794
  // The name the host app already knows beats asking for one again.
2723
- name: n ?? ((o = this.config.user) == null ? void 0 : o.name) ?? null
2795
+ name: n ?? ((i = this.config.user) == null ? void 0 : i.name) ?? null
2724
2796
  });
2725
2797
  }
2726
2798
  /**
@@ -2732,14 +2804,14 @@ class it {
2732
2804
  */
2733
2805
  async confirmSignIn(e, n) {
2734
2806
  var r;
2735
- const o = await Sn({
2807
+ const i = await Mn({
2736
2808
  apiBase: this.config.apiBase,
2737
2809
  apiKey: this.config.apiKey,
2738
2810
  projectId: this.config.projectId,
2739
2811
  email: e,
2740
2812
  code: n
2741
2813
  });
2742
- return (r = this.config.user) != null && r.email || (this.config.user = { email: o.email, name: o.name || void 0 }), this.emit("signin", { email: o.email, name: o.name }), { email: o.email, name: o.name };
2814
+ return (r = this.config.user) != null && r.email || (this.config.user = { email: i.email, name: i.name || void 0 }), this.emit("signin", { email: i.email, name: i.name }), { email: i.email, name: i.name };
2743
2815
  }
2744
2816
  /**
2745
2817
  * Sign out of this project.
@@ -2749,14 +2821,14 @@ class it {
2749
2821
  * says — sign-out on a shared machine has to mean signed out on it.
2750
2822
  */
2751
2823
  async signOut() {
2752
- var o;
2753
- const e = j(this.config.projectId), n = await Cn({
2824
+ var i;
2825
+ const e = M(this.config.projectId), n = await Rn({
2754
2826
  apiBase: this.config.apiBase,
2755
2827
  apiKey: this.config.apiKey,
2756
2828
  projectId: this.config.projectId,
2757
2829
  token: e == null ? void 0 : e.token
2758
2830
  });
2759
- return e != null && e.email && ((o = this.config.user) == null ? void 0 : o.email) === e.email && (this.config.user = null), this.emit("signout", { email: (e == null ? void 0 : e.email) || null }), n;
2831
+ return e != null && e.email && ((i = this.config.user) == null ? void 0 : i.email) === e.email && (this.config.user = null), this.emit("signout", { email: (e == null ? void 0 : e.email) || null }), n;
2760
2832
  }
2761
2833
  /**
2762
2834
  * What this project is already known to be having trouble with.
@@ -2768,11 +2840,11 @@ class it {
2768
2840
  */
2769
2841
  knownIssues() {
2770
2842
  var e;
2771
- return gn({
2843
+ return In({
2772
2844
  apiBase: this.config.apiBase,
2773
2845
  apiKey: this.config.apiKey,
2774
2846
  projectId: this.config.projectId,
2775
- sessionToken: (e = j(this.config.projectId)) == null ? void 0 : e.token
2847
+ sessionToken: (e = M(this.config.projectId)) == null ? void 0 : e.token
2776
2848
  });
2777
2849
  }
2778
2850
  /**
@@ -2782,13 +2854,13 @@ class it {
2782
2854
  * the results of whichever request happens to return last.
2783
2855
  */
2784
2856
  matchKnownIssues(e, { signal: n } = {}) {
2785
- var o;
2786
- return mn({
2857
+ var i;
2858
+ return Cn({
2787
2859
  apiBase: this.config.apiBase,
2788
2860
  apiKey: this.config.apiKey,
2789
2861
  projectId: this.config.projectId,
2790
2862
  q: e || "",
2791
- sessionToken: (o = j(this.config.projectId)) == null ? void 0 : o.token,
2863
+ sessionToken: (i = M(this.config.projectId)) == null ? void 0 : i.token,
2792
2864
  signal: n
2793
2865
  });
2794
2866
  }
@@ -2805,21 +2877,21 @@ class it {
2805
2877
  * me when this is fixed", and there is no way to keep that promise to
2806
2878
  * somebody anonymous.
2807
2879
  */
2808
- async meToo(e, { email: n, name: o } = {}) {
2880
+ async meToo(e, { email: n, name: i } = {}) {
2809
2881
  var a, s;
2810
- const r = j(this.config.projectId), i = await me();
2811
- return wn({
2882
+ const r = M(this.config.projectId), o = await ve();
2883
+ return Sn({
2812
2884
  apiBase: this.config.apiBase,
2813
2885
  apiKey: this.config.apiKey,
2814
2886
  projectId: this.config.projectId,
2815
2887
  bugId: e,
2816
2888
  reporterEmail: n || ((a = this.config.user) == null ? void 0 : a.email),
2817
- reporterName: o || ((s = this.config.user) == null ? void 0 : s.name),
2889
+ reporterName: i || ((s = this.config.user) == null ? void 0 : s.name),
2818
2890
  metadata: {
2819
- ...i,
2891
+ ...o,
2820
2892
  user: this.config.user || void 0,
2821
2893
  ...Object.keys(this.context).length ? { context: this.context } : {},
2822
- sdk: K
2894
+ sdk: D
2823
2895
  },
2824
2896
  logs: {
2825
2897
  console: { entries: this.consoleBuffer.all() },
@@ -2835,7 +2907,7 @@ class it {
2835
2907
  context: { ...this.context },
2836
2908
  console: this.consoleBuffer.all(),
2837
2909
  network: this.networkBuffer.all(),
2838
- environment: Le()
2910
+ environment: _e()
2839
2911
  };
2840
2912
  }
2841
2913
  clear() {
@@ -2851,12 +2923,12 @@ class it {
2851
2923
  }), this.teardown = [], this.notifier = null, this.started = !1;
2852
2924
  }
2853
2925
  }
2854
- m = new WeakSet(), /** Call a host callback without letting it break the SDK. */
2855
- P = function(e, n) {
2856
- const o = this.config[e];
2857
- if (typeof o == "function")
2926
+ w = new WeakSet(), /** Call a host callback without letting it break the SDK. */
2927
+ F = function(e, n) {
2928
+ const i = this.config[e];
2929
+ if (typeof i == "function")
2858
2930
  try {
2859
- o(n);
2931
+ i(n);
2860
2932
  } catch (r) {
2861
2933
  console.error(`[BugCatch] your ${e} callback threw:`, r);
2862
2934
  }
@@ -2870,14 +2942,14 @@ P = function(e, n) {
2870
2942
  * version string and four booleans. Every failure is silent — this must
2871
2943
  * never cost a page anything but one small request a day.
2872
2944
  */
2873
- rt = function() {
2945
+ ft = function() {
2874
2946
  if (typeof window > "u" || typeof fetch != "function") return;
2875
2947
  const e = `bugcatch:hello:${this.config.projectId}`, n = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2876
2948
  try {
2877
2949
  if (window.localStorage.getItem(e) === n) return;
2878
2950
  } catch {
2879
2951
  }
2880
- const o = setTimeout(() => {
2952
+ const i = setTimeout(() => {
2881
2953
  try {
2882
2954
  window.localStorage.setItem(e, n);
2883
2955
  } catch {
@@ -2888,7 +2960,7 @@ rt = function() {
2888
2960
  headers: { "Content-Type": "application/json", "X-BugCatch-Key": this.config.apiKey },
2889
2961
  body: JSON.stringify({
2890
2962
  projectId: this.config.projectId,
2891
- version: K.version,
2963
+ version: D.version,
2892
2964
  identify: !!this.config.user,
2893
2965
  context: !!(this.context && Object.keys(this.context).length),
2894
2966
  widget: !!this.config.widget,
@@ -2898,7 +2970,7 @@ rt = function() {
2898
2970
  }).catch(() => {
2899
2971
  });
2900
2972
  }, 5e3);
2901
- this.teardown.push(() => clearTimeout(o));
2973
+ this.teardown.push(() => clearTimeout(i));
2902
2974
  }, /**
2903
2975
  * Redraw the built-in notifications, and tell anyone counting.
2904
2976
  *
@@ -2906,12 +2978,12 @@ rt = function() {
2906
2978
  * here, so the cards on screen and a host app's own badge cannot disagree
2907
2979
  * about what is outstanding.
2908
2980
  */
2909
- O = function() {
2910
- const e = N();
2981
+ R = function() {
2982
+ const e = H();
2911
2983
  if (this.emit("unread", { count: e.length, updates: e }), !!this.config.updateToast) {
2912
2984
  if (!this.notifier) {
2913
2985
  if (!e.length) return;
2914
- this.notifier = pn({
2986
+ this.notifier = vn({
2915
2987
  accent: this.config.accent,
2916
2988
  position: this.config.widgetPosition,
2917
2989
  onRead: (n) => this.markUpdateRead(n),
@@ -2938,35 +3010,35 @@ O = function() {
2938
3010
  * myReport(). The first sighting counts as a change: a host that has just
2939
3011
  * opened a report wants to know it is being analysed.
2940
3012
  */
2941
- at = function(e, n) {
2942
- const o = n == null ? void 0 : n.phase;
2943
- if (!e || typeof o != "string" || this.phases.get(e) === o) return;
2944
- this.phases.set(e, o);
2945
- const r = { bugId: e, phase: o, title: n.title ?? null, detail: n.detail ?? null };
2946
- this.debugLog("assistant", r), x(this, m, P).call(this, "onAssistantPhase", r), this.emit("assistant", r);
3013
+ pt = function(e, n) {
3014
+ const i = n == null ? void 0 : n.phase;
3015
+ if (!e || typeof i != "string" || this.phases.get(e) === i) return;
3016
+ this.phases.set(e, i);
3017
+ const r = { bugId: e, phase: i, title: n.title ?? null, detail: n.detail ?? null };
3018
+ this.debugLog("assistant", r), x(this, w, F).call(this, "onAssistantPhase", r), this.emit("assistant", r);
2947
3019
  }, /** A report was accepted: tell the host app, however it was filed. */
2948
- re = function(e, { title: n, via: o }) {
3020
+ de = function(e, { title: n, via: i }) {
2949
3021
  if (!(e != null && e.id)) return;
2950
- const r = { bugId: e.id, title: n ?? null, via: o, result: e };
2951
- this.debugLog("report accepted", r), x(this, m, P).call(this, "onReportSubmitted", r), this.emit("report", r);
3022
+ const r = { bugId: e.id, title: n ?? null, via: i, result: e };
3023
+ this.debugLog("report accepted", r), x(this, w, F).call(this, "onReportSubmitted", r), this.emit("report", r);
2952
3024
  }, /** Something done on the page's behalf failed. */
2953
- H = function(e, n) {
2954
- x(this, m, P).call(this, "onError", { action: e, error: n }), this.emit("error", { action: e, error: n });
2955
- }, z = async function({ title: e, description: n = "", priority: o = "MEDIUM", metadata: r = {}, media: i = [], references: a = [], context: s = null, issue: c = null }) {
2956
- var f, p;
2957
- const l = s ? $e(this.context, s, (d) => this.warn(d.replace("setContext()", "report({ context })"))) : this.context;
3025
+ X = function(e, n) {
3026
+ x(this, w, F).call(this, "onError", { action: e, error: n }), this.emit("error", { action: e, error: n });
3027
+ }, W = async function({ title: e, description: n = "", priority: i = "MEDIUM", metadata: r = {}, media: o = [], references: a = [], context: s = null, issue: c = null }) {
3028
+ var h, f;
3029
+ const l = s ? Le(this.context, s, (d) => this.warn(d.replace("setContext()", "report({ context })"))) : this.context;
2958
3030
  return {
2959
3031
  projectId: this.config.projectId,
2960
3032
  ...e ? { title: e } : {},
2961
3033
  description: n,
2962
- priority: o,
3034
+ priority: i,
2963
3035
  url: window.location.href,
2964
- reporterEmail: (f = this.config.user) == null ? void 0 : f.email,
3036
+ reporterEmail: (h = this.config.user) == null ? void 0 : h.email,
2965
3037
  // Sent alongside the address so the dashboard can show a person rather
2966
3038
  // than a mailbox, and so the resolution email can open with their name.
2967
- reporterName: (p = this.config.user) == null ? void 0 : p.name,
3039
+ reporterName: (f = this.config.user) == null ? void 0 : f.name,
2968
3040
  metadata: {
2969
- ...await me(),
3041
+ ...await ve(),
2970
3042
  release: this.config.release,
2971
3043
  environment: this.config.environment,
2972
3044
  buildId: this.config.buildId,
@@ -2978,7 +3050,7 @@ H = function(e, n) {
2978
3050
  // The screen the report came from — setContext(). Its identifiers
2979
3051
  // outrank the same kind on `user`.
2980
3052
  ...Object.keys(l).length ? { context: l } : {},
2981
- sdk: K
3053
+ sdk: D
2982
3054
  },
2983
3055
  logs: {
2984
3056
  console: { entries: this.consoleBuffer.all() },
@@ -2986,7 +3058,7 @@ H = function(e, n) {
2986
3058
  },
2987
3059
  // Omitted rather than sent empty: the field is optional server-side, and
2988
3060
  // an empty array in every payload makes beforeSend hooks harder to read.
2989
- ...i.length ? { attachments: i } : {},
3061
+ ...o.length ? { attachments: o } : {},
2990
3062
  // What the reporter answered when asked which record this is about. Only
2991
3063
  // ever what they typed into the box — never what this browser matched in
2992
3064
  // their own text, which the API reads for itself out of the title and
@@ -3017,22 +3089,22 @@ H = function(e, n) {
3017
3089
  *
3018
3090
  * Returns the payload to send, or false when the host cancelled.
3019
3091
  */
3020
- ae = function(e) {
3092
+ he = function(e) {
3021
3093
  if (typeof this.config.beforeSend != "function") return e;
3022
3094
  let n;
3023
3095
  try {
3024
3096
  n = this.config.beforeSend(e);
3025
- } catch (o) {
3026
- return this.warn(`beforeSend threw, so nothing was sent: ${(o == null ? void 0 : o.message) || o}`), !1;
3097
+ } catch (i) {
3098
+ return this.warn(`beforeSend threw, so nothing was sent: ${(i == null ? void 0 : i.message) || i}`), !1;
3027
3099
  }
3028
3100
  return n === !1 ? !1 : n && typeof n == "object" ? n : e;
3029
- }, st = async function() {
3030
- const e = j(this.config.projectId), n = x(this, m, ae).call(this, await x(this, m, z).call(this, {}));
3101
+ }, gt = async function() {
3102
+ const e = M(this.config.projectId), n = x(this, w, he).call(this, await x(this, w, W).call(this, {}));
3031
3103
  if (n === !1)
3032
3104
  return this.debugLog("call cancelled by beforeSend"), { cancelled: !0 };
3033
- let o;
3105
+ let i;
3034
3106
  try {
3035
- o = await on({
3107
+ i = await hn({
3036
3108
  apiBase: this.config.apiBase,
3037
3109
  apiKey: this.config.apiKey,
3038
3110
  token: e == null ? void 0 : e.token,
@@ -3042,32 +3114,32 @@ ae = function(e) {
3042
3114
  watchToken: E()
3043
3115
  });
3044
3116
  } catch (r) {
3045
- throw r.status === 401 && e && ne(this.config.projectId), x(this, m, H).call(this, "call", r), r;
3117
+ throw r.status === 401 && e && ce(this.config.projectId), x(this, w, X).call(this, "call", r), r;
3046
3118
  }
3047
- return x(this, m, re).call(this, o, { title: null, via: "call" }), o.watchToken && (te(o.watchToken), this.config.updates && this.startWatching()), o;
3048
- }, ct = async function(e) {
3049
- const { joinLiveCall: n, liveCallSupported: o, openMicrophone: r } = await _(this.config.chunkBase);
3050
- if (!o())
3119
+ return x(this, w, de).call(this, i, { title: null, via: "call" }), i.watchToken && (se(i.watchToken), this.config.updates && this.startWatching()), i;
3120
+ }, mt = async function(e) {
3121
+ const { joinLiveCall: n, liveCallSupported: i, openMicrophone: r } = await q(this.config.chunkBase);
3122
+ if (!i())
3051
3123
  throw new Error("[BugCatch] this browser cannot make live calls.");
3052
- const i = await r();
3124
+ const o = await r();
3053
3125
  let a, s = null;
3054
3126
  try {
3055
3127
  if (e)
3056
- a = await rn({ apiBase: this.config.apiBase, bugId: e });
3057
- else if (s = await x(this, m, st).call(this), e = s.id, a = s.live_call, !(a != null && a.realtime_url)) {
3128
+ a = await fn({ apiBase: this.config.apiBase, bugId: e });
3129
+ else if (s = await x(this, w, gt).call(this), e = s.id, a = s.live_call, !(a != null && a.realtime_url)) {
3058
3130
  const l = new Error(`[BugCatch] the report was filed, but the team could not be rung${s.call_error ? `: ${s.call_error}` : "."}`);
3059
3131
  throw l.filed = s, l.reason = s.call_error || null, l;
3060
3132
  }
3061
3133
  } catch (l) {
3062
- for (const f of i.getTracks()) f.stop();
3134
+ for (const h of o.getTracks()) h.stop();
3063
3135
  throw l;
3064
3136
  }
3065
3137
  const c = await n({
3066
3138
  realtimeUrl: a.realtime_url,
3067
- stream: i,
3139
+ stream: o,
3068
3140
  ringsUntil: a.rings_until,
3069
- onState: (l, f) => {
3070
- (l === "ended" || l === "failed" || l === "missed") && (this.call = null), l === "missed" && an({ apiBase: this.config.apiBase, bugId: e, callId: a.call_id }), typeof this.config.onCallState == "function" && this.config.onCallState(l, { bugId: e, live: !0, ...f }), this.emit("call", { bugId: e, live: !0, state: l, ...f });
3141
+ onState: (l, h) => {
3142
+ (l === "ended" || l === "failed" || l === "missed") && (this.call = null), l === "missed" && pn({ apiBase: this.config.apiBase, bugId: e, callId: a.call_id }), typeof this.config.onCallState == "function" && this.config.onCallState(l, { bugId: e, live: !0, ...h }), this.emit("call", { bugId: e, live: !0, state: l, ...h });
3071
3143
  }
3072
3144
  });
3073
3145
  return this.call = c, Object.assign(c, {
@@ -3092,27 +3164,27 @@ ae = function(e) {
3092
3164
  * said `voice: false` has said its customers are not to be rung, and a card
3093
3165
  * offering a call this page could not join would be worse than none.
3094
3166
  */
3095
- lt = function(e) {
3167
+ wt = function(e) {
3096
3168
  var r;
3097
3169
  const n = e.incomingCall;
3098
3170
  if (!this.config.voice || ((r = this.ringing) == null ? void 0 : r.callId) === n.callId || this.call || this.callStarting) return;
3099
- x(this, m, F).call(this);
3100
- const o = { callId: n.callId, dismiss: () => {
3171
+ x(this, w, J).call(this);
3172
+ const i = { callId: n.callId, dismiss: () => {
3101
3173
  } };
3102
- this.ringing = o, _(this.config.chunkBase).then(({ liveCallSupported: i, showIncomingCall: a }) => {
3103
- if (this.ringing !== o || (this.ringing = null, !i()) || this.call || this.callStarting) return;
3174
+ this.ringing = i, q(this.config.chunkBase).then(({ liveCallSupported: o, showIncomingCall: a }) => {
3175
+ if (this.ringing !== i || (this.ringing = null, !o()) || this.call || this.callStarting) return;
3104
3176
  const s = a({
3105
3177
  call: n,
3106
3178
  accent: this.config.accent,
3107
3179
  position: this.config.widgetPosition,
3108
3180
  // Whether the page has been touched, which is when the card may ring
3109
3181
  // out loud — tracked since load, which the card's own code cannot be.
3110
- touched: Bn,
3182
+ touched: Ln,
3111
3183
  onAnswer: () => {
3112
- x(this, m, ut).call(this, e.bugId, n);
3184
+ x(this, w, yt).call(this, e.bugId, n);
3113
3185
  },
3114
3186
  onDecline: () => {
3115
- this.ringing = null, Se({
3187
+ this.ringing = null, je({
3116
3188
  apiBase: this.config.apiBase,
3117
3189
  bugId: e.bugId,
3118
3190
  callId: n.callId
@@ -3133,10 +3205,10 @@ lt = function(e) {
3133
3205
  }
3134
3206
  this.emit("incoming-call", { bugId: e.bugId, callId: n.callId, state: "ringing" });
3135
3207
  }, () => {
3136
- this.ringing === o && (this.ringing = null);
3208
+ this.ringing === i && (this.ringing = null);
3137
3209
  });
3138
3210
  }, /** Take the card away, whatever it is showing. */
3139
- F = function(e) {
3211
+ J = function(e) {
3140
3212
  if (this.ringing && !(e && this.ringing.callId !== e)) {
3141
3213
  try {
3142
3214
  this.ringing.dismiss();
@@ -3144,33 +3216,33 @@ F = function(e) {
3144
3216
  }
3145
3217
  this.ringing = null;
3146
3218
  }
3147
- }, ut = async function(e, n) {
3219
+ }, yt = async function(e, n) {
3148
3220
  if (this.ringing = null, this.call || this.callStarting) return;
3149
3221
  this.callStarting = !0;
3150
- let o, r;
3222
+ let i, r;
3151
3223
  try {
3152
- const a = await _(this.config.chunkBase);
3153
- r = a.joinLiveCall, o = await a.openMicrophone();
3224
+ const a = await q(this.config.chunkBase);
3225
+ r = a.joinLiveCall, i = await a.openMicrophone();
3154
3226
  } catch (a) {
3155
- this.callStarting = !1, Se({ apiBase: this.config.apiBase, bugId: e, callId: n.callId }), this.emit("incoming-call", { bugId: e, callId: n.callId, state: "failed", error: a });
3227
+ this.callStarting = !1, je({ apiBase: this.config.apiBase, bugId: e, callId: n.callId }), this.emit("incoming-call", { bugId: e, callId: n.callId, state: "failed", error: a });
3156
3228
  return;
3157
3229
  }
3158
- let i;
3230
+ let o;
3159
3231
  try {
3160
- i = await sn({
3232
+ o = await gn({
3161
3233
  apiBase: this.config.apiBase,
3162
3234
  bugId: e,
3163
3235
  callId: n.callId
3164
3236
  });
3165
3237
  } catch (a) {
3166
- for (const s of o.getTracks()) s.stop();
3238
+ for (const s of i.getTracks()) s.stop();
3167
3239
  this.callStarting = !1, this.emit("incoming-call", { bugId: e, callId: n.callId, state: "missed", error: a });
3168
3240
  return;
3169
3241
  }
3170
3242
  try {
3171
3243
  const a = await r({
3172
- realtimeUrl: i.realtime_url,
3173
- stream: o,
3244
+ realtimeUrl: o.realtime_url,
3245
+ stream: i,
3174
3246
  // No deadline on this side. The ringing is over — it ended when this
3175
3247
  // browser claimed the call — and a countdown here would hang up on a
3176
3248
  // conversation that has already started.
@@ -3180,35 +3252,41 @@ F = function(e) {
3180
3252
  });
3181
3253
  this.call = a, this.emit("incoming-call", { bugId: e, callId: n.callId, state: "answered" });
3182
3254
  } catch (a) {
3183
- for (const s of o.getTracks()) s.stop();
3255
+ for (const s of i.getTracks()) s.stop();
3184
3256
  this.emit("incoming-call", { bugId: e, callId: n.callId, state: "failed", error: a });
3185
3257
  } finally {
3186
3258
  this.callStarting = !1;
3187
3259
  }
3188
3260
  };
3189
- const dt = new it();
3190
- dt.Client = it;
3191
- dt.version = K.version;
3261
+ const bt = new ht();
3262
+ bt.Client = ht;
3263
+ bt.version = D.version;
3192
3264
  export {
3193
- dt as B,
3194
- ke as R,
3195
- fo as S,
3196
- zt as U,
3197
- io as a,
3198
- ao as b,
3199
- Ue as c,
3200
- so as d,
3201
- uo as e,
3202
- Ke as f,
3203
- At as g,
3204
- lo as h,
3205
- Mt as i,
3206
- oo as j,
3207
- co as k,
3208
- Ct as l,
3209
- ee as n,
3210
- ho as r,
3211
- ro as s,
3212
- An as v
3265
+ bt as B,
3266
+ Je as I,
3267
+ re as P,
3268
+ $e as R,
3269
+ vi as S,
3270
+ Zt as U,
3271
+ Kt as a,
3272
+ gi as b,
3273
+ qe as c,
3274
+ pi as d,
3275
+ mi as e,
3276
+ wi as f,
3277
+ xi as g,
3278
+ bi as h,
3279
+ ze as i,
3280
+ Nt as j,
3281
+ Dt as k,
3282
+ fi as l,
3283
+ Lt as m,
3284
+ ae as n,
3285
+ yi as o,
3286
+ hi as p,
3287
+ Ye as q,
3288
+ ki as r,
3289
+ Rt as s,
3290
+ Pn as v
3213
3291
  };
3214
3292
  //# sourceMappingURL=bugcatch-core.es.js.map