@diegotsi/flint-react 0.1.6 → 0.2.1

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
@@ -270,7 +270,7 @@ function FlintModal({
270
270
  boxShadow: colors.shadow,
271
271
  border: `1px solid ${colors.border}`,
272
272
  width: "100%",
273
- maxWidth: "480px",
273
+ maxWidth: "600px",
274
274
  maxHeight: "92vh",
275
275
  overflowY: "auto",
276
276
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
@@ -284,7 +284,7 @@ function FlintModal({
284
284
  border: `1px solid ${inputBorder}`,
285
285
  background: colors.backgroundSecondary,
286
286
  color: colors.text,
287
- fontSize: "14px",
287
+ fontSize: "16px",
288
288
  outline: "none",
289
289
  boxSizing: "border-box",
290
290
  fontFamily: "inherit",
@@ -359,7 +359,7 @@ function FlintModal({
359
359
  display: "flex",
360
360
  alignItems: "center",
361
361
  justifyContent: "center",
362
- fontSize: 17,
362
+ fontSize: 19,
363
363
  fontWeight: 700,
364
364
  color: colors.text,
365
365
  letterSpacing: "-0.02em",
@@ -373,7 +373,7 @@ function FlintModal({
373
373
  display: "flex",
374
374
  alignItems: "center",
375
375
  justifyContent: "center",
376
- fontSize: 17,
376
+ fontSize: 19,
377
377
  fontWeight: 700,
378
378
  color: colors.text,
379
379
  letterSpacing: "-0.02em",
@@ -392,7 +392,7 @@ function FlintModal({
392
392
  justifyContent: "center",
393
393
  gap: 6,
394
394
  color: colors.textMuted,
395
- fontSize: 13,
395
+ fontSize: 15,
396
396
  opacity: isSuccess ? 0 : 1,
397
397
  transition: "opacity 0.2s ease",
398
398
  pointerEvents: "none"
@@ -412,46 +412,30 @@ function FlintModal({
412
412
  transition: "opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s",
413
413
  pointerEvents: isSuccess ? "auto" : "none"
414
414
  }, children: [
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}` : "" }),
416
- result?.slackMessageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
417
- "a",
418
- {
419
- href: result.slackMessageUrl,
420
- target: "_blank",
421
- rel: "noreferrer",
422
- style: {
423
- display: "inline-flex",
424
- alignItems: "center",
425
- gap: 6,
426
- padding: "9px 18px",
427
- borderRadius: "10px",
428
- background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
429
- color: colors.buttonText,
430
- textDecoration: "none",
431
- fontSize: "13px",
432
- fontWeight: 600,
433
- boxShadow: accentGlow
434
- },
435
- children: [
436
- t("successSlack"),
437
- " \u2197"
438
- ]
439
- }
440
- ),
415
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result ? `ID: ${result.id}` : "" }),
441
416
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
442
417
  "button",
443
418
  {
444
419
  onClick: onClose,
445
420
  style: {
446
- background: "none",
421
+ width: "100%",
422
+ padding: "13px 20px",
423
+ borderRadius: 12,
447
424
  border: "none",
425
+ background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
426
+ color: colors.buttonText,
427
+ fontSize: 17,
428
+ fontWeight: 700,
448
429
  cursor: "pointer",
449
- fontSize: 13,
450
- color: colors.textMuted,
451
- padding: "4px 8px",
452
- fontFamily: "inherit"
430
+ letterSpacing: "-0.01em",
431
+ boxShadow: accentGlow,
432
+ fontFamily: "inherit",
433
+ display: "flex",
434
+ alignItems: "center",
435
+ justifyContent: "center",
436
+ gap: 8
453
437
  },
454
- children: t("cancel")
438
+ children: t("close")
455
439
  }
456
440
  )
457
441
  ] })
@@ -532,7 +516,7 @@ function FlintModal({
532
516
  borderRadius: 10,
533
517
  border: `1px dashed ${inputBorder}`,
534
518
  cursor: "pointer",
535
- fontSize: 13,
519
+ fontSize: 15,
536
520
  color: colors.textMuted,
537
521
  background: colors.backgroundSecondary
538
522
  },
@@ -564,8 +548,8 @@ function FlintModal({
564
548
  border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
565
549
  marginBottom: 16
566
550
  }, 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") })
551
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
552
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
569
553
  ] }),
570
554
  status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
571
555
  padding: "10px 13px",
@@ -573,7 +557,7 @@ function FlintModal({
573
557
  background: "rgba(239,68,68,0.08)",
574
558
  border: "1px solid rgba(239,68,68,0.2)",
575
559
  color: "#f87171",
576
- fontSize: 12,
560
+ fontSize: 14,
577
561
  marginBottom: 16
578
562
  }, children: [
579
563
  "\u26A0\uFE0F ",
@@ -590,7 +574,7 @@ function FlintModal({
590
574
  border: "none",
591
575
  background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
592
576
  color: colors.buttonText,
593
- fontSize: 15,
577
+ fontSize: 17,
594
578
  fontWeight: 700,
595
579
  cursor: "pointer",
596
580
  letterSpacing: "-0.01em",
@@ -619,7 +603,7 @@ function FlintModal({
619
603
  background: "none",
620
604
  border: "none",
621
605
  cursor: "pointer",
622
- fontSize: 13,
606
+ fontSize: 15,
623
607
  color: colors.textMuted,
624
608
  fontFamily: "inherit",
625
609
  borderRadius: 8
@@ -656,7 +640,7 @@ function ModalHeader({
656
640
  justifyContent: "center",
657
641
  flexShrink: 0
658
642
  }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SparkIcon, { color: colors.accent, size: 13 }) }),
659
- titleId && title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: titleId, style: { margin: 0, fontSize: 14, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 }, children: title }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { flex: 1, fontSize: 13, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
643
+ titleId && title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: titleId, style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 }, children: title }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
660
644
  showClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
661
645
  "button",
662
646
  {
@@ -668,7 +652,7 @@ function ModalHeader({
668
652
  cursor: "pointer",
669
653
  padding: 4,
670
654
  color: colors.textMuted,
671
- fontSize: 20,
655
+ fontSize: 22,
672
656
  lineHeight: 1,
673
657
  borderRadius: 6,
674
658
  display: "flex",
@@ -693,7 +677,7 @@ function FieldLabel({
693
677
  htmlFor,
694
678
  style: {
695
679
  display: "block",
696
- fontSize: "10px",
680
+ fontSize: "12px",
697
681
  fontWeight: 700,
698
682
  color: colors.textMuted,
699
683
  marginBottom: 6,
@@ -742,8 +726,8 @@ function SeverityButton({ sev, label, selected, hint, color, accent, border, bg,
742
726
  },
743
727
  children: [
744
728
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
745
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: "0.02em" }, children: sev }),
746
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 9, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
729
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 13, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: "0.02em" }, children: sev }),
730
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
747
731
  ]
748
732
  }
749
733
  );
@@ -779,6 +763,7 @@ var en_default = {
779
763
  screenshotLabel: "Screenshot (optional)",
780
764
  screenshotPlaceholder: "Click to attach...",
781
765
  submitLabel: "Submit",
766
+ close: "Close",
782
767
  successTitle: "Bug reported!",
783
768
  successDuplicate: "Looks like a duplicate of an existing bug.",
784
769
  successGitHub: "View GitHub issue",
@@ -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","../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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAA4C;AAC5C,IAAAC,wBAAgD;;;ACDhD,mBAAyD;AACzD,2BAA+B;;;ACA/B,oBAAyB;AAGzB,eAAsB,aACpB,WACA,YACA,SACA,YACuB;AACvB,QAAM,MAAM,GAAG,UAAU,QAAQ,OAAO,EAAE,CAAC;AAE3C,MAAI;AACJ,MAAI,UAAkC;AAAA,IACpC,iBAAiB;AAAA,EACnB;AAEA,MAAI,YAAY;AACd,UAAM,OAAO,IAAI,SAAS;AAC1B,SAAK,OAAO,cAAc,QAAQ,UAAU;AAC5C,SAAK,OAAO,gBAAgB,QAAQ,YAAY;AAChD,SAAK,OAAO,eAAe,QAAQ,WAAW;AAC9C,QAAI,QAAQ,iBAAkB,MAAK,OAAO,oBAAoB,QAAQ,gBAAgB;AACtF,QAAI,QAAQ,iBAAkB,MAAK,OAAO,oBAAoB,KAAK,UAAU,QAAQ,gBAAgB,CAAC;AACtG,QAAI,QAAQ,kBAAmB,MAAK,OAAO,qBAAqB,QAAQ,iBAAiB;AACzF,QAAI,QAAQ,kBAAmB,MAAK,OAAO,qBAAqB,QAAQ,iBAAiB;AACzF,SAAK,OAAO,YAAY,QAAQ,QAAQ;AACxC,QAAI,QAAQ,IAAK,MAAK,OAAO,OAAO,QAAQ,GAAG;AAC/C,QAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ,KAAK,UAAU,QAAQ,IAAI,CAAC;AAClE,SAAK,OAAO,cAAc,UAAU;AACpC,WAAO;AAAA,EACT,OAAO;AACL,WAAO,KAAK,UAAU,OAAO;AAC7B,YAAQ,cAAc,IAAI;AAAA,EAC5B;AAEA,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,SAAS,KAAK,CAAC;AAE9D,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,gBAAgB,EAAE;AACrE,UAAM,IAAI,MAAO,IAA2B,SAAS,QAAQ,IAAI,MAAM,EAAE;AAAA,EAC3E;AAEA,SAAO,IAAI,KAAK;AAClB;AAEA,eAAsB,aACpB,WACA,YACA,UACA,QACe;AACf,QAAM,OAAO,KAAK,UAAU,MAAM;AAClC,QAAM,UAAU,IAAI,YAAY,EAAE,OAAO,IAAI;AAC7C,QAAM,iBAAa,wBAAS,OAAO;AAEnC,QAAM,MAAM,GAAG,UAAU,QAAQ,OAAO,EAAE,CAAC,uBAAuB,QAAQ;AAC1E,QAAM,MAAM,KAAK;AAAA,IACf,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,WAAW;AAAA,EACnB,CAAC;AACH;;;AClDA,IAAM,QAAuB;AAAA,EAC3B,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QACE;AAAA,EACF,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAEA,IAAM,OAAsB;AAAA,EAC1B,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QACE;AAAA,EACF,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAEO,SAAS,aAAa,OAA6B;AACxD,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,UAAU,QAAS,QAAO;AAE9B,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,SAAS,cAAc,MAAM;AAAA,IACzC,QAAQ,SAAS,UAAU,MAAM;AAAA,IACjC,aAAa,SAAS,UAAU,MAAM;AAAA,IACtC,MAAM,SAAS,QAAQ,MAAM;AAAA,IAC7B,QAAQ,SAAS,UAAU,MAAM;AAAA,EACnC;AACF;;;AF0KU;AApMV,IAAM,aAAyB,CAAC,MAAM,MAAM,MAAM,IAAI;AACtD,IAAM,YAAsC;AAAA,EAC1C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAKA,SAAS,kBAAkB;AACzB,MAAI,OAAO,aAAa,YAAa;AACrC,MAAI,SAAS,eAAe,WAAW,EAAG;AAC1C,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BhB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAU;AACR,QAAM,EAAE,EAAE,QAAI,qCAAe;AAC7B,QAAM,SAAS,aAAa,KAAK;AACjC,QAAM,SAAS,UAAU;AAEzB,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAmB,IAAI;AACvD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,EAAE;AACjD,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAAS,EAAE;AAC3D,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAsB,IAAI;AAC9D,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAiB,MAAM;AACnD,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAA8B,IAAI;AAC9D,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,EAAE;AAE3C,QAAM,cAAU,qBAAyB,IAAI;AAC7C,QAAM,iBAAa,qBAAuB,IAAI;AAE9C,8BAAU,MAAM;AAAE,oBAAgB;AAAA,EAAG,GAAG,CAAC,CAAC;AAE1C,8BAAU,MAAM;AACd,UAAM,UAAU,CAAC,MAAqB;AACpC,UAAI,EAAE,QAAQ,YAAY,WAAW,aAAc,SAAQ;AAAA,IAC7D;AACA,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,MAAM,OAAO,oBAAoB,WAAW,OAAO;AAAA,EAC5D,GAAG,CAAC,SAAS,MAAM,CAAC;AAEpB,QAAM,yBAAqB;AAAA,IACzB,CAAC,MAAwB;AACvB,UAAI,EAAE,WAAW,WAAW,WAAW,WAAW,aAAc,SAAQ;AAAA,IAC1E;AAAA,IACA,CAAC,SAAS,MAAM;AAAA,EAClB;AAEA,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,QAAI,CAAC,YAAY,KAAK,EAAG;AAEzB,cAAU,YAAY;AACtB,gBAAY,EAAE;AAEd,UAAM,gBAAyC;AAAA,MAC7C,GAAG;AAAA,MACH,aAAa,eAAe;AAAA,MAC5B,aAAa,eAAe;AAAA,MAC5B,eAAe,iBAAiB;AAAA,IAClC;AAEA,QAAI;AACF,YAAM,MAAM,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,UACE,YAAY,MAAM,MAAM;AAAA,UACxB,cAAc,MAAM,QAAQ;AAAA,UAC5B,aAAa,YAAY,KAAK;AAAA,UAC9B,kBAAkB,iBAAiB,KAAK,KAAK;AAAA,UAC7C,mBAAmB,qBAAqB,KAAK;AAAA,UAC7C;AAAA,UACA,KAAK,OAAO,SAAS;AAAA,UACrB,MAAM;AAAA,QACR;AAAA,QACA,cAAc;AAAA,MAChB;AACA,gBAAU,GAAG;AACb,gBAAU,SAAS;AAEnB,YAAM,SAAS,gBAAgB;AAC/B,UAAI,OAAO,SAAS,GAAG;AACrB,qBAAa,WAAW,YAAY,IAAI,IAAI,MAAM,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACpE;AAAA,IACF,SAAS,KAAK;AACZ,kBAAY,eAAe,QAAQ,IAAI,UAAU,EAAE,YAAY,CAAC;AAChE,gBAAU,OAAO;AAAA,IACnB;AAAA,EACF;AAGA,QAAM,cAAc,SAAS,0BAA0B;AACvD,QAAM,aAAa,YAAY,OAAO,MAAM;AAE5C,QAAM,eAAoC;AAAA,IACxC,UAAU;AAAA,IACV,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB;AAAA,IACA,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,WAAW;AAAA,EACb;AAEA,QAAM,aAAkC;AAAA,IACtC,YAAY,OAAO;AAAA,IACnB,gBAAgB,OAAO;AAAA,IACvB,sBAAsB,OAAO;AAAA,IAC7B,cAAc;AAAA,IACd,WAAW,OAAO;AAAA,IAClB,QAAQ,aAAa,OAAO,MAAM;AAAA,IAClC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAO,OAAO;AAAA,IACd,WAAW;AAAA,EACb;AAEA,QAAM,aAAkC;AAAA,IACtC,OAAO;AAAA,IACP,SAAS;AAAA,IACT,cAAc;AAAA,IACd,QAAQ,aAAa,WAAW;AAAA,IAChC,YAAY,OAAO;AAAA,IACnB,OAAO,OAAO;AAAA,IACd,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAGA,MAAI,WAAW,gBAAgB,WAAW,WAAW;AACnD,UAAM,YAAY,WAAW;AAC7B,UAAM,aAAa,YACf,sBACA,aAAa,SAAS,2BAA2B,kBAAkB;AACvE,UAAM,eAAe,YAAY,YAAY,OAAO;AAEpD,WACE,4CAAC,SAAI,OAAO,cACV,uDAAC,SAAI,OAAO,YAAY,MAAK,UAAS,cAAW,QAAO,cAAY,YAAY,EAAE,cAAc,IAAI,EAAE,SAAS,GAC7G;AAAA,kDAAC,eAAY,QAAgB,aAA0B,WAAW,OAAO,SAAkB;AAAA,MAE3F,6CAAC,SAAI,OAAO,EAAE,SAAS,kBAAkB,WAAW,UAAU,SAAS,QAAQ,eAAe,UAAU,YAAY,SAAS,GAE3H;AAAA,qDAAC,SAAI,OAAO,EAAE,UAAU,YAAY,OAAO,IAAI,QAAQ,IAAI,cAAc,GAAG,GAE1E;AAAA,sDAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,cAAc;AAAA,YACd,QAAQ,eAAe,OAAO,MAAM;AAAA,YACpC,WAAW;AAAA,YACX,SAAS,YAAY,IAAI;AAAA,YACzB,YAAY;AAAA,UACd,GAAG;AAAA,UAEH,4CAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,cAAc;AAAA,YACd,QAAQ,eAAe,OAAO,MAAM;AAAA,YACpC,WAAW;AAAA,YACX,SAAS,YAAY,IAAI;AAAA,YACzB,YAAY;AAAA,UACd,GAAG;AAAA,UAEH,4CAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,gBAAgB;AAAA,YAChB,WAAW,YAAY,SAAS;AAAA,YAChC,YAAY;AAAA,UACd,GAAG;AAAA,UAEH,6CAAC,SAAI,OAAO,EAAE,UAAU,YAAY,OAAO,IAAI,cAAc,MAAM,GAEjE;AAAA,wDAAC,SAAI,OAAO;AAAA,cACV,UAAU;AAAA,cAAY,OAAO;AAAA,cAC7B,cAAc;AAAA,cACd,YAAY,2BAA2B,OAAO,MAAM,OAAO,OAAO,WAAW;AAAA,cAC7E,SAAS;AAAA,cAAQ,YAAY;AAAA,cAAU,gBAAgB;AAAA,cACvD,WAAW,YAAY,SAAS;AAAA,cAChC,SAAS,YAAY,IAAI;AAAA,cACzB,YAAY;AAAA,YACd,GACE,sDAAC,aAAU,OAAO,OAAO,QAAQ,MAAM,IAAI,GAC7C;AAAA,YAEA,4CAAC,SAAI,OAAO;AAAA,cACV,UAAU;AAAA,cAAY,OAAO;AAAA,cAC7B,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,SAAS;AAAA,cAAQ,YAAY;AAAA,cAAU,gBAAgB;AAAA,cACvD,SAAS,YAAY,IAAI;AAAA,cACzB,WAAW,YAAY,aAAa;AAAA,cACpC,YAAY;AAAA,YACd,GACE,sDAAC,aAAU,MAAM,IAAI,GACvB;AAAA,aACF;AAAA,WACF;AAAA,QAGA,6CAAC,SAAI,OAAO,EAAE,UAAU,YAAY,QAAQ,IAAI,OAAO,QAAQ,cAAc,GAAG,GAC9E;AAAA,sDAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,gBAAgB;AAAA,YACvD,UAAU;AAAA,YAAI,YAAY;AAAA,YAAK,OAAO,OAAO;AAAA,YAAM,eAAe;AAAA,YAClE,SAAS,YAAY,IAAI;AAAA,YACzB,YAAY;AAAA,YACZ,eAAe;AAAA,UACjB,GACG,YAAE,SAAS,GACd;AAAA,UACA,4CAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,gBAAgB;AAAA,YACvD,UAAU;AAAA,YAAI,YAAY;AAAA,YAAK,OAAO,OAAO;AAAA,YAAM,eAAe;AAAA,YAClE,SAAS,YAAY,IAAI;AAAA,YACzB,WAAW,YAAY,kBAAkB;AAAA,YACzC,YAAY;AAAA,YACZ,eAAe,YAAY,SAAS;AAAA,UACtC,GACG,YAAE,cAAc,GACnB;AAAA,WACF;AAAA,QAGA,6CAAC,SAAI,OAAO,EAAE,UAAU,YAAY,WAAW,IAAI,OAAO,OAAO,GAE/D;AAAA,uDAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,gBAAgB;AAAA,YACvD,KAAK;AAAA,YAAG,OAAO,OAAO;AAAA,YAAW,UAAU;AAAA,YAC3C,SAAS,YAAY,IAAI;AAAA,YACzB,YAAY;AAAA,YACZ,eAAe;AAAA,UACjB,GACE;AAAA,wDAAC,UAAM,YAAE,kBAAkB,GAAE;AAAA,YAC7B,4CAAC,eAAY,OAAO,OAAO,QAAQ;AAAA,aACrC;AAAA,UAEA,6CAAC,SAAI,OAAO;AAAA,YACV,UAAU;AAAA,YAAY,OAAO;AAAA,YAC7B,SAAS;AAAA,YAAQ,eAAe;AAAA,YAAU,YAAY;AAAA,YAAU,KAAK;AAAA,YACrE,SAAS,YAAY,IAAI;AAAA,YACzB,WAAW,YAAY,kBAAkB;AAAA,YACzC,YAAY;AAAA,YACZ,eAAe,YAAY,SAAS;AAAA,UACtC,GACE;AAAA,wDAAC,OAAE,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,WAAW,QAAQ,EAAE,GAC1D,kBAAQ,cAAc,EAAE,kBAAkB,IAAI,SAAS,OAAO,OAAO,EAAE,KAAK,IAC/E;AAAA,YACC,QAAQ,mBACP;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM,OAAO;AAAA,gBACb,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,KAAK;AAAA,kBACL,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,YAAY,2BAA2B,OAAO,MAAM,KAAK,OAAO,WAAW;AAAA,kBAC3E,OAAO,OAAO;AAAA,kBACd,gBAAgB;AAAA,kBAChB,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,WAAW;AAAA,gBACb;AAAA,gBAEC;AAAA,oBAAE,cAAc;AAAA,kBAAE;AAAA;AAAA;AAAA,YACrB;AAAA,YAEF;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,UAAU;AAAA,kBACV,OAAO,OAAO;AAAA,kBACd,SAAS;AAAA,kBACT,YAAY;AAAA,gBACd;AAAA,gBAEC,YAAE,QAAQ;AAAA;AAAA,YACb;AAAA,aACF;AAAA,WACF;AAAA,SACF;AAAA,OACF,GACF;AAAA,EAEJ;AAGA,SACE,4CAAC,SAAI,KAAK,YAAY,OAAO,cAAc,SAAS,oBAClD,uDAAC,SAAI,OAAO,YAAY,MAAK,UAAS,cAAW,QAAO,mBAAgB,qBACtE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,WAAS;AAAA,QACT;AAAA,QACA,SAAQ;AAAA,QACR,OAAO,EAAE,YAAY;AAAA;AAAA,IACvB;AAAA,IAEA,6CAAC,UAAK,UAAU,cAAc,OAAO,EAAE,SAAS,iBAAiB,GAE/D;AAAA,mDAAC,SAAI,OAAO,EAAE,cAAc,GAAG,GAC7B;AAAA,oDAAC,cAAW,QAAiB,YAAE,eAAe,GAAE;AAAA,QAChD,4CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,iBAAiB,KAAK,EAAE,GACzE,qBAAW,IAAI,CAAC,QACf;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA,OAAO,EAAE,YAAY,GAAG,QAAQ;AAAA,YAChC,UAAU,aAAa;AAAA,YACvB,MAAM,EAAE,YAAY,GAAG,OAAO;AAAA,YAC9B,OAAO,UAAU,GAAG;AAAA,YACpB,QAAQ,OAAO;AAAA,YACf,QAAQ;AAAA,YACR,IAAI,OAAO;AAAA,YACX,MAAM,OAAO;AAAA,YACb,SAAS,MAAM,YAAY,GAAG;AAAA;AAAA,UAVzB;AAAA,QAWP,CACD,GACH;AAAA,SACF;AAAA,MAGA,6CAAC,SAAI,OAAO,EAAE,cAAc,GAAG,GAC7B;AAAA,oDAAC,cAAW,QAAgB,SAAQ,qBAAqB,YAAE,mBAAmB,GAAE;AAAA,QAChF;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAO,EAAE,GAAG,YAAY,QAAQ,YAAY,WAAW,GAAG;AAAA,YAC1D,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,aAAa,EAAE,yBAAyB;AAAA,YACxC,UAAQ;AAAA;AAAA,QACV;AAAA,SACF;AAAA,MAGA,6CAAC,SAAI,OAAO,EAAE,cAAc,GAAG,GAC7B;AAAA,oDAAC,cAAW,QAAgB,SAAQ,kBAAkB,YAAE,uBAAuB,GAAE;AAAA,QACjF;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAO,EAAE,GAAG,YAAY,QAAQ,YAAY,WAAW,GAAG;AAAA,YAC1D,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,oBAAoB,EAAE,OAAO,KAAK;AAAA,YACnD,aAAa,EAAE,6BAA6B;AAAA;AAAA,QAC9C;AAAA,SACF;AAAA,MAGA,6CAAC,SAAI,OAAO,EAAE,cAAc,GAAG,GAC7B;AAAA,oDAAC,cAAW,QAAiB,YAAE,iBAAiB,GAAE;AAAA,QAClD;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,SAAS;AAAA,cACT,cAAc;AAAA,cACd,QAAQ,cAAc,WAAW;AAAA,cACjC,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,OAAO,OAAO;AAAA,cACd,YAAY,OAAO;AAAA,YACrB;AAAA,YACD;AAAA;AAAA,cACK,aAAa,WAAW,OAAO,EAAE,uBAAuB;AAAA;AAAA;AAAA,QAC9D;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,KAAK;AAAA,YACL,MAAK;AAAA,YACL,QAAO;AAAA,YACP,OAAO,EAAE,SAAS,OAAO;AAAA,YACzB,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,QAAQ,CAAC,KAAK,IAAI;AAAA;AAAA,QAC5D;AAAA,SACF;AAAA,MAGA,6CAAC,SAAI,OAAO;AAAA,QACV,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAc;AAAA,QACd,YAAY,SAAS,2BAA2B;AAAA,QAChD,QAAQ,aAAa,SAAS,2BAA2B,oBAAoB;AAAA,QAC7E,cAAc;AAAA,MAChB,GACE;AAAA,oDAAC,UAAK,OAAO,EAAE,UAAU,GAAG,GAAG,uBAAE;AAAA,QACjC,4CAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,WAAW,YAAY,IAAI,GACnE,YAAE,YAAY,GACjB;AAAA,SACF;AAAA,MAGC,WAAW,WACV,6CAAC,SAAI,OAAO;AAAA,QACV,SAAS;AAAA,QACT,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,GAAG;AAAA;AAAA,QACG,YAAY,EAAE,YAAY;AAAA,SAChC;AAAA,MAIF;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAO;AAAA,YACL,OAAO;AAAA,YACP,SAAS;AAAA,YACT,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,YAAY,2BAA2B,OAAO,MAAM,KAAK,OAAO,WAAW;AAAA,YAC3E,OAAO,OAAO;AAAA,YACd,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,eAAe;AAAA,YACf,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,KAAK;AAAA,UACP;AAAA,UAEA;AAAA,wDAAC,aAAU,OAAO,OAAO,YAAY,MAAM,IAAI;AAAA,YAC9C,EAAE,aAAa;AAAA;AAAA;AAAA,MAClB;AAAA,MAGA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,OAAO;AAAA,YACP,SAAS;AAAA,YACT,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,OAAO,OAAO;AAAA,YACd,YAAY;AAAA,YACZ,cAAc;AAAA,UAChB;AAAA,UAEC,YAAE,QAAQ;AAAA;AAAA,MACb;AAAA,OACF;AAAA,KACF,GACF;AAEJ;AAIA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,SACE,6CAAC,SAAI,OAAO;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,SAAS;AAAA,IACT,cAAc,aAAa,WAAW;AAAA,EACxC,GAEE;AAAA,gDAAC,SAAI,OAAO;AAAA,MACV,OAAO;AAAA,MAAI,QAAQ;AAAA,MACnB,cAAc;AAAA,MACd,YAAY,2BAA2B,OAAO,MAAM,OAAO,OAAO,WAAW;AAAA,MAC7E,QAAQ,aAAa,OAAO,MAAM;AAAA,MAClC,SAAS;AAAA,MAAQ,YAAY;AAAA,MAAU,gBAAgB;AAAA,MACvD,YAAY;AAAA,IACd,GACE,sDAAC,aAAU,OAAO,OAAO,QAAQ,MAAM,IAAI,GAC7C;AAAA,IAEC,WAAW,QACV,4CAAC,QAAG,IAAI,SAAS,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM,eAAe,WAAW,MAAM,EAAE,GACvH,iBACH,IAEA,4CAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,UAAU,GAAG,mBAAK;AAAA,IAGxF,aACC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,cAAW;AAAA,QACX,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,OAAO,OAAO;AAAA,UACd,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,SAAS;AAAA,UAAQ,YAAY;AAAA,UAAU,gBAAgB;AAAA,UACvD,SAAS;AAAA,UACT,YAAY;AAAA,QACd;AAAA,QACD;AAAA;AAAA,IAED;AAAA,KAEJ;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,OAAO,OAAO;AAAA,QACd,cAAc;AAAA,QACd,eAAe;AAAA,QACf,eAAe;AAAA,MACjB;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,YAAY,EAAE,MAAM,GAAsB;AACjD,SACE,4CAAC,UAAK,OAAO,EAAE,SAAS,eAAe,KAAK,GAAG,YAAY,SAAS,GACjE,WAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACd;AAAA,IAAC;AAAA;AAAA,MAEC,OAAO;AAAA,QACL,OAAO;AAAA,QAAG,QAAQ;AAAA,QAClB,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,WAAW,gDAAgD,IAAI,GAAG;AAAA,MACpE;AAAA;AAAA,IAPK;AAAA,EAQP,CACD,GACH;AAEJ;AAeA,SAAS,eAAe,EAAE,KAAK,OAAO,UAAU,MAAM,OAAO,QAAQ,QAAQ,IAAI,MAAM,QAAQ,GAAgB;AAC7G,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,cAAc;AAAA,QACd,QAAQ,WAAW,aAAa,MAAM,KAAK,eAAe,MAAM;AAAA,QAChE,YAAY,WAAW,GAAG,MAAM,OAAO;AAAA,QACvC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAAA,MAEA;AAAA,oDAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,OAAO,YAAY,OAAO,SAAS,QAAQ,GAAG;AAAA,QAChG,4CAAC,UAAK,OAAO,EAAE,UAAU,IAAI,YAAY,WAAW,MAAM,KAAK,OAAO,WAAW,SAAS,MAAM,eAAe,SAAS,GACrH,eACH;AAAA,QACA,4CAAC,UAAK,OAAO,EAAE,UAAU,GAAG,OAAO,WAAW,SAAS,MAAM,SAAS,KAAK,eAAe,SAAS,GAChG,iBACH;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,UAAU,EAAE,QAAQ,gBAAgB,OAAO,GAAG,GAAsC;AAC3F,SACE,4CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAQ,OAAO,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QACxJ,sDAAC,UAAK,GAAE,mCAAkC,GAC5C;AAEJ;AAEA,SAAS,UAAU,EAAE,OAAO,GAAG,GAAsB;AACnD,SACE,4CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,WAAU,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,eAAY,QAC1J,sDAAC,cAAS,QAAO,kBAAiB,GACpC;AAEJ;;;AG1tBA,qBAAwC;AACxC,IAAAC,wBAAiC;;;ACDjC;AAAA,EACE,aAAe;AAAA,EACf,YAAc;AAAA,EACd,eAAiB;AAAA,EACjB,kBAAoB;AAAA,EACpB,kBAAoB;AAAA,EACpB,kBAAoB;AAAA,EACpB,kBAAoB;AAAA,EACpB,mBAAqB;AAAA,EACrB,mBAAqB;AAAA,EACrB,mBAAqB;AAAA,EACrB,mBAAqB;AAAA,EACrB,mBAAqB;AAAA,EACrB,yBAA2B;AAAA,EAC3B,uBAAyB;AAAA,EACzB,6BAA+B;AAAA,EAC/B,iBAAmB;AAAA,EACnB,uBAAyB;AAAA,EACzB,aAAe;AAAA,EACf,cAAgB;AAAA,EAChB,kBAAoB;AAAA,EACpB,eAAiB;AAAA,EACjB,cAAgB;AAAA,EAChB,YAAc;AAAA,EACd,YAAc;AAAA,EACd,QAAU;AAAA,EACV,SAAW;AAAA,EACX,kBAAoB;AACtB;;;ADxBO,IAAM,iBAAgD,+BAAe;AAE5E,WAAW,IAAI,sCAAgB,EAAE,KAAK;AAAA,EACpC,KAAK;AAAA,EACL,aAAa;AAAA,EACb,WAAW,EAAE,SAAS,EAAE,aAAa,WAAG,EAAE;AAAA,EAC1C,eAAe,EAAE,aAAa,MAAM;AAAA,EACpC,eAAe;AACjB,CAAC;AAED,IAAO,eAAQ;;;AEZR,SAAS,qBAAsC;AACpD,QAAM,KAAK,UAAU;AAGrB,MAAI,UAAU;AACd,QAAM,UAAU,GAAG,MAAM,eAAe;AACxC,QAAM,WAAW,GAAG,MAAM,gBAAgB;AAC1C,QAAM,QAAQ,GAAG,MAAM,YAAY;AACnC,QAAM,UAAU,GAAG,MAAM,gBAAgB;AACzC,QAAM,SAAS,GAAG,MAAM,YAAY;AAEpC,MAAI,QAAQ;AACV,cAAU,SAAS,OAAO,CAAC,CAAC;AAAA,EAC9B,WAAW,OAAO;AAChB,cAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC5B,WAAW,WAAW,CAAC,UAAU,KAAK,EAAE,GAAG;AACzC,cAAU,UAAU,QAAQ,CAAC,CAAC;AAAA,EAChC,WAAW,UAAU;AACnB,cAAU,WAAW,SAAS,CAAC,CAAC;AAAA,EAClC,WAAW,WAAW,WAAW,KAAK,EAAE,GAAG;AACzC,cAAU,UAAU,QAAQ,CAAC,CAAC;AAAA,EAChC;AAGA,MAAI,KAAK;AACT,QAAM,OAAO,GAAG,MAAM,uBAAuB;AAC7C,QAAM,OAAO,GAAG,MAAM,uBAAuB;AAC7C,QAAM,WAAW,GAAG,MAAM,eAAe;AACzC,QAAM,OAAO,GAAG,MAAM,wBAAwB;AAE9C,MAAI,MAAM;AACR,SAAK,SAAS,KAAK,CAAC,EAAE,QAAQ,KAAK,GAAG,CAAC;AAAA,EACzC,WAAW,MAAM;AACf,UAAM,SAAiC;AAAA,MACrC,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,SAAK,WAAW,OAAO,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;AAAA,EAC5C,WAAW,UAAU;AACnB,SAAK,WAAW,SAAS,CAAC,CAAC;AAAA,EAC7B,WAAW,MAAM;AACf,SAAK,OAAO,KAAK,CAAC,EAAE,QAAQ,MAAM,GAAG,CAAC;AAAA,EACxC,WAAW,QAAQ,KAAK,EAAE,GAAG;AAC3B,SAAK;AAAA,EACP;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,GAAG,OAAO,UAAU,IAAI,OAAO,WAAW;AAAA,IACpD,QAAQ,GAAG,OAAO,KAAK,IAAI,OAAO,MAAM;AAAA,IACxC,UAAU,UAAU;AAAA,IACpB,UAAU,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,IAClD,QAAQ,UAAU;AAAA,EACpB;AACF;;;ACzDA,IAAM,cAAc;AAQb,SAAS,yBAA2C;AACzD,QAAM,UAA0B,CAAC;AACjC,MAAI,SAAS;AAEb,QAAM,YAAY;AAAA,IAChB,KAAK,QAAQ,IAAI,KAAK,OAAO;AAAA,IAC7B,MAAM,QAAQ,KAAK,KAAK,OAAO;AAAA,IAC/B,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,EACnC;AAEA,MAAI,cAAqC;AACzC,MAAI,gBAAoD;AAExD,WAAS,KAAK,OAA8B,MAAiB;AAC3D,QAAI;AACJ,QAAI;AACF,YAAM,KACH,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC,CAAE,EAC1D,KAAK,GAAG;AAAA,IACb,QAAQ;AACN,YAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACtB;AACA,QAAI,IAAI,SAAS,IAAK,OAAM,IAAI,MAAM,GAAG,GAAG,IAAI;AAChD,YAAQ,KAAK,EAAE,OAAO,MAAM,KAAK,WAAW,KAAK,IAAI,EAAE,CAAC;AACxD,QAAI,QAAQ,SAAS,YAAa,SAAQ,MAAM;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,QAAQ;AACN,UAAI,OAAQ;AACZ,eAAS;AAET,cAAQ,MAAM,IAAI,SAAoB;AACpC,aAAK,OAAO,IAAI;AAChB,kBAAU,IAAI,GAAG,IAAI;AAAA,MACvB;AACA,cAAQ,OAAO,IAAI,SAAoB;AACrC,aAAK,QAAQ,IAAI;AACjB,kBAAU,KAAK,GAAG,IAAI;AAAA,MACxB;AACA,cAAQ,QAAQ,IAAI,SAAoB;AACtC,aAAK,SAAS,IAAI;AAClB,kBAAU,MAAM,GAAG,IAAI;AAAA,MACzB;AAEA,oBAAc,OAAO;AACrB,aAAO,UAAU,CAAC,KAAK,KAAK,MAAM,KAAK,QAAQ;AAC7C,aAAK,SAAS,CAAC,KAAK,WAAW,OAAO,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;AACpE,YAAI,OAAO,gBAAgB;AACzB,iBAAO,YAAY,KAAK,KAAK,MAAM,KAAK,GAAG;AAC7C,eAAO;AAAA,MACT;AAEA,sBAAgB,OAAO;AACvB,aAAO,uBAAuB,CAAC,UAAU;AACvC,cAAM,SACJ,MAAM,kBAAkB,QACpB,MAAM,OAAO,UACb,KAAK,UAAU,MAAM,MAAM;AACjC,aAAK,SAAS,CAAC,uBAAuB,MAAM,CAAC;AAC7C,YAAI,OAAO,kBAAkB;AAC3B,wBAAc,KAAK,QAAQ,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,OAAO;AACL,UAAI,CAAC,OAAQ;AACb,eAAS;AACT,cAAQ,MAAM,UAAU;AACxB,cAAQ,OAAO,UAAU;AACzB,cAAQ,QAAQ,UAAU;AAC1B,aAAO,UAAU;AACjB,aAAO,uBAAuB;AAAA,IAChC;AAAA,IAEA,aAAa;AACX,aAAO,CAAC,GAAG,OAAO;AAAA,IACpB;AAAA,EACF;AACF;;;ACvFA,IAAMC,eAAc;AAQpB,SAAS,YAAY,KAAqB;AACxC,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI;AACpC,UAAM,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,QAAQ;AACrC,WAAO,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,GAAG,IAAI,WAAM;AAAA,EACxD,QAAQ;AACN,WAAO,IAAI,SAAS,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI,WAAM;AAAA,EACtD;AACF;AAEO,SAAS,yBAA2C;AACzD,QAAM,UAA0B,CAAC;AACjC,MAAI,YAAwC;AAC5C,MAAI,cAA2D;AAC/D,MAAI,SAAS;AAEb,WAAS,KAAK,OAAqB;AACjC,YAAQ,KAAK,KAAK;AAClB,QAAI,QAAQ,SAASA,aAAa,SAAQ,MAAM;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,QAAQ;AACN,UAAI,OAAQ;AACZ,eAAS;AAGT,kBAAY,OAAO;AACnB,aAAO,QAAQ,OACb,OACA,SACsB;AACtB,cAAM,UAAW,MAAM,UAAU,OAAkB,YAAY;AAC/D,cAAM,MACJ,OAAO,UAAU,WACb,QACA,iBAAiB,MACf,MAAM,OACL,MAAkB;AAC3B,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,MAAM,MAAM,UAAW,KAAK,QAAQ,OAAO,IAAI;AACrD,aAAK;AAAA,UACH;AAAA,UACA,KAAK,YAAY,GAAG;AAAA,UACpB,QAAQ,IAAI;AAAA,UACZ,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB,WAAW;AAAA,QACb,CAAC;AACD,eAAO;AAAA,MACT;AAGA,oBAAc,eAAe,UAAU;AACvC,qBAAe,UAAU,OAAO,SAC9B,QACA,KACA,OACA,UACA,UACA;AACA,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,SACJ,OAAO,QAAQ,WAAW,MAAO,IAAY;AAE/C,aAAK,iBAAiB,QAAQ,MAAM;AAClC,eAAK;AAAA,YACH,QAAQ,OAAO,YAAY;AAAA,YAC3B,KAAK,YAAY,MAAM;AAAA,YACvB,QAAQ,KAAK;AAAA,YACb,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB,WAAW;AAAA,UACb,CAAC;AAAA,QACH,CAAC;AAED,eAAO,YAAa,MAAM,MAAM;AAAA,UAC9B;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QACF,CAAqD;AAAA,MACvD;AAAA,IACF;AAAA,IAEA,OAAO;AACL,UAAI,CAAC,OAAQ;AACb,eAAS;AACT,UAAI,UAAW,QAAO,QAAQ;AAC9B,UAAI,YAAa,gBAAe,UAAU,OAAO;AAAA,IACnD;AAAA,IAEA,aAAa;AACX,aAAO,CAAC,GAAG,OAAO;AAAA,IACpB;AAAA,EACF;AACF;;;ACzGA,IAAAC,gBAAqC;AAQrC,IAAI,QAAoB,EAAE,MAAM,QAAW,eAAe,OAAU;AACpE,IAAM,YAAY,oBAAI,IAAgB;AAEtC,SAAS,OAAO;AACd,YAAU,QAAQ,CAAC,OAAO,GAAG,CAAC;AAChC;AAEA,SAAS,eAAe,IAAgB;AACtC,YAAU,IAAI,EAAE;AAChB,SAAO,MAAM,UAAU,OAAO,EAAE;AAClC;AAEA,SAAS,cAA0B;AACjC,SAAO;AACT;AAEO,SAAS,gBAAgB;AAC9B,aAAO,oCAAqB,gBAAgB,WAAW;AACzD;AAEO,IAAM,QAAQ;AAAA,EACnB,QAAQ,MAAwB;AAC9B,YAAQ,EAAE,GAAG,OAAO,MAAM,QAAQ,OAAU;AAC5C,SAAK;AAAA,EACP;AAAA,EACA,iBAAiB,KAA8B;AAC7C,YAAQ,EAAE,GAAG,OAAO,eAAe,IAAI;AACvC,SAAK;AAAA,EACP;AACF;;;AT3BA,mBAAuB;AAcjB,IAAAC,sBAAA;AAXN,IAAM,mBAAmB;AAElB,SAAS,YAAY,OAAyB;AACnD,QAAM,EAAE,SAAS,QAAQ,IAAI;AAE7B,+BAAU,MAAM;AACd,iBAAW,eAAe,MAAM;AAAA,EAClC,GAAG,CAAC,MAAM,CAAC;AAEX,SACE,6CAAC,yCAAgB,MAAM,cACrB,uDAAC,iBAAe,GAAG,OAAO,GAC5B;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AACX,GAAqB;AACnB,QAAM,cAAc,cAAc;AAClC,QAAM,eAAe,QAAQ,YAAY;AACzC,QAAM,wBAAwB,aAAa,iBAAiB,YAAY;AACxE,QAAM,uBAAuB,MAAM;AACjC,UAAM,MAAM;AACZ,WAAO,OAAO,QAAQ,aAAa,IAAI,IAAI;AAAA,EAC7C;AACA,QAAM,EAAE,EAAE,QAAI,sCAAe;AAC7B,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAS,KAAK;AACtC,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAC5C,QAAM,SAAS,aAAa,KAAK;AAKjC,QAAM,uBAAmB,sBAAyD,IAAI;AACtF,QAAM,uBAAmB,sBAAyD,IAAI;AACtF,QAAM,mBAAe,sBAAwB,CAAC,CAAC;AAC/C,QAAM,iBAAa,sBAA4B,IAAI;AAEnD,MAAI,CAAC,iBAAiB,SAAS;AAC7B,qBAAiB,UAAU,uBAAuB;AAClD,qBAAiB,QAAQ,MAAM;AAAA,EACjC;AACA,MAAI,CAAC,iBAAiB,SAAS;AAC7B,qBAAiB,UAAU,uBAAuB;AAClD,qBAAiB,QAAQ,MAAM;AAAA,EACjC;AAEA,+BAAU,MAAM;AAEd,UAAM,aAAS,qBAAO;AAAA,MACpB,KAAK,OAAO;AACV,qBAAa,QAAQ,KAAK,KAAK;AAE/B,cAAM,SAAS,KAAK,IAAI,IAAI;AAC5B,eACE,aAAa,QAAQ,SAAS,KAC9B,aAAa,QAAQ,CAAC,EAAE,YAAY,QACpC;AACA,uBAAa,QAAQ,MAAM;AAAA,QAC7B;AAAA,MACF;AAAA,IACF,CAAC;AACD,eAAW,UAAU,UAAU;AAE/B,WAAO,MAAM;AACX,uBAAiB,SAAS,KAAK;AAC/B,uBAAiB,SAAS,KAAK;AAC/B,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,eAAe,EAAE,aAAa;AAE5C,SACE,8EAEE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM,QAAQ,IAAI;AAAA,QAC3B,cAAc,MAAM,WAAW,IAAI;AAAA,QACnC,cAAc,MAAM,WAAW,KAAK;AAAA,QACpC,cAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,QAAQ,SAAS;AAAA,UACjB,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,YAAY,2BAA2B,OAAO,MAAM,KAAK,OAAO,WAAW;AAAA,UAC3E,OAAO,OAAO;AAAA,UACd,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,WAAW,UACP,YAAY,OAAO,MAAM,mCACzB,YAAY,OAAO,MAAM;AAAA,UAC7B,YACE;AAAA,UACF,WAAW,UAAU,qBAAqB;AAAA,UAC1C,YAAY;AAAA,UACZ,eAAe;AAAA,QACjB;AAAA,QAEA;AAAA,uDAACC,YAAA,EAAU;AAAA,UACV;AAAA;AAAA;AAAA,IACH;AAAA,IAGC,QACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,MAAM,QAAQ,KAAK;AAAA,QAC5B,gBAAgB;AAAA,QAChB,gBAAgB,MAAM,iBAAiB,SAAS,WAAW,KAAK,CAAC;AAAA,QACjE,kBAAkB,MAAM,iBAAiB,SAAS,WAAW,KAAK,CAAC;AAAA,QACnE,iBAAiB,MAAM,CAAC,GAAG,aAAa,OAAO;AAAA,QAC/C;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;AAEA,SAASA,aAAY;AACnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAY;AAAA,MAEZ,uDAAC,UAAK,GAAE,mCAAkC;AAAA;AAAA,EAC5C;AAEJ;","names":["import_react","import_react_i18next","import_react_i18next","MAX_ENTRIES","import_react","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: \"600px\",\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: \"16px\",\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: 19, 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: 19, 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: 15,\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: 15, color: colors.textMuted, margin: 0 }}> \n {result ? `ID: ${result.id}` : \"\"}\n </p>\n {/* \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: \"15px\",\n fontWeight: 600,\n boxShadow: accentGlow,\n }}\n >\n {t(\"successSlack\")} ↗\n </a>\n )} */}\n <button\n onClick={onClose}\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: 17,\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 {t(\"close\")}\n </button>\n \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: 15,\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: 16 }}>🎥</span>\n <span style={{ fontSize: 14, 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: 14,\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: 17,\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: 15,\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: 16, fontWeight: 600, color: colors.text, letterSpacing: \"-0.01em\", flex: 1 }}>\n {title}\n </h2>\n ) : (\n <span style={{ flex: 1, fontSize: 15, 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: 22,\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: \"12px\",\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: 13, fontWeight: selected ? 700 : 500, color: selected ? accent : text, letterSpacing: \"0.02em\" }}>\n {sev}\n </span>\n <span style={{ fontSize: 11, 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 \"close\": \"Close\",\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}","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"]}