glitchgrab 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -724,7 +724,7 @@ function ReportButton({
|
|
|
724
724
|
style: {
|
|
725
725
|
position: "fixed",
|
|
726
726
|
inset: 0,
|
|
727
|
-
zIndex:
|
|
727
|
+
zIndex: 2147483647,
|
|
728
728
|
display: "flex",
|
|
729
729
|
alignItems: "center",
|
|
730
730
|
justifyContent: "center",
|
|
@@ -741,7 +741,7 @@ function ReportButton({
|
|
|
741
741
|
style: {
|
|
742
742
|
position: children ? "relative" : "fixed",
|
|
743
743
|
...modalPositionStyles,
|
|
744
|
-
zIndex:
|
|
744
|
+
zIndex: 2147483647,
|
|
745
745
|
width: "340px",
|
|
746
746
|
maxWidth: "calc(100% - 32px)",
|
|
747
747
|
backgroundColor: t.bg,
|
|
@@ -749,7 +749,8 @@ function ReportButton({
|
|
|
749
749
|
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
750
750
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
751
751
|
overflow: "hidden",
|
|
752
|
-
color: t.text
|
|
752
|
+
color: t.text,
|
|
753
|
+
isolation: "isolate"
|
|
753
754
|
},
|
|
754
755
|
children: [
|
|
755
756
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -789,12 +790,12 @@ function ReportButton({
|
|
|
789
790
|
border: "none",
|
|
790
791
|
cursor: "pointer",
|
|
791
792
|
padding: "4px",
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
793
|
+
display: "flex",
|
|
794
|
+
alignItems: "center",
|
|
795
|
+
justifyContent: "center"
|
|
795
796
|
},
|
|
796
797
|
"aria-label": "Close",
|
|
797
|
-
children: "
|
|
798
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { display: "block" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 4L12 12M12 4L4 12", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round" }) })
|
|
798
799
|
}
|
|
799
800
|
)
|
|
800
801
|
]
|
|
@@ -845,18 +846,15 @@ function ReportButton({
|
|
|
845
846
|
background: "rgba(0,0,0,0.6)",
|
|
846
847
|
border: "none",
|
|
847
848
|
borderRadius: "50%",
|
|
848
|
-
color: "#fff",
|
|
849
849
|
width: "20px",
|
|
850
850
|
height: "20px",
|
|
851
|
-
fontSize: "12px",
|
|
852
851
|
cursor: "pointer",
|
|
853
852
|
display: "flex",
|
|
854
853
|
alignItems: "center",
|
|
855
|
-
justifyContent: "center"
|
|
856
|
-
lineHeight: 1
|
|
854
|
+
justifyContent: "center"
|
|
857
855
|
},
|
|
858
856
|
"aria-label": "Remove screenshot",
|
|
859
|
-
children: "
|
|
857
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M1 1L9 9M9 1L1 9", stroke: "#fff", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
860
858
|
}
|
|
861
859
|
),
|
|
862
860
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
@@ -899,13 +897,14 @@ function ReportButton({
|
|
|
899
897
|
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
900
898
|
},
|
|
901
899
|
style: {
|
|
902
|
-
background:
|
|
903
|
-
color: t.
|
|
900
|
+
background: t.accent,
|
|
901
|
+
color: t.accentText,
|
|
904
902
|
fontSize: "10px",
|
|
905
|
-
padding: "
|
|
903
|
+
padding: "3px 8px",
|
|
906
904
|
borderRadius: "4px",
|
|
907
905
|
border: "none",
|
|
908
|
-
cursor: "pointer"
|
|
906
|
+
cursor: "pointer",
|
|
907
|
+
fontWeight: 600
|
|
909
908
|
},
|
|
910
909
|
children: "Upload"
|
|
911
910
|
}
|
|
@@ -916,13 +915,14 @@ function ReportButton({
|
|
|
916
915
|
type: "button",
|
|
917
916
|
onClick: retakeScreenshot,
|
|
918
917
|
style: {
|
|
919
|
-
background:
|
|
920
|
-
color: t.
|
|
918
|
+
background: t.accent,
|
|
919
|
+
color: t.accentText,
|
|
921
920
|
fontSize: "10px",
|
|
922
|
-
padding: "
|
|
921
|
+
padding: "3px 8px",
|
|
923
922
|
borderRadius: "4px",
|
|
924
923
|
border: "none",
|
|
925
|
-
cursor: "pointer"
|
|
924
|
+
cursor: "pointer",
|
|
925
|
+
fontWeight: 600
|
|
926
926
|
},
|
|
927
927
|
children: "Retake"
|
|
928
928
|
}
|
|
@@ -1040,7 +1040,7 @@ function ReportButton({
|
|
|
1040
1040
|
style: {
|
|
1041
1041
|
position: "fixed",
|
|
1042
1042
|
inset: 0,
|
|
1043
|
-
zIndex:
|
|
1043
|
+
zIndex: 2147483647,
|
|
1044
1044
|
backgroundColor: "rgba(0,0,0,0.85)",
|
|
1045
1045
|
display: "flex",
|
|
1046
1046
|
flexDirection: "column",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/report-button.tsx"],"sourcesContent":["\"use client\";\n\n// ─── Core (required) ─────────────────────────────────────\nexport { GlitchgrabProvider, useGlitchgrab } from \"./provider\";\n\n// ─── Optional Components ─────────────────────────────────\nexport { ReportButton } from \"./report-button\";\nexport { GlitchgrabErrorBoundary } from \"./error-boundary\";\n\n// ─── Breadcrumbs ─────────────────────────────────────────\nexport {\n addBreadcrumb,\n getBreadcrumbs,\n clearBreadcrumbs,\n initBreadcrumbs,\n} from \"./breadcrumbs\";\n\n// ─── Utilities ───────────────────────────────────────────\nexport { sanitizeUrl, captureContext, captureDeviceInfo, sendReport } from \"./utils\";\n\n// ─── Types ───────────────────────────────────────────────\nexport type {\n GlitchgrabConfig,\n GlitchgrabProviderProps,\n ReportPayload,\n ReportResult,\n ReportType,\n CapturedContext,\n DeviceInfo,\n Breadcrumb,\n BreadcrumbType,\n UseGlitchgrabReturn,\n ReportButtonProps,\n GlitchgrabSession,\n} from \"./types\";\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: reason instanceof Error ? reason.message : String(reason),\n errorStack: reason instanceof Error ? reason.stack : undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n // Auto-detect baseUrl from window.location if not provided\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || (typeof window !== \"undefined\" ? window.location.origin : DEFAULT_BASE_URL),\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n keepalive: true,\n });\n\n if (response.ok) {\n const data = (await response.json()) as { success: boolean; data?: ReportResult };\n return data.data ?? { success: data.success };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps, UseGlitchgrabReturn } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe(): UseGlitchgrabReturn | null {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n const bg = getComputedStyle(document.body).backgroundColor;\n const match = bg.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map(Number);\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\nfunction getTheme(dark: boolean) {\n return dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n}\n\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n /** Render prop — receives { onClick, capturing } so you can use your own trigger button */\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const glitchgrab = useGlitchgrabSafe();\n\n // If no provider context, render nothing\n if (!glitchgrab) return null;\n\n const { reportBug } = glitchgrab;\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n // Small delay so the modal is gone before capture\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setCapturing(true);\n setSubmitted(false);\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setCapturing(false);\n setIsOpen(true);\n };\n\n // Close modal on Escape key\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else setIsOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n const handleSubmit = () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n setIsSubmitting(true);\n reportBug(description.trim(), screenshot ? { screenshot } : undefined);\n\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n setIsSubmitting(false);\n\n setTimeout(() => {\n setSubmitted(false);\n setIsOpen(false);\n }, 2000);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const modalPositionStyles: CSSProperties = children\n ? {} // user controls positioning\n : {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"64px\" } : { bottom: \"64px\" }),\n };\n\n return (\n <>\n {/* Trigger: user's custom button OR default floating button */}\n {children ? (\n children({ onClick: handleOpen, capturing })\n ) : (\n <DefaultTrigger\n onClick={handleOpen}\n capturing={capturing}\n label={label}\n className={className}\n position={position}\n isLeft={isLeft}\n isTop={isTop}\n />\n )}\n\n {/* Report modal */}\n {isOpen && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 99999,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n }}\n onClick={() => { if (!previewOpen) setIsOpen(false); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: children ? \"relative\" : \"fixed\",\n ...modalPositionStyles,\n zIndex: 100000,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n Report a Bug\n </span>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n color: t.textMuted,\n fontSize: \"18px\",\n lineHeight: 1,\n }}\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n Bug report sent. Thank you!\n </div>\n ) : (\n <>\n {/* Screenshot preview */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"120px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n color: \"#fff\",\n width: \"20px\",\n height: \"20px\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n lineHeight: 1,\n }}\n aria-label=\"Remove screenshot\"\n >\n ×\n </button>\n <div\n style={{\n position: \"absolute\",\n bottom: \"4px\",\n left: \"6px\",\n right: \"6px\",\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: \"#fff\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n }}\n >\n Screenshot ({Math.round(screenshot.length * 0.75 / 1024)}KB) — click to preview\n </span>\n <div style={{ display: \"flex\", gap: \"4px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: t.accent,\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: t.accent,\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake\n </button>\n </div>\n </div>\n </div>\n )}\n {!screenshot && !submitted && (\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n marginBottom: \"10px\",\n padding: \"10px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n width: \"100%\",\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Click to upload a screenshot\n </button>\n )}\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe what went wrong...\"\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.accent;\n }}\n onBlur={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder;\n }}\n autoFocus\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!description.trim() || isSubmitting}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor:\n !description.trim() || isSubmitting\n ? t.bgSecondary\n : t.accent,\n color:\n !description.trim() || isSubmitting\n ? t.textMuted\n : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor:\n !description.trim() || isSubmitting\n ? \"not-allowed\"\n : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Hidden file input for screenshot upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 200000,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>\n )}\n </>\n );\n}\n\n/** Default floating trigger button (used when no children provided) */\nfunction DefaultTrigger({\n onClick,\n capturing,\n label,\n className,\n position,\n isLeft,\n isTop,\n}: {\n onClick: () => void;\n capturing: boolean;\n label: string;\n className?: string;\n position?: string;\n isLeft: boolean;\n isTop: boolean;\n}) {\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAOO;;;ACPP,YAAuB;;;ACAvB,IAAM,cAAc;AAEpB,IAAI,cAA4B,CAAC;AACjC,IAAI,iBAAiB;AACrB,IAAI,cAAc;AAEX,SAAS,gBAAgB,KAAc;AAC5C,MAAI,YAAa;AACjB,mBAAiB,oBAAO;AAExB,MAAI;AACF,QAAI,OAAO,WAAW,YAAa;AACnC,qBAAiB;AACjB,mBAAe;AACf,wBAAoB;AACpB,oBAAgB;AAChB,kBAAc;AAAA,EAChB,SAAQ;AAAA,EAER;AACF;AAEO,SAAS,cACd,MACA,SACA,MACA;AACA,MAAI;AACF,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,SAAS,QAAQ,MAAM,GAAG,GAAG;AAAA,MAC7B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,IACF,CAAC;AACD,QAAI,YAAY,SAAS,gBAAgB;AACvC,oBAAc,YAAY,MAAM,CAAC,cAAc;AAAA,IACjD;AAAA,EACF,SAAQ;AAAA,EAER;AACF;AAEO,SAAS,iBAA+B;AAC7C,SAAO,CAAC,GAAG,WAAW;AACxB;AAEO,SAAS,mBAAmB;AACjC,gBAAc,CAAC;AACjB;AAIA,SAAS,mBAAmB;AAC1B,QAAM,UAAU,QAAQ;AACxB,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,QAAQ;AAE1B,UAAQ,MAAM,YAAa,MAAiB;AAC1C,kBAAc,WAAW,SAAS,aAAa,IAAI,CAAC,EAAE;AACtD,YAAQ,MAAM,SAAS,IAAI;AAAA,EAC7B;AAEA,UAAQ,OAAO,YAAa,MAAiB;AAC3C,kBAAc,WAAW,UAAU,aAAa,IAAI,CAAC,EAAE;AACvD,aAAS,MAAM,SAAS,IAAI;AAAA,EAC9B;AAEA,UAAQ,QAAQ,YAAa,MAAiB;AAC5C,kBAAc,WAAW,WAAW,aAAa,IAAI,CAAC,EAAE;AACxD,cAAU,MAAM,SAAS,IAAI;AAAA,EAC/B;AACF;AAEA,SAAS,aAAa,MAAyB;AAC7C,MAAI;AACF,WAAO,KACJ,IAAI,CAAC,MAAM;AACV,UAAI,OAAO,MAAM,SAAU,QAAO;AAClC,UAAI,aAAa,MAAO,QAAO,EAAE;AACjC,UAAI;AACF,eAAO,KAAK,UAAU,CAAC;AAAA,MACzB,SAAQ;AACN,eAAO,OAAO,CAAC;AAAA,MACjB;AAAA,IACF,CAAC,EACA,KAAK,GAAG,EACR,MAAM,GAAG,GAAG;AAAA,EACjB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,iBAAiB;AACxB,QAAM,YAAY,OAAO;AAEzB,SAAO,QAAQ,eAAgB,OAAO,MAAM;AAnG9C;AAoGI,UAAM,MACJ,OAAO,UAAU,WACb,QACA,iBAAiB,MACf,MAAM,SAAS,IACf,iBAAiB,UACf,MAAM,MACN,OAAO,KAAK;AACtB,UAAM,UAAS,kCAAM,WAAN,YAAgB;AAC/B,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,MAAM,QAAQ,CAAC,OAAO,IAAI,CAAC;AAC5D,oBAAc,OAAO,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,WAAM,SAAS,MAAM,IAAI;AAAA,QAC1E;AAAA,QACA,QAAQ,OAAO,SAAS,MAAM;AAAA,QAC9B,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,MACjC,CAAC;AACD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,oBAAc,OAAO,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,kBAAa;AAAA,QAC9D;AAAA,QACA,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,QAC5C,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,MACjC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAIA,SAAS,sBAAsB;AAC7B,QAAM,WAAW,QAAQ,UAAU,KAAK,OAAO;AAC/C,QAAM,cAAc,QAAQ,aAAa,KAAK,OAAO;AAErD,UAAQ,YAAY,YAAa,MAAM;AACrC,aAAS,GAAG,IAAI;AAChB,kBAAc,cAAc,eAAe,OAAO,SAAS,QAAQ,EAAE;AAAA,EACvE;AAEA,UAAQ,eAAe,YAAa,MAAM;AACxC,gBAAY,GAAG,IAAI;AACnB,kBAAc,cAAc,cAAc,OAAO,SAAS,QAAQ,EAAE;AAAA,EACtE;AAEA,SAAO,iBAAiB,YAAY,MAAM;AACxC,kBAAc,cAAc,mBAAmB,OAAO,SAAS,QAAQ,EAAE;AAAA,EAC3E,CAAC;AACH;AAIA,SAAS,kBAAkB;AACzB,WAAS;AAAA,IACP;AAAA,IACA,CAAC,MAAM;AA5JX;AA6JM,UAAI;AACF,cAAM,SAAS,EAAE;AACjB,cAAM,OAAM,YAAO,YAAP,mBAAgB;AAC5B,cAAM,QAAO,kBAAO,gBAAP,mBAAoB,OAAO,MAAM,GAAG,QAApC,YAA2C;AACxD,cAAM,KAAK,OAAO,KAAK,IAAI,OAAO,EAAE,KAAK;AACzC,cAAM,MAAM,OAAO,aAAa,OAAO,OAAO,cAAc,WACxD,IAAI,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC,CAAC,KAClC;AAEJ,sBAAc,SAAS,SAAS,GAAG,GAAG,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG;AAAA,MAC5D,SAAQA,IAAA;AAAA,MAER;AAAA,IACF;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EAClB;AACF;;;AC1KA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EAAS;AAAA,EAAO;AAAA,EAAU;AAAA,EAAY;AAAA,EAAU;AAAA,EAAQ;AAAA,EACxD;AAAA,EAAW;AAAA,EAAa;AAAA,EAAc;AAAA,EAAW;AAAA,EAAU;AAAA,EAC3D;AAAA,EAAiB;AAAA,EAAiB;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAc;AAC5E;AAEO,SAAS,YAAY,KAAqB;AATjD;AAUE,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAM,SAAS,IAAI,gBAAgB,OAAO,MAAM;AAChD,QAAI,WAAW;AACf,eAAW,OAAO,MAAM,KAAK,OAAO,KAAK,CAAC,GAAG;AAC3C,UAAI,iBAAiB,KAAK,CAAC,MAAM,IAAI,YAAY,EAAE,SAAS,CAAC,CAAC,GAAG;AAC/D,eAAO,IAAI,KAAK,YAAY;AAC5B,mBAAW;AAAA,MACb;AAAA,IACF;AACA,QAAI,SAAU,QAAO,SAAS,OAAO,SAAS;AAC9C,WAAO,OAAO,SAAS;AAAA,EACzB,SAAQ;AACN,YAAO,SAAI,MAAM,GAAG,EAAE,CAAC,MAAhB,YAAqB;AAAA,EAC9B;AACF;AAEO,SAAS,oBAAuC;AA3BvD;AA4BE,MAAI;AACF,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,eAAe,OAAO;AAAA,MACtB,gBAAgB,OAAO;AAAA,MACvB,WAAU,eAAU,aAAV,YAAsB;AAAA,MAChC,WAAU,eAAU,aAAV,YAAsB;AAAA,MAChC,QAAQ,UAAU;AAAA,MAClB,aAAa,OAAO,WAAW,8BAA8B,EAAE,UAAU,SAAS;AAAA,MAClF,mBAAkB,YAAO,qBAAP,YAA2B;AAAA,IAC/C;AAAA,EACF,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,cAAyC;AACtE,MAAI;AACF,WAAO;AAAA,MACL,KAAK,YAAY,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO,EAAE;AAAA,MAC1E,WAAW,OAAO,cAAc,cAAc,UAAU,YAAY;AAAA,MACpE,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,cAAc,aAAa,IAAI,WAAW;AAAA,MAC1C,aAAa,eAAe;AAAA,MAC5B,YAAY,kBAAkB;AAAA,IAChC;AAAA,EACF,SAAQ;AACN,WAAO;AAAA,MACL,KAAK;AAAA,MACL,WAAW;AAAA,MACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,cAAc,CAAC;AAAA,MACf,aAAa,CAAC;AAAA,MACd,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEA,IAAM,mBAAmB;AACzB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AAMtB,eAAsB,WACpB,SACA,SAC8B;AA/EhC;AAgFE,MAAI;AACF,UAAM,MAAM,GAAG,4BAAW,gBAAgB;AAC1C,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,QAAQ,KAAK;AAAA,IACxC;AAEA,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AAED,YAAI,SAAS,IAAI;AACf,gBAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,kBAAO,UAAK,SAAL,YAAa,EAAE,SAAS,KAAK,QAAQ;AAAA,QAC9C;AAEA,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,iBAAO;AAAA,QACT;AAAA,MACF,SAAQ;AAAA,MAER;AAEA,UAAI,UAAU,cAAc,GAAG;AAC7B,cAAM,IAAI;AAAA,UAAQ,CAAC,YACjB,WAAW,SAAS,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,cAAc,eAAe,UAAU,YAAY;AAC5D,UAAI;AACF,kBAAU,WAAW,KAAK,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC,CAAC;AAAA,MAC1E,SAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AF9GO,IAAM,0BAAN,cAA4C,gBAGjD;AAAA,EACA,YAAY,OAA2B;AACrC,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,MAAM;AAAA,EACjC;AAAA,EAEA,OAAO,2BAA+C;AACpD,WAAO,EAAE,UAAU,KAAK;AAAA,EAC1B;AAAA,EAEA,kBAAkB,OAAc,WAAkC;AAhCpE;AAiCI,QAAI;AACF,YAAM,UAAU,eAAe,KAAK,MAAM,YAAY;AAEtD,YAAM,UAAyB;AAAA,QAC7B,OAAO,KAAK,MAAM;AAAA,QAClB,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,cAAc,MAAM;AAAA,QACpB,YAAY,MAAM;AAAA,QAClB,iBAAgB,eAAU,mBAAV,YAA4B;AAAA,QAC5C,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,QACnB,aAAa,QAAQ;AAAA,QACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,QAClC,UAAU;AAAA,UACR,WAAW,QAAQ;AAAA,UACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,QACnD;AAAA,MACF;AAEA,iBAAW,SAAS,KAAK,MAAM,OAAO;AAEtC,UAAI,KAAK,MAAM,SAAS;AACtB,aAAK,MAAM,QAAQ,KAAK;AAAA,MAC1B;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,SAA0B;AACxB,QAAI,KAAK,MAAM,UAAU;AACvB,UAAI,KAAK,MAAM,UAAU;AACvB,eAAO,KAAK,MAAM;AAAA,MACpB;AAGA,aAAO,KAAK,MAAM;AAAA,IACpB;AAEA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;;;AD4LM;AA9ON,IAAMC,oBAAmB;AAEzB,IAAM,wBAAoB,4BAA0C,IAAI;AAmBjE,SAAS,gBAAqC;AACnD,QAAM,UAAM,yBAAW,iBAAiB;AACxC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa,oBAAoB;AAAA,EACjC,gBAAAC,kBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,sBAAkB,qBAAiB,CAAC,CAAC;AAG3C,8BAAU,MAAM;AACd,QAAI,mBAAmB;AACrB,sBAAgBA,eAAc;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,mBAAmBA,eAAc,CAAC;AAGtC,8BAAU,MAAM;AACd,QAAI;AACF,UAAI,OAAO,WAAW,YAAa;AAEnC,YAAM,YAAY,MAAM;AACtB,YAAI;AACF,gBAAM,YAAY,YAAY,OAAO,SAAS,IAAI;AAClD,gBAAM,QAAQ,gBAAgB;AAC9B,cAAI,MAAM,MAAM,SAAS,CAAC,MAAM,WAAW;AACzC,kBAAM,KAAK,SAAS;AACpB,gBAAI,MAAM,SAAS,IAAI;AACrB,oBAAM,OAAO,GAAG,MAAM,SAAS,EAAE;AAAA,YACnC;AAAA,UACF;AAAA,QACF,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,gBAAU;AACV,YAAM,iBAAiB,MAAM,UAAU;AACvC,aAAO,iBAAiB,YAAY,cAAc;AAElD,YAAM,gBAAgB,QAAQ,UAAU,KAAK,OAAO;AACpD,YAAM,mBAAmB,QAAQ,aAAa,KAAK,OAAO;AAE1D,cAAQ,YAAY,YAAa,MAAM;AACrC,sBAAc,GAAG,IAAI;AACrB,kBAAU;AAAA,MACZ;AACA,cAAQ,eAAe,YAAa,MAAM;AACxC,yBAAiB,GAAG,IAAI;AACxB,kBAAU;AAAA,MACZ;AAEA,aAAO,MAAM;AACX,eAAO,oBAAoB,YAAY,cAAc;AACrD,gBAAQ,YAAY;AACpB,gBAAQ,eAAe;AAAA,MACzB;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,QAAI;AACF,UAAI,OAAO,WAAW,YAAa;AACnC,UAAI,QAAQ,IAAI,aAAa,cAAe;AAE5C,YAAM,cAAc,CAAC,UAAsB;AA9HjD;AA+HQ,YAAI;AACF,gBAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,gBAAM,UAAyB;AAAA,YAC7B;AAAA,YACA,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,cAAc,MAAM;AAAA,YACpB,aAAY,WAAM,UAAN,mBAAa;AAAA,YACzB,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,aAAa,QAAQ;AAAA,YACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,YAClC,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,cACjD,WAAU,WAAM,aAAN,YAAkB;AAAA,cAC5B,QAAQ,QAAO,WAAM,WAAN,YAAgB,EAAE;AAAA,cACjC,OAAO,QAAO,WAAM,UAAN,YAAe,EAAE;AAAA,cAC/B,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,cAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,cACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACtE;AAAA,UACF;AACA,qBAAW,SAAS,OAAO,EAAE,KAAK,CAAC,WAAW;AAC5C,gBAAI,UAAU,aAAc,cAAa,MAAM;AAAA,UACjD,CAAC;AACD,cAAI,WAAW,MAAM,MAAO,SAAQ,MAAM,KAAK;AAAA,QACjD,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,kBAAkB,CAAC,UAAiC;AA/JhE;AAgKQ,YAAI;AACF,gBAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,gBAAM,SAAS,MAAM;AACrB,gBAAM,UAAyB;AAAA,YAC7B;AAAA,YACA,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,cAAc,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AAAA,YACtE,YAAY,kBAAkB,QAAQ,OAAO,QAAQ;AAAA,YACrD,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,aAAa,QAAQ;AAAA,YACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,YAClC,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,cACjD,MAAM;AAAA,cACN,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,cAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,cACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACtE;AAAA,UACF;AACA,qBAAW,SAAS,OAAO,EAAE,KAAK,CAAC,WAAW;AAC5C,gBAAI,UAAU,aAAc,cAAa,MAAM;AAAA,UACjD,CAAC;AACD,cAAI,WAAW,kBAAkB,MAAO,SAAQ,MAAM;AAAA,QACxD,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,aAAO,iBAAiB,SAAS,WAAW;AAC5C,aAAO,iBAAiB,sBAAsB,eAAe;AAE7D,aAAO,MAAM;AACX,eAAO,oBAAoB,SAAS,WAAW;AAC/C,eAAO,oBAAoB,sBAAsB,eAAe;AAAA,MAClE;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,SAAS,YAAY,CAAC;AAE1C,QAAM,aAAS;AAAA,IACb,OACE,MACA,aACA,aACiC;AAhNvC;AAiNM,UAAI;AACF,cAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,cAAM,UAAyB;AAAA,UAC7B;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,SAAS,QAAQ;AAAA,UACjB,WAAW,QAAQ;AAAA,UACnB,aAAa,QAAQ;AAAA,UACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,UAClC,UAAU;AAAA,YACR,WAAW,QAAQ;AAAA,YACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,YACjD,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,YAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,YACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACpE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACpE,GAAG;AAAA,UACL;AAAA,QACF;AACA,cAAM,SAAS,MAAM,WAAW,SAAS,OAAO;AAChD,YAAI,UAAU,aAAc,cAAa,MAAM;AAC/C,eAAO;AAAA,MACT,SAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,OAAO,SAAS,YAAY;AAAA,EAC/B;AAEA,QAAM,gBAAY;AAAA,IAChB,CAAC,aAAqB,aACpB,OAAO,OAAO,aAAa,QAAQ;AAAA,IACrC,CAAC,MAAM;AAAA,EACT;AAEA,QAAMC,qBAAgB;AAAA,IACpB,CAAC,SAAiB,SAAkC;AAClD,oBAAsB,UAAU,SAAS,IAAI;AAAA,IAC/C;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA,SAAS,4BAAWF;AAAA,QACpB;AAAA,QACA;AAAA,QACA,eAAAE;AAAA,MACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,cAAc,gBAAgB;AAAA,UAE7B;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,mBAAmB,OAAgC;AAEjE,MAAI,CAAC,MAAM,MAAO,QAAO,2EAAG,gBAAM,UAAS;AAG3C,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,SAAS,MAAM,YAAY,OAAO,WAAW,cAAc,OAAO,SAAS,SAASF;AAAA,EACtF;AAEA,MAAI;AACF,WAAO,4CAAC,2BAAyB,GAAG,eAAe;AAAA,EACrD,SAAQ;AACN,WAAO,2EAAG,gBAAM,UAAS;AAAA,EAC3B;AACF;;;AIjSA,IAAAG,gBAAgF;AAmKxE,IAAAC,sBAAA;AA9JR,SAAS,oBAAgD;AACvD,MAAI;AACF,WAAO,cAAc;AAAA,EACvB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,YAAqB;AAC5B,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,KAAK,iBAAiB,SAAS,IAAI,EAAE;AAC3C,UAAM,QAAQ,GAAG,MAAM,MAAM;AAC7B,QAAI,SAAS,MAAM,UAAU,GAAG;AAC9B,YAAM,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM;AAClC,cAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,MAAO;AAAA,IAChD;AACA,WAAO,OAAO,WAAW,8BAA8B,EAAE;AAAA,EAC3D,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,MAAe;AAC/B,SAAO,OACH,EAAE,IAAI,WAAW,aAAa,WAAW,QAAQ,WAAW,MAAM,WAAW,WAAW,WAAW,QAAQ,WAAW,YAAY,WAAW,SAAS,WAAW,aAAa,UAAU,IACxL,EAAE,IAAI,WAAW,aAAa,WAAW,QAAQ,WAAW,MAAM,WAAW,WAAW,WAAW,QAAQ,WAAW,YAAY,WAAW,SAAS,WAAW,aAAa,UAAU;AAC9L;AAEO,SAAS,aAAa;AAAA,EAC3B,WAAW;AAAA,EACX,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAGG;AA7CH;AA8CE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAC1C,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,EAAE;AACjD,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAS,KAAK;AACtD,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAwB,IAAI;AAChE,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,mBAAe,sBAAyB,IAAI;AAClD,QAAM,eAAW,sBAAuB,IAAI;AAC5C,QAAM,aAAa,kBAAkB;AAGrC,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,EAAE,UAAU,IAAI;AACtB,QAAM,SAAS,UAAU;AACzB,QAAM,IAAI,SAAS,MAAM;AAEzB,QAAM,mBAAmB,CAAC,MAA2C;AAhEvE,QAAAC;AAiEI,UAAM,QAAOA,MAAA,EAAE,OAAO,UAAT,gBAAAA,IAAiB;AAC9B,QAAI,CAAC,KAAM;AACX,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,SAAS,MAAM;AACpB,oBAAc,OAAO,MAAgB;AAAA,IACvC;AACA,WAAO,cAAc,IAAI;AACzB,MAAE,OAAO,QAAQ;AAAA,EACnB;AAEA,QAAM,mBAAmB,YAAY;AACnC,mBAAe,KAAK;AACpB,cAAU,KAAK;AACf,kBAAc,IAAI;AAElB,UAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC3C,QAAI;AACF,YAAM,EAAE,SAAS,YAAY,IAAI,MAAM,OAAO,iBAAiB;AAC/D,YAAM,SAAS,MAAM,YAAY,SAAS,MAAM;AAAA,QAC9C,OAAO;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AACD,oBAAc,OAAO,UAAU,cAAc,GAAG,CAAC;AAAA,IACnD,SAAQ;AAAA,IAER;AACA,cAAU,IAAI;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY;AAC7B,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,QAAI;AACF,YAAM,EAAE,SAAS,YAAY,IAAI,MAAM,OAAO,iBAAiB;AAC/D,YAAM,SAAS,MAAM,YAAY,SAAS,MAAM;AAAA,QAC9C,OAAO;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AACD,oBAAc,OAAO,UAAU,cAAc,GAAG,CAAC;AAAA,IACnD,SAAQ;AAAA,IAER;AACA,iBAAa,KAAK;AAClB,cAAU,IAAI;AAAA,EAChB;AAGA,+BAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,CAAC,MAAqB;AACtC,UAAI,EAAE,QAAQ,UAAU;AACtB,YAAI,YAAa,gBAAe,KAAK;AAAA,YAChC,WAAU,KAAK;AAAA,MACtB;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM,SAAS,oBAAoB,WAAW,SAAS;AAAA,EAChE,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,QAAM,eAAe,MAAM;AACzB,QAAI;AACF,UAAI,CAAC,YAAY,KAAK,KAAK,aAAc;AAEzC,sBAAgB,IAAI;AACpB,gBAAU,YAAY,KAAK,GAAG,aAAa,EAAE,WAAW,IAAI,MAAS;AAErE,mBAAa,IAAI;AACjB,qBAAe,EAAE;AACjB,oBAAc,IAAI;AAClB,sBAAgB,KAAK;AAErB,iBAAW,MAAM;AACf,qBAAa,KAAK;AAClB,kBAAU,KAAK;AAAA,MACjB,GAAG,GAAI;AAAA,IACT,SAAQ;AACN,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,SAAQ,0CAAU,WAAW,WAArB,YAA+B;AAC7C,QAAM,UAAS,0CAAU,SAAS,YAAnB,YAA8B;AAE7C,QAAM,sBAAqC,WACvC,CAAC,IACD;AAAA,IACE,GAAI,SAAS,EAAE,MAAM,OAAO,IAAI,EAAE,OAAO,OAAO;AAAA,IAChD,GAAI,QAAQ,EAAE,KAAK,OAAO,IAAI,EAAE,QAAQ,OAAO;AAAA,EACjD;AAEJ,SACE,8EAEG;AAAA,eACC,SAAS,EAAE,SAAS,YAAY,UAAU,CAAC,IAE3C;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IAID,UACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,QACnB;AAAA,QACA,SAAS,MAAM;AAAE,cAAI,CAAC,YAAa,WAAU,KAAK;AAAA,QAAG;AAAA,QAErD;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAClC,OAAO;AAAA,cACL,UAAU,WAAW,aAAa;AAAA,cAClC,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,UAAU;AAAA,cACV,iBAAiB,EAAE;AAAA,cACnB,cAAc;AAAA,cACd,WACE;AAAA,cACF,YACE;AAAA,cACF,UAAU;AAAA,cACV,OAAO,EAAE;AAAA,YACX;AAAA,YAGA;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc,aAAa,EAAE,MAAM;AAAA,kBACrC;AAAA,kBAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,SAAS;AAAA,wBACT,gBAAgB;AAAA,wBAChB,YAAY;AAAA,sBACd;AAAA,sBAEA;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,UAAU;AAAA,8BACV,YAAY;AAAA,8BACZ,OAAO,EAAE;AAAA,4BACX;AAAA,4BACD;AAAA;AAAA,wBAED;AAAA,wBACA;AAAA,0BAAC;AAAA;AAAA,4BACC,MAAK;AAAA,4BACL,SAAS,MAAM,UAAU,KAAK;AAAA,4BAC9B,OAAO;AAAA,8BACL,YAAY;AAAA,8BACZ,QAAQ;AAAA,8BACR,QAAQ;AAAA,8BACR,SAAS;AAAA,8BACT,OAAO,EAAE;AAAA,8BACT,UAAU;AAAA,8BACV,YAAY;AAAA,4BACd;AAAA,4BACA,cAAW;AAAA,4BACZ;AAAA;AAAA,wBAED;AAAA;AAAA;AAAA,kBACF;AAAA;AAAA,cACF;AAAA,cAGA,6CAAC,SAAI,OAAO,EAAE,SAAS,OAAO,GAC3B,sBACC;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,WAAW;AAAA,oBACX,SAAS;AAAA,oBACT,OAAO,EAAE;AAAA,oBACT,UAAU;AAAA,oBACV,YAAY;AAAA,kBACd;AAAA,kBACD;AAAA;AAAA,cAED,IAEA,8EAEG;AAAA,8BACC,8CAAC,SAAI,OAAO,EAAE,cAAc,QAAQ,UAAU,WAAW,GACvD;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,KAAK;AAAA,sBACL,KAAI;AAAA,sBACJ,SAAS,MAAM,eAAe,IAAI;AAAA,sBAClC,OAAO;AAAA,wBACL,OAAO;AAAA,wBACP,cAAc;AAAA,wBACd,QAAQ,aAAa,EAAE,MAAM;AAAA,wBAC7B,WAAW;AAAA,wBACX,WAAW;AAAA,wBACX,gBAAgB;AAAA,wBAChB,QAAQ;AAAA,sBACV;AAAA;AAAA,kBACF;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS,MAAM,cAAc,IAAI;AAAA,sBACjC,OAAO;AAAA,wBACL,UAAU;AAAA,wBACV,KAAK;AAAA,wBACL,OAAO;AAAA,wBACP,YAAY;AAAA,wBACZ,QAAQ;AAAA,wBACR,cAAc;AAAA,wBACd,OAAO;AAAA,wBACP,OAAO;AAAA,wBACP,QAAQ;AAAA,wBACR,UAAU;AAAA,wBACV,QAAQ;AAAA,wBACR,SAAS;AAAA,wBACT,YAAY;AAAA,wBACZ,gBAAgB;AAAA,wBAChB,YAAY;AAAA,sBACd;AAAA,sBACA,cAAW;AAAA,sBACZ;AAAA;AAAA,kBAED;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,UAAU;AAAA,wBACV,QAAQ;AAAA,wBACR,MAAM;AAAA,wBACN,OAAO;AAAA,wBACP,SAAS;AAAA,wBACT,gBAAgB;AAAA,wBAChB,YAAY;AAAA,sBACd;AAAA,sBAEA;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,YAAY;AAAA,8BACZ,OAAO;AAAA,8BACP,UAAU;AAAA,8BACV,SAAS;AAAA,8BACT,cAAc;AAAA,4BAChB;AAAA,4BACD;AAAA;AAAA,8BACc,KAAK,MAAM,WAAW,SAAS,OAAO,IAAI;AAAA,8BAAE;AAAA;AAAA;AAAA,wBAC3D;AAAA,wBACA,8CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,MAAM,GACxC;AAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,MAAK;AAAA,8BACL,SAAS,MAAG;AA7UxC,oCAAAA;AA6U2C,wCAAAA,MAAA,aAAa,YAAb,gBAAAA,IAAsB;AAAA;AAAA,8BACrC,OAAO;AAAA,gCACL,YAAY;AAAA,gCACZ,OAAO,EAAE;AAAA,gCACT,UAAU;AAAA,gCACV,SAAS;AAAA,gCACT,cAAc;AAAA,gCACd,QAAQ;AAAA,gCACR,QAAQ;AAAA,8BACV;AAAA,8BACD;AAAA;AAAA,0BAED;AAAA,0BACA;AAAA,4BAAC;AAAA;AAAA,8BACC,MAAK;AAAA,8BACL,SAAS;AAAA,8BACT,OAAO;AAAA,gCACL,YAAY;AAAA,gCACZ,OAAO,EAAE;AAAA,gCACT,UAAU;AAAA,gCACV,SAAS;AAAA,gCACT,cAAc;AAAA,gCACd,QAAQ;AAAA,gCACR,QAAQ;AAAA,8BACV;AAAA,8BACD;AAAA;AAAA,0BAED;AAAA,2BACF;AAAA;AAAA;AAAA,kBACF;AAAA,mBACF;AAAA,gBAED,CAAC,cAAc,CAAC,aACf;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAG;AAhXlC,0BAAAA;AAgXqC,8BAAAA,MAAA,aAAa,YAAb,gBAAAA,IAAsB;AAAA;AAAA,oBACrC,OAAO;AAAA,sBACL,cAAc;AAAA,sBACd,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ,cAAc,EAAE,WAAW;AAAA,sBACnC,WAAW;AAAA,sBACX,UAAU;AAAA,sBACV,OAAO,EAAE;AAAA,sBACT,OAAO;AAAA,sBACP,YAAY;AAAA,sBACZ,QAAQ;AAAA,oBACV;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA,gBAEF;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,oBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,oBAC9C,aAAY;AAAA,oBACZ,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,WAAW;AAAA,sBACX,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ,aAAa,EAAE,WAAW;AAAA,sBAClC,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,QAAQ;AAAA,sBACR,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,OAAO,EAAE;AAAA,sBACT,iBAAiB,EAAE;AAAA,oBACrB;AAAA,oBACA,SAAS,CAAC,MAAM;AACd,sBAAC,EAAE,OAA+B,MAAM,cAAc,EAAE;AAAA,oBAC1D;AAAA,oBACA,QAAQ,CAAC,MAAM;AACb,sBAAC,EAAE,OAA+B,MAAM,cAAc,EAAE;AAAA,oBAC1D;AAAA,oBACA,WAAS;AAAA;AAAA,gBACX;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS;AAAA,oBACT,UAAU,CAAC,YAAY,KAAK,KAAK;AAAA,oBACjC,OAAO;AAAA,sBACL,WAAW;AAAA,sBACX,OAAO;AAAA,sBACP,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ;AAAA,sBACR,iBACE,CAAC,YAAY,KAAK,KAAK,eACnB,EAAE,cACF,EAAE;AAAA,sBACR,OACE,CAAC,YAAY,KAAK,KAAK,eACnB,EAAE,YACF,EAAE;AAAA,sBACR,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,QACE,CAAC,YAAY,KAAK,KAAK,eACnB,gBACA;AAAA,sBACN,YAAY;AAAA,sBACZ,YAAY;AAAA,oBACd;AAAA,oBAEC,yBAAe,eAAe;AAAA;AAAA,gBACjC;AAAA,iBACF,GAEJ;AAAA,cAGA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,WAAW,aAAa,EAAE,MAAM;AAAA,oBAChC,WAAW;AAAA,kBACb;AAAA,kBAEA,uDAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,OAAO,EAAE,UAAU,GAAG,mCAEvD;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAIF;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,IAC3B;AAAA,IAGC,eAAe,cACd;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,QACA,SAAS,CAAC,MAAM;AAAE,YAAE,gBAAgB;AAAG,yBAAe,KAAK;AAAA,QAAG;AAAA,QAC9D,aAAa,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAEtC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAI;AAAA,cACJ,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAClC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,WAAW;AAAA,gBACX,cAAc;AAAA,gBACd,WAAW;AAAA,gBACX,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,WAAW;AAAA,gBACX,OAAO,EAAE;AAAA,gBACT,UAAU;AAAA,cACZ;AAAA,cACD;AAAA;AAAA,UAED;AAAA;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;AAGA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,QAAM,iBAAgC;AAAA,IACpC,GAAI,SAAS,EAAE,MAAM,OAAO,IAAI,EAAE,OAAO,OAAO;AAAA,IAChD,GAAI,QAAQ,EAAE,KAAK,OAAO,IAAI,EAAE,QAAQ,OAAO;AAAA,EACjD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,YACE;AAAA,QACF,QAAQ,YAAY,SAAS;AAAA,QAC7B,WACE;AAAA,QACF,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS,YAAY,MAAM;AAAA,MAC7B;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,QAAC,EAAE,OAAuB,MAAM,YAAY;AAAA,MAC9C;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,QAAC,EAAE,OAAuB,MAAM,YAAY;AAAA,MAC9C;AAAA,MACA,cAAY;AAAA,MAEZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,OAAO,EAAE,YAAY,EAAE;AAAA,YAEvB;AAAA,cAAC;AAAA;AAAA,gBACC,GAAE;AAAA,gBACF,MAAK;AAAA;AAAA,YACP;AAAA;AAAA,QACF;AAAA,QACC,YAAY,iBAAiB;AAAA;AAAA;AAAA,EAChC;AAEJ;","names":["e","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","import_react","import_jsx_runtime","_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/report-button.tsx"],"sourcesContent":["\"use client\";\n\n// ─── Core (required) ─────────────────────────────────────\nexport { GlitchgrabProvider, useGlitchgrab } from \"./provider\";\n\n// ─── Optional Components ─────────────────────────────────\nexport { ReportButton } from \"./report-button\";\nexport { GlitchgrabErrorBoundary } from \"./error-boundary\";\n\n// ─── Breadcrumbs ─────────────────────────────────────────\nexport {\n addBreadcrumb,\n getBreadcrumbs,\n clearBreadcrumbs,\n initBreadcrumbs,\n} from \"./breadcrumbs\";\n\n// ─── Utilities ───────────────────────────────────────────\nexport { sanitizeUrl, captureContext, captureDeviceInfo, sendReport } from \"./utils\";\n\n// ─── Types ───────────────────────────────────────────────\nexport type {\n GlitchgrabConfig,\n GlitchgrabProviderProps,\n ReportPayload,\n ReportResult,\n ReportType,\n CapturedContext,\n DeviceInfo,\n Breadcrumb,\n BreadcrumbType,\n UseGlitchgrabReturn,\n ReportButtonProps,\n GlitchgrabSession,\n} from \"./types\";\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: reason instanceof Error ? reason.message : String(reason),\n errorStack: reason instanceof Error ? reason.stack : undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n // Auto-detect baseUrl from window.location if not provided\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || (typeof window !== \"undefined\" ? window.location.origin : DEFAULT_BASE_URL),\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n keepalive: true,\n });\n\n if (response.ok) {\n const data = (await response.json()) as { success: boolean; data?: ReportResult };\n return data.data ?? { success: data.success };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps, UseGlitchgrabReturn } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe(): UseGlitchgrabReturn | null {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n const bg = getComputedStyle(document.body).backgroundColor;\n const match = bg.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map(Number);\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\nfunction getTheme(dark: boolean) {\n return dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n}\n\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n /** Render prop — receives { onClick, capturing } so you can use your own trigger button */\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const glitchgrab = useGlitchgrabSafe();\n\n // If no provider context, render nothing\n if (!glitchgrab) return null;\n\n const { reportBug } = glitchgrab;\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n // Small delay so the modal is gone before capture\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setCapturing(true);\n setSubmitted(false);\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setCapturing(false);\n setIsOpen(true);\n };\n\n // Close modal on Escape key\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else setIsOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n const handleSubmit = () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n setIsSubmitting(true);\n reportBug(description.trim(), screenshot ? { screenshot } : undefined);\n\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n setIsSubmitting(false);\n\n setTimeout(() => {\n setSubmitted(false);\n setIsOpen(false);\n }, 2000);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const modalPositionStyles: CSSProperties = children\n ? {} // user controls positioning\n : {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"64px\" } : { bottom: \"64px\" }),\n };\n\n return (\n <>\n {/* Trigger: user's custom button OR default floating button */}\n {children ? (\n children({ onClick: handleOpen, capturing })\n ) : (\n <DefaultTrigger\n onClick={handleOpen}\n capturing={capturing}\n label={label}\n className={className}\n position={position}\n isLeft={isLeft}\n isTop={isTop}\n />\n )}\n\n {/* Report modal */}\n {isOpen && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n }}\n onClick={() => { if (!previewOpen) setIsOpen(false); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: children ? \"relative\" : \"fixed\",\n ...modalPositionStyles,\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n Report a Bug\n </span>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n Bug report sent. Thank you!\n </div>\n ) : (\n <>\n {/* Screenshot preview */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"120px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n <div\n style={{\n position: \"absolute\",\n bottom: \"4px\",\n left: \"6px\",\n right: \"6px\",\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: \"#fff\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n }}\n >\n Screenshot ({Math.round(screenshot.length * 0.75 / 1024)}KB) — click to preview\n </span>\n <div style={{ display: \"flex\", gap: \"4px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n background: t.accent,\n color: t.accentText,\n fontSize: \"10px\",\n padding: \"3px 8px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n fontWeight: 600,\n }}\n >\n Upload\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n background: t.accent,\n color: t.accentText,\n fontSize: \"10px\",\n padding: \"3px 8px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n fontWeight: 600,\n }}\n >\n Retake\n </button>\n </div>\n </div>\n </div>\n )}\n {!screenshot && !submitted && (\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n marginBottom: \"10px\",\n padding: \"10px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n width: \"100%\",\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Click to upload a screenshot\n </button>\n )}\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe what went wrong...\"\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.accent;\n }}\n onBlur={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder;\n }}\n autoFocus\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!description.trim() || isSubmitting}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor:\n !description.trim() || isSubmitting\n ? t.bgSecondary\n : t.accent,\n color:\n !description.trim() || isSubmitting\n ? t.textMuted\n : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor:\n !description.trim() || isSubmitting\n ? \"not-allowed\"\n : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Hidden file input for screenshot upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>\n )}\n </>\n );\n}\n\n/** Default floating trigger button (used when no children provided) */\nfunction DefaultTrigger({\n onClick,\n capturing,\n label,\n className,\n position,\n isLeft,\n isTop,\n}: {\n onClick: () => void;\n capturing: boolean;\n label: string;\n className?: string;\n position?: string;\n isLeft: boolean;\n isTop: boolean;\n}) {\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n"],"mappings":"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","names":["e","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","import_react","import_jsx_runtime","_a"]}
|
package/dist/index.mjs
CHANGED
|
@@ -684,7 +684,7 @@ function ReportButton({
|
|
|
684
684
|
style: {
|
|
685
685
|
position: "fixed",
|
|
686
686
|
inset: 0,
|
|
687
|
-
zIndex:
|
|
687
|
+
zIndex: 2147483647,
|
|
688
688
|
display: "flex",
|
|
689
689
|
alignItems: "center",
|
|
690
690
|
justifyContent: "center",
|
|
@@ -701,7 +701,7 @@ function ReportButton({
|
|
|
701
701
|
style: {
|
|
702
702
|
position: children ? "relative" : "fixed",
|
|
703
703
|
...modalPositionStyles,
|
|
704
|
-
zIndex:
|
|
704
|
+
zIndex: 2147483647,
|
|
705
705
|
width: "340px",
|
|
706
706
|
maxWidth: "calc(100% - 32px)",
|
|
707
707
|
backgroundColor: t.bg,
|
|
@@ -709,7 +709,8 @@ function ReportButton({
|
|
|
709
709
|
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
710
710
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
711
711
|
overflow: "hidden",
|
|
712
|
-
color: t.text
|
|
712
|
+
color: t.text,
|
|
713
|
+
isolation: "isolate"
|
|
713
714
|
},
|
|
714
715
|
children: [
|
|
715
716
|
/* @__PURE__ */ jsx2(
|
|
@@ -749,12 +750,12 @@ function ReportButton({
|
|
|
749
750
|
border: "none",
|
|
750
751
|
cursor: "pointer",
|
|
751
752
|
padding: "4px",
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
753
|
+
display: "flex",
|
|
754
|
+
alignItems: "center",
|
|
755
|
+
justifyContent: "center"
|
|
755
756
|
},
|
|
756
757
|
"aria-label": "Close",
|
|
757
|
-
children: "
|
|
758
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { display: "block" }, children: /* @__PURE__ */ jsx2("path", { d: "M4 4L12 12M12 4L4 12", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round" }) })
|
|
758
759
|
}
|
|
759
760
|
)
|
|
760
761
|
]
|
|
@@ -805,18 +806,15 @@ function ReportButton({
|
|
|
805
806
|
background: "rgba(0,0,0,0.6)",
|
|
806
807
|
border: "none",
|
|
807
808
|
borderRadius: "50%",
|
|
808
|
-
color: "#fff",
|
|
809
809
|
width: "20px",
|
|
810
810
|
height: "20px",
|
|
811
|
-
fontSize: "12px",
|
|
812
811
|
cursor: "pointer",
|
|
813
812
|
display: "flex",
|
|
814
813
|
alignItems: "center",
|
|
815
|
-
justifyContent: "center"
|
|
816
|
-
lineHeight: 1
|
|
814
|
+
justifyContent: "center"
|
|
817
815
|
},
|
|
818
816
|
"aria-label": "Remove screenshot",
|
|
819
|
-
children: "
|
|
817
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx2("path", { d: "M1 1L9 9M9 1L1 9", stroke: "#fff", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
820
818
|
}
|
|
821
819
|
),
|
|
822
820
|
/* @__PURE__ */ jsxs(
|
|
@@ -859,13 +857,14 @@ function ReportButton({
|
|
|
859
857
|
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
860
858
|
},
|
|
861
859
|
style: {
|
|
862
|
-
background:
|
|
863
|
-
color: t.
|
|
860
|
+
background: t.accent,
|
|
861
|
+
color: t.accentText,
|
|
864
862
|
fontSize: "10px",
|
|
865
|
-
padding: "
|
|
863
|
+
padding: "3px 8px",
|
|
866
864
|
borderRadius: "4px",
|
|
867
865
|
border: "none",
|
|
868
|
-
cursor: "pointer"
|
|
866
|
+
cursor: "pointer",
|
|
867
|
+
fontWeight: 600
|
|
869
868
|
},
|
|
870
869
|
children: "Upload"
|
|
871
870
|
}
|
|
@@ -876,13 +875,14 @@ function ReportButton({
|
|
|
876
875
|
type: "button",
|
|
877
876
|
onClick: retakeScreenshot,
|
|
878
877
|
style: {
|
|
879
|
-
background:
|
|
880
|
-
color: t.
|
|
878
|
+
background: t.accent,
|
|
879
|
+
color: t.accentText,
|
|
881
880
|
fontSize: "10px",
|
|
882
|
-
padding: "
|
|
881
|
+
padding: "3px 8px",
|
|
883
882
|
borderRadius: "4px",
|
|
884
883
|
border: "none",
|
|
885
|
-
cursor: "pointer"
|
|
884
|
+
cursor: "pointer",
|
|
885
|
+
fontWeight: 600
|
|
886
886
|
},
|
|
887
887
|
children: "Retake"
|
|
888
888
|
}
|
|
@@ -1000,7 +1000,7 @@ function ReportButton({
|
|
|
1000
1000
|
style: {
|
|
1001
1001
|
position: "fixed",
|
|
1002
1002
|
inset: 0,
|
|
1003
|
-
zIndex:
|
|
1003
|
+
zIndex: 2147483647,
|
|
1004
1004
|
backgroundColor: "rgba(0,0,0,0.85)",
|
|
1005
1005
|
display: "flex",
|
|
1006
1006
|
flexDirection: "column",
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/report-button.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: reason instanceof Error ? reason.message : String(reason),\n errorStack: reason instanceof Error ? reason.stack : undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n // Auto-detect baseUrl from window.location if not provided\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || (typeof window !== \"undefined\" ? window.location.origin : DEFAULT_BASE_URL),\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n keepalive: true,\n });\n\n if (response.ok) {\n const data = (await response.json()) as { success: boolean; data?: ReportResult };\n return data.data ?? { success: data.success };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps, UseGlitchgrabReturn } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe(): UseGlitchgrabReturn | null {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n const bg = getComputedStyle(document.body).backgroundColor;\n const match = bg.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map(Number);\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\nfunction getTheme(dark: boolean) {\n return dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n}\n\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n /** Render prop — receives { onClick, capturing } so you can use your own trigger button */\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const glitchgrab = useGlitchgrabSafe();\n\n // If no provider context, render nothing\n if (!glitchgrab) return null;\n\n const { reportBug } = glitchgrab;\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n // Small delay so the modal is gone before capture\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setCapturing(true);\n setSubmitted(false);\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setCapturing(false);\n setIsOpen(true);\n };\n\n // Close modal on Escape key\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else setIsOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n const handleSubmit = () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n setIsSubmitting(true);\n reportBug(description.trim(), screenshot ? { screenshot } : undefined);\n\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n setIsSubmitting(false);\n\n setTimeout(() => {\n setSubmitted(false);\n setIsOpen(false);\n }, 2000);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const modalPositionStyles: CSSProperties = children\n ? {} // user controls positioning\n : {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"64px\" } : { bottom: \"64px\" }),\n };\n\n return (\n <>\n {/* Trigger: user's custom button OR default floating button */}\n {children ? (\n children({ onClick: handleOpen, capturing })\n ) : (\n <DefaultTrigger\n onClick={handleOpen}\n capturing={capturing}\n label={label}\n className={className}\n position={position}\n isLeft={isLeft}\n isTop={isTop}\n />\n )}\n\n {/* Report modal */}\n {isOpen && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 99999,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n }}\n onClick={() => { if (!previewOpen) setIsOpen(false); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: children ? \"relative\" : \"fixed\",\n ...modalPositionStyles,\n zIndex: 100000,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n Report a Bug\n </span>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n color: t.textMuted,\n fontSize: \"18px\",\n lineHeight: 1,\n }}\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n Bug report sent. Thank you!\n </div>\n ) : (\n <>\n {/* Screenshot preview */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"120px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n color: \"#fff\",\n width: \"20px\",\n height: \"20px\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n lineHeight: 1,\n }}\n aria-label=\"Remove screenshot\"\n >\n ×\n </button>\n <div\n style={{\n position: \"absolute\",\n bottom: \"4px\",\n left: \"6px\",\n right: \"6px\",\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: \"#fff\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n }}\n >\n Screenshot ({Math.round(screenshot.length * 0.75 / 1024)}KB) — click to preview\n </span>\n <div style={{ display: \"flex\", gap: \"4px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: t.accent,\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: t.accent,\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake\n </button>\n </div>\n </div>\n </div>\n )}\n {!screenshot && !submitted && (\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n marginBottom: \"10px\",\n padding: \"10px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n width: \"100%\",\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Click to upload a screenshot\n </button>\n )}\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe what went wrong...\"\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.accent;\n }}\n onBlur={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder;\n }}\n autoFocus\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!description.trim() || isSubmitting}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor:\n !description.trim() || isSubmitting\n ? t.bgSecondary\n : t.accent,\n color:\n !description.trim() || isSubmitting\n ? t.textMuted\n : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor:\n !description.trim() || isSubmitting\n ? \"not-allowed\"\n : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Hidden file input for screenshot upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 200000,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>\n )}\n </>\n );\n}\n\n/** Default floating trigger button (used when no children provided) */\nfunction DefaultTrigger({\n onClick,\n capturing,\n label,\n className,\n position,\n isLeft,\n isTop,\n}: {\n onClick: () => void;\n capturing: boolean;\n label: string;\n className?: string;\n position?: string;\n isLeft: boolean;\n isTop: boolean;\n}) {\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n"],"mappings":"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","names":["e","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","useState","useRef","useEffect","Fragment","jsx","useState","useRef","_a","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/report-button.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: reason instanceof Error ? reason.message : String(reason),\n errorStack: reason instanceof Error ? reason.stack : undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n // Auto-detect baseUrl from window.location if not provided\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || (typeof window !== \"undefined\" ? window.location.origin : DEFAULT_BASE_URL),\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n keepalive: true,\n });\n\n if (response.ok) {\n const data = (await response.json()) as { success: boolean; data?: ReportResult };\n return data.data ?? { success: data.success };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps, UseGlitchgrabReturn } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe(): UseGlitchgrabReturn | null {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n const bg = getComputedStyle(document.body).backgroundColor;\n const match = bg.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map(Number);\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\nfunction getTheme(dark: boolean) {\n return dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n}\n\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n /** Render prop — receives { onClick, capturing } so you can use your own trigger button */\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const glitchgrab = useGlitchgrabSafe();\n\n // If no provider context, render nothing\n if (!glitchgrab) return null;\n\n const { reportBug } = glitchgrab;\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n // Small delay so the modal is gone before capture\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setCapturing(true);\n setSubmitted(false);\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setCapturing(false);\n setIsOpen(true);\n };\n\n // Close modal on Escape key\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else setIsOpen(false);\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n const handleSubmit = () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n setIsSubmitting(true);\n reportBug(description.trim(), screenshot ? { screenshot } : undefined);\n\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n setIsSubmitting(false);\n\n setTimeout(() => {\n setSubmitted(false);\n setIsOpen(false);\n }, 2000);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const modalPositionStyles: CSSProperties = children\n ? {} // user controls positioning\n : {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"64px\" } : { bottom: \"64px\" }),\n };\n\n return (\n <>\n {/* Trigger: user's custom button OR default floating button */}\n {children ? (\n children({ onClick: handleOpen, capturing })\n ) : (\n <DefaultTrigger\n onClick={handleOpen}\n capturing={capturing}\n label={label}\n className={className}\n position={position}\n isLeft={isLeft}\n isTop={isTop}\n />\n )}\n\n {/* Report modal */}\n {isOpen && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n }}\n onClick={() => { if (!previewOpen) setIsOpen(false); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: children ? \"relative\" : \"fixed\",\n ...modalPositionStyles,\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n Report a Bug\n </span>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n Bug report sent. Thank you!\n </div>\n ) : (\n <>\n {/* Screenshot preview */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"120px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n <div\n style={{\n position: \"absolute\",\n bottom: \"4px\",\n left: \"6px\",\n right: \"6px\",\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n background: \"rgba(0,0,0,0.6)\",\n color: \"#fff\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n }}\n >\n Screenshot ({Math.round(screenshot.length * 0.75 / 1024)}KB) — click to preview\n </span>\n <div style={{ display: \"flex\", gap: \"4px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n background: t.accent,\n color: t.accentText,\n fontSize: \"10px\",\n padding: \"3px 8px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n fontWeight: 600,\n }}\n >\n Upload\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n background: t.accent,\n color: t.accentText,\n fontSize: \"10px\",\n padding: \"3px 8px\",\n borderRadius: \"4px\",\n border: \"none\",\n cursor: \"pointer\",\n fontWeight: 600,\n }}\n >\n Retake\n </button>\n </div>\n </div>\n </div>\n )}\n {!screenshot && !submitted && (\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n marginBottom: \"10px\",\n padding: \"10px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n width: \"100%\",\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Click to upload a screenshot\n </button>\n )}\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe what went wrong...\"\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.accent;\n }}\n onBlur={(e) => {\n (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder;\n }}\n autoFocus\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!description.trim() || isSubmitting}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor:\n !description.trim() || isSubmitting\n ? t.bgSecondary\n : t.accent,\n color:\n !description.trim() || isSubmitting\n ? t.textMuted\n : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor:\n !description.trim() || isSubmitting\n ? \"not-allowed\"\n : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Hidden file input for screenshot upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && (\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>\n )}\n </>\n );\n}\n\n/** Default floating trigger button (used when no children provided) */\nfunction DefaultTrigger({\n onClick,\n capturing,\n label,\n className,\n position,\n isLeft,\n isTop,\n}: {\n onClick: () => void;\n capturing: boolean;\n label: string;\n className?: string;\n position?: string;\n isLeft: boolean;\n isTop: boolean;\n}) {\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;;;ACPP,YAAY,WAAW;;;ACAvB,IAAM,cAAc;AAEpB,IAAI,cAA4B,CAAC;AACjC,IAAI,iBAAiB;AACrB,IAAI,cAAc;AAEX,SAAS,gBAAgB,KAAc;AAC5C,MAAI,YAAa;AACjB,mBAAiB,oBAAO;AAExB,MAAI;AACF,QAAI,OAAO,WAAW,YAAa;AACnC,qBAAiB;AACjB,mBAAe;AACf,wBAAoB;AACpB,oBAAgB;AAChB,kBAAc;AAAA,EAChB,SAAQ;AAAA,EAER;AACF;AAEO,SAAS,cACd,MACA,SACA,MACA;AACA,MAAI;AACF,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,SAAS,QAAQ,MAAM,GAAG,GAAG;AAAA,MAC7B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,IACF,CAAC;AACD,QAAI,YAAY,SAAS,gBAAgB;AACvC,oBAAc,YAAY,MAAM,CAAC,cAAc;AAAA,IACjD;AAAA,EACF,SAAQ;AAAA,EAER;AACF;AAEO,SAAS,iBAA+B;AAC7C,SAAO,CAAC,GAAG,WAAW;AACxB;AAEO,SAAS,mBAAmB;AACjC,gBAAc,CAAC;AACjB;AAIA,SAAS,mBAAmB;AAC1B,QAAM,UAAU,QAAQ;AACxB,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,QAAQ;AAE1B,UAAQ,MAAM,YAAa,MAAiB;AAC1C,kBAAc,WAAW,SAAS,aAAa,IAAI,CAAC,EAAE;AACtD,YAAQ,MAAM,SAAS,IAAI;AAAA,EAC7B;AAEA,UAAQ,OAAO,YAAa,MAAiB;AAC3C,kBAAc,WAAW,UAAU,aAAa,IAAI,CAAC,EAAE;AACvD,aAAS,MAAM,SAAS,IAAI;AAAA,EAC9B;AAEA,UAAQ,QAAQ,YAAa,MAAiB;AAC5C,kBAAc,WAAW,WAAW,aAAa,IAAI,CAAC,EAAE;AACxD,cAAU,MAAM,SAAS,IAAI;AAAA,EAC/B;AACF;AAEA,SAAS,aAAa,MAAyB;AAC7C,MAAI;AACF,WAAO,KACJ,IAAI,CAAC,MAAM;AACV,UAAI,OAAO,MAAM,SAAU,QAAO;AAClC,UAAI,aAAa,MAAO,QAAO,EAAE;AACjC,UAAI;AACF,eAAO,KAAK,UAAU,CAAC;AAAA,MACzB,SAAQ;AACN,eAAO,OAAO,CAAC;AAAA,MACjB;AAAA,IACF,CAAC,EACA,KAAK,GAAG,EACR,MAAM,GAAG,GAAG;AAAA,EACjB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,iBAAiB;AACxB,QAAM,YAAY,OAAO;AAEzB,SAAO,QAAQ,eAAgB,OAAO,MAAM;AAnG9C;AAoGI,UAAM,MACJ,OAAO,UAAU,WACb,QACA,iBAAiB,MACf,MAAM,SAAS,IACf,iBAAiB,UACf,MAAM,MACN,OAAO,KAAK;AACtB,UAAM,UAAS,kCAAM,WAAN,YAAgB;AAC/B,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,MAAM,QAAQ,CAAC,OAAO,IAAI,CAAC;AAC5D,oBAAc,OAAO,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,WAAM,SAAS,MAAM,IAAI;AAAA,QAC1E;AAAA,QACA,QAAQ,OAAO,SAAS,MAAM;AAAA,QAC9B,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,MACjC,CAAC;AACD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,oBAAc,OAAO,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,kBAAa;AAAA,QAC9D;AAAA,QACA,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,QAC5C,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,MACjC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAIA,SAAS,sBAAsB;AAC7B,QAAM,WAAW,QAAQ,UAAU,KAAK,OAAO;AAC/C,QAAM,cAAc,QAAQ,aAAa,KAAK,OAAO;AAErD,UAAQ,YAAY,YAAa,MAAM;AACrC,aAAS,GAAG,IAAI;AAChB,kBAAc,cAAc,eAAe,OAAO,SAAS,QAAQ,EAAE;AAAA,EACvE;AAEA,UAAQ,eAAe,YAAa,MAAM;AACxC,gBAAY,GAAG,IAAI;AACnB,kBAAc,cAAc,cAAc,OAAO,SAAS,QAAQ,EAAE;AAAA,EACtE;AAEA,SAAO,iBAAiB,YAAY,MAAM;AACxC,kBAAc,cAAc,mBAAmB,OAAO,SAAS,QAAQ,EAAE;AAAA,EAC3E,CAAC;AACH;AAIA,SAAS,kBAAkB;AACzB,WAAS;AAAA,IACP;AAAA,IACA,CAAC,MAAM;AA5JX;AA6JM,UAAI;AACF,cAAM,SAAS,EAAE;AACjB,cAAM,OAAM,YAAO,YAAP,mBAAgB;AAC5B,cAAM,QAAO,kBAAO,gBAAP,mBAAoB,OAAO,MAAM,GAAG,QAApC,YAA2C;AACxD,cAAM,KAAK,OAAO,KAAK,IAAI,OAAO,EAAE,KAAK;AACzC,cAAM,MAAM,OAAO,aAAa,OAAO,OAAO,cAAc,WACxD,IAAI,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC,CAAC,KAClC;AAEJ,sBAAc,SAAS,SAAS,GAAG,GAAG,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG;AAAA,MAC5D,SAAQA,IAAA;AAAA,MAER;AAAA,IACF;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EAClB;AACF;;;AC1KA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EAAS;AAAA,EAAO;AAAA,EAAU;AAAA,EAAY;AAAA,EAAU;AAAA,EAAQ;AAAA,EACxD;AAAA,EAAW;AAAA,EAAa;AAAA,EAAc;AAAA,EAAW;AAAA,EAAU;AAAA,EAC3D;AAAA,EAAiB;AAAA,EAAiB;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAc;AAC5E;AAEO,SAAS,YAAY,KAAqB;AATjD;AAUE,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAM,SAAS,IAAI,gBAAgB,OAAO,MAAM;AAChD,QAAI,WAAW;AACf,eAAW,OAAO,MAAM,KAAK,OAAO,KAAK,CAAC,GAAG;AAC3C,UAAI,iBAAiB,KAAK,CAAC,MAAM,IAAI,YAAY,EAAE,SAAS,CAAC,CAAC,GAAG;AAC/D,eAAO,IAAI,KAAK,YAAY;AAC5B,mBAAW;AAAA,MACb;AAAA,IACF;AACA,QAAI,SAAU,QAAO,SAAS,OAAO,SAAS;AAC9C,WAAO,OAAO,SAAS;AAAA,EACzB,SAAQ;AACN,YAAO,SAAI,MAAM,GAAG,EAAE,CAAC,MAAhB,YAAqB;AAAA,EAC9B;AACF;AAEO,SAAS,oBAAuC;AA3BvD;AA4BE,MAAI;AACF,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,eAAe,OAAO;AAAA,MACtB,gBAAgB,OAAO;AAAA,MACvB,WAAU,eAAU,aAAV,YAAsB;AAAA,MAChC,WAAU,eAAU,aAAV,YAAsB;AAAA,MAChC,QAAQ,UAAU;AAAA,MAClB,aAAa,OAAO,WAAW,8BAA8B,EAAE,UAAU,SAAS;AAAA,MAClF,mBAAkB,YAAO,qBAAP,YAA2B;AAAA,IAC/C;AAAA,EACF,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,cAAyC;AACtE,MAAI;AACF,WAAO;AAAA,MACL,KAAK,YAAY,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO,EAAE;AAAA,MAC1E,WAAW,OAAO,cAAc,cAAc,UAAU,YAAY;AAAA,MACpE,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,cAAc,aAAa,IAAI,WAAW;AAAA,MAC1C,aAAa,eAAe;AAAA,MAC5B,YAAY,kBAAkB;AAAA,IAChC;AAAA,EACF,SAAQ;AACN,WAAO;AAAA,MACL,KAAK;AAAA,MACL,WAAW;AAAA,MACX,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,cAAc,CAAC;AAAA,MACf,aAAa,CAAC;AAAA,MACd,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEA,IAAM,mBAAmB;AACzB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AAMtB,eAAsB,WACpB,SACA,SAC8B;AA/EhC;AAgFE,MAAI;AACF,UAAM,MAAM,GAAG,4BAAW,gBAAgB;AAC1C,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,QAAQ,KAAK;AAAA,IACxC;AAEA,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AAED,YAAI,SAAS,IAAI;AACf,gBAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,kBAAO,UAAK,SAAL,YAAa,EAAE,SAAS,KAAK,QAAQ;AAAA,QAC9C;AAEA,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,iBAAO;AAAA,QACT;AAAA,MACF,SAAQ;AAAA,MAER;AAEA,UAAI,UAAU,cAAc,GAAG;AAC7B,cAAM,IAAI;AAAA,UAAQ,CAAC,YACjB,WAAW,SAAS,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,cAAc,eAAe,UAAU,YAAY;AAC5D,UAAI;AACF,kBAAU,WAAW,KAAK,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC,CAAC;AAAA,MAC1E,SAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AF9GO,IAAM,0BAAN,cAA4C,gBAGjD;AAAA,EACA,YAAY,OAA2B;AACrC,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,MAAM;AAAA,EACjC;AAAA,EAEA,OAAO,2BAA+C;AACpD,WAAO,EAAE,UAAU,KAAK;AAAA,EAC1B;AAAA,EAEA,kBAAkB,OAAc,WAAkC;AAhCpE;AAiCI,QAAI;AACF,YAAM,UAAU,eAAe,KAAK,MAAM,YAAY;AAEtD,YAAM,UAAyB;AAAA,QAC7B,OAAO,KAAK,MAAM;AAAA,QAClB,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,cAAc,MAAM;AAAA,QACpB,YAAY,MAAM;AAAA,QAClB,iBAAgB,eAAU,mBAAV,YAA4B;AAAA,QAC5C,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,QACnB,aAAa,QAAQ;AAAA,QACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,QAClC,UAAU;AAAA,UACR,WAAW,QAAQ;AAAA,UACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,QACnD;AAAA,MACF;AAEA,iBAAW,SAAS,KAAK,MAAM,OAAO;AAEtC,UAAI,KAAK,MAAM,SAAS;AACtB,aAAK,MAAM,QAAQ,KAAK;AAAA,MAC1B;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,SAA0B;AACxB,QAAI,KAAK,MAAM,UAAU;AACvB,UAAI,KAAK,MAAM,UAAU;AACvB,eAAO,KAAK,MAAM;AAAA,MACpB;AAGA,aAAO,KAAK,MAAM;AAAA,IACpB;AAEA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;;;AD4LM,SAeqB,UAfrB;AA9ON,IAAMC,oBAAmB;AAEzB,IAAM,oBAAoB,cAA0C,IAAI;AAmBjE,SAAS,gBAAqC;AACnD,QAAM,MAAM,WAAW,iBAAiB;AACxC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa,oBAAoB;AAAA,EACjC,gBAAAC,kBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,kBAAkB,OAAiB,CAAC,CAAC;AAG3C,YAAU,MAAM;AACd,QAAI,mBAAmB;AACrB,sBAAgBA,eAAc;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,mBAAmBA,eAAc,CAAC;AAGtC,YAAU,MAAM;AACd,QAAI;AACF,UAAI,OAAO,WAAW,YAAa;AAEnC,YAAM,YAAY,MAAM;AACtB,YAAI;AACF,gBAAM,YAAY,YAAY,OAAO,SAAS,IAAI;AAClD,gBAAM,QAAQ,gBAAgB;AAC9B,cAAI,MAAM,MAAM,SAAS,CAAC,MAAM,WAAW;AACzC,kBAAM,KAAK,SAAS;AACpB,gBAAI,MAAM,SAAS,IAAI;AACrB,oBAAM,OAAO,GAAG,MAAM,SAAS,EAAE;AAAA,YACnC;AAAA,UACF;AAAA,QACF,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,gBAAU;AACV,YAAM,iBAAiB,MAAM,UAAU;AACvC,aAAO,iBAAiB,YAAY,cAAc;AAElD,YAAM,gBAAgB,QAAQ,UAAU,KAAK,OAAO;AACpD,YAAM,mBAAmB,QAAQ,aAAa,KAAK,OAAO;AAE1D,cAAQ,YAAY,YAAa,MAAM;AACrC,sBAAc,GAAG,IAAI;AACrB,kBAAU;AAAA,MACZ;AACA,cAAQ,eAAe,YAAa,MAAM;AACxC,yBAAiB,GAAG,IAAI;AACxB,kBAAU;AAAA,MACZ;AAEA,aAAO,MAAM;AACX,eAAO,oBAAoB,YAAY,cAAc;AACrD,gBAAQ,YAAY;AACpB,gBAAQ,eAAe;AAAA,MACzB;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI;AACF,UAAI,OAAO,WAAW,YAAa;AACnC,UAAI,QAAQ,IAAI,aAAa,cAAe;AAE5C,YAAM,cAAc,CAAC,UAAsB;AA9HjD;AA+HQ,YAAI;AACF,gBAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,gBAAM,UAAyB;AAAA,YAC7B;AAAA,YACA,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,cAAc,MAAM;AAAA,YACpB,aAAY,WAAM,UAAN,mBAAa;AAAA,YACzB,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,aAAa,QAAQ;AAAA,YACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,YAClC,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,cACjD,WAAU,WAAM,aAAN,YAAkB;AAAA,cAC5B,QAAQ,QAAO,WAAM,WAAN,YAAgB,EAAE;AAAA,cACjC,OAAO,QAAO,WAAM,UAAN,YAAe,EAAE;AAAA,cAC/B,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,cAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,cACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACtE;AAAA,UACF;AACA,qBAAW,SAAS,OAAO,EAAE,KAAK,CAAC,WAAW;AAC5C,gBAAI,UAAU,aAAc,cAAa,MAAM;AAAA,UACjD,CAAC;AACD,cAAI,WAAW,MAAM,MAAO,SAAQ,MAAM,KAAK;AAAA,QACjD,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,kBAAkB,CAAC,UAAiC;AA/JhE;AAgKQ,YAAI;AACF,gBAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,gBAAM,SAAS,MAAM;AACrB,gBAAM,UAAyB;AAAA,YAC7B;AAAA,YACA,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,cAAc,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AAAA,YACtE,YAAY,kBAAkB,QAAQ,OAAO,QAAQ;AAAA,YACrD,SAAS,QAAQ;AAAA,YACjB,WAAW,QAAQ;AAAA,YACnB,aAAa,QAAQ;AAAA,YACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,YAClC,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,cACjD,MAAM;AAAA,cACN,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,cAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,cACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACtE;AAAA,UACF;AACA,qBAAW,SAAS,OAAO,EAAE,KAAK,CAAC,WAAW;AAC5C,gBAAI,UAAU,aAAc,cAAa,MAAM;AAAA,UACjD,CAAC;AACD,cAAI,WAAW,kBAAkB,MAAO,SAAQ,MAAM;AAAA,QACxD,SAAQ;AAAA,QAER;AAAA,MACF;AAEA,aAAO,iBAAiB,SAAS,WAAW;AAC5C,aAAO,iBAAiB,sBAAsB,eAAe;AAE7D,aAAO,MAAM;AACX,eAAO,oBAAoB,SAAS,WAAW;AAC/C,eAAO,oBAAoB,sBAAsB,eAAe;AAAA,MAClE;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,SAAS,YAAY,CAAC;AAE1C,QAAM,SAAS;AAAA,IACb,OACE,MACA,aACA,aACiC;AAhNvC;AAiNM,UAAI;AACF,cAAM,UAAU,eAAe,gBAAgB,OAAO;AACtD,cAAM,UAAyB;AAAA,UAC7B;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,SAAS,QAAQ;AAAA,UACjB,WAAW,QAAQ;AAAA,UACnB,aAAa,QAAQ;AAAA,UACrB,aAAY,aAAQ,eAAR,YAAsB;AAAA,UAClC,UAAU;AAAA,YACR,WAAW,QAAQ;AAAA,YACnB,cAAc,KAAK,UAAU,QAAQ,YAAY;AAAA,YACjD,IAAI,mCAAS,UAAS,EAAE,eAAe,QAAQ,OAAO,IAAI,CAAC;AAAA,YAC3D,IAAI,mCAAS,QAAO,EAAE,iBAAiB,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,YACjE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACpE,IAAI,mCAAS,SAAQ,EAAE,kBAAkB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,YACpE,GAAG;AAAA,UACL;AAAA,QACF;AACA,cAAM,SAAS,MAAM,WAAW,SAAS,OAAO;AAChD,YAAI,UAAU,aAAc,cAAa,MAAM;AAC/C,eAAO;AAAA,MACT,SAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,OAAO,SAAS,YAAY;AAAA,EAC/B;AAEA,QAAM,YAAY;AAAA,IAChB,CAAC,aAAqB,aACpB,OAAO,OAAO,aAAa,QAAQ;AAAA,IACrC,CAAC,MAAM;AAAA,EACT;AAEA,QAAMC,iBAAgB;AAAA,IACpB,CAAC,SAAiB,SAAkC;AAClD,oBAAsB,UAAU,SAAS,IAAI;AAAA,IAC/C;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA,SAAS,4BAAWF;AAAA,QACpB;AAAA,QACA;AAAA,QACA,eAAAE;AAAA,MACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,cAAc,gBAAgB;AAAA,UAE7B;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,mBAAmB,OAAgC;AAEjE,MAAI,CAAC,MAAM,MAAO,QAAO,gCAAG,gBAAM,UAAS;AAG3C,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,SAAS,MAAM,YAAY,OAAO,WAAW,cAAc,OAAO,SAAS,SAASF;AAAA,EACtF;AAEA,MAAI;AACF,WAAO,oBAAC,2BAAyB,GAAG,eAAe;AAAA,EACrD,SAAQ;AACN,WAAO,gCAAG,gBAAM,UAAS;AAAA,EAC3B;AACF;;;AIjSA,SAAS,YAAAG,WAAU,UAAAC,SAAQ,aAAAC,kBAAqD;AAmKxE,SAwGQ,YAAAC,WAxGR,OAAAC,MAoDM,YApDN;AA9JR,SAAS,oBAAgD;AACvD,MAAI;AACF,WAAO,cAAc;AAAA,EACvB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,YAAqB;AAC5B,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,KAAK,iBAAiB,SAAS,IAAI,EAAE;AAC3C,UAAM,QAAQ,GAAG,MAAM,MAAM;AAC7B,QAAI,SAAS,MAAM,UAAU,GAAG;AAC9B,YAAM,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM;AAClC,cAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,MAAO;AAAA,IAChD;AACA,WAAO,OAAO,WAAW,8BAA8B,EAAE;AAAA,EAC3D,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,MAAe;AAC/B,SAAO,OACH,EAAE,IAAI,WAAW,aAAa,WAAW,QAAQ,WAAW,MAAM,WAAW,WAAW,WAAW,QAAQ,WAAW,YAAY,WAAW,SAAS,WAAW,aAAa,UAAU,IACxL,EAAE,IAAI,WAAW,aAAa,WAAW,QAAQ,WAAW,MAAM,WAAW,WAAW,WAAW,QAAQ,WAAW,YAAY,WAAW,SAAS,WAAW,aAAa,UAAU;AAC9L;AAEO,SAAS,aAAa;AAAA,EAC3B,WAAW;AAAA,EACX,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAGG;AA7CH;AA8CE,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,EAAE;AACjD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,KAAK;AACtD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAwB,IAAI;AAChE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,eAAeC,QAAyB,IAAI;AAClD,QAAM,WAAWA,QAAuB,IAAI;AAC5C,QAAM,aAAa,kBAAkB;AAGrC,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,EAAE,UAAU,IAAI;AACtB,QAAM,SAAS,UAAU;AACzB,QAAM,IAAI,SAAS,MAAM;AAEzB,QAAM,mBAAmB,CAAC,MAA2C;AAhEvE,QAAAC;AAiEI,UAAM,QAAOA,MAAA,EAAE,OAAO,UAAT,gBAAAA,IAAiB;AAC9B,QAAI,CAAC,KAAM;AACX,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,SAAS,MAAM;AACpB,oBAAc,OAAO,MAAgB;AAAA,IACvC;AACA,WAAO,cAAc,IAAI;AACzB,MAAE,OAAO,QAAQ;AAAA,EACnB;AAEA,QAAM,mBAAmB,YAAY;AACnC,mBAAe,KAAK;AACpB,cAAU,KAAK;AACf,kBAAc,IAAI;AAElB,UAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC3C,QAAI;AACF,YAAM,EAAE,SAAS,YAAY,IAAI,MAAM,OAAO,iBAAiB;AAC/D,YAAM,SAAS,MAAM,YAAY,SAAS,MAAM;AAAA,QAC9C,OAAO;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AACD,oBAAc,OAAO,UAAU,cAAc,GAAG,CAAC;AAAA,IACnD,SAAQ;AAAA,IAER;AACA,cAAU,IAAI;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY;AAC7B,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,QAAI;AACF,YAAM,EAAE,SAAS,YAAY,IAAI,MAAM,OAAO,iBAAiB;AAC/D,YAAM,SAAS,MAAM,YAAY,SAAS,MAAM;AAAA,QAC9C,OAAO;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AACD,oBAAc,OAAO,UAAU,cAAc,GAAG,CAAC;AAAA,IACnD,SAAQ;AAAA,IAER;AACA,iBAAa,KAAK;AAClB,cAAU,IAAI;AAAA,EAChB;AAGA,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,CAAC,MAAqB;AACtC,UAAI,EAAE,QAAQ,UAAU;AACtB,YAAI,YAAa,gBAAe,KAAK;AAAA,YAChC,WAAU,KAAK;AAAA,MACtB;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM,SAAS,oBAAoB,WAAW,SAAS;AAAA,EAChE,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,QAAM,eAAe,MAAM;AACzB,QAAI;AACF,UAAI,CAAC,YAAY,KAAK,KAAK,aAAc;AAEzC,sBAAgB,IAAI;AACpB,gBAAU,YAAY,KAAK,GAAG,aAAa,EAAE,WAAW,IAAI,MAAS;AAErE,mBAAa,IAAI;AACjB,qBAAe,EAAE;AACjB,oBAAc,IAAI;AAClB,sBAAgB,KAAK;AAErB,iBAAW,MAAM;AACf,qBAAa,KAAK;AAClB,kBAAU,KAAK;AAAA,MACjB,GAAG,GAAI;AAAA,IACT,SAAQ;AACN,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,SAAQ,0CAAU,WAAW,WAArB,YAA+B;AAC7C,QAAM,UAAS,0CAAU,SAAS,YAAnB,YAA8B;AAE7C,QAAM,sBAAqC,WACvC,CAAC,IACD;AAAA,IACE,GAAI,SAAS,EAAE,MAAM,OAAO,IAAI,EAAE,OAAO,OAAO;AAAA,IAChD,GAAI,QAAQ,EAAE,KAAK,OAAO,IAAI,EAAE,QAAQ,OAAO;AAAA,EACjD;AAEJ,SACE,qBAAAL,WAAA,EAEG;AAAA,eACC,SAAS,EAAE,SAAS,YAAY,UAAU,CAAC,IAE3C,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IAID,UACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,QACnB;AAAA,QACA,SAAS,MAAM;AAAE,cAAI,CAAC,YAAa,WAAU,KAAK;AAAA,QAAG;AAAA,QAErD;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAClC,OAAO;AAAA,cACL,UAAU,WAAW,aAAa;AAAA,cAClC,GAAG;AAAA,cACH,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,UAAU;AAAA,cACV,iBAAiB,EAAE;AAAA,cACnB,cAAc;AAAA,cACd,WACE;AAAA,cACF,YACE;AAAA,cACF,UAAU;AAAA,cACV,OAAO,EAAE;AAAA,cACT,WAAW;AAAA,YACb;AAAA,YAGA;AAAA,8BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc,aAAa,EAAE,MAAM;AAAA,kBACrC;AAAA,kBAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,SAAS;AAAA,wBACT,gBAAgB;AAAA,wBAChB,YAAY;AAAA,sBACd;AAAA,sBAEA;AAAA,wCAAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,UAAU;AAAA,8BACV,YAAY;AAAA,8BACZ,OAAO,EAAE;AAAA,4BACX;AAAA,4BACD;AAAA;AAAA,wBAED;AAAA,wBACA,gBAAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,MAAK;AAAA,4BACL,SAAS,MAAM,UAAU,KAAK;AAAA,4BAC9B,OAAO;AAAA,8BACL,YAAY;AAAA,8BACZ,QAAQ;AAAA,8BACR,QAAQ;AAAA,8BACR,SAAS;AAAA,8BACT,SAAS;AAAA,8BACT,YAAY;AAAA,8BACZ,gBAAgB;AAAA,4BAClB;AAAA,4BACA,cAAW;AAAA,4BAEX,0BAAAA,KAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,OAAO,EAAE,SAAS,QAAQ,GACpF,0BAAAA,KAAC,UAAK,GAAE,wBAAuB,QAAQ,EAAE,WAAW,aAAY,KAAI,eAAc,SAAQ,GAC5F;AAAA;AAAA,wBACF;AAAA;AAAA;AAAA,kBACF;AAAA;AAAA,cACF;AAAA,cAGA,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,OAAO,GAC3B,sBACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,WAAW;AAAA,oBACX,SAAS;AAAA,oBACT,OAAO,EAAE;AAAA,oBACT,UAAU;AAAA,oBACV,YAAY;AAAA,kBACd;AAAA,kBACD;AAAA;AAAA,cAED,IAEA,qBAAAD,WAAA,EAEG;AAAA,8BACC,qBAAC,SAAI,OAAO,EAAE,cAAc,QAAQ,UAAU,WAAW,GACvD;AAAA,kCAAAC;AAAA,oBAAC;AAAA;AAAA,sBACC,KAAK;AAAA,sBACL,KAAI;AAAA,sBACJ,SAAS,MAAM,eAAe,IAAI;AAAA,sBAClC,OAAO;AAAA,wBACL,OAAO;AAAA,wBACP,cAAc;AAAA,wBACd,QAAQ,aAAa,EAAE,MAAM;AAAA,wBAC7B,WAAW;AAAA,wBACX,WAAW;AAAA,wBACX,gBAAgB;AAAA,wBAChB,QAAQ;AAAA,sBACV;AAAA;AAAA,kBACF;AAAA,kBACA,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS,MAAM,cAAc,IAAI;AAAA,sBACjC,OAAO;AAAA,wBACL,UAAU;AAAA,wBACV,KAAK;AAAA,wBACL,OAAO;AAAA,wBACP,YAAY;AAAA,wBACZ,QAAQ;AAAA,wBACR,cAAc;AAAA,wBACd,OAAO;AAAA,wBACP,QAAQ;AAAA,wBACR,QAAQ;AAAA,wBACR,SAAS;AAAA,wBACT,YAAY;AAAA,wBACZ,gBAAgB;AAAA,sBAClB;AAAA,sBACA,cAAW;AAAA,sBAEX,0BAAAA,KAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QACnD,0BAAAA,KAAC,UAAK,GAAE,oBAAmB,QAAO,QAAO,aAAY,OAAM,eAAc,SAAQ,GACnF;AAAA;AAAA,kBACF;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,UAAU;AAAA,wBACV,QAAQ;AAAA,wBACR,MAAM;AAAA,wBACN,OAAO;AAAA,wBACP,SAAS;AAAA,wBACT,gBAAgB;AAAA,wBAChB,YAAY;AAAA,sBACd;AAAA,sBAEA;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,YAAY;AAAA,8BACZ,OAAO;AAAA,8BACP,UAAU;AAAA,8BACV,SAAS;AAAA,8BACT,cAAc;AAAA,4BAChB;AAAA,4BACD;AAAA;AAAA,8BACc,KAAK,MAAM,WAAW,SAAS,OAAO,IAAI;AAAA,8BAAE;AAAA;AAAA;AAAA,wBAC3D;AAAA,wBACA,qBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,MAAM,GACxC;AAAA,0CAAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,MAAK;AAAA,8BACL,SAAS,MAAG;AA/UxC,oCAAAG;AA+U2C,wCAAAA,MAAA,aAAa,YAAb,gBAAAA,IAAsB;AAAA;AAAA,8BACrC,OAAO;AAAA,gCACL,YAAY,EAAE;AAAA,gCACd,OAAO,EAAE;AAAA,gCACT,UAAU;AAAA,gCACV,SAAS;AAAA,gCACT,cAAc;AAAA,gCACd,QAAQ;AAAA,gCACR,QAAQ;AAAA,gCACR,YAAY;AAAA,8BACd;AAAA,8BACD;AAAA;AAAA,0BAED;AAAA,0BACA,gBAAAH;AAAA,4BAAC;AAAA;AAAA,8BACC,MAAK;AAAA,8BACL,SAAS;AAAA,8BACT,OAAO;AAAA,gCACL,YAAY,EAAE;AAAA,gCACd,OAAO,EAAE;AAAA,gCACT,UAAU;AAAA,gCACV,SAAS;AAAA,gCACT,cAAc;AAAA,gCACd,QAAQ;AAAA,gCACR,QAAQ;AAAA,gCACR,YAAY;AAAA,8BACd;AAAA,8BACD;AAAA;AAAA,0BAED;AAAA,2BACF;AAAA;AAAA;AAAA,kBACF;AAAA,mBACF;AAAA,gBAED,CAAC,cAAc,CAAC,aACf,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAG;AApXlC,0BAAAG;AAoXqC,8BAAAA,MAAA,aAAa,YAAb,gBAAAA,IAAsB;AAAA;AAAA,oBACrC,OAAO;AAAA,sBACL,cAAc;AAAA,sBACd,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ,cAAc,EAAE,WAAW;AAAA,sBACnC,WAAW;AAAA,sBACX,UAAU;AAAA,sBACV,OAAO,EAAE;AAAA,sBACT,OAAO;AAAA,sBACP,YAAY;AAAA,sBACZ,QAAQ;AAAA,oBACV;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA,gBAEF,gBAAAH;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,oBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,oBAC9C,aAAY;AAAA,oBACZ,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,WAAW;AAAA,sBACX,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ,aAAa,EAAE,WAAW;AAAA,sBAClC,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,QAAQ;AAAA,sBACR,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,OAAO,EAAE;AAAA,sBACT,iBAAiB,EAAE;AAAA,oBACrB;AAAA,oBACA,SAAS,CAAC,MAAM;AACd,sBAAC,EAAE,OAA+B,MAAM,cAAc,EAAE;AAAA,oBAC1D;AAAA,oBACA,QAAQ,CAAC,MAAM;AACb,sBAAC,EAAE,OAA+B,MAAM,cAAc,EAAE;AAAA,oBAC1D;AAAA,oBACA,WAAS;AAAA;AAAA,gBACX;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS;AAAA,oBACT,UAAU,CAAC,YAAY,KAAK,KAAK;AAAA,oBACjC,OAAO;AAAA,sBACL,WAAW;AAAA,sBACX,OAAO;AAAA,sBACP,SAAS;AAAA,sBACT,cAAc;AAAA,sBACd,QAAQ;AAAA,sBACR,iBACE,CAAC,YAAY,KAAK,KAAK,eACnB,EAAE,cACF,EAAE;AAAA,sBACR,OACE,CAAC,YAAY,KAAK,KAAK,eACnB,EAAE,YACF,EAAE;AAAA,sBACR,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,QACE,CAAC,YAAY,KAAK,KAAK,eACnB,gBACA;AAAA,sBACN,YAAY;AAAA,sBACZ,YAAY;AAAA,oBACd;AAAA,oBAEC,yBAAe,eAAe;AAAA;AAAA,gBACjC;AAAA,iBACF,GAEJ;AAAA,cAGA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,WAAW,aAAa,EAAE,MAAM;AAAA,oBAChC,WAAW;AAAA,kBACb;AAAA,kBAEA,0BAAAA,KAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,OAAO,EAAE,UAAU,GAAG,mCAEvD;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAIF,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,IAC3B;AAAA,IAGC,eAAe,cACd;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,QACA,SAAS,CAAC,MAAM;AAAE,YAAE,gBAAgB;AAAG,yBAAe,KAAK;AAAA,QAAG;AAAA,QAC9D,aAAa,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAEtC;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAI;AAAA,cACJ,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAClC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,WAAW;AAAA,gBACX,cAAc;AAAA,gBACd,WAAW;AAAA,gBACX,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,WAAW;AAAA,gBACX,OAAO,EAAE;AAAA,gBACT,UAAU;AAAA,cACZ;AAAA,cACD;AAAA;AAAA,UAED;AAAA;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;AAGA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,QAAM,iBAAgC;AAAA,IACpC,GAAI,SAAS,EAAE,MAAM,OAAO,IAAI,EAAE,OAAO,OAAO;AAAA,IAChD,GAAI,QAAQ,EAAE,KAAK,OAAO,IAAI,EAAE,QAAQ,OAAO;AAAA,EACjD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,YACE;AAAA,QACF,QAAQ,YAAY,SAAS;AAAA,QAC7B,WACE;AAAA,QACF,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS,YAAY,MAAM;AAAA,MAC7B;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,QAAC,EAAE,OAAuB,MAAM,YAAY;AAAA,MAC9C;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,QAAC,EAAE,OAAuB,MAAM,YAAY;AAAA,MAC9C;AAAA,MACA,cAAY;AAAA,MAEZ;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,OAAO,EAAE,YAAY,EAAE;AAAA,YAEvB,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,GAAE;AAAA,gBACF,MAAK;AAAA;AAAA,YACP;AAAA;AAAA,QACF;AAAA,QACC,YAAY,iBAAiB;AAAA;AAAA;AAAA,EAChC;AAEJ;","names":["e","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","useState","useRef","useEffect","Fragment","jsx","useState","useRef","_a","useEffect"]}
|