@diegotsi/flint-react 0.1.2 → 0.1.5

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.cjs CHANGED
@@ -21,12 +21,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  FlintModal: () => FlintModal,
24
- FlintWidget: () => FlintWidget
24
+ FlintWidget: () => FlintWidget,
25
+ flint: () => flint
25
26
  });
26
27
  module.exports = __toCommonJS(index_exports);
27
28
 
28
29
  // src/FlintWidget.tsx
29
- var import_react2 = require("react");
30
+ var import_react3 = require("react");
30
31
  var import_react_i18next3 = require("react-i18next");
31
32
 
32
33
  // src/FlintModal.tsx
@@ -177,7 +178,7 @@ function FlintModal({
177
178
  getConsoleLogs,
178
179
  getNetworkErrors,
179
180
  getReplayEvents,
180
- externalReplayUrl
181
+ getExternalReplayUrl
181
182
  }) {
182
183
  const { t } = (0, import_react_i18next.useTranslation)();
183
184
  const colors = resolveTheme(theme);
@@ -227,7 +228,7 @@ function FlintModal({
227
228
  reporterName: user?.name ?? "Anonymous",
228
229
  description: description.trim(),
229
230
  expectedBehavior: expectedBehavior.trim() || void 0,
230
- externalReplayUrl: externalReplayUrl || void 0,
231
+ externalReplayUrl: getExternalReplayUrl() || void 0,
231
232
  severity,
232
233
  url: window.location.href,
233
234
  meta: collectedMeta
@@ -412,10 +413,10 @@ function FlintModal({
412
413
  pointerEvents: isSuccess ? "auto" : "none"
413
414
  }, children: [
414
415
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: 13, color: colors.textMuted, margin: 0 }, children: result?.isDuplicate ? t("successDuplicate") : result ? `ID: ${result.id}` : "" }),
415
- result?.githubIssueUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
416
+ result?.slackMessageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
416
417
  "a",
417
418
  {
418
- href: result.githubIssueUrl,
419
+ href: result.slackMessageUrl,
419
420
  target: "_blank",
420
421
  rel: "noreferrer",
421
422
  style: {
@@ -432,7 +433,7 @@ function FlintModal({
432
433
  boxShadow: accentGlow
433
434
  },
434
435
  children: [
435
- t("successGitHub"),
436
+ t("successSlack"),
436
437
  " \u2197"
437
438
  ]
438
439
  }
@@ -553,6 +554,19 @@ function FlintModal({
553
554
  }
554
555
  )
555
556
  ] }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
558
+ display: "flex",
559
+ alignItems: "center",
560
+ gap: 8,
561
+ padding: "9px 12px",
562
+ borderRadius: 10,
563
+ background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
564
+ border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
565
+ marginBottom: 16
566
+ }, children: [
567
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 14 }, children: "\u{1F3A5}" }),
568
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 12, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
569
+ ] }),
556
570
  status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
557
571
  padding: "10px 13px",
558
572
  borderRadius: 10,
@@ -768,6 +782,8 @@ var en_default = {
768
782
  successTitle: "Bug reported!",
769
783
  successDuplicate: "Looks like a duplicate of an existing bug.",
770
784
  successGitHub: "View GitHub issue",
785
+ successSlack: "View Slack message",
786
+ replayInfo: "No need to record your screen \u2014 we automatically capture a session replay when you submit.",
771
787
  errorLabel: "Failed to submit. Please try again.",
772
788
  cancel: "Cancel",
773
789
  sending: "Sending report",
@@ -980,13 +996,41 @@ function createNetworkCollector() {
980
996
  };
981
997
  }
982
998
 
999
+ // src/store.ts
1000
+ var import_react2 = require("react");
1001
+ var state = { user: void 0, sessionReplay: void 0 };
1002
+ var listeners = /* @__PURE__ */ new Set();
1003
+ function emit() {
1004
+ listeners.forEach((fn) => fn());
1005
+ }
1006
+ function subscribeStore(fn) {
1007
+ listeners.add(fn);
1008
+ return () => listeners.delete(fn);
1009
+ }
1010
+ function getSnapshot() {
1011
+ return state;
1012
+ }
1013
+ function useFlintStore() {
1014
+ return (0, import_react2.useSyncExternalStore)(subscribeStore, getSnapshot);
1015
+ }
1016
+ var flint = {
1017
+ setUser(user) {
1018
+ state = { ...state, user: user ?? void 0 };
1019
+ emit();
1020
+ },
1021
+ setSessionReplay(url) {
1022
+ state = { ...state, sessionReplay: url };
1023
+ emit();
1024
+ }
1025
+ };
1026
+
983
1027
  // src/FlintWidget.tsx
984
1028
  var import_rrweb = require("rrweb");
985
1029
  var import_jsx_runtime2 = require("react/jsx-runtime");
986
1030
  var REPLAY_WINDOW_MS = 6e4;
987
1031
  function FlintWidget(props) {
988
1032
  const { locale = "en-US" } = props;
989
- (0, import_react2.useEffect)(() => {
1033
+ (0, import_react3.useEffect)(() => {
990
1034
  i18n_default.changeLanguage(locale);
991
1035
  }, [locale]);
992
1036
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_i18next3.I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(WidgetContent, { ...props }) });
@@ -1001,15 +1045,21 @@ function WidgetContent({
1001
1045
  theme = "dark",
1002
1046
  zIndex = 9999
1003
1047
  }) {
1004
- const externalReplayUrl = extraFields?.sessionReplay;
1048
+ const globalState = useFlintStore();
1049
+ const resolvedUser = user ?? globalState.user;
1050
+ const resolvedSessionReplay = extraFields?.sessionReplay ?? globalState.sessionReplay;
1051
+ const getExternalReplayUrl = () => {
1052
+ const src = resolvedSessionReplay;
1053
+ return typeof src === "function" ? src() : src;
1054
+ };
1005
1055
  const { t } = (0, import_react_i18next3.useTranslation)();
1006
- const [open, setOpen] = (0, import_react2.useState)(false);
1007
- const [hovered, setHovered] = (0, import_react2.useState)(false);
1056
+ const [open, setOpen] = (0, import_react3.useState)(false);
1057
+ const [hovered, setHovered] = (0, import_react3.useState)(false);
1008
1058
  const colors = resolveTheme(theme);
1009
- const consoleCollector = (0, import_react2.useRef)(null);
1010
- const networkCollector = (0, import_react2.useRef)(null);
1011
- const replayEvents = (0, import_react2.useRef)([]);
1012
- const stopReplay = (0, import_react2.useRef)(null);
1059
+ const consoleCollector = (0, import_react3.useRef)(null);
1060
+ const networkCollector = (0, import_react3.useRef)(null);
1061
+ const replayEvents = (0, import_react3.useRef)([]);
1062
+ const stopReplay = (0, import_react3.useRef)(null);
1013
1063
  if (!consoleCollector.current) {
1014
1064
  consoleCollector.current = createConsoleCollector();
1015
1065
  consoleCollector.current.start();
@@ -1018,7 +1068,7 @@ function WidgetContent({
1018
1068
  networkCollector.current = createNetworkCollector();
1019
1069
  networkCollector.current.start();
1020
1070
  }
1021
- (0, import_react2.useEffect)(() => {
1071
+ (0, import_react3.useEffect)(() => {
1022
1072
  const stopFn = (0, import_rrweb.record)({
1023
1073
  emit(event) {
1024
1074
  replayEvents.current.push(event);
@@ -1046,7 +1096,7 @@ function WidgetContent({
1046
1096
  "aria-label": label,
1047
1097
  style: {
1048
1098
  position: "fixed",
1049
- bottom: "20px",
1099
+ bottom: "40px",
1050
1100
  right: "20px",
1051
1101
  zIndex: zIndex - 1,
1052
1102
  display: "flex",
@@ -1077,7 +1127,7 @@ function WidgetContent({
1077
1127
  {
1078
1128
  projectKey,
1079
1129
  serverUrl,
1080
- user,
1130
+ user: resolvedUser,
1081
1131
  meta,
1082
1132
  theme,
1083
1133
  zIndex,
@@ -1086,7 +1136,7 @@ function WidgetContent({
1086
1136
  getConsoleLogs: () => consoleCollector.current?.getEntries() ?? [],
1087
1137
  getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
1088
1138
  getReplayEvents: () => [...replayEvents.current],
1089
- externalReplayUrl
1139
+ getExternalReplayUrl
1090
1140
  }
1091
1141
  )
1092
1142
  ] });
@@ -1111,6 +1161,7 @@ function SparkIcon2() {
1111
1161
  // Annotate the CommonJS export names for ESM import in node:
1112
1162
  0 && (module.exports = {
1113
1163
  FlintModal,
1114
- FlintWidget
1164
+ FlintWidget,
1165
+ flint
1115
1166
  });
1116
1167
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/FlintWidget.tsx","../src/FlintModal.tsx","../src/api.ts","../src/theme.ts","../src/i18n/index.ts","../src/i18n/locales/en.json","../src/collectors/environment.ts","../src/collectors/console.ts","../src/collectors/network.ts"],"sourcesContent":["export { FlintWidget } from \"./FlintWidget.js\";\nexport { FlintModal } from \"./FlintModal.js\";\nexport type {\n FlintWidgetProps,\n FlintUser,\n Severity,\n Locale,\n Theme,\n ThemeOverride,\n ReportPayload,\n ReportResult,\n} from \"@flint/types\";\n","import { useState, useEffect, useRef } from \"react\";\nimport { I18nextProvider, useTranslation } from \"react-i18next\";\nimport { FlintModal } from \"./FlintModal.js\";\nimport type { FlintWidgetProps } from \"@flint/types\";\nimport { resolveTheme } from \"./theme.js\";\nimport widgetI18n from \"./i18n/index.js\";\nimport { collectEnvironment } from \"./collectors/environment.js\";\nimport { createConsoleCollector } from \"./collectors/console.js\";\nimport { createNetworkCollector } from \"./collectors/network.js\";\nimport { record } from \"rrweb\";\nimport type { eventWithTime } from \"@rrweb/types\";\n\nconst REPLAY_WINDOW_MS = 60_000; // rolling 60-second buffer\n\nexport function FlintWidget(props: FlintWidgetProps) {\n const { locale = \"en-US\" } = props;\n\n useEffect(() => {\n widgetI18n.changeLanguage(locale);\n }, [locale]);\n\n return (\n <I18nextProvider i18n={widgetI18n}>\n <WidgetContent {...props} />\n </I18nextProvider>\n );\n}\n\nfunction WidgetContent({\n projectKey,\n serverUrl,\n user,\n meta,\n extraFields,\n buttonLabel,\n theme = \"dark\",\n zIndex = 9999,\n}: FlintWidgetProps) {\n const externalReplayUrl = extraFields?.sessionReplay;\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [hovered, setHovered] = useState(false);\n const colors = resolveTheme(theme);\n\n // ── Collectors ─────────────────────────────────────────────────────────────\n // Start synchronously so window.fetch is patched before React effects run,\n // ensuring the admin's initial API requests are captured.\n const consoleCollector = useRef<ReturnType<typeof createConsoleCollector> | null>(null);\n const networkCollector = useRef<ReturnType<typeof createNetworkCollector> | null>(null);\n const replayEvents = useRef<eventWithTime[]>([]);\n const stopReplay = useRef<(() => void) | null>(null);\n\n if (!consoleCollector.current) {\n consoleCollector.current = createConsoleCollector();\n consoleCollector.current.start();\n }\n if (!networkCollector.current) {\n networkCollector.current = createNetworkCollector();\n networkCollector.current.start();\n }\n\n useEffect(() => {\n // Start rrweb recording with rolling buffer (must be in effect for DOM access)\n const stopFn = record({\n emit(event) {\n replayEvents.current.push(event);\n // Trim to rolling window\n const cutoff = Date.now() - REPLAY_WINDOW_MS;\n while (\n replayEvents.current.length > 0 &&\n replayEvents.current[0].timestamp < cutoff\n ) {\n replayEvents.current.shift();\n }\n },\n });\n stopReplay.current = stopFn ?? null;\n\n return () => {\n consoleCollector.current?.stop();\n networkCollector.current?.stop();\n stopReplay.current?.();\n };\n }, []);\n\n const label = buttonLabel ?? t(\"buttonLabel\");\n\n return (\n <>\n {/* Floating trigger button */}\n <button\n onClick={() => setOpen(true)}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n aria-label={label}\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n right: \"20px\",\n zIndex: zIndex - 1,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n fontSize: \"13px\",\n fontWeight: 600,\n cursor: \"pointer\",\n boxShadow: hovered\n ? `0 0 28px ${colors.accent}55, 0 8px 24px rgba(0,0,0,0.3)`\n : `0 0 16px ${colors.accent}33, 0 4px 16px rgba(0,0,0,0.2)`,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n transform: hovered ? \"translateY(-2px)\" : \"translateY(0)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n letterSpacing: \"0.01em\",\n }}\n >\n <SparkIcon />\n {label}\n </button>\n\n {/* Modal */}\n {open && (\n <FlintModal\n projectKey={projectKey}\n serverUrl={serverUrl}\n user={user}\n meta={meta}\n theme={theme}\n zIndex={zIndex}\n onClose={() => setOpen(false)}\n getEnvironment={collectEnvironment}\n getConsoleLogs={() => consoleCollector.current?.getEntries() ?? []}\n getNetworkErrors={() => networkCollector.current?.getEntries() ?? []}\n getReplayEvents={() => [...replayEvents.current]}\n externalReplayUrl={externalReplayUrl}\n />\n )}\n </>\n );\n}\n\nfunction SparkIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n );\n}\n","import { useRef, useState, useEffect, useCallback } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type {\n Severity,\n FlintUser,\n Theme,\n ReportResult,\n EnvironmentInfo,\n ConsoleEntry,\n NetworkEntry,\n} from \"@flint/types\";\nimport type { eventWithTime } from \"@rrweb/types\";\nimport { submitReport, submitReplay } from \"./api.js\";\nimport { resolveTheme } from \"./theme.js\";\n\ninterface Props {\n projectKey: string;\n serverUrl: string;\n user?: FlintUser;\n meta?: Record<string, unknown>;\n theme: Theme;\n zIndex: number;\n onClose: () => void;\n getEnvironment: () => EnvironmentInfo;\n getConsoleLogs: () => ConsoleEntry[];\n getNetworkErrors: () => NetworkEntry[];\n getReplayEvents: () => eventWithTime[];\n externalReplayUrl?: string;\n}\n\nconst SEVERITIES: Severity[] = [\"P1\", \"P2\", \"P3\", \"P4\"];\nconst SEV_COLOR: Record<Severity, string> = {\n P1: \"#ef4444\",\n P2: \"#f97316\",\n P3: \"#eab308\",\n P4: \"#22c55e\",\n};\n\ntype Status = \"idle\" | \"submitting\" | \"success\" | \"error\";\n\n// Inject CSS keyframes once — animations can't be done with inline styles alone\nfunction injectKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(\"_flint_kf\")) return;\n const s = document.createElement(\"style\");\n s.id = \"_flint_kf\";\n s.textContent = `\n @keyframes _flint_in {\n from { opacity: 0; transform: scale(0.93) translateY(10px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n }\n @keyframes _flint_overlay_in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes _flint_spin {\n to { transform: rotate(360deg); }\n }\n @keyframes _flint_pulse {\n 0%, 100% { opacity: 0.5; transform: scale(0.88); }\n 50% { opacity: 1; transform: scale(1.08); }\n }\n @keyframes _flint_ripple {\n 0% { opacity: 0.5; transform: scale(0.75); }\n 100% { opacity: 0; transform: scale(1.55); }\n }\n @keyframes _flint_sending_dot {\n 0%, 80%, 100% { opacity: 0.2; transform: scale(0.8); }\n 40% { opacity: 1; transform: scale(1); }\n }\n @keyframes _flint_success_up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `;\n document.head.appendChild(s);\n}\n\nexport function FlintModal({\n projectKey,\n serverUrl,\n user,\n meta,\n theme,\n zIndex,\n onClose,\n getEnvironment,\n getConsoleLogs,\n getNetworkErrors,\n getReplayEvents,\n externalReplayUrl,\n}: Props) {\n const { t } = useTranslation();\n const colors = resolveTheme(theme);\n const isDark = theme === \"dark\";\n\n const [severity, setSeverity] = useState<Severity>(\"P2\");\n const [description, setDescription] = useState(\"\");\n const [expectedBehavior, setExpectedBehavior] = useState(\"\");\n const [screenshot, setScreenshot] = useState<File | null>(null);\n const [status, setStatus] = useState<Status>(\"idle\");\n const [result, setResult] = useState<ReportResult | null>(null);\n const [errorMsg, setErrorMsg] = useState(\"\");\n\n const fileRef = useRef<HTMLInputElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => { injectKeyframes(); }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && status !== \"submitting\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [onClose, status]);\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent) => {\n if (e.target === overlayRef.current && status !== \"submitting\") onClose();\n },\n [onClose, status],\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!description.trim()) return;\n\n setStatus(\"submitting\");\n setErrorMsg(\"\");\n\n const collectedMeta: Record<string, unknown> = {\n ...meta,\n environment: getEnvironment(),\n consoleLogs: getConsoleLogs(),\n networkErrors: getNetworkErrors(),\n };\n\n try {\n const res = await submitReport(\n serverUrl,\n projectKey,\n {\n reporterId: user?.id ?? \"anonymous\",\n reporterName: user?.name ?? \"Anonymous\",\n description: description.trim(),\n expectedBehavior: expectedBehavior.trim() || undefined,\n externalReplayUrl: externalReplayUrl || undefined,\n severity,\n url: window.location.href,\n meta: collectedMeta,\n },\n screenshot ?? undefined,\n );\n setResult(res);\n setStatus(\"success\");\n\n const events = getReplayEvents();\n if (events.length > 0) {\n submitReplay(serverUrl, projectKey, res.id, events).catch(() => {});\n }\n } catch (err) {\n setErrorMsg(err instanceof Error ? err.message : t(\"errorLabel\"));\n setStatus(\"error\");\n }\n };\n\n // ── Shared style tokens ────────────────────────────────────────────────────\n const inputBorder = isDark ? \"rgba(255,255,255,0.1)\" : \"rgba(0,0,0,0.1)\";\n const accentGlow = `0 0 20px ${colors.accent}40, 0 4px 16px rgba(0,0,0,0.2)`;\n\n const overlayStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n background: \"rgba(0,0,0,0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex,\n padding: \"16px\",\n backdropFilter: \"blur(10px)\",\n WebkitBackdropFilter: \"blur(10px)\",\n animation: \"_flint_overlay_in 0.2s ease\",\n };\n\n const modalStyle: React.CSSProperties = {\n background: colors.background,\n backdropFilter: colors.backdropFilter,\n WebkitBackdropFilter: colors.backdropFilter,\n borderRadius: \"20px\",\n boxShadow: colors.shadow,\n border: `1px solid ${colors.border}`,\n width: \"100%\",\n maxWidth: \"480px\",\n maxHeight: \"92vh\",\n overflowY: \"auto\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n color: colors.text,\n animation: \"_flint_in 0.28s cubic-bezier(0.16, 1, 0.3, 1)\",\n };\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\",\n padding: \"11px 13px\",\n borderRadius: \"10px\",\n border: `1px solid ${inputBorder}`,\n background: colors.backgroundSecondary,\n color: colors.text,\n fontSize: \"14px\",\n outline: \"none\",\n boxSizing: \"border-box\",\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s\",\n };\n\n // ── Loading + Success (unified animated state) ────────────────────────────\n if (status === \"submitting\" || status === \"success\") {\n const isSuccess = status === \"success\";\n const ringBorder = isSuccess\n ? \"3px solid #22c55e\"\n : `3px solid ${isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.08)\"}`;\n const ringTopColor = isSuccess ? \"#22c55e\" : colors.accent;\n\n return (\n <div style={overlayStyle}>\n <div style={modalStyle} role=\"dialog\" aria-modal=\"true\" aria-label={isSuccess ? t(\"successTitle\") : t(\"sending\")}>\n <ModalHeader colors={colors} inputBorder={inputBorder} showClose={false} onClose={onClose} />\n\n <div style={{ padding: \"40px 32px 48px\", textAlign: \"center\", display: \"flex\", flexDirection: \"column\", alignItems: \"center\" }}>\n {/* Animated rings */}\n <div style={{ position: \"relative\", width: 80, height: 80, marginBottom: 28 }}>\n {/* Ripple 1 — fade out on success */}\n <div style={{\n position: \"absolute\", inset: -10,\n borderRadius: \"50%\",\n border: `1.5px solid ${colors.accent}`,\n animation: \"_flint_ripple 1.8s ease-out infinite\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }} />\n {/* Ripple 2 (delayed) */}\n <div style={{\n position: \"absolute\", inset: -10,\n borderRadius: \"50%\",\n border: `1.5px solid ${colors.accent}`,\n animation: \"_flint_ripple 1.8s ease-out infinite 0.6s\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }} />\n {/* Spinning ring — transitions to solid green on success */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n border: ringBorder,\n borderTopColor: ringTopColor,\n animation: isSuccess ? \"none\" : \"_flint_spin 0.85s linear infinite\",\n transition: \"border-color 0.45s ease, border-top-color 0.45s ease\",\n }} />\n {/* Center: spark fades out, check fades in */}\n <div style={{ position: \"absolute\", inset: 14, borderRadius: \"50%\" }}>\n {/* Spark */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n background: `linear-gradient(135deg, ${colors.accent}30, ${colors.accentHover}50)`,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n animation: isSuccess ? \"none\" : \"_flint_pulse 2s ease-in-out infinite\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }}>\n <SparkIcon color={colors.accent} size={20} />\n </div>\n {/* Checkmark */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n background: \"rgba(34,197,94,0.15)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"scale(1)\" : \"scale(0.65)\",\n transition: \"opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s\",\n }}>\n <CheckIcon size={20} />\n </div>\n </div>\n </div>\n\n {/* Title crossfade */}\n <div style={{ position: \"relative\", height: 26, width: \"100%\", marginBottom: 10 }}>\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n fontSize: 17, fontWeight: 700, color: colors.text, letterSpacing: \"-0.02em\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.25s ease\",\n pointerEvents: \"none\",\n }}>\n {t(\"sending\")}\n </div>\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n fontSize: 17, fontWeight: 700, color: colors.text, letterSpacing: \"-0.02em\",\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"translateY(0)\" : \"translateY(6px)\",\n transition: \"opacity 0.35s ease 0.25s, transform 0.35s ease 0.25s\",\n pointerEvents: isSuccess ? \"auto\" : \"none\",\n }}>\n {t(\"successTitle\")}\n </div>\n </div>\n\n {/* Subtitle crossfade */}\n <div style={{ position: \"relative\", minHeight: 76, width: \"100%\" }}>\n {/* Loading subtitle */}\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n gap: 6, color: colors.textMuted, fontSize: 13,\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.2s ease\",\n pointerEvents: \"none\",\n }}>\n <span>{t(\"capturingContext\")}</span>\n <SendingDots color={colors.accent} />\n </div>\n {/* Success subtitle */}\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 10,\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"translateY(0)\" : \"translateY(8px)\",\n transition: \"opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s\",\n pointerEvents: isSuccess ? \"auto\" : \"none\",\n }}>\n <p style={{ fontSize: 13, color: colors.textMuted, margin: 0 }}>\n {result?.isDuplicate ? t(\"successDuplicate\") : result ? `ID: ${result.id}` : \"\"}\n </p>\n {result?.githubIssueUrl && (\n <a\n href={result.githubIssueUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"9px 18px\",\n borderRadius: \"10px\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n textDecoration: \"none\",\n fontSize: \"13px\",\n fontWeight: 600,\n boxShadow: accentGlow,\n }}\n >\n {t(\"successGitHub\")} ↗\n </a>\n )}\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n padding: \"4px 8px\",\n fontFamily: \"inherit\",\n }}\n >\n {t(\"cancel\")}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // ── Form ──────────────────────────────────────────────────────────────────\n return (\n <div ref={overlayRef} style={overlayStyle} onClick={handleOverlayClick}>\n <div style={modalStyle} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"flint-modal-title\">\n <ModalHeader\n colors={colors}\n inputBorder={inputBorder}\n showClose\n onClose={onClose}\n titleId=\"flint-modal-title\"\n title={t(\"modalTitle\")}\n />\n\n <form onSubmit={handleSubmit} style={{ padding: \"20px 24px 24px\" }}>\n {/* Severity */}\n <div style={{ marginBottom: 18 }}>\n <FieldLabel colors={colors}>{t(\"severityLabel\")}</FieldLabel>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(4,1fr)\", gap: 8 }}>\n {SEVERITIES.map((sev) => (\n <SeverityButton\n key={sev}\n sev={sev}\n label={t(`severity_${sev}_label`)}\n selected={severity === sev}\n hint={t(`severity_${sev}_hint`)}\n color={SEV_COLOR[sev]}\n accent={colors.accent}\n border={inputBorder}\n bg={colors.backgroundSecondary}\n text={colors.text}\n onClick={() => setSeverity(sev)}\n />\n ))}\n </div>\n </div>\n\n {/* What Is Broken */}\n <div style={{ marginBottom: 14 }}>\n <FieldLabel colors={colors} htmlFor=\"flint-description\">{t(\"whatIsBrokenLabel\")}</FieldLabel>\n <textarea\n id=\"flint-description\"\n style={{ ...inputStyle, resize: \"vertical\", minHeight: 80 }}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t(\"whatIsBrokenPlaceholder\")}\n required\n />\n </div>\n\n {/* Expected Behavior (optional) */}\n <div style={{ marginBottom: 14 }}>\n <FieldLabel colors={colors} htmlFor=\"flint-expected\">{t(\"expectedBehaviorLabel\")}</FieldLabel>\n <textarea\n id=\"flint-expected\"\n style={{ ...inputStyle, resize: \"vertical\", minHeight: 72 }}\n value={expectedBehavior}\n onChange={(e) => setExpectedBehavior(e.target.value)}\n placeholder={t(\"expectedBehaviorPlaceholder\")}\n />\n </div>\n\n {/* Screenshot */}\n <div style={{ marginBottom: 20 }}>\n <FieldLabel colors={colors}>{t(\"screenshotLabel\")}</FieldLabel>\n <label\n htmlFor=\"flint-screenshot\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"10px 13px\",\n borderRadius: 10,\n border: `1px dashed ${inputBorder}`,\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n background: colors.backgroundSecondary,\n }}\n >\n 📎 {screenshot ? screenshot.name : t(\"screenshotPlaceholder\")}\n </label>\n <input\n id=\"flint-screenshot\"\n ref={fileRef}\n type=\"file\"\n accept=\"image/*\"\n style={{ display: \"none\" }}\n onChange={(e) => setScreenshot(e.target.files?.[0] ?? null)}\n />\n </div>\n\n {/* Error */}\n {status === \"error\" && (\n <div style={{\n padding: \"10px 13px\",\n borderRadius: 10,\n background: \"rgba(239,68,68,0.08)\",\n border: \"1px solid rgba(239,68,68,0.2)\",\n color: \"#f87171\",\n fontSize: 12,\n marginBottom: 16,\n }}>\n ⚠️ {errorMsg || t(\"errorLabel\")}\n </div>\n )}\n\n {/* Submit */}\n <button\n type=\"submit\"\n style={{\n width: \"100%\",\n padding: \"13px 20px\",\n borderRadius: 12,\n border: \"none\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n fontSize: 15,\n fontWeight: 700,\n cursor: \"pointer\",\n letterSpacing: \"-0.01em\",\n boxShadow: accentGlow,\n fontFamily: \"inherit\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 8,\n }}\n >\n <SparkIcon color={colors.buttonText} size={15} />\n {t(\"submitLabel\")}\n </button>\n\n {/* Cancel */}\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n width: \"100%\",\n padding: \"10px\",\n marginTop: 8,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n fontFamily: \"inherit\",\n borderRadius: 8,\n }}\n >\n {t(\"cancel\")}\n </button>\n </form>\n </div>\n </div>\n );\n}\n\n// ─── Sub-components ──────────────────────────────────────────────────────────\n\nfunction ModalHeader({\n colors,\n inputBorder,\n showClose,\n onClose,\n titleId,\n title,\n}: {\n colors: ReturnType<typeof resolveTheme>;\n inputBorder: string;\n showClose: boolean;\n onClose: () => void;\n titleId?: string;\n title?: string;\n}) {\n return (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"16px 20px 14px\",\n borderBottom: `1px solid ${inputBorder}`,\n }}>\n {/* Brand chip */}\n <div style={{\n width: 28, height: 28,\n borderRadius: 8,\n background: `linear-gradient(135deg, ${colors.accent}20, ${colors.accentHover}35)`,\n border: `1px solid ${colors.accent}30`,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n flexShrink: 0,\n }}>\n <SparkIcon color={colors.accent} size={13} />\n </div>\n\n {titleId && title ? (\n <h2 id={titleId} style={{ margin: 0, fontSize: 14, fontWeight: 600, color: colors.text, letterSpacing: \"-0.01em\", flex: 1 }}>\n {title}\n </h2>\n ) : (\n <span style={{ flex: 1, fontSize: 13, fontWeight: 600, color: colors.textMuted }}>Flint</span>\n )}\n\n {showClose && (\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 4,\n color: colors.textMuted,\n fontSize: 20,\n lineHeight: 1,\n borderRadius: 6,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n opacity: 0.6,\n fontFamily: \"inherit\",\n }}\n >\n ×\n </button>\n )}\n </div>\n );\n}\n\nfunction FieldLabel({\n children,\n colors,\n htmlFor,\n}: {\n children: React.ReactNode;\n colors: ReturnType<typeof resolveTheme>;\n htmlFor?: string;\n}) {\n return (\n <label\n htmlFor={htmlFor}\n style={{\n display: \"block\",\n fontSize: \"10px\",\n fontWeight: 700,\n color: colors.textMuted,\n marginBottom: 6,\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.07em\",\n }}\n >\n {children}\n </label>\n );\n}\n\nfunction SendingDots({ color }: { color: string }) {\n return (\n <span style={{ display: \"inline-flex\", gap: 3, alignItems: \"center\" }}>\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n style={{\n width: 4, height: 4,\n borderRadius: \"50%\",\n background: color,\n display: \"inline-block\",\n animation: `_flint_sending_dot 1.4s ease-in-out infinite ${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n );\n}\n\ninterface SevBtnProps {\n sev: Severity;\n label: string;\n selected: boolean;\n hint: string;\n color: string;\n accent: string;\n border: string;\n bg: string;\n text: string;\n onClick: () => void;\n}\n\nfunction SeverityButton({ sev, label, selected, hint, color, accent, border, bg, text, onClick }: SevBtnProps) {\n return (\n <button\n type=\"button\"\n title={hint}\n onClick={onClick}\n style={{\n padding: \"9px 6px 8px\",\n borderRadius: 10,\n border: selected ? `2px solid ${accent}` : `1.5px solid ${border}`,\n background: selected ? `${accent}15` : bg,\n cursor: \"pointer\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 5,\n transition: \"border-color 0.12s, background 0.12s\",\n fontFamily: \"inherit\",\n }}\n >\n <span style={{ width: 8, height: 8, borderRadius: \"50%\", background: color, display: \"block\" }} />\n <span style={{ fontSize: 11, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: \"0.02em\" }}>\n {sev}\n </span>\n <span style={{ fontSize: 9, color: selected ? accent : text, opacity: 0.6, letterSpacing: \"0.02em\" }}>\n {label}\n </span>\n </button>\n );\n}\n\nfunction SparkIcon({ color = \"currentColor\", size = 14 }: { color?: string; size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke={color} strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n );\n}\n\nfunction CheckIcon({ size = 20 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n","import type { ReportPayload, ReportResult } from \"@flint/types\";\nimport { gzipSync } from \"fflate\";\nimport type { eventWithTime } from \"@rrweb/types\";\n\nexport async function submitReport(\n serverUrl: string,\n projectKey: string,\n payload: ReportPayload,\n screenshot?: File,\n): Promise<ReportResult> {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports`;\n\n let body: BodyInit;\n let headers: Record<string, string> = {\n \"x-project-key\": projectKey,\n };\n\n if (screenshot) {\n const form = new FormData();\n form.append(\"reporterId\", payload.reporterId);\n form.append(\"reporterName\", payload.reporterName);\n form.append(\"description\", payload.description);\n if (payload.expectedBehavior) form.append(\"expectedBehavior\", payload.expectedBehavior);\n if (payload.stepsToReproduce) form.append(\"stepsToReproduce\", JSON.stringify(payload.stepsToReproduce));\n if (payload.externalReplayUrl) form.append(\"externalReplayUrl\", payload.externalReplayUrl);\n if (payload.additionalContext) form.append(\"additionalContext\", payload.additionalContext);\n form.append(\"severity\", payload.severity);\n if (payload.url) form.append(\"url\", payload.url);\n if (payload.meta) form.append(\"meta\", JSON.stringify(payload.meta));\n form.append(\"screenshot\", screenshot);\n body = form;\n } else {\n body = JSON.stringify(payload);\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const res = await fetch(url, { method: \"POST\", headers, body });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error((err as { error?: string }).error ?? `HTTP ${res.status}`);\n }\n\n return res.json() as Promise<ReportResult>;\n}\n\nexport async function submitReplay(\n serverUrl: string,\n projectKey: string,\n reportId: string,\n events: eventWithTime[],\n): Promise<void> {\n const json = JSON.stringify(events);\n const encoded = new TextEncoder().encode(json);\n const compressed = gzipSync(encoded);\n\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports/${reportId}/replay`;\n await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-project-key\": projectKey,\n \"Content-Type\": \"application/octet-stream\",\n },\n body: compressed.buffer as ArrayBuffer,\n });\n}\n","import type { Theme, ThemeOverride } from \"@flint/types\";\n\nexport interface ResolvedTheme {\n background: string;\n backgroundSecondary: string;\n accent: string;\n accentHover: string;\n text: string;\n textMuted: string;\n border: string;\n shadow: string;\n buttonText: string;\n backdropFilter: string;\n}\n\nconst light: ResolvedTheme = {\n background: \"rgba(255,255,255,0.90)\",\n backgroundSecondary: \"rgba(249,250,251,0.75)\",\n accent: \"#2563eb\",\n accentHover: \"#1d4ed8\",\n text: \"#111827\",\n textMuted: \"#6b7280\",\n border: \"rgba(255,255,255,0.9)\",\n shadow:\n \"0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.8)\",\n};\n\nconst dark: ResolvedTheme = {\n background: \"rgba(15,20,35,0.88)\",\n backgroundSecondary: \"rgba(5,8,18,0.65)\",\n accent: \"#f97316\",\n accentHover: \"#ea6c0a\",\n text: \"#dde3ef\",\n textMuted: \"#6b7a93\",\n border: \"rgba(255,255,255,0.08)\",\n shadow:\n \"0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.6)\",\n};\n\nexport function resolveTheme(theme: Theme): ResolvedTheme {\n if (theme === \"dark\") return dark;\n if (theme === \"light\") return light;\n // ThemeOverride — merge over light base\n const override = theme as ThemeOverride;\n return {\n ...light,\n background: override.background ?? light.background,\n accent: override.accent ?? light.accent,\n accentHover: override.accent ?? light.accentHover,\n text: override.text ?? light.text,\n border: override.border ?? light.border,\n };\n}\n","import i18next, { createInstance } from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\nimport en from \"./locales/en.json\";\n\nexport const widgetI18n: ReturnType<typeof createInstance> = createInstance();\n\nwidgetI18n.use(initReactI18next).init({\n lng: \"en-US\",\n fallbackLng: \"en-US\",\n resources: { \"en-US\": { translation: en } },\n interpolation: { escapeValue: false },\n initImmediate: false,\n});\n\nexport default widgetI18n;\n","{\n \"buttonLabel\": \"Report bug\",\n \"modalTitle\": \"Report an issue\",\n \"severityLabel\": \"Severity\",\n \"severity_P1_hint\": \"Critical — system down\",\n \"severity_P2_hint\": \"High — core feature broken\",\n \"severity_P3_hint\": \"Medium — noticeable but workable\",\n \"severity_P4_hint\": \"Low — cosmetic or improvement\",\n \"severity_P1_label\": \"Critical\",\n \"severity_P2_label\": \"High\",\n \"severity_P3_label\": \"Medium\",\n \"severity_P4_label\": \"Low\",\n \"whatIsBrokenLabel\": \"What Is Broken\",\n \"whatIsBrokenPlaceholder\": \"1–2 sentences: what is currently happening that should NOT happen.\",\n \"expectedBehaviorLabel\": \"Expected Behavior (optional)\",\n \"expectedBehaviorPlaceholder\": \"Describe exactly what the user should see or receive after the fix.\",\n \"screenshotLabel\": \"Screenshot (optional)\",\n \"screenshotPlaceholder\": \"Click to attach...\",\n \"submitLabel\": \"Submit\",\n \"successTitle\": \"Bug reported!\",\n \"successDuplicate\": \"Looks like a duplicate of an existing bug.\",\n \"successGitHub\": \"View GitHub issue\",\n \"errorLabel\": \"Failed to submit. Please try again.\",\n \"cancel\": \"Cancel\",\n \"sending\": \"Sending report\",\n \"capturingContext\": \"Capturing context\"\n}\n","import type { EnvironmentInfo } from \"@flint/types\";\n\nexport function collectEnvironment(): EnvironmentInfo {\n const ua = navigator.userAgent;\n\n // ── Browser ──────────────────────────────────────────────────────────────\n let browser = \"Unknown\";\n const chromeM = ua.match(/Chrome\\/(\\d+)/);\n const firefoxM = ua.match(/Firefox\\/(\\d+)/);\n const edgeM = ua.match(/Edg\\/(\\d+)/);\n const safariM = ua.match(/Version\\/(\\d+)/);\n const operaM = ua.match(/OPR\\/(\\d+)/);\n\n if (operaM) {\n browser = `Opera ${operaM[1]}`;\n } else if (edgeM) {\n browser = `Edge ${edgeM[1]}`;\n } else if (chromeM && !/Edg|OPR/.test(ua)) {\n browser = `Chrome ${chromeM[1]}`;\n } else if (firefoxM) {\n browser = `Firefox ${firefoxM[1]}`;\n } else if (safariM && /Safari\\//.test(ua)) {\n browser = `Safari ${safariM[1]}`;\n }\n\n // ── OS ────────────────────────────────────────────────────────────────────\n let os = \"Unknown\";\n const macM = ua.match(/Mac OS X (\\d+[._]\\d+)/);\n const winM = ua.match(/Windows NT (\\d+\\.\\d+)/);\n const androidM = ua.match(/Android (\\d+)/);\n const iosM = ua.match(/iPhone OS (\\d+[._]\\d+)/);\n\n if (macM) {\n os = `macOS ${macM[1].replace(\"_\", \".\")}`;\n } else if (winM) {\n const winMap: Record<string, string> = {\n \"10.0\": \"10/11\",\n \"6.3\": \"8.1\",\n \"6.2\": \"8\",\n \"6.1\": \"7\",\n };\n os = `Windows ${winMap[winM[1]] ?? winM[1]}`;\n } else if (androidM) {\n os = `Android ${androidM[1]}`;\n } else if (iosM) {\n os = `iOS ${iosM[1].replace(/_/g, \".\")}`;\n } else if (/Linux/.test(ua)) {\n os = \"Linux\";\n }\n\n return {\n browser,\n os,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n screen: `${screen.width}x${screen.height}`,\n language: navigator.language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n online: navigator.onLine,\n };\n}\n","import type { ConsoleEntry } from \"@flint/types\";\n\nconst MAX_ENTRIES = 50;\n\nexport interface ConsoleCollector {\n start(): void;\n stop(): void;\n getEntries(): ConsoleEntry[];\n}\n\nexport function createConsoleCollector(): ConsoleCollector {\n const entries: ConsoleEntry[] = [];\n let active = false;\n\n const originals = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n };\n\n let origOnerror: typeof window.onerror = null;\n let origUnhandled: typeof window.onunhandledrejection = null;\n\n function push(level: ConsoleEntry[\"level\"], args: unknown[]) {\n let str: string;\n try {\n str = args\n .map((a) => (typeof a === \"string\" ? a : JSON.stringify(a)))\n .join(\" \");\n } catch {\n str = String(args[0]);\n }\n if (str.length > 500) str = str.slice(0, 500) + \"…\";\n entries.push({ level, args: str, timestamp: Date.now() });\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n console.log = (...args: unknown[]) => {\n push(\"log\", args);\n originals.log(...args);\n };\n console.warn = (...args: unknown[]) => {\n push(\"warn\", args);\n originals.warn(...args);\n };\n console.error = (...args: unknown[]) => {\n push(\"error\", args);\n originals.error(...args);\n };\n\n origOnerror = window.onerror;\n window.onerror = (msg, src, line, col, err) => {\n push(\"error\", [err?.message ?? String(msg), `${src}:${line}:${col}`]);\n if (typeof origOnerror === \"function\")\n return origOnerror(msg, src, line, col, err);\n return false;\n };\n\n origUnhandled = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const reason =\n event.reason instanceof Error\n ? event.reason.message\n : JSON.stringify(event.reason);\n push(\"error\", [\"UnhandledRejection:\", reason]);\n if (typeof origUnhandled === \"function\")\n origUnhandled.call(window, event);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n console.log = originals.log;\n console.warn = originals.warn;\n console.error = originals.error;\n window.onerror = origOnerror;\n window.onunhandledrejection = origUnhandled;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import type { NetworkEntry } from \"@flint/types\";\n\nconst MAX_ENTRIES = 20;\n\nexport interface NetworkCollector {\n start(): void;\n stop(): void;\n getEntries(): NetworkEntry[];\n}\n\nfunction truncateUrl(url: string): string {\n try {\n const u = new URL(url, location.href);\n const base = `${u.origin}${u.pathname}`;\n return base.length > 200 ? base.slice(0, 200) + \"…\" : base;\n } catch {\n return url.length > 200 ? url.slice(0, 200) + \"…\" : url;\n }\n}\n\nexport function createNetworkCollector(): NetworkCollector {\n const entries: NetworkEntry[] = [];\n let origFetch: typeof window.fetch | null = null;\n let origXHROpen: typeof XMLHttpRequest.prototype.open | null = null;\n let active = false;\n\n function push(entry: NetworkEntry) {\n entries.push(entry);\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // ── Patch fetch ────────────────────────────────────────────────────────\n origFetch = window.fetch;\n window.fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const method = ((init?.method ?? \"GET\") as string).toUpperCase();\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.href\n : (input as Request).url;\n const startTime = Date.now();\n const res = await origFetch!.call(window, input, init);\n push({\n method,\n url: truncateUrl(url),\n status: res.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n });\n return res;\n };\n\n // ── Patch XHR ─────────────────────────────────────────────────────────\n origXHROpen = XMLHttpRequest.prototype.open;\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async?: boolean,\n username?: string | null,\n password?: string | null,\n ) {\n const startTime = Date.now();\n const urlStr =\n typeof url === \"string\" ? url : (url as URL).href;\n\n this.addEventListener(\"load\", () => {\n push({\n method: method.toUpperCase(),\n url: truncateUrl(urlStr),\n status: this.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n });\n });\n\n return origXHROpen!.apply(this, [\n method,\n url,\n async ?? true,\n username,\n password,\n ] as Parameters<typeof XMLHttpRequest.prototype.open>);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (origFetch) window.fetch = origFetch;\n if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n"],"mappings":"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","names":["import_react","import_react_i18next","import_react_i18next","MAX_ENTRIES","import_jsx_runtime","SparkIcon"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/FlintWidget.tsx","../src/FlintModal.tsx","../src/api.ts","../src/theme.ts","../src/i18n/index.ts","../src/i18n/locales/en.json","../src/collectors/environment.ts","../src/collectors/console.ts","../src/collectors/network.ts","../src/store.ts"],"sourcesContent":["export { FlintWidget } from \"./FlintWidget.js\";\nexport { FlintModal } from \"./FlintModal.js\";\nexport { flint } from \"./store.js\";\nexport type {\n FlintWidgetProps,\n FlintUser,\n Severity,\n Locale,\n Theme,\n ThemeOverride,\n ReportPayload,\n ReportResult,\n} from \"@flint/types\";\n","import { useState, useEffect, useRef } from \"react\";\nimport { I18nextProvider, useTranslation } from \"react-i18next\";\nimport { FlintModal } from \"./FlintModal.js\";\nimport type { FlintWidgetProps } from \"@flint/types\";\nimport { resolveTheme } from \"./theme.js\";\nimport widgetI18n from \"./i18n/index.js\";\nimport { collectEnvironment } from \"./collectors/environment.js\";\nimport { createConsoleCollector } from \"./collectors/console.js\";\nimport { createNetworkCollector } from \"./collectors/network.js\";\nimport { useFlintStore } from \"./store.js\";\nimport { record } from \"rrweb\";\nimport type { eventWithTime } from \"@rrweb/types\";\n\nconst REPLAY_WINDOW_MS = 60_000; // rolling 60-second buffer\n\nexport function FlintWidget(props: FlintWidgetProps) {\n const { locale = \"en-US\" } = props;\n\n useEffect(() => {\n widgetI18n.changeLanguage(locale);\n }, [locale]);\n\n return (\n <I18nextProvider i18n={widgetI18n}>\n <WidgetContent {...props} />\n </I18nextProvider>\n );\n}\n\nfunction WidgetContent({\n projectKey,\n serverUrl,\n user,\n meta,\n extraFields,\n buttonLabel,\n theme = \"dark\",\n zIndex = 9999,\n}: FlintWidgetProps) {\n const globalState = useFlintStore();\n const resolvedUser = user ?? globalState.user;\n const resolvedSessionReplay = extraFields?.sessionReplay ?? globalState.sessionReplay;\n const getExternalReplayUrl = () => {\n const src = resolvedSessionReplay;\n return typeof src === \"function\" ? src() : src;\n };\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [hovered, setHovered] = useState(false);\n const colors = resolveTheme(theme);\n\n // ── Collectors ─────────────────────────────────────────────────────────────\n // Start synchronously so window.fetch is patched before React effects run,\n // ensuring the admin's initial API requests are captured.\n const consoleCollector = useRef<ReturnType<typeof createConsoleCollector> | null>(null);\n const networkCollector = useRef<ReturnType<typeof createNetworkCollector> | null>(null);\n const replayEvents = useRef<eventWithTime[]>([]);\n const stopReplay = useRef<(() => void) | null>(null);\n\n if (!consoleCollector.current) {\n consoleCollector.current = createConsoleCollector();\n consoleCollector.current.start();\n }\n if (!networkCollector.current) {\n networkCollector.current = createNetworkCollector();\n networkCollector.current.start();\n }\n\n useEffect(() => {\n // Start rrweb recording with rolling buffer (must be in effect for DOM access)\n const stopFn = record({\n emit(event) {\n replayEvents.current.push(event);\n // Trim to rolling window\n const cutoff = Date.now() - REPLAY_WINDOW_MS;\n while (\n replayEvents.current.length > 0 &&\n replayEvents.current[0].timestamp < cutoff\n ) {\n replayEvents.current.shift();\n }\n },\n });\n stopReplay.current = stopFn ?? null;\n\n return () => {\n consoleCollector.current?.stop();\n networkCollector.current?.stop();\n stopReplay.current?.();\n };\n }, []);\n\n const label = buttonLabel ?? t(\"buttonLabel\");\n\n return (\n <>\n {/* Floating trigger button */}\n <button\n onClick={() => setOpen(true)}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n aria-label={label}\n style={{\n position: \"fixed\",\n bottom: \"40px\",\n right: \"20px\",\n zIndex: zIndex - 1,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n fontSize: \"13px\",\n fontWeight: 600,\n cursor: \"pointer\",\n boxShadow: hovered\n ? `0 0 28px ${colors.accent}55, 0 8px 24px rgba(0,0,0,0.3)`\n : `0 0 16px ${colors.accent}33, 0 4px 16px rgba(0,0,0,0.2)`,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n transform: hovered ? \"translateY(-2px)\" : \"translateY(0)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n letterSpacing: \"0.01em\",\n }}\n >\n <SparkIcon />\n {label}\n </button>\n\n {/* Modal */}\n {open && (\n <FlintModal\n projectKey={projectKey}\n serverUrl={serverUrl}\n user={resolvedUser}\n meta={meta}\n theme={theme}\n zIndex={zIndex}\n onClose={() => setOpen(false)}\n getEnvironment={collectEnvironment}\n getConsoleLogs={() => consoleCollector.current?.getEntries() ?? []}\n getNetworkErrors={() => networkCollector.current?.getEntries() ?? []}\n getReplayEvents={() => [...replayEvents.current]}\n getExternalReplayUrl={getExternalReplayUrl}\n />\n )}\n </>\n );\n}\n\nfunction SparkIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n );\n}\n","import { useRef, useState, useEffect, useCallback } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type {\n Severity,\n FlintUser,\n Theme,\n ReportResult,\n EnvironmentInfo,\n ConsoleEntry,\n NetworkEntry,\n} from \"@flint/types\";\nimport type { eventWithTime } from \"@rrweb/types\";\nimport { submitReport, submitReplay } from \"./api.js\";\nimport { resolveTheme } from \"./theme.js\";\n\ninterface Props {\n projectKey: string;\n serverUrl: string;\n user?: FlintUser;\n meta?: Record<string, unknown>;\n theme: Theme;\n zIndex: number;\n onClose: () => void;\n getEnvironment: () => EnvironmentInfo;\n getConsoleLogs: () => ConsoleEntry[];\n getNetworkErrors: () => NetworkEntry[];\n getReplayEvents: () => eventWithTime[];\n getExternalReplayUrl: () => string | undefined;\n}\n\nconst SEVERITIES: Severity[] = [\"P1\", \"P2\", \"P3\", \"P4\"];\nconst SEV_COLOR: Record<Severity, string> = {\n P1: \"#ef4444\",\n P2: \"#f97316\",\n P3: \"#eab308\",\n P4: \"#22c55e\",\n};\n\ntype Status = \"idle\" | \"submitting\" | \"success\" | \"error\";\n\n// Inject CSS keyframes once — animations can't be done with inline styles alone\nfunction injectKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(\"_flint_kf\")) return;\n const s = document.createElement(\"style\");\n s.id = \"_flint_kf\";\n s.textContent = `\n @keyframes _flint_in {\n from { opacity: 0; transform: scale(0.93) translateY(10px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n }\n @keyframes _flint_overlay_in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes _flint_spin {\n to { transform: rotate(360deg); }\n }\n @keyframes _flint_pulse {\n 0%, 100% { opacity: 0.5; transform: scale(0.88); }\n 50% { opacity: 1; transform: scale(1.08); }\n }\n @keyframes _flint_ripple {\n 0% { opacity: 0.5; transform: scale(0.75); }\n 100% { opacity: 0; transform: scale(1.55); }\n }\n @keyframes _flint_sending_dot {\n 0%, 80%, 100% { opacity: 0.2; transform: scale(0.8); }\n 40% { opacity: 1; transform: scale(1); }\n }\n @keyframes _flint_success_up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `;\n document.head.appendChild(s);\n}\n\nexport function FlintModal({\n projectKey,\n serverUrl,\n user,\n meta,\n theme,\n zIndex,\n onClose,\n getEnvironment,\n getConsoleLogs,\n getNetworkErrors,\n getReplayEvents,\n getExternalReplayUrl,\n}: Props) {\n const { t } = useTranslation();\n const colors = resolveTheme(theme);\n const isDark = theme === \"dark\";\n\n const [severity, setSeverity] = useState<Severity>(\"P2\");\n const [description, setDescription] = useState(\"\");\n const [expectedBehavior, setExpectedBehavior] = useState(\"\");\n const [screenshot, setScreenshot] = useState<File | null>(null);\n const [status, setStatus] = useState<Status>(\"idle\");\n const [result, setResult] = useState<ReportResult | null>(null);\n const [errorMsg, setErrorMsg] = useState(\"\");\n\n const fileRef = useRef<HTMLInputElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => { injectKeyframes(); }, []);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && status !== \"submitting\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [onClose, status]);\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent) => {\n if (e.target === overlayRef.current && status !== \"submitting\") onClose();\n },\n [onClose, status],\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!description.trim()) return;\n\n setStatus(\"submitting\");\n setErrorMsg(\"\");\n\n const collectedMeta: Record<string, unknown> = {\n ...meta,\n environment: getEnvironment(),\n consoleLogs: getConsoleLogs(),\n networkErrors: getNetworkErrors(),\n };\n\n try {\n const res = await submitReport(\n serverUrl,\n projectKey,\n {\n reporterId: user?.id ?? \"anonymous\",\n reporterName: user?.name ?? \"Anonymous\",\n description: description.trim(),\n expectedBehavior: expectedBehavior.trim() || undefined,\n externalReplayUrl: getExternalReplayUrl() || undefined,\n severity,\n url: window.location.href,\n meta: collectedMeta,\n },\n screenshot ?? undefined,\n );\n setResult(res);\n setStatus(\"success\");\n\n const events = getReplayEvents();\n if (events.length > 0) {\n submitReplay(serverUrl, projectKey, res.id, events).catch(() => {});\n }\n } catch (err) {\n setErrorMsg(err instanceof Error ? err.message : t(\"errorLabel\"));\n setStatus(\"error\");\n }\n };\n\n // ── Shared style tokens ────────────────────────────────────────────────────\n const inputBorder = isDark ? \"rgba(255,255,255,0.1)\" : \"rgba(0,0,0,0.1)\";\n const accentGlow = `0 0 20px ${colors.accent}40, 0 4px 16px rgba(0,0,0,0.2)`;\n\n const overlayStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n background: \"rgba(0,0,0,0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex,\n padding: \"16px\",\n backdropFilter: \"blur(10px)\",\n WebkitBackdropFilter: \"blur(10px)\",\n animation: \"_flint_overlay_in 0.2s ease\",\n };\n\n const modalStyle: React.CSSProperties = {\n background: colors.background,\n backdropFilter: colors.backdropFilter,\n WebkitBackdropFilter: colors.backdropFilter,\n borderRadius: \"20px\",\n boxShadow: colors.shadow,\n border: `1px solid ${colors.border}`,\n width: \"100%\",\n maxWidth: \"480px\",\n maxHeight: \"92vh\",\n overflowY: \"auto\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n color: colors.text,\n animation: \"_flint_in 0.28s cubic-bezier(0.16, 1, 0.3, 1)\",\n };\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\",\n padding: \"11px 13px\",\n borderRadius: \"10px\",\n border: `1px solid ${inputBorder}`,\n background: colors.backgroundSecondary,\n color: colors.text,\n fontSize: \"14px\",\n outline: \"none\",\n boxSizing: \"border-box\",\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s\",\n };\n\n // ── Loading + Success (unified animated state) ────────────────────────────\n if (status === \"submitting\" || status === \"success\") {\n const isSuccess = status === \"success\";\n const ringBorder = isSuccess\n ? \"3px solid #22c55e\"\n : `3px solid ${isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.08)\"}`;\n const ringTopColor = isSuccess ? \"#22c55e\" : colors.accent;\n\n return (\n <div style={overlayStyle}>\n <div style={modalStyle} role=\"dialog\" aria-modal=\"true\" aria-label={isSuccess ? t(\"successTitle\") : t(\"sending\")}>\n <ModalHeader colors={colors} inputBorder={inputBorder} showClose={false} onClose={onClose} />\n\n <div style={{ padding: \"40px 32px 48px\", textAlign: \"center\", display: \"flex\", flexDirection: \"column\", alignItems: \"center\" }}>\n {/* Animated rings */}\n <div style={{ position: \"relative\", width: 80, height: 80, marginBottom: 28 }}>\n {/* Ripple 1 — fade out on success */}\n <div style={{\n position: \"absolute\", inset: -10,\n borderRadius: \"50%\",\n border: `1.5px solid ${colors.accent}`,\n animation: \"_flint_ripple 1.8s ease-out infinite\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }} />\n {/* Ripple 2 (delayed) */}\n <div style={{\n position: \"absolute\", inset: -10,\n borderRadius: \"50%\",\n border: `1.5px solid ${colors.accent}`,\n animation: \"_flint_ripple 1.8s ease-out infinite 0.6s\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }} />\n {/* Spinning ring — transitions to solid green on success */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n border: ringBorder,\n borderTopColor: ringTopColor,\n animation: isSuccess ? \"none\" : \"_flint_spin 0.85s linear infinite\",\n transition: \"border-color 0.45s ease, border-top-color 0.45s ease\",\n }} />\n {/* Center: spark fades out, check fades in */}\n <div style={{ position: \"absolute\", inset: 14, borderRadius: \"50%\" }}>\n {/* Spark */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n background: `linear-gradient(135deg, ${colors.accent}30, ${colors.accentHover}50)`,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n animation: isSuccess ? \"none\" : \"_flint_pulse 2s ease-in-out infinite\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n }}>\n <SparkIcon color={colors.accent} size={20} />\n </div>\n {/* Checkmark */}\n <div style={{\n position: \"absolute\", inset: 0,\n borderRadius: \"50%\",\n background: \"rgba(34,197,94,0.15)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"scale(1)\" : \"scale(0.65)\",\n transition: \"opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s\",\n }}>\n <CheckIcon size={20} />\n </div>\n </div>\n </div>\n\n {/* Title crossfade */}\n <div style={{ position: \"relative\", height: 26, width: \"100%\", marginBottom: 10 }}>\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n fontSize: 17, fontWeight: 700, color: colors.text, letterSpacing: \"-0.02em\",\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.25s ease\",\n pointerEvents: \"none\",\n }}>\n {t(\"sending\")}\n </div>\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n fontSize: 17, fontWeight: 700, color: colors.text, letterSpacing: \"-0.02em\",\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"translateY(0)\" : \"translateY(6px)\",\n transition: \"opacity 0.35s ease 0.25s, transform 0.35s ease 0.25s\",\n pointerEvents: isSuccess ? \"auto\" : \"none\",\n }}>\n {t(\"successTitle\")}\n </div>\n </div>\n\n {/* Subtitle crossfade */}\n <div style={{ position: \"relative\", minHeight: 76, width: \"100%\" }}>\n {/* Loading subtitle */}\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n gap: 6, color: colors.textMuted, fontSize: 13,\n opacity: isSuccess ? 0 : 1,\n transition: \"opacity 0.2s ease\",\n pointerEvents: \"none\",\n }}>\n <span>{t(\"capturingContext\")}</span>\n <SendingDots color={colors.accent} />\n </div>\n {/* Success subtitle */}\n <div style={{\n position: \"absolute\", inset: 0,\n display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 10,\n opacity: isSuccess ? 1 : 0,\n transform: isSuccess ? \"translateY(0)\" : \"translateY(8px)\",\n transition: \"opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s\",\n pointerEvents: isSuccess ? \"auto\" : \"none\",\n }}>\n <p style={{ fontSize: 13, color: colors.textMuted, margin: 0 }}>\n {result?.isDuplicate ? t(\"successDuplicate\") : result ? `ID: ${result.id}` : \"\"}\n </p>\n {result?.slackMessageUrl && (\n <a\n href={result.slackMessageUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"9px 18px\",\n borderRadius: \"10px\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n textDecoration: \"none\",\n fontSize: \"13px\",\n fontWeight: 600,\n boxShadow: accentGlow,\n }}\n >\n {t(\"successSlack\")} ↗\n </a>\n )}\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n padding: \"4px 8px\",\n fontFamily: \"inherit\",\n }}\n >\n {t(\"cancel\")}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // ── Form ──────────────────────────────────────────────────────────────────\n return (\n <div ref={overlayRef} style={overlayStyle} onClick={handleOverlayClick}>\n <div style={modalStyle} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"flint-modal-title\">\n <ModalHeader\n colors={colors}\n inputBorder={inputBorder}\n showClose\n onClose={onClose}\n titleId=\"flint-modal-title\"\n title={t(\"modalTitle\")}\n />\n\n <form onSubmit={handleSubmit} style={{ padding: \"20px 24px 24px\" }}>\n {/* Severity */}\n <div style={{ marginBottom: 18 }}>\n <FieldLabel colors={colors}>{t(\"severityLabel\")}</FieldLabel>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(4,1fr)\", gap: 8 }}>\n {SEVERITIES.map((sev) => (\n <SeverityButton\n key={sev}\n sev={sev}\n label={t(`severity_${sev}_label`)}\n selected={severity === sev}\n hint={t(`severity_${sev}_hint`)}\n color={SEV_COLOR[sev]}\n accent={colors.accent}\n border={inputBorder}\n bg={colors.backgroundSecondary}\n text={colors.text}\n onClick={() => setSeverity(sev)}\n />\n ))}\n </div>\n </div>\n\n {/* What Is Broken */}\n <div style={{ marginBottom: 14 }}>\n <FieldLabel colors={colors} htmlFor=\"flint-description\">{t(\"whatIsBrokenLabel\")}</FieldLabel>\n <textarea\n id=\"flint-description\"\n style={{ ...inputStyle, resize: \"vertical\", minHeight: 80 }}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t(\"whatIsBrokenPlaceholder\")}\n required\n />\n </div>\n\n {/* Expected Behavior (optional) */}\n <div style={{ marginBottom: 14 }}>\n <FieldLabel colors={colors} htmlFor=\"flint-expected\">{t(\"expectedBehaviorLabel\")}</FieldLabel>\n <textarea\n id=\"flint-expected\"\n style={{ ...inputStyle, resize: \"vertical\", minHeight: 72 }}\n value={expectedBehavior}\n onChange={(e) => setExpectedBehavior(e.target.value)}\n placeholder={t(\"expectedBehaviorPlaceholder\")}\n />\n </div>\n\n {/* Screenshot */}\n <div style={{ marginBottom: 20 }}>\n <FieldLabel colors={colors}>{t(\"screenshotLabel\")}</FieldLabel>\n <label\n htmlFor=\"flint-screenshot\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"10px 13px\",\n borderRadius: 10,\n border: `1px dashed ${inputBorder}`,\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n background: colors.backgroundSecondary,\n }}\n >\n 📎 {screenshot ? screenshot.name : t(\"screenshotPlaceholder\")}\n </label>\n <input\n id=\"flint-screenshot\"\n ref={fileRef}\n type=\"file\"\n accept=\"image/*\"\n style={{ display: \"none\" }}\n onChange={(e) => setScreenshot(e.target.files?.[0] ?? null)}\n />\n </div>\n\n {/* Session replay info */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"9px 12px\",\n borderRadius: 10,\n background: isDark ? \"rgba(255,255,255,0.04)\" : \"rgba(0,77,240,0.04)\",\n border: `1px solid ${isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,77,240,0.1)\"}`,\n marginBottom: 16,\n }}>\n <span style={{ fontSize: 14 }}>🎥</span>\n <span style={{ fontSize: 12, color: colors.textMuted, lineHeight: 1.4 }}>\n {t(\"replayInfo\")}\n </span>\n </div>\n\n {/* Error */}\n {status === \"error\" && (\n <div style={{\n padding: \"10px 13px\",\n borderRadius: 10,\n background: \"rgba(239,68,68,0.08)\",\n border: \"1px solid rgba(239,68,68,0.2)\",\n color: \"#f87171\",\n fontSize: 12,\n marginBottom: 16,\n }}>\n ⚠️ {errorMsg || t(\"errorLabel\")}\n </div>\n )}\n\n {/* Submit */}\n <button\n type=\"submit\"\n style={{\n width: \"100%\",\n padding: \"13px 20px\",\n borderRadius: 12,\n border: \"none\",\n background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,\n color: colors.buttonText,\n fontSize: 15,\n fontWeight: 700,\n cursor: \"pointer\",\n letterSpacing: \"-0.01em\",\n boxShadow: accentGlow,\n fontFamily: \"inherit\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 8,\n }}\n >\n <SparkIcon color={colors.buttonText} size={15} />\n {t(\"submitLabel\")}\n </button>\n\n {/* Cancel */}\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n width: \"100%\",\n padding: \"10px\",\n marginTop: 8,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n color: colors.textMuted,\n fontFamily: \"inherit\",\n borderRadius: 8,\n }}\n >\n {t(\"cancel\")}\n </button>\n </form>\n </div>\n </div>\n );\n}\n\n// ─── Sub-components ──────────────────────────────────────────────────────────\n\nfunction ModalHeader({\n colors,\n inputBorder,\n showClose,\n onClose,\n titleId,\n title,\n}: {\n colors: ReturnType<typeof resolveTheme>;\n inputBorder: string;\n showClose: boolean;\n onClose: () => void;\n titleId?: string;\n title?: string;\n}) {\n return (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"16px 20px 14px\",\n borderBottom: `1px solid ${inputBorder}`,\n }}>\n {/* Brand chip */}\n <div style={{\n width: 28, height: 28,\n borderRadius: 8,\n background: `linear-gradient(135deg, ${colors.accent}20, ${colors.accentHover}35)`,\n border: `1px solid ${colors.accent}30`,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n flexShrink: 0,\n }}>\n <SparkIcon color={colors.accent} size={13} />\n </div>\n\n {titleId && title ? (\n <h2 id={titleId} style={{ margin: 0, fontSize: 14, fontWeight: 600, color: colors.text, letterSpacing: \"-0.01em\", flex: 1 }}>\n {title}\n </h2>\n ) : (\n <span style={{ flex: 1, fontSize: 13, fontWeight: 600, color: colors.textMuted }}>Flint</span>\n )}\n\n {showClose && (\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 4,\n color: colors.textMuted,\n fontSize: 20,\n lineHeight: 1,\n borderRadius: 6,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n opacity: 0.6,\n fontFamily: \"inherit\",\n }}\n >\n ×\n </button>\n )}\n </div>\n );\n}\n\nfunction FieldLabel({\n children,\n colors,\n htmlFor,\n}: {\n children: React.ReactNode;\n colors: ReturnType<typeof resolveTheme>;\n htmlFor?: string;\n}) {\n return (\n <label\n htmlFor={htmlFor}\n style={{\n display: \"block\",\n fontSize: \"10px\",\n fontWeight: 700,\n color: colors.textMuted,\n marginBottom: 6,\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.07em\",\n }}\n >\n {children}\n </label>\n );\n}\n\nfunction SendingDots({ color }: { color: string }) {\n return (\n <span style={{ display: \"inline-flex\", gap: 3, alignItems: \"center\" }}>\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n style={{\n width: 4, height: 4,\n borderRadius: \"50%\",\n background: color,\n display: \"inline-block\",\n animation: `_flint_sending_dot 1.4s ease-in-out infinite ${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n );\n}\n\ninterface SevBtnProps {\n sev: Severity;\n label: string;\n selected: boolean;\n hint: string;\n color: string;\n accent: string;\n border: string;\n bg: string;\n text: string;\n onClick: () => void;\n}\n\nfunction SeverityButton({ sev, label, selected, hint, color, accent, border, bg, text, onClick }: SevBtnProps) {\n return (\n <button\n type=\"button\"\n title={hint}\n onClick={onClick}\n style={{\n padding: \"9px 6px 8px\",\n borderRadius: 10,\n border: selected ? `2px solid ${accent}` : `1.5px solid ${border}`,\n background: selected ? `${accent}15` : bg,\n cursor: \"pointer\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 5,\n transition: \"border-color 0.12s, background 0.12s\",\n fontFamily: \"inherit\",\n }}\n >\n <span style={{ width: 8, height: 8, borderRadius: \"50%\", background: color, display: \"block\" }} />\n <span style={{ fontSize: 11, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: \"0.02em\" }}>\n {sev}\n </span>\n <span style={{ fontSize: 9, color: selected ? accent : text, opacity: 0.6, letterSpacing: \"0.02em\" }}>\n {label}\n </span>\n </button>\n );\n}\n\nfunction SparkIcon({ color = \"currentColor\", size = 14 }: { color?: string; size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke={color} strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n );\n}\n\nfunction CheckIcon({ size = 20 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n","import type { ReportPayload, ReportResult } from \"@flint/types\";\nimport { gzipSync } from \"fflate\";\nimport type { eventWithTime } from \"@rrweb/types\";\n\nexport async function submitReport(\n serverUrl: string,\n projectKey: string,\n payload: ReportPayload,\n screenshot?: File,\n): Promise<ReportResult> {\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports`;\n\n let body: BodyInit;\n let headers: Record<string, string> = {\n \"x-project-key\": projectKey,\n };\n\n if (screenshot) {\n const form = new FormData();\n form.append(\"reporterId\", payload.reporterId);\n form.append(\"reporterName\", payload.reporterName);\n form.append(\"description\", payload.description);\n if (payload.expectedBehavior) form.append(\"expectedBehavior\", payload.expectedBehavior);\n if (payload.stepsToReproduce) form.append(\"stepsToReproduce\", JSON.stringify(payload.stepsToReproduce));\n if (payload.externalReplayUrl) form.append(\"externalReplayUrl\", payload.externalReplayUrl);\n if (payload.additionalContext) form.append(\"additionalContext\", payload.additionalContext);\n form.append(\"severity\", payload.severity);\n if (payload.url) form.append(\"url\", payload.url);\n if (payload.meta) form.append(\"meta\", JSON.stringify(payload.meta));\n form.append(\"screenshot\", screenshot);\n body = form;\n } else {\n body = JSON.stringify(payload);\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const res = await fetch(url, { method: \"POST\", headers, body });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: \"Unknown error\" }));\n throw new Error((err as { error?: string }).error ?? `HTTP ${res.status}`);\n }\n\n return res.json() as Promise<ReportResult>;\n}\n\nexport async function submitReplay(\n serverUrl: string,\n projectKey: string,\n reportId: string,\n events: eventWithTime[],\n): Promise<void> {\n const json = JSON.stringify(events);\n const encoded = new TextEncoder().encode(json);\n const compressed = gzipSync(encoded);\n\n const url = `${serverUrl.replace(/\\/$/, \"\")}/api/v1/bug-reports/${reportId}/replay`;\n await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-project-key\": projectKey,\n \"Content-Type\": \"application/octet-stream\",\n },\n body: compressed.buffer as ArrayBuffer,\n });\n}\n","import type { Theme, ThemeOverride } from \"@flint/types\";\n\nexport interface ResolvedTheme {\n background: string;\n backgroundSecondary: string;\n accent: string;\n accentHover: string;\n text: string;\n textMuted: string;\n border: string;\n shadow: string;\n buttonText: string;\n backdropFilter: string;\n}\n\nconst light: ResolvedTheme = {\n background: \"rgba(255,255,255,0.90)\",\n backgroundSecondary: \"rgba(249,250,251,0.75)\",\n accent: \"#2563eb\",\n accentHover: \"#1d4ed8\",\n text: \"#111827\",\n textMuted: \"#6b7280\",\n border: \"rgba(255,255,255,0.9)\",\n shadow:\n \"0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.8)\",\n};\n\nconst dark: ResolvedTheme = {\n background: \"rgba(15,20,35,0.88)\",\n backgroundSecondary: \"rgba(5,8,18,0.65)\",\n accent: \"#f97316\",\n accentHover: \"#ea6c0a\",\n text: \"#dde3ef\",\n textMuted: \"#6b7a93\",\n border: \"rgba(255,255,255,0.08)\",\n shadow:\n \"0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n buttonText: \"#ffffff\",\n backdropFilter: \"blur(32px) saturate(1.6)\",\n};\n\nexport function resolveTheme(theme: Theme): ResolvedTheme {\n if (theme === \"dark\") return dark;\n if (theme === \"light\") return light;\n // ThemeOverride — merge over light base\n const override = theme as ThemeOverride;\n return {\n ...light,\n background: override.background ?? light.background,\n accent: override.accent ?? light.accent,\n accentHover: override.accent ?? light.accentHover,\n text: override.text ?? light.text,\n border: override.border ?? light.border,\n };\n}\n","import i18next, { createInstance } from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\nimport en from \"./locales/en.json\";\n\nexport const widgetI18n: ReturnType<typeof createInstance> = createInstance();\n\nwidgetI18n.use(initReactI18next).init({\n lng: \"en-US\",\n fallbackLng: \"en-US\",\n resources: { \"en-US\": { translation: en } },\n interpolation: { escapeValue: false },\n initImmediate: false,\n});\n\nexport default widgetI18n;\n","{\n \"buttonLabel\": \"Report bug\",\n \"modalTitle\": \"Report an issue\",\n \"severityLabel\": \"Severity\",\n \"severity_P1_hint\": \"Critical — system down\",\n \"severity_P2_hint\": \"High — core feature broken\",\n \"severity_P3_hint\": \"Medium — noticeable but workable\",\n \"severity_P4_hint\": \"Low — cosmetic or improvement\",\n \"severity_P1_label\": \"Critical\",\n \"severity_P2_label\": \"High\",\n \"severity_P3_label\": \"Medium\",\n \"severity_P4_label\": \"Low\",\n \"whatIsBrokenLabel\": \"What Is Broken\",\n \"whatIsBrokenPlaceholder\": \"1–2 sentences: what is currently happening that should NOT happen.\",\n \"expectedBehaviorLabel\": \"Expected Behavior (optional)\",\n \"expectedBehaviorPlaceholder\": \"Describe exactly what the user should see or receive after the fix.\",\n \"screenshotLabel\": \"Screenshot (optional)\",\n \"screenshotPlaceholder\": \"Click to attach...\",\n \"submitLabel\": \"Submit\",\n \"successTitle\": \"Bug reported!\",\n \"successDuplicate\": \"Looks like a duplicate of an existing bug.\",\n \"successGitHub\": \"View GitHub issue\",\n \"successSlack\": \"View Slack message\",\n \"replayInfo\": \"No need to record your screen — we automatically capture a session replay when you submit.\",\n \"errorLabel\": \"Failed to submit. Please try again.\",\n \"cancel\": \"Cancel\",\n \"sending\": \"Sending report\",\n \"capturingContext\": \"Capturing context\"\n}\n","import type { EnvironmentInfo } from \"@flint/types\";\n\nexport function collectEnvironment(): EnvironmentInfo {\n const ua = navigator.userAgent;\n\n // ── Browser ──────────────────────────────────────────────────────────────\n let browser = \"Unknown\";\n const chromeM = ua.match(/Chrome\\/(\\d+)/);\n const firefoxM = ua.match(/Firefox\\/(\\d+)/);\n const edgeM = ua.match(/Edg\\/(\\d+)/);\n const safariM = ua.match(/Version\\/(\\d+)/);\n const operaM = ua.match(/OPR\\/(\\d+)/);\n\n if (operaM) {\n browser = `Opera ${operaM[1]}`;\n } else if (edgeM) {\n browser = `Edge ${edgeM[1]}`;\n } else if (chromeM && !/Edg|OPR/.test(ua)) {\n browser = `Chrome ${chromeM[1]}`;\n } else if (firefoxM) {\n browser = `Firefox ${firefoxM[1]}`;\n } else if (safariM && /Safari\\//.test(ua)) {\n browser = `Safari ${safariM[1]}`;\n }\n\n // ── OS ────────────────────────────────────────────────────────────────────\n let os = \"Unknown\";\n const macM = ua.match(/Mac OS X (\\d+[._]\\d+)/);\n const winM = ua.match(/Windows NT (\\d+\\.\\d+)/);\n const androidM = ua.match(/Android (\\d+)/);\n const iosM = ua.match(/iPhone OS (\\d+[._]\\d+)/);\n\n if (macM) {\n os = `macOS ${macM[1].replace(\"_\", \".\")}`;\n } else if (winM) {\n const winMap: Record<string, string> = {\n \"10.0\": \"10/11\",\n \"6.3\": \"8.1\",\n \"6.2\": \"8\",\n \"6.1\": \"7\",\n };\n os = `Windows ${winMap[winM[1]] ?? winM[1]}`;\n } else if (androidM) {\n os = `Android ${androidM[1]}`;\n } else if (iosM) {\n os = `iOS ${iosM[1].replace(/_/g, \".\")}`;\n } else if (/Linux/.test(ua)) {\n os = \"Linux\";\n }\n\n return {\n browser,\n os,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n screen: `${screen.width}x${screen.height}`,\n language: navigator.language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n online: navigator.onLine,\n };\n}\n","import type { ConsoleEntry } from \"@flint/types\";\n\nconst MAX_ENTRIES = 50;\n\nexport interface ConsoleCollector {\n start(): void;\n stop(): void;\n getEntries(): ConsoleEntry[];\n}\n\nexport function createConsoleCollector(): ConsoleCollector {\n const entries: ConsoleEntry[] = [];\n let active = false;\n\n const originals = {\n log: console.log.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n };\n\n let origOnerror: typeof window.onerror = null;\n let origUnhandled: typeof window.onunhandledrejection = null;\n\n function push(level: ConsoleEntry[\"level\"], args: unknown[]) {\n let str: string;\n try {\n str = args\n .map((a) => (typeof a === \"string\" ? a : JSON.stringify(a)))\n .join(\" \");\n } catch {\n str = String(args[0]);\n }\n if (str.length > 500) str = str.slice(0, 500) + \"…\";\n entries.push({ level, args: str, timestamp: Date.now() });\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n console.log = (...args: unknown[]) => {\n push(\"log\", args);\n originals.log(...args);\n };\n console.warn = (...args: unknown[]) => {\n push(\"warn\", args);\n originals.warn(...args);\n };\n console.error = (...args: unknown[]) => {\n push(\"error\", args);\n originals.error(...args);\n };\n\n origOnerror = window.onerror;\n window.onerror = (msg, src, line, col, err) => {\n push(\"error\", [err?.message ?? String(msg), `${src}:${line}:${col}`]);\n if (typeof origOnerror === \"function\")\n return origOnerror(msg, src, line, col, err);\n return false;\n };\n\n origUnhandled = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const reason =\n event.reason instanceof Error\n ? event.reason.message\n : JSON.stringify(event.reason);\n push(\"error\", [\"UnhandledRejection:\", reason]);\n if (typeof origUnhandled === \"function\")\n origUnhandled.call(window, event);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n console.log = originals.log;\n console.warn = originals.warn;\n console.error = originals.error;\n window.onerror = origOnerror;\n window.onunhandledrejection = origUnhandled;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import type { NetworkEntry } from \"@flint/types\";\n\nconst MAX_ENTRIES = 20;\n\nexport interface NetworkCollector {\n start(): void;\n stop(): void;\n getEntries(): NetworkEntry[];\n}\n\nfunction truncateUrl(url: string): string {\n try {\n const u = new URL(url, location.href);\n const base = `${u.origin}${u.pathname}`;\n return base.length > 200 ? base.slice(0, 200) + \"…\" : base;\n } catch {\n return url.length > 200 ? url.slice(0, 200) + \"…\" : url;\n }\n}\n\nexport function createNetworkCollector(): NetworkCollector {\n const entries: NetworkEntry[] = [];\n let origFetch: typeof window.fetch | null = null;\n let origXHROpen: typeof XMLHttpRequest.prototype.open | null = null;\n let active = false;\n\n function push(entry: NetworkEntry) {\n entries.push(entry);\n if (entries.length > MAX_ENTRIES) entries.shift();\n }\n\n return {\n start() {\n if (active) return;\n active = true;\n\n // ── Patch fetch ────────────────────────────────────────────────────────\n origFetch = window.fetch;\n window.fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const method = ((init?.method ?? \"GET\") as string).toUpperCase();\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.href\n : (input as Request).url;\n const startTime = Date.now();\n const res = await origFetch!.call(window, input, init);\n push({\n method,\n url: truncateUrl(url),\n status: res.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n });\n return res;\n };\n\n // ── Patch XHR ─────────────────────────────────────────────────────────\n origXHROpen = XMLHttpRequest.prototype.open;\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async?: boolean,\n username?: string | null,\n password?: string | null,\n ) {\n const startTime = Date.now();\n const urlStr =\n typeof url === \"string\" ? url : (url as URL).href;\n\n this.addEventListener(\"load\", () => {\n push({\n method: method.toUpperCase(),\n url: truncateUrl(urlStr),\n status: this.status,\n duration: Date.now() - startTime,\n timestamp: startTime,\n });\n });\n\n return origXHROpen!.apply(this, [\n method,\n url,\n async ?? true,\n username,\n password,\n ] as Parameters<typeof XMLHttpRequest.prototype.open>);\n };\n },\n\n stop() {\n if (!active) return;\n active = false;\n if (origFetch) window.fetch = origFetch;\n if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;\n },\n\n getEntries() {\n return [...entries];\n },\n };\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { FlintUser } from \"@flint/types\";\n\nexport interface FlintState {\n user: FlintUser | undefined;\n sessionReplay: string | (() => string) | undefined;\n}\n\nlet state: FlintState = { user: undefined, sessionReplay: undefined };\nconst listeners = new Set<() => void>();\n\nfunction emit() {\n listeners.forEach((fn) => fn());\n}\n\nfunction subscribeStore(fn: () => void) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n}\n\nfunction getSnapshot(): FlintState {\n return state;\n}\n\nexport function useFlintStore() {\n return useSyncExternalStore(subscribeStore, getSnapshot);\n}\n\nexport const flint = {\n setUser(user: FlintUser | null) {\n state = { ...state, user: user ?? undefined };\n emit();\n },\n setSessionReplay(url: string | (() => string)) {\n state = { ...state, sessionReplay: url };\n emit();\n },\n};\n"],"mappings":"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","names":["import_react","import_react_i18next","import_react_i18next","MAX_ENTRIES","import_react","import_jsx_runtime","SparkIcon"]}