glitchgrab 1.42.0 → 1.43.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.
package/dist/index.js CHANGED
@@ -68,7 +68,7 @@ __export(index_exports, {
68
68
  module.exports = __toCommonJS(index_exports);
69
69
 
70
70
  // src/provider.tsx
71
- var import_react5 = require("react");
71
+ var import_react6 = require("react");
72
72
 
73
73
  // src/error-boundary.tsx
74
74
  var React = __toESM(require("react"));
@@ -186,21 +186,84 @@ function interceptConsole() {
186
186
  origError.apply(console, args);
187
187
  };
188
188
  }
189
+ var CONSOLE_TEXT_MAX = 200;
189
190
  function argsToString(args) {
190
191
  try {
191
192
  return args.map((a) => {
192
- if (typeof a === "string") return a;
193
+ if (typeof a === "string") return a.slice(0, CONSOLE_TEXT_MAX);
193
194
  if (a instanceof Error) return a.message;
194
195
  try {
195
- return JSON.stringify(a);
196
+ return previewJson(a, CONSOLE_TEXT_MAX);
196
197
  } catch (e) {
197
198
  return String(a);
198
199
  }
199
- }).join(" ").slice(0, 200);
200
+ }).join(" ").slice(0, CONSOLE_TEXT_MAX);
200
201
  } catch (e) {
201
202
  return "[unknown]";
202
203
  }
203
204
  }
205
+ function previewJson(value, max) {
206
+ let out = "";
207
+ const path = /* @__PURE__ */ new WeakSet();
208
+ const write = (input, inArray) => {
209
+ if (out.length > max) return;
210
+ let v = input;
211
+ if (v !== null && typeof v === "object" && typeof v.toJSON === "function") {
212
+ v = v.toJSON();
213
+ }
214
+ if (v === null) {
215
+ out += "null";
216
+ return;
217
+ }
218
+ switch (typeof v) {
219
+ case "string":
220
+ out += JSON.stringify(v.length > max ? v.slice(0, max) : v);
221
+ return;
222
+ case "number":
223
+ out += Number.isFinite(v) ? String(v) : "null";
224
+ return;
225
+ case "boolean":
226
+ case "bigint":
227
+ out += String(v);
228
+ return;
229
+ case "object":
230
+ break;
231
+ default:
232
+ if (inArray) out += "null";
233
+ return;
234
+ }
235
+ const obj = v;
236
+ if (path.has(obj)) {
237
+ out += '"[Circular]"';
238
+ return;
239
+ }
240
+ path.add(obj);
241
+ if (Array.isArray(obj)) {
242
+ out += "[";
243
+ for (let i = 0; i < obj.length && out.length <= max; i++) {
244
+ if (i > 0) out += ",";
245
+ write(obj[i], true);
246
+ }
247
+ out += "]";
248
+ } else {
249
+ out += "{";
250
+ let first = true;
251
+ for (const key in obj) {
252
+ if (out.length > max) break;
253
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
254
+ const child = obj[key];
255
+ if (child === void 0 || typeof child === "function" || typeof child === "symbol") continue;
256
+ out += `${first ? "" : ","}${JSON.stringify(key)}:`;
257
+ first = false;
258
+ write(child, false);
259
+ }
260
+ out += "}";
261
+ }
262
+ path.delete(obj);
263
+ };
264
+ write(value, false);
265
+ return out;
266
+ }
204
267
  async function readErrorBody(response, url) {
205
268
  try {
206
269
  if (response.ok) return "";
@@ -317,15 +380,27 @@ function interceptNavigation() {
317
380
  addBreadcrumb("navigation", `Back/Forward to ${window.location.pathname}`);
318
381
  });
319
382
  }
383
+ var CLICK_TEXT_MAX = 50;
384
+ var CLICK_TEXT_NODE_LIMIT = 500;
385
+ function leadingText(el, max) {
386
+ var _a;
387
+ let text = "";
388
+ let visited = 0;
389
+ const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
390
+ while (text.trimStart().length < max && visited++ < CLICK_TEXT_NODE_LIMIT && walker.nextNode()) {
391
+ text += (_a = walker.currentNode.nodeValue) != null ? _a : "";
392
+ }
393
+ return text.trim().slice(0, max);
394
+ }
320
395
  function interceptClicks() {
321
396
  document.addEventListener(
322
397
  "click",
323
398
  (e) => {
324
- var _a, _b, _c;
399
+ var _a;
325
400
  try {
326
401
  const target = e.target;
327
402
  const tag = (_a = target.tagName) == null ? void 0 : _a.toLowerCase();
328
- const text = (_c = (_b = target.textContent) == null ? void 0 : _b.trim().slice(0, 50)) != null ? _c : "";
403
+ const text = target instanceof Node ? leadingText(target, CLICK_TEXT_MAX) : "";
329
404
  const id = target.id ? `#${target.id}` : "";
330
405
  const cls = target.className && typeof target.className === "string" ? `.${target.className.split(" ")[0]}` : "";
331
406
  addBreadcrumb("click", `Click ${tag}${id}${cls} "${text}"`);
@@ -647,7 +722,7 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
647
722
  }
648
723
  }
649
724
  async function assistTurn(params, token, baseUrl) {
650
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
725
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
651
726
  const offline = {
652
727
  conversationId: null,
653
728
  question: null,
@@ -680,6 +755,7 @@ async function assistTurn(params, token, baseUrl) {
680
755
  report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
681
756
  duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
682
757
  solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
758
+ aboutGlitchgrab: ((_n = envelope.data) == null ? void 0 : _n.aboutGlitchgrab) === true,
683
759
  degraded: null
684
760
  };
685
761
  } catch (e) {
@@ -900,7 +976,10 @@ var import_jsx_runtime = require("react/jsx-runtime");
900
976
  var import_react3 = require("react");
901
977
  var import_react_dom2 = require("react-dom");
902
978
  var import_jsx_runtime2 = require("react/jsx-runtime");
979
+ var import_react4 = require("react");
980
+ var import_react_dom3 = require("react-dom");
903
981
  var import_jsx_runtime3 = require("react/jsx-runtime");
982
+ var import_jsx_runtime4 = require("react/jsx-runtime");
904
983
  var MAX_SCREENSHOT_DATA_URL_LENGTH = 18e5;
905
984
  var QUALITY_LADDER = [0.92, 0.85, 0.75];
906
985
  var DOWNSCALE_FACTOR = 0.7;
@@ -1392,7 +1471,8 @@ function AssistSheet({
1392
1471
  onSend,
1393
1472
  onDegrade,
1394
1473
  onClose,
1395
- onFinish
1474
+ onFinish,
1475
+ onReportGlitchgrabProblem
1396
1476
  }) {
1397
1477
  const narrow = useIsNarrow();
1398
1478
  const severityAsked = showSeverity && currentTile === "BUG";
@@ -1403,6 +1483,7 @@ function AssistSheet({
1403
1483
  const [hoveredStar, setHoveredStar] = (0, import_react3.useState)(0);
1404
1484
  const [options, setOptions] = (0, import_react3.useState)([]);
1405
1485
  const [duplicate, setDuplicate] = (0, import_react3.useState)(null);
1486
+ const [glitchgrabOffer, setGlitchgrabOffer] = (0, import_react3.useState)(false);
1406
1487
  const [solved, setSolved] = (0, import_react3.useState)(null);
1407
1488
  const [phase, setPhase] = (0, import_react3.useState)(
1408
1489
  !typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
@@ -1470,7 +1551,10 @@ function AssistSheet({
1470
1551
  screenshots: sent,
1471
1552
  context: {
1472
1553
  ...context != null ? context : {},
1473
- imageSources: sent.map((shot) => pageShot && shot === pageShot ? "page" : "attached")
1554
+ imageSources: sent.map((shot) => pageShot && shot === pageShot ? "page" : "attached"),
1555
+ // Whether this dialog can open the #366 panel at all. A hint — the
1556
+ // server decides whether the model may offer it.
1557
+ canReportGlitchgrab: !!onReportGlitchgrabProblem
1474
1558
  },
1475
1559
  events
1476
1560
  });
@@ -1493,6 +1577,7 @@ function AssistSheet({
1493
1577
  }
1494
1578
  setDuplicate((_a = result.duplicate) != null ? _a : null);
1495
1579
  onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
1580
+ setGlitchgrabOffer(!!result.aboutGlitchgrab && !!onReportGlitchgrabProblem && !!result.question);
1496
1581
  if (result.solved) {
1497
1582
  setSolved(result.solved);
1498
1583
  setOptions([]);
@@ -1529,6 +1614,7 @@ function AssistSheet({
1529
1614
  const value = text.trim();
1530
1615
  if (!value || busy) return;
1531
1616
  setOptions([]);
1617
+ setGlitchgrabOffer(false);
1532
1618
  const underDraft = phase === "draft";
1533
1619
  if (underDraft) {
1534
1620
  const edited = aiDraftRef.current !== null && description.trim() !== aiDraftRef.current.trim();
@@ -2086,7 +2172,82 @@ function AssistSheet({
2086
2172
  );
2087
2173
  }),
2088
2174
  duplicate && !busy && phase === "chat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: renderKnownIssue({ title: false }) }),
2089
- options.length > 0 && !busy && phase === "chat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2175
+ glitchgrabOffer && onReportGlitchgrabProblem && !busy && phase === "chat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2176
+ "div",
2177
+ {
2178
+ "data-gg-glitchgrab-offer": "",
2179
+ style: {
2180
+ display: "flex",
2181
+ flexDirection: "column",
2182
+ gap: "8px",
2183
+ padding: "10px",
2184
+ borderRadius: "8px",
2185
+ border: `1px solid ${t2.accent}55`,
2186
+ backgroundColor: `${t2.accent}14`,
2187
+ fontSize: "12px",
2188
+ lineHeight: 1.5
2189
+ },
2190
+ children: [
2191
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.text, fontWeight: 600 }, children: "This is about Glitchgrab, not this app" }),
2192
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted }, children: "It goes to the team that builds this reporter, with your chat attached." }),
2193
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px" }, children: [
2194
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2195
+ "button",
2196
+ {
2197
+ type: "button",
2198
+ "data-gg-glitchgrab-offer-send": "",
2199
+ onClick: () => {
2200
+ logEvent("glitchgrab_offer_tap");
2201
+ setGlitchgrabOffer(false);
2202
+ onReportGlitchgrabProblem(
2203
+ messages.filter((m) => m.role === "user").map((m) => m.content.trim()).filter(Boolean).join("\n\n")
2204
+ );
2205
+ },
2206
+ style: {
2207
+ padding: "8px 12px",
2208
+ borderRadius: "999px",
2209
+ border: "none",
2210
+ backgroundColor: t2.accent,
2211
+ color: t2.accentText,
2212
+ fontSize: "12px",
2213
+ fontWeight: 700,
2214
+ fontFamily: "inherit",
2215
+ cursor: "pointer",
2216
+ // Both stretch, so on a phone each wrapped line reads as
2217
+ // a choice rather than one button left stranded.
2218
+ flex: "1 1 auto"
2219
+ },
2220
+ children: "Send to the Glitchgrab team"
2221
+ }
2222
+ ),
2223
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2224
+ "button",
2225
+ {
2226
+ type: "button",
2227
+ "data-gg-glitchgrab-offer-no": "",
2228
+ onClick: () => {
2229
+ logEvent("glitchgrab_offer_declined");
2230
+ send("No \u2014 it's about this app, not the reporting tool");
2231
+ },
2232
+ style: {
2233
+ padding: "8px 12px",
2234
+ borderRadius: "999px",
2235
+ border: `1px solid ${t2.inputBorder}`,
2236
+ background: "transparent",
2237
+ color: t2.textMuted,
2238
+ fontSize: "12px",
2239
+ fontFamily: "inherit",
2240
+ cursor: "pointer",
2241
+ flex: "1 1 auto"
2242
+ },
2243
+ children: "No, it's about this app"
2244
+ }
2245
+ )
2246
+ ] })
2247
+ ]
2248
+ }
2249
+ ) }),
2250
+ options.length > 0 && !busy && phase === "chat" && !glitchgrabOffer && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2090
2251
  "div",
2091
2252
  {
2092
2253
  style: {
@@ -2672,6 +2833,30 @@ function AssistSheet({
2672
2833
  },
2673
2834
  children: "Not getting it? Fill the form yourself \u2192"
2674
2835
  }
2836
+ ),
2837
+ onReportGlitchgrabProblem && phase !== "solved" && !glitchgrabOffer && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2838
+ "button",
2839
+ {
2840
+ type: "button",
2841
+ "data-gg-self-report": "",
2842
+ onClick: () => onReportGlitchgrabProblem(),
2843
+ style: {
2844
+ display: "block",
2845
+ // ~32px tap target; the negative margins keep the composer
2846
+ // from growing to make room for it.
2847
+ margin: "-2px auto -8px",
2848
+ border: "none",
2849
+ background: "transparent",
2850
+ color: t2.textMuted,
2851
+ fontSize: "11.5px",
2852
+ fontFamily: "inherit",
2853
+ padding: "10px 8px",
2854
+ cursor: "pointer",
2855
+ textDecoration: "underline",
2856
+ textUnderlineOffset: "2px"
2857
+ },
2858
+ children: "Assistant misbehaving? Tell Glitchgrab"
2859
+ }
2675
2860
  )
2676
2861
  ]
2677
2862
  }
@@ -2685,6 +2870,240 @@ function AssistSheet({
2685
2870
  document.body
2686
2871
  );
2687
2872
  }
2873
+ var FONT = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
2874
+ var FAILED = "Couldn't send it. Try again in a moment.";
2875
+ function describeSentAlong(hasChat, screenshotCount) {
2876
+ const parts = [
2877
+ ...hasChat ? ["your AI chat"] : [],
2878
+ "what you did on this page",
2879
+ ...screenshotCount > 0 ? [`${screenshotCount} screenshot${screenshotCount === 1 ? "" : "s"}`] : []
2880
+ ];
2881
+ if (parts.length === 1) return parts[0];
2882
+ return `${parts.slice(0, -1).join(", ")} and ${parts[parts.length - 1]}`;
2883
+ }
2884
+ function GlitchgrabProblemPanel({
2885
+ send,
2886
+ theme: t2,
2887
+ surface,
2888
+ conversationId,
2889
+ reportType,
2890
+ screenshots,
2891
+ initialText = "",
2892
+ onClose
2893
+ }) {
2894
+ const [text, setText] = (0, import_react4.useState)(initialText);
2895
+ const [busy, setBusy] = (0, import_react4.useState)(false);
2896
+ const [sent, setSent] = (0, import_react4.useState)(false);
2897
+ const [error, setError] = (0, import_react4.useState)(null);
2898
+ const inputRef = (0, import_react4.useRef)(null);
2899
+ (0, import_react4.useEffect)(() => {
2900
+ var _a;
2901
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
2902
+ }, []);
2903
+ (0, import_react4.useEffect)(() => {
2904
+ const onKey = (e) => {
2905
+ if (e.key !== "Escape") return;
2906
+ e.stopPropagation();
2907
+ onClose();
2908
+ };
2909
+ window.addEventListener("keydown", onKey, true);
2910
+ return () => window.removeEventListener("keydown", onKey, true);
2911
+ }, [onClose]);
2912
+ const submit = async () => {
2913
+ const description = text.trim();
2914
+ if (!description || busy) return;
2915
+ setBusy(true);
2916
+ setError(null);
2917
+ try {
2918
+ const result = await send({ description, surface, conversationId, reportType, screenshots });
2919
+ if (result == null ? void 0 : result.success) setSent(true);
2920
+ else setError((result == null ? void 0 : result.message) || FAILED);
2921
+ } catch (e) {
2922
+ setError(FAILED);
2923
+ } finally {
2924
+ setBusy(false);
2925
+ }
2926
+ };
2927
+ const canSend = !!text.trim() && !busy;
2928
+ const secondaryButton = {
2929
+ padding: "10px 14px",
2930
+ borderRadius: "8px",
2931
+ border: `1px solid ${t2.inputBorder}`,
2932
+ background: "transparent",
2933
+ color: t2.text,
2934
+ fontSize: "13px",
2935
+ fontWeight: 600,
2936
+ fontFamily: "inherit",
2937
+ cursor: "pointer"
2938
+ };
2939
+ const primaryButton = (enabled) => ({
2940
+ padding: "10px 14px",
2941
+ borderRadius: "8px",
2942
+ border: "none",
2943
+ backgroundColor: enabled ? t2.accent : t2.bgSecondary,
2944
+ color: enabled ? t2.accentText : t2.textMuted,
2945
+ fontSize: "13px",
2946
+ fontWeight: 700,
2947
+ fontFamily: "inherit",
2948
+ cursor: enabled ? "pointer" : "default"
2949
+ });
2950
+ return (0, import_react_dom3.createPortal)(
2951
+ // No close on backdrop click: a stray click would throw away what they typed.
2952
+ // `data-glitchgrab-layer` exempts this from the dialog's anti-focus-trap
2953
+ // sweep, which sets `inert` on every other role="dialog" on the page —
2954
+ // without it the panel renders but cannot be typed into.
2955
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2956
+ "div",
2957
+ {
2958
+ "data-glitchgrab-layer": "",
2959
+ "data-gg-self-report-panel": "",
2960
+ role: "dialog",
2961
+ "aria-modal": "true",
2962
+ "aria-labelledby": "gg-self-report-title",
2963
+ style: {
2964
+ position: "fixed",
2965
+ inset: 0,
2966
+ zIndex: 2147483647,
2967
+ backgroundColor: "rgba(0,0,0,0.55)",
2968
+ display: "flex",
2969
+ alignItems: "center",
2970
+ justifyContent: "center",
2971
+ padding: "16px",
2972
+ boxSizing: "border-box",
2973
+ fontFamily: FONT
2974
+ },
2975
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2976
+ "div",
2977
+ {
2978
+ style: {
2979
+ width: "100%",
2980
+ maxWidth: "420px",
2981
+ boxSizing: "border-box",
2982
+ backgroundColor: t2.bg,
2983
+ color: t2.text,
2984
+ border: `1px solid ${t2.border}`,
2985
+ borderRadius: "12px",
2986
+ boxShadow: "0 20px 50px rgba(0,0,0,0.5)",
2987
+ padding: "18px"
2988
+ },
2989
+ children: sent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2990
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { id: "gg-self-report-title", style: { fontSize: "15px", fontWeight: 600 }, children: "Sent to the Glitchgrab team" }),
2991
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "6px 0 16px", fontSize: "13px", lineHeight: 1.5, color: t2.textMuted }, children: "Thanks \u2014 we'll look into it. Your report is still open behind this, exactly as you left it." }),
2992
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2993
+ "button",
2994
+ {
2995
+ type: "button",
2996
+ "data-gg-self-report-done": "",
2997
+ onClick: onClose,
2998
+ style: { ...primaryButton(true), width: "100%" },
2999
+ children: "Back to your report"
3000
+ }
3001
+ )
3002
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
3003
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3004
+ "div",
3005
+ {
3006
+ style: {
3007
+ display: "flex",
3008
+ alignItems: "flex-start",
3009
+ justifyContent: "space-between",
3010
+ gap: "12px"
3011
+ },
3012
+ children: [
3013
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { id: "gg-self-report-title", style: { fontSize: "15px", fontWeight: 600 }, children: "Problem with Glitchgrab?" }),
3014
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3015
+ "button",
3016
+ {
3017
+ type: "button",
3018
+ onClick: onClose,
3019
+ "aria-label": "Close",
3020
+ style: {
3021
+ border: "none",
3022
+ background: "transparent",
3023
+ color: t2.textMuted,
3024
+ fontSize: "18px",
3025
+ lineHeight: 1,
3026
+ cursor: "pointer",
3027
+ padding: "4px 6px",
3028
+ margin: "-4px -6px 0 0"
3029
+ },
3030
+ children: "\xD7"
3031
+ }
3032
+ )
3033
+ ]
3034
+ }
3035
+ ),
3036
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "6px 0 12px", fontSize: "13px", lineHeight: 1.5, color: t2.textMuted }, children: "This goes to the people who build this reporter \u2014 not to this project's team. Tell us what went wrong: the AI chat, a button, anything." }),
3037
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3038
+ "textarea",
3039
+ {
3040
+ ref: inputRef,
3041
+ "data-gg-self-report-input": "",
3042
+ value: text,
3043
+ onChange: (e) => {
3044
+ setText(e.target.value);
3045
+ if (error) setError(null);
3046
+ },
3047
+ onKeyDown: (e) => {
3048
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
3049
+ e.preventDefault();
3050
+ void submit();
3051
+ }
3052
+ },
3053
+ rows: 4,
3054
+ placeholder: "e.g. The assistant kept asking the same question and never wrote a draft",
3055
+ style: {
3056
+ width: "100%",
3057
+ boxSizing: "border-box",
3058
+ resize: "vertical",
3059
+ padding: "10px 12px",
3060
+ borderRadius: "8px",
3061
+ border: `1px solid ${t2.inputBorder}`,
3062
+ backgroundColor: t2.inputBg,
3063
+ color: t2.text,
3064
+ fontSize: "14px",
3065
+ lineHeight: 1.45,
3066
+ fontFamily: "inherit",
3067
+ outline: "none"
3068
+ }
3069
+ }
3070
+ ),
3071
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3072
+ "p",
3073
+ {
3074
+ "data-gg-self-report-includes": "",
3075
+ style: { margin: "8px 0 0", fontSize: "11.5px", lineHeight: 1.45, color: t2.textMuted },
3076
+ children: [
3077
+ "Also sent, so we can see what happened:",
3078
+ " ",
3079
+ describeSentAlong(conversationId !== null, screenshots.length),
3080
+ "."
3081
+ ]
3082
+ }
3083
+ ),
3084
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { role: "alert", style: { margin: "8px 0 0", fontSize: "12px", color: "#ef4444" }, children: error }),
3085
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: "8px", marginTop: "14px" }, children: [
3086
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: onClose, style: secondaryButton, children: "Cancel" }),
3087
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3088
+ "button",
3089
+ {
3090
+ type: "button",
3091
+ "data-gg-self-report-send": "",
3092
+ onClick: () => void submit(),
3093
+ disabled: !canSend,
3094
+ style: primaryButton(canSend),
3095
+ children: busy ? "Sending\u2026" : "Send to Glitchgrab"
3096
+ }
3097
+ )
3098
+ ] })
3099
+ ] })
3100
+ }
3101
+ )
3102
+ }
3103
+ ),
3104
+ document.body
3105
+ );
3106
+ }
2688
3107
  var GLITCHGRAB_SHORTCUT = "Ctrl+Shift+G";
2689
3108
  var GLITCHGRAB_SHORTCUT_MAC = "\u2318\u21E7G";
2690
3109
  function isMac() {
@@ -2732,6 +3151,7 @@ var ATTACHMENT_ACCEPT = [
2732
3151
  ].join(",");
2733
3152
  var MAX_SCALE = 2;
2734
3153
  var FRAME_TIMEOUT_MS = 3e3;
3154
+ var GRAB_TIMEOUT_MS = FRAME_TIMEOUT_MS + 2e3;
2735
3155
  function canCaptureTabPixels() {
2736
3156
  var _a;
2737
3157
  try {
@@ -2798,7 +3218,13 @@ async function captureViaTabPixels() {
2798
3218
  stream = await navigator.mediaDevices.getDisplayMedia(options);
2799
3219
  const surface = (_b = (_a = stream.getVideoTracks()[0]) == null ? void 0 : _a.getSettings()) == null ? void 0 : _b.displaySurface;
2800
3220
  if (surface && surface !== "browser") return null;
2801
- const canvas = await grabFrame(stream);
3221
+ let timer;
3222
+ const timedOut = new Promise((resolve) => {
3223
+ timer = setTimeout(() => resolve(null), GRAB_TIMEOUT_MS);
3224
+ });
3225
+ const canvas = await Promise.race([grabFrame(stream), timedOut]).finally(
3226
+ () => clearTimeout(timer)
3227
+ );
2802
3228
  return canvas ? encodeScreenshot(canvas) : null;
2803
3229
  } catch (e) {
2804
3230
  return null;
@@ -2806,6 +3232,10 @@ async function captureViaTabPixels() {
2806
3232
  stream == null ? void 0 : stream.getTracks().forEach((track) => track.stop());
2807
3233
  }
2808
3234
  }
3235
+ var IMAGE_TIMEOUT_MS = 3e3;
3236
+ function isGlitchgrabLayer(el) {
3237
+ return el.hasAttribute("data-glitchgrab-layer");
3238
+ }
2809
3239
  async function captureViaHtml2Canvas() {
2810
3240
  try {
2811
3241
  const { default: html2canvas } = await import("html2canvas-pro");
@@ -2815,6 +3245,8 @@ async function captureViaHtml2Canvas() {
2815
3245
  logging: false,
2816
3246
  useCORS: true,
2817
3247
  allowTaint: true,
3248
+ imageTimeout: IMAGE_TIMEOUT_MS,
3249
+ ignoreElements: isGlitchgrabLayer,
2818
3250
  x: window.scrollX,
2819
3251
  y: window.scrollY,
2820
3252
  width: window.innerWidth,
@@ -2827,12 +3259,40 @@ async function captureViaHtml2Canvas() {
2827
3259
  return null;
2828
3260
  }
2829
3261
  }
2830
- async function captureDefaultScreenshot() {
2831
- var _a;
2832
- return (_a = await captureViaTabPixels()) != null ? _a : await captureViaHtml2Canvas();
3262
+ var inFlight = null;
3263
+ function nextPaint() {
3264
+ return new Promise((resolve) => {
3265
+ const cap = setTimeout(resolve, 100);
3266
+ if (typeof requestAnimationFrame !== "function") return;
3267
+ requestAnimationFrame(
3268
+ () => setTimeout(() => {
3269
+ clearTimeout(cap);
3270
+ resolve();
3271
+ }, 0)
3272
+ );
3273
+ });
3274
+ }
3275
+ function captureDefaultScreenshot(options) {
3276
+ if (inFlight) return inFlight;
3277
+ inFlight = (async () => {
3278
+ const pixels = await captureViaTabPixels();
3279
+ if (pixels) return pixels;
3280
+ if (options == null ? void 0 : options.onRedraw) {
3281
+ try {
3282
+ options.onRedraw();
3283
+ } catch (e) {
3284
+ }
3285
+ await nextPaint();
3286
+ }
3287
+ return captureViaHtml2Canvas();
3288
+ })().finally(() => {
3289
+ inFlight = null;
3290
+ });
3291
+ return inFlight;
2833
3292
  }
2834
3293
  var SEVERITY_REQUIRED = "Pick how bad it is before sending.";
2835
- function useIsDark() {
3294
+ var SHOT_WAIT_MS = 3e3;
3295
+ function detectDark() {
2836
3296
  if (typeof window === "undefined") return true;
2837
3297
  try {
2838
3298
  for (const el of [document.body, document.documentElement]) {
@@ -2966,13 +3426,13 @@ function ReporterChip({
2966
3426
  const label = isAnonymous ? "Anonymous" : name;
2967
3427
  const title = isAnonymous ? "No reporter identity was passed to Glitchgrab \u2014 this report won't be attributed to anyone" : [name, reporter == null ? void 0 : reporter.email, reporter == null ? void 0 : reporter.role].filter(Boolean).join(" \xB7 ");
2968
3428
  const showAvatarImage = !!avatarUrl && !avatarFailed;
2969
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3429
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2970
3430
  "span",
2971
3431
  {
2972
3432
  title,
2973
3433
  style: { display: "flex", alignItems: "center", gap: "6px", minWidth: 0 },
2974
3434
  children: [
2975
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3435
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2976
3436
  "span",
2977
3437
  {
2978
3438
  "aria-hidden": "true",
@@ -2992,7 +3452,7 @@ function ReporterChip({
2992
3452
  color: isAnonymous ? t2.textMuted : t2.accentText,
2993
3453
  border: `1px solid ${isAnonymous ? t2.inputBorder : "transparent"}`
2994
3454
  },
2995
- children: showAvatarImage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3455
+ children: showAvatarImage ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2996
3456
  "img",
2997
3457
  {
2998
3458
  src: avatarUrl,
@@ -3002,9 +3462,9 @@ function ReporterChip({
3002
3462
  onError: () => setAvatarFailed(true),
3003
3463
  style: { width: "100%", height: "100%", objectFit: "cover" }
3004
3464
  }
3005
- ) : initials ? initials : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
3006
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
3007
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3465
+ ) : initials ? initials : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
3466
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
3467
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3008
3468
  "path",
3009
3469
  {
3010
3470
  d: "M2.75 13.5c0-2.35 2.35-3.75 5.25-3.75s5.25 1.4 5.25 3.75",
@@ -3016,7 +3476,7 @@ function ReporterChip({
3016
3476
  ] })
3017
3477
  }
3018
3478
  ),
3019
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3479
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3020
3480
  "span",
3021
3481
  {
3022
3482
  style: {
@@ -3145,13 +3605,16 @@ function ReportDialog({
3145
3605
  captureScreenshot = captureDefaultScreenshot,
3146
3606
  reporter,
3147
3607
  onClose,
3148
- headerSlot
3608
+ headerSlot,
3609
+ reportGlitchgrabProblem
3149
3610
  }) {
3150
3611
  var _a;
3151
3612
  const [isEnhancing, setIsEnhancing] = (0, import_react.useState)(false);
3152
3613
  const [assistOpen, setAssistOpen] = (0, import_react.useState)(false);
3153
3614
  const [assistNotice, setAssistNotice] = (0, import_react.useState)(null);
3154
3615
  const [assistUsed, setAssistUsed] = (0, import_react.useState)(false);
3616
+ const [selfReportFrom, setSelfReportFrom] = (0, import_react.useState)(null);
3617
+ const [selfReportPrefill, setSelfReportPrefill] = (0, import_react.useState)("");
3155
3618
  const [typeChosen, setTypeChosen] = (0, import_react.useState)(false);
3156
3619
  const [duplicateIssueNumber, setDuplicateIssueNumber] = (0, import_react.useState)(null);
3157
3620
  const [aiConversationId, setAiConversationId] = (0, import_react.useState)(null);
@@ -3173,6 +3636,9 @@ function ReportDialog({
3173
3636
  const [submitted, setSubmitted] = (0, import_react.useState)(false);
3174
3637
  const [screenshots, setScreenshots] = (0, import_react.useState)([]);
3175
3638
  const [pageShot, setPageShot] = (0, import_react.useState)(null);
3639
+ const [shotPending, setShotPending] = (0, import_react.useState)(false);
3640
+ const pendingShotRef = (0, import_react.useRef)(null);
3641
+ const openGenRef = (0, import_react.useRef)(0);
3176
3642
  const [attachments, setAttachments] = (0, import_react.useState)([]);
3177
3643
  const [previewIndex, setPreviewIndex] = (0, import_react.useState)(null);
3178
3644
  const [annotatingIndex, setAnnotatingIndex] = (0, import_react.useState)(null);
@@ -3301,8 +3767,19 @@ function ReportDialog({
3301
3767
  const next = current === -1 ? 0 : Math.min(Math.max(current + delta, 0), tiles.length - 1);
3302
3768
  (_c = tiles[next]) == null ? void 0 : _c.focus();
3303
3769
  };
3304
- const isDark = useIsDark();
3770
+ const isDark = (0, import_react.useMemo)(() => isOpen ? detectDark() : true, [isOpen]);
3305
3771
  const t2 = getTheme(isDark);
3772
+ const layerTheme = {
3773
+ bg: t2.bg,
3774
+ bgSecondary: t2.bgSecondary,
3775
+ border: t2.border,
3776
+ text: t2.text,
3777
+ textMuted: t2.textMuted,
3778
+ inputBg: t2.inputBg,
3779
+ inputBorder: t2.inputBorder,
3780
+ accent: t2.accent,
3781
+ accentText: t2.accentText
3782
+ };
3306
3783
  const canZoomPreview = previewNatural !== null && typeof window !== "undefined" && (previewNatural.w > window.innerWidth - 32 || previewNatural.h > window.innerHeight - 80);
3307
3784
  const handleFileUpload = (e) => {
3308
3785
  const files = e.target.files;
@@ -3332,6 +3809,7 @@ function ReportDialog({
3332
3809
  });
3333
3810
  };
3334
3811
  const handleOpen = async () => {
3812
+ const gen = openGenRef.current;
3335
3813
  setSubmitted(false);
3336
3814
  closePreview();
3337
3815
  setAnnotatingIndex(null);
@@ -3340,11 +3818,32 @@ function ReportDialog({
3340
3818
  setTypeChosen(true);
3341
3819
  setStep(2);
3342
3820
  }
3343
- const shot = await captureScreenshot();
3821
+ const show = () => {
3822
+ if (gen !== openGenRef.current) return;
3823
+ if (assist && !assistUsed) setAssistOpen(true);
3824
+ setIsOpen(true);
3825
+ };
3826
+ const capture = captureScreenshot({
3827
+ onRedraw: () => {
3828
+ if (gen !== openGenRef.current) return;
3829
+ setShotPending(true);
3830
+ show();
3831
+ }
3832
+ });
3833
+ pendingShotRef.current = capture;
3834
+ const previousPageShot = pageShot;
3835
+ const shot = await capture.catch(() => null);
3836
+ if (gen !== openGenRef.current) return;
3837
+ pendingShotRef.current = null;
3838
+ setShotPending(false);
3344
3839
  setPageShot(shot != null ? shot : null);
3345
- if (shot) setScreenshots([shot]);
3346
- if (assist && !assistUsed) setAssistOpen(true);
3347
- setIsOpen(true);
3840
+ if (shot) {
3841
+ setScreenshots((prev) => [
3842
+ shot,
3843
+ ...prev.filter((s) => s !== shot && s !== previousPageShot)
3844
+ ]);
3845
+ }
3846
+ show();
3348
3847
  };
3349
3848
  (0, import_react.useEffect)(() => {
3350
3849
  const handler = (e) => {
@@ -3537,6 +4036,9 @@ function ReportDialog({
3537
4036
  stopVoice();
3538
4037
  setIsOpen(false);
3539
4038
  onClose == null ? void 0 : onClose();
4039
+ openGenRef.current += 1;
4040
+ pendingShotRef.current = null;
4041
+ setShotPending(false);
3540
4042
  closePreview();
3541
4043
  setAnnotatingIndex(null);
3542
4044
  setStep(1);
@@ -3547,6 +4049,7 @@ function ReportDialog({
3547
4049
  setDuplicateIssueNumber(null);
3548
4050
  setSeverity(null);
3549
4051
  setValidationError(null);
4052
+ setSelfReportFrom(null);
3550
4053
  setVoiceError(null);
3551
4054
  setIsEnhanced(false);
3552
4055
  setOriginalDescription(null);
@@ -3769,8 +4272,19 @@ function ReportDialog({
3769
4272
  return;
3770
4273
  }
3771
4274
  setIsSubmitting(true);
4275
+ let shots = screenshots;
4276
+ const pending = pendingShotRef.current;
4277
+ if (pending) {
4278
+ const shot = await Promise.race([
4279
+ pending.catch(() => null),
4280
+ new Promise((resolve) => setTimeout(() => resolve(null), SHOT_WAIT_MS))
4281
+ ]);
4282
+ if (shot && !shots.includes(shot)) {
4283
+ shots = [shot, ...shots.filter((s) => s !== pageShot)];
4284
+ }
4285
+ }
3772
4286
  const metadata = {};
3773
- if (screenshots.length > 0) metadata.screenshots = JSON.stringify(screenshots);
4287
+ if (shots.length > 0) metadata.screenshots = JSON.stringify(shots);
3774
4288
  if (attachments.length > 0) metadata.attachments = JSON.stringify(attachments);
3775
4289
  if (showSeverity && reportType === "BUG" && severity) {
3776
4290
  metadata.severity = severity;
@@ -3806,9 +4320,9 @@ function ReportDialog({
3806
4320
  }
3807
4321
  };
3808
4322
  if (!mounted) return null;
3809
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
4323
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
3810
4324
  isOpen && (0, import_react_dom.createPortal)(
3811
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
4325
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: `
3812
4326
  @keyframes gg-pulse{0%,100%{opacity:1}50%{opacity:0.35}}
3813
4327
  @keyframes gg-b1{0%,100%{height:3px}40%{height:13px}}
3814
4328
  @keyframes gg-b2{0%,100%{height:8px}50%{height:3px}}
@@ -3845,7 +4359,7 @@ function ReportDialog({
3845
4359
  document.body
3846
4360
  ),
3847
4361
  isOpen && (0, import_react_dom.createPortal)(
3848
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4362
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3849
4363
  "div",
3850
4364
  {
3851
4365
  "data-glitchgrab-layer": "",
@@ -3868,10 +4382,13 @@ function ReportDialog({
3868
4382
  },
3869
4383
  onPointerDown: (e) => e.stopPropagation(),
3870
4384
  onFocus: (e) => e.stopPropagation(),
3871
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4385
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3872
4386
  "div",
3873
4387
  {
3874
4388
  ref: modalRef,
4389
+ role: "dialog",
4390
+ "aria-modal": "true",
4391
+ "aria-label": "Report an issue",
3875
4392
  onClick: (e) => e.stopPropagation(),
3876
4393
  style: {
3877
4394
  position: "relative",
@@ -3890,7 +4407,7 @@ function ReportDialog({
3890
4407
  isolation: "isolate"
3891
4408
  },
3892
4409
  children: [
3893
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4410
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3894
4411
  "div",
3895
4412
  {
3896
4413
  style: {
@@ -3899,7 +4416,7 @@ function ReportDialog({
3899
4416
  borderBottom: `1px solid ${t2.border}`
3900
4417
  },
3901
4418
  children: [
3902
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4419
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3903
4420
  "div",
3904
4421
  {
3905
4422
  style: {
@@ -3908,7 +4425,7 @@ function ReportDialog({
3908
4425
  alignItems: "center"
3909
4426
  },
3910
4427
  children: [
3911
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4428
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3912
4429
  "div",
3913
4430
  {
3914
4431
  style: {
@@ -3917,7 +4434,7 @@ function ReportDialog({
3917
4434
  gap: "8px"
3918
4435
  },
3919
4436
  children: [
3920
- step > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4437
+ step > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3921
4438
  "button",
3922
4439
  {
3923
4440
  type: "button",
@@ -3931,14 +4448,14 @@ function ReportDialog({
3931
4448
  alignItems: "center"
3932
4449
  },
3933
4450
  "aria-label": "Back",
3934
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4451
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3935
4452
  "svg",
3936
4453
  {
3937
4454
  width: "16",
3938
4455
  height: "16",
3939
4456
  viewBox: "0 0 16 16",
3940
4457
  fill: "none",
3941
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4458
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3942
4459
  "path",
3943
4460
  {
3944
4461
  d: "M10 3L5 8L10 13",
@@ -3952,7 +4469,7 @@ function ReportDialog({
3952
4469
  )
3953
4470
  }
3954
4471
  ),
3955
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4472
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3956
4473
  "span",
3957
4474
  {
3958
4475
  style: {
@@ -3966,7 +4483,7 @@ function ReportDialog({
3966
4483
  ]
3967
4484
  }
3968
4485
  ),
3969
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4486
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3970
4487
  "div",
3971
4488
  {
3972
4489
  style: {
@@ -3975,7 +4492,7 @@ function ReportDialog({
3975
4492
  gap: "8px"
3976
4493
  },
3977
4494
  children: [
3978
- step === 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4495
+ step === 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3979
4496
  "span",
3980
4497
  {
3981
4498
  title: "Press this anywhere to open Glitchgrab",
@@ -3993,7 +4510,7 @@ function ReportDialog({
3993
4510
  children: getShortcutLabel()
3994
4511
  }
3995
4512
  ),
3996
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4513
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3997
4514
  "button",
3998
4515
  {
3999
4516
  type: "button",
@@ -4008,7 +4525,7 @@ function ReportDialog({
4008
4525
  justifyContent: "center"
4009
4526
  },
4010
4527
  "aria-label": "Close",
4011
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4528
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4012
4529
  "svg",
4013
4530
  {
4014
4531
  width: "16",
@@ -4016,7 +4533,7 @@ function ReportDialog({
4016
4533
  viewBox: "0 0 16 16",
4017
4534
  fill: "none",
4018
4535
  style: { display: "block" },
4019
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4536
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4020
4537
  "path",
4021
4538
  {
4022
4539
  d: "M4 4L12 12M12 4L4 12",
@@ -4035,7 +4552,7 @@ function ReportDialog({
4035
4552
  ]
4036
4553
  }
4037
4554
  ),
4038
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4555
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4039
4556
  "div",
4040
4557
  {
4041
4558
  style: {
@@ -4045,12 +4562,12 @@ function ReportDialog({
4045
4562
  gap: "0",
4046
4563
  marginTop: "12px"
4047
4564
  },
4048
- children: [1, 2].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4565
+ children: [1, 2].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4049
4566
  "div",
4050
4567
  {
4051
4568
  style: { display: "flex", alignItems: "center" },
4052
4569
  children: [
4053
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4570
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4054
4571
  "div",
4055
4572
  {
4056
4573
  style: {
@@ -4062,7 +4579,7 @@ function ReportDialog({
4062
4579
  }
4063
4580
  }
4064
4581
  ),
4065
- i < 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4582
+ i < 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4066
4583
  "div",
4067
4584
  {
4068
4585
  style: {
@@ -4082,7 +4599,7 @@ function ReportDialog({
4082
4599
  ]
4083
4600
  }
4084
4601
  ),
4085
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4602
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4086
4603
  "div",
4087
4604
  {
4088
4605
  style: {
@@ -4091,7 +4608,7 @@ function ReportDialog({
4091
4608
  flex: "1 1 auto",
4092
4609
  minHeight: 0
4093
4610
  },
4094
- children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4611
+ children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4095
4612
  "div",
4096
4613
  {
4097
4614
  style: {
@@ -4106,9 +4623,9 @@ function ReportDialog({
4106
4623
  " sent. Thank you!"
4107
4624
  ]
4108
4625
  }
4109
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
4110
- step === 1 && headerSlot ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
4111
- step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4626
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
4627
+ step === 1 && headerSlot ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
4628
+ step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4112
4629
  "div",
4113
4630
  {
4114
4631
  style: {
@@ -4125,16 +4642,16 @@ function ReportDialog({
4125
4642
  },
4126
4643
  onMouseLeave: () => setHoveredStar(0),
4127
4644
  children: [
4128
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4645
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4129
4646
  "span",
4130
4647
  {
4131
4648
  style: { fontSize: "13px", fontWeight: 600, color: t2.text },
4132
4649
  children: "How are we doing?"
4133
4650
  }
4134
4651
  ),
4135
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
4652
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
4136
4653
  const filled = star <= (hoveredStar || rating);
4137
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4654
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4138
4655
  "button",
4139
4656
  {
4140
4657
  type: "button",
@@ -4155,7 +4672,7 @@ function ReportDialog({
4155
4672
  cursor: "pointer",
4156
4673
  lineHeight: 0
4157
4674
  },
4158
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4675
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4159
4676
  "path",
4160
4677
  {
4161
4678
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -4172,7 +4689,7 @@ function ReportDialog({
4172
4689
  ]
4173
4690
  }
4174
4691
  ),
4175
- step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4692
+ step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4176
4693
  "div",
4177
4694
  {
4178
4695
  style: {
@@ -4182,13 +4699,13 @@ function ReportDialog({
4182
4699
  marginBottom: "16px"
4183
4700
  },
4184
4701
  children: [
4185
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } }),
4186
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
4187
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } })
4702
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } }),
4703
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
4704
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } })
4188
4705
  ]
4189
4706
  }
4190
4707
  ),
4191
- step === 1 && screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4708
+ step === 1 && screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4192
4709
  "div",
4193
4710
  {
4194
4711
  style: {
@@ -4202,7 +4719,7 @@ function ReportDialog({
4202
4719
  background: t2.inputBg
4203
4720
  },
4204
4721
  children: [
4205
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4722
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4206
4723
  "img",
4207
4724
  {
4208
4725
  src: screenshots[0],
@@ -4217,8 +4734,8 @@ function ReportDialog({
4217
4734
  }
4218
4735
  }
4219
4736
  ),
4220
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
4221
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4737
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
4738
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4222
4739
  "button",
4223
4740
  {
4224
4741
  type: "button",
@@ -4239,7 +4756,7 @@ function ReportDialog({
4239
4756
  ]
4240
4757
  }
4241
4758
  ),
4242
- step === 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4759
+ step === 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4243
4760
  "div",
4244
4761
  {
4245
4762
  ref: tileGridRef,
@@ -4249,7 +4766,7 @@ function ReportDialog({
4249
4766
  gridTemplateColumns: "1fr 1fr 1fr",
4250
4767
  gap: "10px"
4251
4768
  },
4252
- children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4769
+ children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4253
4770
  "button",
4254
4771
  {
4255
4772
  type: "button",
@@ -4280,7 +4797,7 @@ function ReportDialog({
4280
4797
  },
4281
4798
  children: [
4282
4799
  getTypeIcon(type, t2.accent, 22),
4283
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4800
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4284
4801
  "span",
4285
4802
  {
4286
4803
  style: {
@@ -4298,8 +4815,8 @@ function ReportDialog({
4298
4815
  ))
4299
4816
  }
4300
4817
  ),
4301
- step === 2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
4302
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4818
+ step === 2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
4819
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4303
4820
  "button",
4304
4821
  {
4305
4822
  type: "button",
@@ -4322,11 +4839,11 @@ function ReportDialog({
4322
4839
  children: [
4323
4840
  getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
4324
4841
  getTypeLabel(reportType),
4325
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
4842
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
4326
4843
  ]
4327
4844
  }
4328
4845
  ),
4329
- isRating && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4846
+ isRating && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4330
4847
  "div",
4331
4848
  {
4332
4849
  style: {
@@ -4337,7 +4854,7 @@ function ReportDialog({
4337
4854
  onMouseLeave: () => setHoveredStar(0),
4338
4855
  children: [1, 2, 3, 4, 5].map((star) => {
4339
4856
  const filled = star <= (hoveredStar || rating);
4340
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4857
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4341
4858
  "button",
4342
4859
  {
4343
4860
  type: "button",
@@ -4354,7 +4871,7 @@ function ReportDialog({
4354
4871
  cursor: "pointer",
4355
4872
  lineHeight: 0
4356
4873
  },
4357
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4874
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4358
4875
  "path",
4359
4876
  {
4360
4877
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -4370,7 +4887,7 @@ function ReportDialog({
4370
4887
  })
4371
4888
  }
4372
4889
  ),
4373
- assist && !isRating && !assistUsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4890
+ assist && !isRating && !assistUsed && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4374
4891
  "button",
4375
4892
  {
4376
4893
  type: "button",
@@ -4397,7 +4914,7 @@ function ReportDialog({
4397
4914
  },
4398
4915
  title: "Answer a question or two and the assistant writes the report for you",
4399
4916
  children: [
4400
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4917
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4401
4918
  "path",
4402
4919
  {
4403
4920
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3zM19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75L19 15z",
@@ -4410,8 +4927,8 @@ function ReportDialog({
4410
4927
  ]
4411
4928
  }
4412
4929
  ),
4413
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative" }, children: [
4414
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4930
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { position: "relative" }, children: [
4931
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4415
4932
  "textarea",
4416
4933
  {
4417
4934
  ref: textareaRef,
@@ -4453,7 +4970,7 @@ function ReportDialog({
4453
4970
  autoFocus: true
4454
4971
  }
4455
4972
  ),
4456
- (isListening || isTranscribing) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4973
+ (isListening || isTranscribing) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4457
4974
  "span",
4458
4975
  {
4459
4976
  style: {
@@ -4471,7 +4988,7 @@ function ReportDialog({
4471
4988
  zIndex: 1
4472
4989
  },
4473
4990
  children: [
4474
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4991
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4475
4992
  "span",
4476
4993
  {
4477
4994
  style: {
@@ -4486,7 +5003,7 @@ function ReportDialog({
4486
5003
  }
4487
5004
  ),
4488
5005
  isTranscribing ? "Transcribing\u2026" : "REC",
4489
- isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5006
+ isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4490
5007
  "span",
4491
5008
  {
4492
5009
  style: {
@@ -4513,7 +5030,7 @@ function ReportDialog({
4513
5030
  dur: "0.55s",
4514
5031
  delay: "0.15s"
4515
5032
  }
4516
- ].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5033
+ ].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4517
5034
  "span",
4518
5035
  {
4519
5036
  style: {
@@ -4533,7 +5050,7 @@ function ReportDialog({
4533
5050
  ]
4534
5051
  }
4535
5052
  ),
4536
- enhanceText2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5053
+ enhanceText2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4537
5054
  "button",
4538
5055
  {
4539
5056
  type: "button",
@@ -4578,7 +5095,7 @@ function ReportDialog({
4578
5095
  },
4579
5096
  title: "Polish grammar \u2014 preserves your meaning",
4580
5097
  children: [
4581
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5098
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4582
5099
  "svg",
4583
5100
  {
4584
5101
  width: "11",
@@ -4586,7 +5103,7 @@ function ReportDialog({
4586
5103
  viewBox: "0 0 24 24",
4587
5104
  fill: "none",
4588
5105
  "aria-hidden": "true",
4589
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5106
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4590
5107
  "path",
4591
5108
  {
4592
5109
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3zM19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75L19 15z",
@@ -4601,7 +5118,7 @@ function ReportDialog({
4601
5118
  ]
4602
5119
  }
4603
5120
  ),
4604
- transcribeAudio2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5121
+ transcribeAudio2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4605
5122
  "button",
4606
5123
  {
4607
5124
  type: "button",
@@ -4627,7 +5144,7 @@ function ReportDialog({
4627
5144
  padding: 0,
4628
5145
  transition: "border-color 0.2s ease, color 0.2s ease"
4629
5146
  },
4630
- children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5147
+ children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4631
5148
  "svg",
4632
5149
  {
4633
5150
  width: "12",
@@ -4635,7 +5152,7 @@ function ReportDialog({
4635
5152
  viewBox: "0 0 24 24",
4636
5153
  fill: "currentColor",
4637
5154
  "aria-hidden": "true",
4638
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5155
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4639
5156
  "rect",
4640
5157
  {
4641
5158
  x: "6",
@@ -4646,7 +5163,7 @@ function ReportDialog({
4646
5163
  }
4647
5164
  )
4648
5165
  }
4649
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5166
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4650
5167
  "svg",
4651
5168
  {
4652
5169
  width: "13",
@@ -4655,7 +5172,7 @@ function ReportDialog({
4655
5172
  fill: "none",
4656
5173
  "aria-hidden": "true",
4657
5174
  children: [
4658
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5175
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4659
5176
  "rect",
4660
5177
  {
4661
5178
  x: "9",
@@ -4667,7 +5184,7 @@ function ReportDialog({
4667
5184
  strokeWidth: "1.8"
4668
5185
  }
4669
5186
  ),
4670
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5187
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4671
5188
  "path",
4672
5189
  {
4673
5190
  d: "M5 10a7 7 0 0014 0M12 19v3M9 22h6",
@@ -4682,7 +5199,7 @@ function ReportDialog({
4682
5199
  }
4683
5200
  )
4684
5201
  ] }),
4685
- transcribeAudio2 && !isListening && !isTranscribing && !voiceError && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5202
+ transcribeAudio2 && !isListening && !isTranscribing && !voiceError && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4686
5203
  "div",
4687
5204
  {
4688
5205
  style: {
@@ -4696,16 +5213,16 @@ function ReportDialog({
4696
5213
  userSelect: "none"
4697
5214
  },
4698
5215
  children: [
4699
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4700
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
4701
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
4702
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
5216
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5217
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
5218
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
5219
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
4703
5220
  ] }),
4704
5221
  "Hold Space to speak \u2014 we'll transcribe it"
4705
5222
  ]
4706
5223
  }
4707
5224
  ),
4708
- isEnhanced && originalDescription !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5225
+ isEnhanced && originalDescription !== null && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4709
5226
  "div",
4710
5227
  {
4711
5228
  style: {
@@ -4719,7 +5236,7 @@ function ReportDialog({
4719
5236
  border: `1px solid ${t2.accent}40`
4720
5237
  },
4721
5238
  children: [
4722
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5239
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4723
5240
  "svg",
4724
5241
  {
4725
5242
  width: "12",
@@ -4727,7 +5244,7 @@ function ReportDialog({
4727
5244
  viewBox: "0 0 24 24",
4728
5245
  fill: "none",
4729
5246
  style: { flexShrink: 0 },
4730
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5247
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4731
5248
  "path",
4732
5249
  {
4733
5250
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z",
@@ -4738,7 +5255,7 @@ function ReportDialog({
4738
5255
  )
4739
5256
  }
4740
5257
  ),
4741
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5258
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4742
5259
  "span",
4743
5260
  {
4744
5261
  style: {
@@ -4749,7 +5266,7 @@ function ReportDialog({
4749
5266
  children: "AI enhanced"
4750
5267
  }
4751
5268
  ),
4752
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5269
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4753
5270
  "button",
4754
5271
  {
4755
5272
  type: "button",
@@ -4771,7 +5288,7 @@ function ReportDialog({
4771
5288
  children: "Keep"
4772
5289
  }
4773
5290
  ),
4774
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5291
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4775
5292
  "button",
4776
5293
  {
4777
5294
  type: "button",
@@ -4797,7 +5314,7 @@ function ReportDialog({
4797
5314
  ]
4798
5315
  }
4799
5316
  ),
4800
- voiceError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5317
+ voiceError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4801
5318
  "p",
4802
5319
  {
4803
5320
  role: "alert",
@@ -4811,7 +5328,7 @@ function ReportDialog({
4811
5328
  children: voiceError
4812
5329
  }
4813
5330
  ),
4814
- assistNotice && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5331
+ assistNotice && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4815
5332
  "p",
4816
5333
  {
4817
5334
  style: {
@@ -4824,8 +5341,8 @@ function ReportDialog({
4824
5341
  children: assistNotice
4825
5342
  }
4826
5343
  ),
4827
- !isRating && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginTop: "10px" }, children: [
4828
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5344
+ !isRating && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginTop: "10px" }, children: [
5345
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4829
5346
  "span",
4830
5347
  {
4831
5348
  style: {
@@ -4841,7 +5358,7 @@ function ReportDialog({
4841
5358
  ]
4842
5359
  }
4843
5360
  ),
4844
- screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5361
+ (screenshots.length > 0 || shotPending) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4845
5362
  "div",
4846
5363
  {
4847
5364
  style: {
@@ -4850,132 +5367,159 @@ function ReportDialog({
4850
5367
  gap: "8px",
4851
5368
  marginBottom: "8px"
4852
5369
  },
4853
- children: screenshots.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4854
- "div",
4855
- {
4856
- style: {
4857
- position: "relative",
4858
- width: "56px",
4859
- height: "56px"
4860
- },
4861
- children: [
4862
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4863
- "img",
4864
- {
4865
- src,
4866
- alt: `Screenshot ${i + 1}`,
4867
- onClick: () => openPreview(i),
4868
- style: {
4869
- width: "100%",
4870
- height: "100%",
4871
- borderRadius: "6px",
4872
- border: `1px solid ${t2.border}`,
4873
- objectFit: "cover",
4874
- objectPosition: "top",
4875
- cursor: "zoom-in",
4876
- display: "block"
4877
- }
4878
- }
4879
- ),
4880
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4881
- "button",
4882
- {
4883
- type: "button",
4884
- onClick: () => setScreenshots(
4885
- (prev) => prev.filter((_, idx) => idx !== i)
4886
- ),
4887
- "aria-label": `Remove screenshot ${i + 1}`,
4888
- style: {
4889
- position: "absolute",
4890
- top: "-6px",
4891
- right: "-6px",
4892
- width: "17px",
4893
- height: "17px",
4894
- borderRadius: "50%",
4895
- border: "none",
4896
- background: "#ef4444",
4897
- color: "#fff",
4898
- fontSize: "11px",
4899
- lineHeight: 1,
4900
- padding: 0,
4901
- cursor: "pointer",
4902
- display: "flex",
4903
- alignItems: "center",
4904
- justifyContent: "center"
4905
- },
4906
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4907
- "svg",
4908
- {
4909
- width: "8",
4910
- height: "8",
4911
- viewBox: "0 0 10 10",
4912
- fill: "none",
4913
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4914
- "path",
4915
- {
4916
- d: "M1 1L9 9M9 1L1 9",
4917
- stroke: "currentColor",
4918
- strokeWidth: "1.5",
4919
- strokeLinecap: "round"
4920
- }
4921
- )
4922
- }
4923
- )
4924
- }
4925
- ),
4926
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4927
- "button",
4928
- {
4929
- type: "button",
4930
- onClick: () => setAnnotatingIndex(i),
4931
- "aria-label": `Annotate screenshot ${i + 1}`,
4932
- title: "Annotate",
4933
- style: {
4934
- position: "absolute",
4935
- top: "50%",
4936
- left: "50%",
4937
- transform: "translate(-50%, -50%)",
4938
- width: "24px",
4939
- height: "24px",
4940
- borderRadius: "50%",
4941
- border: "none",
4942
- background: t2.accent,
4943
- color: t2.accentText,
4944
- padding: 0,
4945
- cursor: "pointer",
4946
- display: "flex",
4947
- alignItems: "center",
4948
- justifyContent: "center",
4949
- boxShadow: "0 2px 8px rgba(0,0,0,0.45)"
4950
- },
4951
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4952
- "svg",
4953
- {
4954
- width: "12",
4955
- height: "12",
4956
- viewBox: "0 0 24 24",
4957
- fill: "none",
4958
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4959
- "path",
4960
- {
4961
- d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
4962
- stroke: "currentColor",
4963
- strokeWidth: "2.2",
4964
- strokeLinecap: "round",
4965
- strokeLinejoin: "round"
4966
- }
4967
- )
5370
+ children: [
5371
+ shotPending && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5372
+ "div",
5373
+ {
5374
+ role: "status",
5375
+ "aria-label": "Capturing screenshot",
5376
+ title: "Capturing a screenshot of the page\u2026",
5377
+ style: {
5378
+ width: "56px",
5379
+ height: "56px",
5380
+ borderRadius: "6px",
5381
+ border: `1px dashed ${t2.border}`,
5382
+ display: "flex",
5383
+ alignItems: "center",
5384
+ justifyContent: "center",
5385
+ padding: "4px",
5386
+ boxSizing: "border-box",
5387
+ fontSize: "9px",
5388
+ lineHeight: 1.2,
5389
+ textAlign: "center",
5390
+ color: t2.textMuted,
5391
+ animation: "gg-pulse 1.4s ease-in-out infinite"
5392
+ },
5393
+ children: "Capturing\u2026"
5394
+ }
5395
+ ),
5396
+ screenshots.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5397
+ "div",
5398
+ {
5399
+ style: {
5400
+ position: "relative",
5401
+ width: "56px",
5402
+ height: "56px"
5403
+ },
5404
+ children: [
5405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5406
+ "img",
5407
+ {
5408
+ src,
5409
+ alt: `Screenshot ${i + 1}`,
5410
+ onClick: () => openPreview(i),
5411
+ style: {
5412
+ width: "100%",
5413
+ height: "100%",
5414
+ borderRadius: "6px",
5415
+ border: `1px solid ${t2.border}`,
5416
+ objectFit: "cover",
5417
+ objectPosition: "top",
5418
+ cursor: "zoom-in",
5419
+ display: "block"
4968
5420
  }
4969
- )
4970
- }
4971
- )
4972
- ]
4973
- },
4974
- i
4975
- ))
5421
+ }
5422
+ ),
5423
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5424
+ "button",
5425
+ {
5426
+ type: "button",
5427
+ onClick: () => setScreenshots(
5428
+ (prev) => prev.filter((_, idx) => idx !== i)
5429
+ ),
5430
+ "aria-label": `Remove screenshot ${i + 1}`,
5431
+ style: {
5432
+ position: "absolute",
5433
+ top: "-6px",
5434
+ right: "-6px",
5435
+ width: "17px",
5436
+ height: "17px",
5437
+ borderRadius: "50%",
5438
+ border: "none",
5439
+ background: "#ef4444",
5440
+ color: "#fff",
5441
+ fontSize: "11px",
5442
+ lineHeight: 1,
5443
+ padding: 0,
5444
+ cursor: "pointer",
5445
+ display: "flex",
5446
+ alignItems: "center",
5447
+ justifyContent: "center"
5448
+ },
5449
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5450
+ "svg",
5451
+ {
5452
+ width: "8",
5453
+ height: "8",
5454
+ viewBox: "0 0 10 10",
5455
+ fill: "none",
5456
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5457
+ "path",
5458
+ {
5459
+ d: "M1 1L9 9M9 1L1 9",
5460
+ stroke: "currentColor",
5461
+ strokeWidth: "1.5",
5462
+ strokeLinecap: "round"
5463
+ }
5464
+ )
5465
+ }
5466
+ )
5467
+ }
5468
+ ),
5469
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5470
+ "button",
5471
+ {
5472
+ type: "button",
5473
+ onClick: () => setAnnotatingIndex(i),
5474
+ "aria-label": `Annotate screenshot ${i + 1}`,
5475
+ title: "Annotate",
5476
+ style: {
5477
+ position: "absolute",
5478
+ top: "50%",
5479
+ left: "50%",
5480
+ transform: "translate(-50%, -50%)",
5481
+ width: "24px",
5482
+ height: "24px",
5483
+ borderRadius: "50%",
5484
+ border: "none",
5485
+ background: t2.accent,
5486
+ color: t2.accentText,
5487
+ padding: 0,
5488
+ cursor: "pointer",
5489
+ display: "flex",
5490
+ alignItems: "center",
5491
+ justifyContent: "center",
5492
+ boxShadow: "0 2px 8px rgba(0,0,0,0.45)"
5493
+ },
5494
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5495
+ "svg",
5496
+ {
5497
+ width: "12",
5498
+ height: "12",
5499
+ viewBox: "0 0 24 24",
5500
+ fill: "none",
5501
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5502
+ "path",
5503
+ {
5504
+ d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
5505
+ stroke: "currentColor",
5506
+ strokeWidth: "2.2",
5507
+ strokeLinecap: "round",
5508
+ strokeLinejoin: "round"
5509
+ }
5510
+ )
5511
+ }
5512
+ )
5513
+ }
5514
+ )
5515
+ ]
5516
+ },
5517
+ i
5518
+ ))
5519
+ ]
4976
5520
  }
4977
5521
  ),
4978
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5522
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4979
5523
  "div",
4980
5524
  {
4981
5525
  style: {
@@ -4984,7 +5528,7 @@ function ReportDialog({
4984
5528
  gap: "6px",
4985
5529
  marginBottom: "8px"
4986
5530
  },
4987
- children: attachments.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5531
+ children: attachments.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4988
5532
  "div",
4989
5533
  {
4990
5534
  style: {
@@ -4996,7 +5540,7 @@ function ReportDialog({
4996
5540
  border: `1px solid ${t2.border}`
4997
5541
  },
4998
5542
  children: [
4999
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5543
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5000
5544
  "svg",
5001
5545
  {
5002
5546
  width: "14",
@@ -5005,7 +5549,7 @@ function ReportDialog({
5005
5549
  fill: "none",
5006
5550
  style: { flexShrink: 0, opacity: 0.6 },
5007
5551
  children: [
5008
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5552
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5009
5553
  "path",
5010
5554
  {
5011
5555
  d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z",
@@ -5015,7 +5559,7 @@ function ReportDialog({
5015
5559
  strokeLinejoin: "round"
5016
5560
  }
5017
5561
  ),
5018
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5562
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5019
5563
  "path",
5020
5564
  {
5021
5565
  d: "M14 2v6h6",
@@ -5028,7 +5572,7 @@ function ReportDialog({
5028
5572
  ]
5029
5573
  }
5030
5574
  ),
5031
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5575
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5032
5576
  "span",
5033
5577
  {
5034
5578
  style: {
@@ -5042,7 +5586,7 @@ function ReportDialog({
5042
5586
  children: a.name
5043
5587
  }
5044
5588
  ),
5045
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5589
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5046
5590
  "span",
5047
5591
  {
5048
5592
  style: { fontSize: "10px", color: t2.textMuted },
@@ -5052,7 +5596,7 @@ function ReportDialog({
5052
5596
  ]
5053
5597
  }
5054
5598
  ),
5055
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5599
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5056
5600
  "button",
5057
5601
  {
5058
5602
  type: "button",
@@ -5076,14 +5620,14 @@ function ReportDialog({
5076
5620
  justifyContent: "center",
5077
5621
  flexShrink: 0
5078
5622
  },
5079
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5623
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5080
5624
  "svg",
5081
5625
  {
5082
5626
  width: "8",
5083
5627
  height: "8",
5084
5628
  viewBox: "0 0 10 10",
5085
5629
  fill: "none",
5086
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5630
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5087
5631
  "path",
5088
5632
  {
5089
5633
  d: "M1 1L9 9M9 1L1 9",
@@ -5102,7 +5646,7 @@ function ReportDialog({
5102
5646
  ))
5103
5647
  }
5104
5648
  ),
5105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5649
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5106
5650
  "div",
5107
5651
  {
5108
5652
  onClick: () => {
@@ -5128,7 +5672,7 @@ function ReportDialog({
5128
5672
  background: screenshotDragOver ? isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.04)" : "transparent",
5129
5673
  transition: "border-color 0.15s ease, background 0.15s ease"
5130
5674
  },
5131
- children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5675
+ children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5132
5676
  "p",
5133
5677
  {
5134
5678
  style: {
@@ -5139,8 +5683,8 @@ function ReportDialog({
5139
5683
  },
5140
5684
  children: screenshotDragOver ? "Drop to attach" : "+ Add more \xB7 Drag & drop \xB7 Paste"
5141
5685
  }
5142
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
5143
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5686
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
5687
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5144
5688
  "svg",
5145
5689
  {
5146
5690
  width: "22",
@@ -5153,7 +5697,7 @@ function ReportDialog({
5153
5697
  opacity: 0.45
5154
5698
  },
5155
5699
  children: [
5156
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5700
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5157
5701
  "rect",
5158
5702
  {
5159
5703
  x: "3",
@@ -5165,7 +5709,7 @@ function ReportDialog({
5165
5709
  strokeWidth: "1.5"
5166
5710
  }
5167
5711
  ),
5168
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5712
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5169
5713
  "circle",
5170
5714
  {
5171
5715
  cx: "8.5",
@@ -5175,7 +5719,7 @@ function ReportDialog({
5175
5719
  strokeWidth: "1.5"
5176
5720
  }
5177
5721
  ),
5178
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5722
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5179
5723
  "path",
5180
5724
  {
5181
5725
  d: "M21 15l-5-5L5 21",
@@ -5188,7 +5732,7 @@ function ReportDialog({
5188
5732
  ]
5189
5733
  }
5190
5734
  ),
5191
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5735
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5192
5736
  "p",
5193
5737
  {
5194
5738
  style: {
@@ -5200,7 +5744,7 @@ function ReportDialog({
5200
5744
  children: screenshotDragOver ? "Drop to attach" : "Add screenshots or files"
5201
5745
  }
5202
5746
  ),
5203
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5747
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5204
5748
  "p",
5205
5749
  {
5206
5750
  style: {
@@ -5215,8 +5759,8 @@ function ReportDialog({
5215
5759
  }
5216
5760
  )
5217
5761
  ] }),
5218
- showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginTop: "10px" }, children: [
5219
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5762
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginTop: "10px" }, children: [
5763
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5220
5764
  "span",
5221
5765
  {
5222
5766
  style: {
@@ -5229,7 +5773,7 @@ function ReportDialog({
5229
5773
  },
5230
5774
  children: [
5231
5775
  "How bad is it?",
5232
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5233
5777
  "span",
5234
5778
  {
5235
5779
  style: {
@@ -5242,7 +5786,7 @@ function ReportDialog({
5242
5786
  ]
5243
5787
  }
5244
5788
  ),
5245
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5246
5790
  "div",
5247
5791
  {
5248
5792
  role: "radiogroup",
@@ -5250,7 +5794,7 @@ function ReportDialog({
5250
5794
  style: { display: "flex", gap: "6px" },
5251
5795
  children: SEVERITY_LEVELS.map((s) => {
5252
5796
  const on = severity === s;
5253
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5797
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5254
5798
  "button",
5255
5799
  {
5256
5800
  type: "button",
@@ -5291,7 +5835,7 @@ function ReportDialog({
5291
5835
  }
5292
5836
  )
5293
5837
  ] }),
5294
- validationError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5838
+ validationError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5295
5839
  "p",
5296
5840
  {
5297
5841
  style: {
@@ -5302,7 +5846,7 @@ function ReportDialog({
5302
5846
  children: validationError
5303
5847
  }
5304
5848
  ),
5305
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5849
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5306
5850
  "button",
5307
5851
  {
5308
5852
  type: "button",
@@ -5322,14 +5866,14 @@ function ReportDialog({
5322
5866
  fontFamily: "inherit",
5323
5867
  transition: "background-color 0.15s ease"
5324
5868
  },
5325
- children: isSubmitting ? "Sending..." : isRating ? "Send Rating" : "Send Report"
5869
+ children: isSubmitting ? shotPending && !isRating ? "Attaching screenshot\u2026" : "Sending..." : isRating ? "Send Rating" : "Send Report"
5326
5870
  }
5327
5871
  )
5328
5872
  ] })
5329
5873
  ] })
5330
5874
  }
5331
5875
  ),
5332
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5876
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5333
5877
  "div",
5334
5878
  {
5335
5879
  style: {
@@ -5341,8 +5885,35 @@ function ReportDialog({
5341
5885
  gap: "12px"
5342
5886
  },
5343
5887
  children: [
5344
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReporterChip, { reporter, t: t2 }),
5345
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5888
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ReporterChip, { reporter, t: t2 }),
5889
+ reportGlitchgrabProblem ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5890
+ "button",
5891
+ {
5892
+ type: "button",
5893
+ "data-gg-self-report": "",
5894
+ onClick: () => {
5895
+ setSelfReportPrefill("");
5896
+ setSelfReportFrom("form");
5897
+ },
5898
+ title: "Something wrong with this reporter itself? Tell the Glitchgrab team.",
5899
+ style: {
5900
+ fontSize: "11px",
5901
+ color: t2.textMuted,
5902
+ whiteSpace: "nowrap",
5903
+ flexShrink: 0,
5904
+ border: "none",
5905
+ background: "transparent",
5906
+ fontFamily: "inherit",
5907
+ cursor: "pointer",
5908
+ textDecoration: "underline",
5909
+ textUnderlineOffset: "2px",
5910
+ // A ~30px tap target without growing the footer.
5911
+ padding: "9px 0",
5912
+ margin: "-9px 0"
5913
+ },
5914
+ children: "Problem with Glitchgrab?"
5915
+ }
5916
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5346
5917
  "span",
5347
5918
  {
5348
5919
  style: {
@@ -5364,7 +5935,7 @@ function ReportDialog({
5364
5935
  ),
5365
5936
  document.body
5366
5937
  ),
5367
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5938
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5368
5939
  "input",
5369
5940
  {
5370
5941
  ref: fileInputRef,
@@ -5376,7 +5947,7 @@ function ReportDialog({
5376
5947
  }
5377
5948
  ),
5378
5949
  isOpen && previewIndex !== null && screenshots[previewIndex] && (0, import_react_dom.createPortal)(
5379
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5950
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5380
5951
  "div",
5381
5952
  {
5382
5953
  "data-glitchgrab-layer": "",
@@ -5398,7 +5969,7 @@ function ReportDialog({
5398
5969
  },
5399
5970
  onMouseDown: (e) => e.stopPropagation(),
5400
5971
  children: [
5401
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5972
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5402
5973
  "div",
5403
5974
  {
5404
5975
  ref: previewImgRef,
@@ -5410,7 +5981,7 @@ function ReportDialog({
5410
5981
  },
5411
5982
  onClick: (e) => e.stopPropagation(),
5412
5983
  children: [
5413
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5984
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5414
5985
  "div",
5415
5986
  {
5416
5987
  ref: previewScrollRef,
@@ -5429,7 +6000,7 @@ function ReportDialog({
5429
6000
  touchAction: "none",
5430
6001
  cursor: "grab"
5431
6002
  } : { maxWidth: "100%", lineHeight: 0 },
5432
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6003
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5433
6004
  "img",
5434
6005
  {
5435
6006
  ref: previewImgElRef,
@@ -5457,7 +6028,7 @@ function ReportDialog({
5457
6028
  )
5458
6029
  }
5459
6030
  ),
5460
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6031
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
5461
6032
  "button",
5462
6033
  {
5463
6034
  type: "button",
@@ -5485,7 +6056,7 @@ function ReportDialog({
5485
6056
  animation: "gg-pulse 2s ease-in-out infinite"
5486
6057
  },
5487
6058
  children: [
5488
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6059
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5489
6060
  "path",
5490
6061
  {
5491
6062
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -5502,7 +6073,7 @@ function ReportDialog({
5502
6073
  ]
5503
6074
  }
5504
6075
  ),
5505
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6076
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5506
6077
  "div",
5507
6078
  {
5508
6079
  style: {
@@ -5511,7 +6082,7 @@ function ReportDialog({
5511
6082
  alignItems: "center",
5512
6083
  gap: "12px"
5513
6084
  },
5514
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6085
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5515
6086
  "span",
5516
6087
  {
5517
6088
  style: {
@@ -5533,7 +6104,7 @@ function ReportDialog({
5533
6104
  document.body
5534
6105
  ),
5535
6106
  isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && (0, import_react_dom.createPortal)(
5536
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6107
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5537
6108
  AnnotationCanvas,
5538
6109
  {
5539
6110
  imageSrc: screenshots[annotatingIndex],
@@ -5549,21 +6120,24 @@ function ReportDialog({
5549
6120
  ),
5550
6121
  document.body
5551
6122
  ),
5552
- isOpen && sheetUp && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6123
+ isOpen && selfReportFrom && reportGlitchgrabProblem && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6124
+ GlitchgrabProblemPanel,
6125
+ {
6126
+ send: reportGlitchgrabProblem,
6127
+ theme: layerTheme,
6128
+ surface: selfReportFrom,
6129
+ conversationId: aiConversationId,
6130
+ reportType,
6131
+ screenshots,
6132
+ initialText: selfReportPrefill,
6133
+ onClose: () => setSelfReportFrom(null)
6134
+ }
6135
+ ),
6136
+ isOpen && sheetUp && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5553
6137
  AssistSheet,
5554
6138
  {
5555
6139
  assist,
5556
- theme: {
5557
- bg: t2.bg,
5558
- bgSecondary: t2.bgSecondary,
5559
- border: t2.border,
5560
- text: t2.text,
5561
- textMuted: t2.textMuted,
5562
- inputBg: t2.inputBg,
5563
- inputBorder: t2.inputBorder,
5564
- accent: t2.accent,
5565
- accentText: t2.accentText
5566
- },
6140
+ theme: layerTheme,
5567
6141
  screenshots,
5568
6142
  pageShot,
5569
6143
  onAddImages: addFiles,
@@ -5605,6 +6179,10 @@ function ReportDialog({
5605
6179
  isSubmitting,
5606
6180
  submitted,
5607
6181
  onSend: () => void handleSubmit(),
6182
+ onReportGlitchgrabProblem: reportGlitchgrabProblem ? (prefill) => {
6183
+ setSelfReportPrefill(prefill != null ? prefill : "");
6184
+ setSelfReportFrom("assist");
6185
+ } : void 0,
5608
6186
  onDegrade: (message) => {
5609
6187
  setAssistOpen(false);
5610
6188
  setAssistUsed(true);
@@ -5651,7 +6229,7 @@ function getTypeIcon(type, color, size = 24) {
5651
6229
  };
5652
6230
  switch (type) {
5653
6231
  case "RATING":
5654
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6232
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5655
6233
  "path",
5656
6234
  {
5657
6235
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -5661,7 +6239,7 @@ function getTypeIcon(type, color, size = 24) {
5661
6239
  }
5662
6240
  ) });
5663
6241
  case "BUG":
5664
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6242
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5665
6243
  "path",
5666
6244
  {
5667
6245
  d: "M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3",
@@ -5671,7 +6249,7 @@ function getTypeIcon(type, color, size = 24) {
5671
6249
  }
5672
6250
  ) });
5673
6251
  case "FEATURE_REQUEST":
5674
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6252
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5675
6253
  "path",
5676
6254
  {
5677
6255
  d: "M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z",
@@ -5681,8 +6259,8 @@ function getTypeIcon(type, color, size = 24) {
5681
6259
  }
5682
6260
  ) });
5683
6261
  case "UI_IMPROVEMENT":
5684
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { ...props, children: [
5685
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6262
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { ...props, children: [
6263
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5686
6264
  "rect",
5687
6265
  {
5688
6266
  x: "3",
@@ -5694,7 +6272,7 @@ function getTypeIcon(type, color, size = 24) {
5694
6272
  strokeWidth: "1.5"
5695
6273
  }
5696
6274
  ),
5697
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6275
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5698
6276
  "path",
5699
6277
  {
5700
6278
  d: "M3 9h18M9 21V9",
@@ -5705,7 +6283,7 @@ function getTypeIcon(type, color, size = 24) {
5705
6283
  )
5706
6284
  ] });
5707
6285
  case "PERFORMANCE":
5708
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6286
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5709
6287
  "path",
5710
6288
  {
5711
6289
  d: "M12 21a9 9 0 100-18 9 9 0 000 18zM12 12l4-4M12 7v.01",
@@ -5716,7 +6294,7 @@ function getTypeIcon(type, color, size = 24) {
5716
6294
  }
5717
6295
  ) });
5718
6296
  case "SECURITY":
5719
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6297
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5720
6298
  "path",
5721
6299
  {
5722
6300
  d: "M12 3l7 3v5c0 4.5-3 8.5-7 10-4-1.5-7-5.5-7-10V6l7-3z",
@@ -5726,9 +6304,9 @@ function getTypeIcon(type, color, size = 24) {
5726
6304
  }
5727
6305
  ) });
5728
6306
  case "QUESTION":
5729
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { ...props, children: [
5730
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
5731
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6307
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { ...props, children: [
6308
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
6309
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5732
6310
  "path",
5733
6311
  {
5734
6312
  d: "M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01",
@@ -5740,7 +6318,7 @@ function getTypeIcon(type, color, size = 24) {
5740
6318
  )
5741
6319
  ] });
5742
6320
  case "OTHER":
5743
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6321
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
5744
6322
  "path",
5745
6323
  {
5746
6324
  d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z",
@@ -5753,8 +6331,8 @@ function getTypeIcon(type, color, size = 24) {
5753
6331
  }
5754
6332
 
5755
6333
  // src/booking-dialog.tsx
5756
- var import_react4 = require("react");
5757
- var import_jsx_runtime4 = require("react/jsx-runtime");
6334
+ var import_react5 = require("react");
6335
+ var import_jsx_runtime5 = require("react/jsx-runtime");
5758
6336
  var t = {
5759
6337
  bg: "#141414",
5760
6338
  surface: "#1c1c1c",
@@ -5791,28 +6369,28 @@ function BookingDialog({
5791
6369
  onClose
5792
6370
  }) {
5793
6371
  var _a;
5794
- const [step, setStep] = (0, import_react4.useState)("slots");
5795
- const [slots, setSlots] = (0, import_react4.useState)(null);
5796
- const [heading, setHeading] = (0, import_react4.useState)({
6372
+ const [step, setStep] = (0, import_react5.useState)("slots");
6373
+ const [slots, setSlots] = (0, import_react5.useState)(null);
6374
+ const [heading, setHeading] = (0, import_react5.useState)({
5797
6375
  title: "Book a demo",
5798
6376
  description: null
5799
6377
  });
5800
- const [whatsappUrl, setWhatsappUrl] = (0, import_react4.useState)(null);
5801
- const [selected, setSelected] = (0, import_react4.useState)(null);
5802
- const [name, setName] = (0, import_react4.useState)("");
5803
- const [email, setEmail] = (0, import_react4.useState)("");
5804
- const [phone, setPhone] = (0, import_react4.useState)("");
5805
- const [note, setNote] = (0, import_react4.useState)("");
5806
- const [code, setCode] = (0, import_react4.useState)("");
5807
- const [bookingId, setBookingId] = (0, import_react4.useState)(null);
5808
- const [meetUrl, setMeetUrl] = (0, import_react4.useState)(null);
5809
- const [busy, setBusy] = (0, import_react4.useState)(false);
5810
- const [error, setError] = (0, import_react4.useState)(null);
5811
- const headers = (0, import_react4.useMemo)(
6378
+ const [whatsappUrl, setWhatsappUrl] = (0, import_react5.useState)(null);
6379
+ const [selected, setSelected] = (0, import_react5.useState)(null);
6380
+ const [name, setName] = (0, import_react5.useState)("");
6381
+ const [email, setEmail] = (0, import_react5.useState)("");
6382
+ const [phone, setPhone] = (0, import_react5.useState)("");
6383
+ const [note, setNote] = (0, import_react5.useState)("");
6384
+ const [code, setCode] = (0, import_react5.useState)("");
6385
+ const [bookingId, setBookingId] = (0, import_react5.useState)(null);
6386
+ const [meetUrl, setMeetUrl] = (0, import_react5.useState)(null);
6387
+ const [busy, setBusy] = (0, import_react5.useState)(false);
6388
+ const [error, setError] = (0, import_react5.useState)(null);
6389
+ const headers = (0, import_react5.useMemo)(
5812
6390
  () => ({ Authorization: `Bearer ${token}`, "Content-Type": "application/json" }),
5813
6391
  [token]
5814
6392
  );
5815
- const loadSlots = (0, import_react4.useCallback)(async () => {
6393
+ const loadSlots = (0, import_react5.useCallback)(async () => {
5816
6394
  var _a2, _b, _c;
5817
6395
  setError(null);
5818
6396
  setSlots(null);
@@ -5837,7 +6415,7 @@ function BookingDialog({
5837
6415
  setSlots([]);
5838
6416
  }
5839
6417
  }, [baseUrl, headers]);
5840
- (0, import_react4.useEffect)(() => {
6418
+ (0, import_react5.useEffect)(() => {
5841
6419
  if (!open) return;
5842
6420
  setStep("slots");
5843
6421
  setSelected(null);
@@ -5846,7 +6424,7 @@ function BookingDialog({
5846
6424
  setError(null);
5847
6425
  void loadSlots();
5848
6426
  }, [open, loadSlots]);
5849
- (0, import_react4.useEffect)(() => {
6427
+ (0, import_react5.useEffect)(() => {
5850
6428
  if (!open) return;
5851
6429
  const onKey = (e) => {
5852
6430
  if (e.key === "Escape") onClose();
@@ -5916,7 +6494,7 @@ function BookingDialog({
5916
6494
  }
5917
6495
  }
5918
6496
  const canSubmitDetails = name.trim() && email.includes("@") && phone.replace(/\D/g, "").length >= 8;
5919
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6497
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5920
6498
  "div",
5921
6499
  {
5922
6500
  onClick: (e) => {
@@ -5933,7 +6511,7 @@ function BookingDialog({
5933
6511
  padding: 16,
5934
6512
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
5935
6513
  },
5936
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
6514
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5937
6515
  "div",
5938
6516
  {
5939
6517
  role: "dialog",
@@ -5951,7 +6529,7 @@ function BookingDialog({
5951
6529
  overflow: "hidden"
5952
6530
  },
5953
6531
  children: [
5954
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
6532
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5955
6533
  "div",
5956
6534
  {
5957
6535
  style: {
@@ -5963,11 +6541,11 @@ function BookingDialog({
5963
6541
  gap: 12
5964
6542
  },
5965
6543
  children: [
5966
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
5967
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
5968
- heading.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
6544
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
6545
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
6546
+ heading.description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
5969
6547
  ] }),
5970
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6548
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5971
6549
  "button",
5972
6550
  {
5973
6551
  onClick: onClose,
@@ -5979,10 +6557,10 @@ function BookingDialog({
5979
6557
  ]
5980
6558
  }
5981
6559
  ),
5982
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
5983
- error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
5984
- step === "slots" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
5985
- whatsappUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
6560
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
6561
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
6562
+ step === "slots" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6563
+ whatsappUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5986
6564
  "a",
5987
6565
  {
5988
6566
  href: whatsappUrl,
@@ -6001,15 +6579,15 @@ function BookingDialog({
6001
6579
  },
6002
6580
  children: [
6003
6581
  "\u{1F4AC} Rather book on WhatsApp?",
6004
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
6582
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
6005
6583
  ]
6006
6584
  }
6007
6585
  ),
6008
- slots === null && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
6009
- (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
6010
- [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: 18 }, children: [
6011
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
6012
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6586
+ slots === null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
6587
+ (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
6588
+ [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { marginBottom: 18 }, children: [
6589
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
6590
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6013
6591
  "button",
6014
6592
  {
6015
6593
  onClick: () => {
@@ -6031,13 +6609,13 @@ function BookingDialog({
6031
6609
  )) })
6032
6610
  ] }, day))
6033
6611
  ] }),
6034
- step === "details" && selected && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6035
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 13, color: t.muted }, children: [
6612
+ step === "details" && selected && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6613
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: 13, color: t.muted }, children: [
6036
6614
  formatDay(selected.startsAt),
6037
6615
  " \xB7 ",
6038
6616
  formatTime(selected.startsAt),
6039
6617
  " \xB7 ",
6040
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6618
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6041
6619
  "button",
6042
6620
  {
6043
6621
  onClick: () => setStep("slots"),
@@ -6046,9 +6624,9 @@ function BookingDialog({
6046
6624
  }
6047
6625
  )
6048
6626
  ] }),
6049
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Your name", value: name, onChange: setName }),
6050
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
6051
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6627
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: "Your name", value: name, onChange: setName }),
6628
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
6629
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6052
6630
  Field,
6053
6631
  {
6054
6632
  label: "Mobile number",
@@ -6058,8 +6636,8 @@ function BookingDialog({
6058
6636
  hint: "We send a code here to confirm, then a reminder before the call."
6059
6637
  }
6060
6638
  ),
6061
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
6062
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6639
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
6640
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6063
6641
  "button",
6064
6642
  {
6065
6643
  onClick: startBooking,
@@ -6069,10 +6647,10 @@ function BookingDialog({
6069
6647
  }
6070
6648
  )
6071
6649
  ] }),
6072
- step === "code" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6073
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.5 }, children: "We sent a 4-digit code to your phone. Your slot is held for 10 minutes." }),
6074
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Code", value: code, onChange: setCode }),
6075
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6650
+ step === "code" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6651
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.5 }, children: "We sent a 4-digit code to your phone. Your slot is held for 10 minutes." }),
6652
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: "Code", value: code, onChange: setCode }),
6653
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6076
6654
  "button",
6077
6655
  {
6078
6656
  onClick: confirmBooking,
@@ -6082,15 +6660,15 @@ function BookingDialog({
6082
6660
  }
6083
6661
  )
6084
6662
  ] }),
6085
- step === "done" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6086
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
6087
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
6663
+ step === "done" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
6664
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
6665
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
6088
6666
  selected && `${formatDay(selected.startsAt)} at ${formatTime(selected.startsAt)}. `,
6089
6667
  "A calendar invite is on its way to ",
6090
6668
  email,
6091
6669
  ", and we'll send a WhatsApp reminder before the call."
6092
6670
  ] }),
6093
- meetUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
6671
+ meetUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
6094
6672
  ] })
6095
6673
  ] })
6096
6674
  ]
@@ -6119,9 +6697,9 @@ function Field({
6119
6697
  type = "text",
6120
6698
  hint
6121
6699
  }) {
6122
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
6700
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
6123
6701
  label,
6124
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6702
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6125
6703
  "input",
6126
6704
  {
6127
6705
  type,
@@ -6142,7 +6720,7 @@ function Field({
6142
6720
  }
6143
6721
  }
6144
6722
  ),
6145
- hint && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
6723
+ hint && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
6146
6724
  ] });
6147
6725
  }
6148
6726
 
@@ -6283,11 +6861,11 @@ function matchesShortcut(e) {
6283
6861
  }
6284
6862
 
6285
6863
  // src/provider.tsx
6286
- var import_jsx_runtime5 = require("react/jsx-runtime");
6864
+ var import_jsx_runtime6 = require("react/jsx-runtime");
6287
6865
  var DEFAULT_BASE_URL2 = "https://glitchgrab.dev";
6288
- var GlitchgrabContext = (0, import_react5.createContext)(null);
6866
+ var GlitchgrabContext = (0, import_react6.createContext)(null);
6289
6867
  function useGlitchgrab() {
6290
- const ctx = (0, import_react5.useContext)(GlitchgrabContext);
6868
+ const ctx = (0, import_react6.useContext)(GlitchgrabContext);
6291
6869
  if (!ctx) {
6292
6870
  throw new Error("useGlitchgrab must be used within a GlitchgrabProvider");
6293
6871
  }
@@ -6295,7 +6873,7 @@ function useGlitchgrab() {
6295
6873
  }
6296
6874
  function GlitchgrabProviderInner({
6297
6875
  token,
6298
- session,
6876
+ session: sessionProp,
6299
6877
  baseUrl,
6300
6878
  onError,
6301
6879
  onReportSent,
@@ -6310,7 +6888,16 @@ function GlitchgrabProviderInner({
6310
6888
  context: appContext2,
6311
6889
  responseBodyOrigins: responseBodyOrigins2
6312
6890
  }) {
6313
- const visitedPagesRef = (0, import_react5.useRef)([]);
6891
+ const visitedPagesRef = (0, import_react6.useRef)([]);
6892
+ const sessionKey = sessionProp ? [
6893
+ sessionProp.userId,
6894
+ sessionProp.name,
6895
+ sessionProp.email,
6896
+ sessionProp.phone,
6897
+ sessionProp.avatarUrl,
6898
+ sessionProp.image
6899
+ ].map((v) => v == null ? "" : String(v)).join("\0") : "";
6900
+ const session = (0, import_react6.useMemo)(() => sessionProp, [sessionKey]);
6314
6901
  setRelease(release2);
6315
6902
  if (appContext2) setContexts(appContext2);
6316
6903
  registerCaptureConfig({
@@ -6322,12 +6909,12 @@ function GlitchgrabProviderInner({
6322
6909
  onError,
6323
6910
  onReportSent
6324
6911
  });
6325
- (0, import_react5.useEffect)(() => {
6912
+ (0, import_react6.useEffect)(() => {
6326
6913
  if (enableBreadcrumbs) {
6327
6914
  initBreadcrumbs(maxBreadcrumbs2, { responseBodyOrigins: responseBodyOrigins2 });
6328
6915
  }
6329
6916
  }, [enableBreadcrumbs, maxBreadcrumbs2, responseBodyOrigins2 == null ? void 0 : responseBodyOrigins2.join(",")]);
6330
- (0, import_react5.useEffect)(() => {
6917
+ (0, import_react6.useEffect)(() => {
6331
6918
  try {
6332
6919
  if (typeof window === "undefined") return;
6333
6920
  const trackPage = () => {
@@ -6364,7 +6951,7 @@ function GlitchgrabProviderInner({
6364
6951
  } catch (e) {
6365
6952
  }
6366
6953
  }, []);
6367
- (0, import_react5.useEffect)(() => {
6954
+ (0, import_react6.useEffect)(() => {
6368
6955
  try {
6369
6956
  if (typeof window === "undefined") return;
6370
6957
  if (process.env.NODE_ENV === "development") return;
@@ -6491,7 +7078,7 @@ function GlitchgrabProviderInner({
6491
7078
  } catch (e) {
6492
7079
  }
6493
7080
  }, [token, baseUrl, onError, onReportSent, session, ignoreErrors]);
6494
- const report = (0, import_react5.useCallback)(
7081
+ const report = (0, import_react6.useCallback)(
6495
7082
  async (type, description, metadata) => {
6496
7083
  var _a;
6497
7084
  try {
@@ -6525,11 +7112,45 @@ function GlitchgrabProviderInner({
6525
7112
  },
6526
7113
  [token, baseUrl, onReportSent, session]
6527
7114
  );
6528
- const reportBug = (0, import_react5.useCallback)(
7115
+ const reportBug = (0, import_react6.useCallback)(
6529
7116
  (description, metadata) => report("BUG", description, metadata),
6530
7117
  [report]
6531
7118
  );
6532
- const feedback = (0, import_react5.useCallback)(
7119
+ const reportGlitchgrabProblem = (0, import_react6.useCallback)(
7120
+ async (params) => {
7121
+ var _a, _b;
7122
+ try {
7123
+ const context = captureContext(visitedPagesRef.current);
7124
+ const body = JSON.stringify({
7125
+ ...params,
7126
+ pageUrl: context.url,
7127
+ userAgent: context.userAgent,
7128
+ deviceInfo: (_a = context.deviceInfo) != null ? _a : void 0,
7129
+ visitedPages: context.visitedPages,
7130
+ breadcrumbs: context.breadcrumbs,
7131
+ ...(session == null ? void 0 : session.userId) ? { reporterId: session.userId } : {},
7132
+ ...(session == null ? void 0 : session.name) ? { reporterName: String(session.name) } : {},
7133
+ ...(session == null ? void 0 : session.email) ? { reporterEmail: String(session.email) } : {}
7134
+ });
7135
+ const res = await fetch(`${baseUrl}/api/v1/sdk/glitchgrab-report`, {
7136
+ method: "POST",
7137
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
7138
+ body,
7139
+ // keepalive caps the body at 64KB — screenshots blow past it.
7140
+ ...body.length < 6e4 ? { keepalive: true } : {}
7141
+ });
7142
+ const json = await res.json().catch(() => null);
7143
+ if (!res.ok || !(json == null ? void 0 : json.success)) {
7144
+ return { success: false, message: (_b = json == null ? void 0 : json.error) != null ? _b : "Couldn't send it" };
7145
+ }
7146
+ return { success: true, ...json.data };
7147
+ } catch (e) {
7148
+ return null;
7149
+ }
7150
+ },
7151
+ [token, baseUrl, session]
7152
+ );
7153
+ const feedback = (0, import_react6.useCallback)(
6533
7154
  async (rating, message, metadata) => {
6534
7155
  try {
6535
7156
  const context = captureContext(visitedPagesRef.current);
@@ -6557,32 +7178,32 @@ function GlitchgrabProviderInner({
6557
7178
  },
6558
7179
  [token, baseUrl, session]
6559
7180
  );
6560
- const openFeedbackDialog = (0, import_react5.useCallback)(() => {
7181
+ const openFeedbackDialog = (0, import_react6.useCallback)(() => {
6561
7182
  if (typeof window !== "undefined") {
6562
7183
  window.dispatchEvent(
6563
7184
  new CustomEvent("glitchgrab:open-report", { detail: { type: "RATING" } })
6564
7185
  );
6565
7186
  }
6566
7187
  }, []);
6567
- const captureError2 = (0, import_react5.useCallback)(
7188
+ const captureError2 = (0, import_react6.useCallback)(
6568
7189
  (error, options) => {
6569
7190
  captureError(error, options);
6570
7191
  },
6571
7192
  []
6572
7193
  );
6573
- const setContext2 = (0, import_react5.useCallback)((key, value) => {
7194
+ const setContext2 = (0, import_react6.useCallback)((key, value) => {
6574
7195
  setContext(key, value);
6575
7196
  }, []);
6576
- const setContexts2 = (0, import_react5.useCallback)((values) => {
7197
+ const setContexts2 = (0, import_react6.useCallback)((values) => {
6577
7198
  setContexts(values);
6578
7199
  }, []);
6579
- const addBreadcrumb2 = (0, import_react5.useCallback)(
7200
+ const addBreadcrumb2 = (0, import_react6.useCallback)(
6580
7201
  (message, data) => {
6581
7202
  addBreadcrumb("custom", message, data);
6582
7203
  },
6583
7204
  []
6584
7205
  );
6585
- const enhance = (0, import_react5.useCallback)(
7206
+ const enhance = (0, import_react6.useCallback)(
6586
7207
  async (text, screenshot) => {
6587
7208
  try {
6588
7209
  const ctx = captureContext(visitedPagesRef.current);
@@ -6598,7 +7219,7 @@ function GlitchgrabProviderInner({
6598
7219
  },
6599
7220
  [token, baseUrl]
6600
7221
  );
6601
- const assist = (0, import_react5.useCallback)(
7222
+ const assist = (0, import_react6.useCallback)(
6602
7223
  async (params) => {
6603
7224
  var _a;
6604
7225
  const ctx = captureContext(visitedPagesRef.current);
@@ -6624,7 +7245,7 @@ function GlitchgrabProviderInner({
6624
7245
  },
6625
7246
  [token, baseUrl, session]
6626
7247
  );
6627
- const transcribe = (0, import_react5.useCallback)(
7248
+ const transcribe = (0, import_react6.useCallback)(
6628
7249
  async (blob) => {
6629
7250
  try {
6630
7251
  return await transcribeAudio(blob, token, baseUrl);
@@ -6634,12 +7255,12 @@ function GlitchgrabProviderInner({
6634
7255
  },
6635
7256
  [token, baseUrl]
6636
7257
  );
6637
- const openReportDialog = (0, import_react5.useCallback)((options) => {
7258
+ const openReportDialog = (0, import_react6.useCallback)((options) => {
6638
7259
  if (typeof window !== "undefined") {
6639
7260
  window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
6640
7261
  }
6641
7262
  }, []);
6642
- (0, import_react5.useEffect)(() => {
7263
+ (0, import_react6.useEffect)(() => {
6643
7264
  try {
6644
7265
  if (typeof document === "undefined") return;
6645
7266
  document.documentElement.setAttribute("data-glitchgrab-sdk", "1");
@@ -6647,11 +7268,12 @@ function GlitchgrabProviderInner({
6647
7268
  } catch (e) {
6648
7269
  }
6649
7270
  }, []);
6650
- const [projectName, setProjectName] = (0, import_react5.useState)(null);
6651
- const [aiAssist, setAiAssist] = (0, import_react5.useState)(false);
6652
- const [bookingOpen, setBookingOpen] = (0, import_react5.useState)(false);
6653
- const openBookingDialog = (0, import_react5.useCallback)(() => setBookingOpen(true), []);
6654
- (0, import_react5.useEffect)(() => {
7271
+ const [projectName, setProjectName] = (0, import_react6.useState)(null);
7272
+ const [aiAssist, setAiAssist] = (0, import_react6.useState)(false);
7273
+ const [glitchgrabReport, setGlitchgrabReport] = (0, import_react6.useState)(false);
7274
+ const [bookingOpen, setBookingOpen] = (0, import_react6.useState)(false);
7275
+ const openBookingDialog = (0, import_react6.useCallback)(() => setBookingOpen(true), []);
7276
+ (0, import_react6.useEffect)(() => {
6655
7277
  let cancelled = false;
6656
7278
  fetch(`${baseUrl}/api/v1/sdk/project`, {
6657
7279
  headers: { Authorization: `Bearer ${token}` }
@@ -6660,13 +7282,14 @@ function GlitchgrabProviderInner({
6660
7282
  if (cancelled || !(json == null ? void 0 : json.success) || !((_a = json.data) == null ? void 0 : _a.name)) return;
6661
7283
  setProjectName(json.data.name);
6662
7284
  setAiAssist(json.data.aiAssist === true);
7285
+ setGlitchgrabReport(json.data.glitchgrabReport === true);
6663
7286
  }).catch(() => {
6664
7287
  });
6665
7288
  return () => {
6666
7289
  cancelled = true;
6667
7290
  };
6668
7291
  }, [baseUrl, token]);
6669
- (0, import_react5.useEffect)(() => {
7292
+ (0, import_react6.useEffect)(() => {
6670
7293
  try {
6671
7294
  if (typeof window === "undefined") return;
6672
7295
  const handleKeyDown = (e) => {
@@ -6680,7 +7303,7 @@ function GlitchgrabProviderInner({
6680
7303
  } catch (e) {
6681
7304
  }
6682
7305
  }, [openReportDialog]);
6683
- const reporter = (0, import_react5.useMemo)(() => {
7306
+ const reporter = (0, import_react6.useMemo)(() => {
6684
7307
  var _a;
6685
7308
  if (!session) return null;
6686
7309
  const avatar = (_a = session.avatarUrl) != null ? _a : session.image;
@@ -6690,11 +7313,11 @@ function GlitchgrabProviderInner({
6690
7313
  avatarUrl: typeof avatar === "string" ? avatar : null
6691
7314
  };
6692
7315
  }, [session]);
6693
- const [shortcutLabel, setShortcutLabel] = (0, import_react5.useState)(GLITCHGRAB_SHORTCUT2);
6694
- (0, import_react5.useEffect)(() => {
7316
+ const [shortcutLabel, setShortcutLabel] = (0, import_react6.useState)(GLITCHGRAB_SHORTCUT2);
7317
+ (0, import_react6.useEffect)(() => {
6695
7318
  setShortcutLabel(getShortcutLabel2());
6696
7319
  }, []);
6697
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
7320
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
6698
7321
  GlitchgrabContext.Provider,
6699
7322
  {
6700
7323
  value: {
@@ -6714,7 +7337,7 @@ function GlitchgrabProviderInner({
6714
7337
  shortcutLabel
6715
7338
  },
6716
7339
  children: [
6717
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
7340
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
6718
7341
  GlitchgrabErrorBoundary,
6719
7342
  {
6720
7343
  token,
@@ -6726,7 +7349,7 @@ function GlitchgrabProviderInner({
6726
7349
  children
6727
7350
  }
6728
7351
  ),
6729
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
7352
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
6730
7353
  BookingDialog,
6731
7354
  {
6732
7355
  token,
@@ -6735,20 +7358,21 @@ function GlitchgrabProviderInner({
6735
7358
  onClose: () => setBookingOpen(false)
6736
7359
  }
6737
7360
  ),
6738
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
7361
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
6739
7362
  ReportDialog,
6740
7363
  {
6741
7364
  report,
6742
7365
  sendFeedback: feedback,
6743
7366
  enhanceText: enhance,
6744
7367
  assist: aiAssist ? assist : void 0,
7368
+ reportGlitchgrabProblem: glitchgrabReport ? reportGlitchgrabProblem : void 0,
6745
7369
  transcribeAudio: transcribe,
6746
7370
  types,
6747
7371
  showSeverity,
6748
7372
  reporter,
6749
- headerSlot: projectName ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
7373
+ headerSlot: projectName ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
6750
7374
  "Reporting to ",
6751
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { style: { color: "#e5e5e5" }, children: projectName })
7375
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { style: { color: "#e5e5e5" }, children: projectName })
6752
7376
  ] }) : null
6753
7377
  }
6754
7378
  )
@@ -6757,21 +7381,21 @@ function GlitchgrabProviderInner({
6757
7381
  );
6758
7382
  }
6759
7383
  function GlitchgrabProvider(props) {
6760
- if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.children });
7384
+ if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: props.children });
6761
7385
  const resolvedProps = {
6762
7386
  ...props,
6763
7387
  baseUrl: props.baseUrl || DEFAULT_BASE_URL2
6764
7388
  };
6765
7389
  try {
6766
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
7390
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
6767
7391
  } catch (e) {
6768
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.children });
7392
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: props.children });
6769
7393
  }
6770
7394
  }
6771
7395
 
6772
7396
  // src/report-button.tsx
6773
- var import_react6 = require("react");
6774
- var import_jsx_runtime6 = require("react/jsx-runtime");
7397
+ var import_react7 = require("react");
7398
+ var import_jsx_runtime7 = require("react/jsx-runtime");
6775
7399
  function useGlitchgrabSafe() {
6776
7400
  try {
6777
7401
  return useGlitchgrab();
@@ -6786,7 +7410,7 @@ function ReportButton({
6786
7410
  children
6787
7411
  }) {
6788
7412
  var _a, _b;
6789
- const [capturing, setCapturing] = (0, import_react6.useState)(false);
7413
+ const [capturing, setCapturing] = (0, import_react7.useState)(false);
6790
7414
  const glitchgrab = useGlitchgrabSafe();
6791
7415
  if (!glitchgrab) return null;
6792
7416
  const handleClick = async () => {
@@ -6795,7 +7419,7 @@ function ReportButton({
6795
7419
  setCapturing(false);
6796
7420
  };
6797
7421
  if (children) {
6798
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: children({ onClick: handleClick, capturing }) });
7422
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: children({ onClick: handleClick, capturing }) });
6799
7423
  }
6800
7424
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
6801
7425
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -6803,7 +7427,7 @@ function ReportButton({
6803
7427
  ...isLeft ? { left: "16px" } : { right: "16px" },
6804
7428
  ...isTop ? { top: "16px" } : { bottom: "16px" }
6805
7429
  };
6806
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
7430
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
6807
7431
  "button",
6808
7432
  {
6809
7433
  type: "button",
@@ -6838,7 +7462,7 @@ function ReportButton({
6838
7462
  },
6839
7463
  "aria-label": label,
6840
7464
  children: [
6841
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7465
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6842
7466
  "svg",
6843
7467
  {
6844
7468
  width: "16",
@@ -6846,7 +7470,7 @@ function ReportButton({
6846
7470
  viewBox: "0 0 16 16",
6847
7471
  fill: "none",
6848
7472
  style: { flexShrink: 0 },
6849
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7473
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6850
7474
  "path",
6851
7475
  {
6852
7476
  d: "M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z",
@@ -6862,15 +7486,15 @@ function ReportButton({
6862
7486
  }
6863
7487
 
6864
7488
  // src/book-demo-button.tsx
6865
- var import_jsx_runtime7 = require("react/jsx-runtime");
7489
+ var import_jsx_runtime8 = require("react/jsx-runtime");
6866
7490
  function BookDemoButton({
6867
7491
  label = "Book a demo",
6868
7492
  className,
6869
7493
  children
6870
7494
  }) {
6871
7495
  const { openBookingDialog } = useGlitchgrab();
6872
- if (children) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: children({ onClick: openBookingDialog }) });
6873
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
7496
+ if (children) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: children({ onClick: openBookingDialog }) });
7497
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6874
7498
  "button",
6875
7499
  {
6876
7500
  type: "button",
@@ -6892,7 +7516,7 @@ function BookDemoButton({
6892
7516
  }
6893
7517
 
6894
7518
  // src/feedback-button.tsx
6895
- var import_jsx_runtime8 = require("react/jsx-runtime");
7519
+ var import_jsx_runtime9 = require("react/jsx-runtime");
6896
7520
  function useGlitchgrabSafe2() {
6897
7521
  try {
6898
7522
  return useGlitchgrab();
@@ -6911,7 +7535,7 @@ function FeedbackButton({
6911
7535
  if (!glitchgrab) return null;
6912
7536
  const handleClick = () => glitchgrab.openFeedbackDialog();
6913
7537
  if (children) {
6914
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: children({ onClick: handleClick }) });
7538
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: children({ onClick: handleClick }) });
6915
7539
  }
6916
7540
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
6917
7541
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -6919,7 +7543,7 @@ function FeedbackButton({
6919
7543
  ...isLeft ? { left: "16px" } : { right: "16px" },
6920
7544
  ...isTop ? { top: "16px" } : { bottom: "16px" }
6921
7545
  };
6922
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
7546
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
6923
7547
  "button",
6924
7548
  {
6925
7549
  type: "button",
@@ -6952,7 +7576,7 @@ function FeedbackButton({
6952
7576
  },
6953
7577
  "aria-label": label,
6954
7578
  children: [
6955
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
7579
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6956
7580
  "svg",
6957
7581
  {
6958
7582
  width: "16",
@@ -6961,7 +7585,7 @@ function FeedbackButton({
6961
7585
  fill: "none",
6962
7586
  style: { flexShrink: 0 },
6963
7587
  "aria-hidden": "true",
6964
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
7588
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6965
7589
  "path",
6966
7590
  {
6967
7591
  d: "M12 2.5l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.4l-5.8 3 1.1-6.5L2.6 9.3l6.5-.9L12 2.5z",
@@ -6977,18 +7601,18 @@ function FeedbackButton({
6977
7601
  }
6978
7602
 
6979
7603
  // src/use-reports.ts
6980
- var import_react7 = require("react");
7604
+ var import_react8 = require("react");
6981
7605
  var BASE_URL = "https://glitchgrab.dev";
6982
7606
  function useGlitchgrabReports({
6983
7607
  token,
6984
7608
  userId,
6985
7609
  limit = 100
6986
7610
  }) {
6987
- const [reports, setReports] = (0, import_react7.useState)([]);
6988
- const [isLoading, setIsLoading] = (0, import_react7.useState)(true);
6989
- const [isFetching, setIsFetching] = (0, import_react7.useState)(false);
6990
- const [error, setError] = (0, import_react7.useState)(null);
6991
- const fetchReports = (0, import_react7.useCallback)(async () => {
7611
+ const [reports, setReports] = (0, import_react8.useState)([]);
7612
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
7613
+ const [isFetching, setIsFetching] = (0, import_react8.useState)(false);
7614
+ const [error, setError] = (0, import_react8.useState)(null);
7615
+ const fetchReports = (0, import_react8.useCallback)(async () => {
6992
7616
  var _a, _b;
6993
7617
  if (!token || !userId) {
6994
7618
  setIsLoading(false);
@@ -7014,7 +7638,7 @@ function useGlitchgrabReports({
7014
7638
  setIsFetching(false);
7015
7639
  }
7016
7640
  }, [token, userId, limit]);
7017
- (0, import_react7.useEffect)(() => {
7641
+ (0, import_react8.useEffect)(() => {
7018
7642
  fetchReports();
7019
7643
  }, [fetchReports]);
7020
7644
  return { reports, isLoading, isFetching, error, refetch: fetchReports };
@@ -7051,9 +7675,9 @@ function useGlitchgrabActions({
7051
7675
  onSuccess,
7052
7676
  onError
7053
7677
  }) {
7054
- const [isPending, setIsPending] = (0, import_react7.useState)(false);
7055
- const [error, setError] = (0, import_react7.useState)(null);
7056
- const run = (0, import_react7.useCallback)(
7678
+ const [isPending, setIsPending] = (0, import_react8.useState)(false);
7679
+ const [error, setError] = (0, import_react8.useState)(null);
7680
+ const run = (0, import_react8.useCallback)(
7057
7681
  async (reportId, body) => {
7058
7682
  setIsPending(true);
7059
7683
  setError(null);
@@ -7083,7 +7707,7 @@ function useGlitchgrabActions({
7083
7707
  }
7084
7708
 
7085
7709
  // src/use-feedback.ts
7086
- var import_react8 = require("react");
7710
+ var import_react9 = require("react");
7087
7711
  var DEFAULT_BASE_URL3 = "https://glitchgrab.dev";
7088
7712
  function buildUrl({
7089
7713
  approvedOnly,
@@ -7109,11 +7733,11 @@ async function fetchGlitchgrabFeedback(query) {
7109
7733
  }
7110
7734
  function useGlitchgrabFeedback(query) {
7111
7735
  const { token, approvedOnly, userId, minRating, limit, baseUrl } = query;
7112
- const [feedback, setFeedback] = (0, import_react8.useState)([]);
7113
- const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
7114
- const [isFetching, setIsFetching] = (0, import_react8.useState)(false);
7115
- const [error, setError] = (0, import_react8.useState)(null);
7116
- const load = (0, import_react8.useCallback)(async () => {
7736
+ const [feedback, setFeedback] = (0, import_react9.useState)([]);
7737
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(true);
7738
+ const [isFetching, setIsFetching] = (0, import_react9.useState)(false);
7739
+ const [error, setError] = (0, import_react9.useState)(null);
7740
+ const load = (0, import_react9.useCallback)(async () => {
7117
7741
  if (!token) {
7118
7742
  setIsLoading(false);
7119
7743
  return;
@@ -7137,7 +7761,7 @@ function useGlitchgrabFeedback(query) {
7137
7761
  setIsFetching(false);
7138
7762
  }
7139
7763
  }, [token, approvedOnly, userId, minRating, limit, baseUrl]);
7140
- (0, import_react8.useEffect)(() => {
7764
+ (0, import_react9.useEffect)(() => {
7141
7765
  load();
7142
7766
  }, [load]);
7143
7767
  return { feedback, isLoading, isFetching, error, refetch: load };